diff --git a/404.html b/404.html index a14a3777..f8eaa58a 100644 --- a/404.html +++ b/404.html @@ -4,13 +4,13 @@ Page Not Found | Credo - - + +
-
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/09958099.29abfa80.js b/assets/js/09958099.29abfa80.js new file mode 100644 index 00000000..8572e3ac --- /dev/null +++ b/assets/js/09958099.29abfa80.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[2743],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>h});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var d=i.createContext({}),p=function(e){var t=i.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},s=function(e){var t=p(e.components);return i.createElement(d.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},m=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,d=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),c=p(n),m=a,h=c["".concat(d,".").concat(m)]||c[m]||u[m]||r;return n?i.createElement(h,o(o({ref:t},s),{},{components:n})):i.createElement(h,o({ref:t},s))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,o=new Array(r);o[0]=m;var l={};for(var d in t)hasOwnProperty.call(t,d)&&(l[d]=t[d]);l.originalType=e,l[c]="string"==typeof e?e:a,o[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var i=n(7462),a=(n(7294),n(3905));const r={},o="Cheqd Did Module",l={unversionedId:"tutorials/cheqd/index",id:"version-0.4/tutorials/cheqd/index",title:"Cheqd Did Module",description:"In this tutorial we will see how to use the cheqd modules in detail",source:"@site/versioned_docs/version-0.4/tutorials/cheqd/index.md",sourceDirName:"tutorials/cheqd",slug:"/tutorials/cheqd/",permalink:"/guides/0.4/tutorials/cheqd/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Create a connection",permalink:"/guides/0.4/tutorials/create-a-connection"},next:{title:"Registering a schema and credential definition on an AnonCreds Registry",permalink:"/guides/0.4/tutorials/registering-schema-and-credential-definition"}},d={},p=[{value:"DID Module",id:"did-module",level:2},{value:"Create DID",id:"create-did",level:3},{value:"Parameters",id:"parameters",level:4},{value:"Option 1",id:"option-1",level:5},{value:"Option 2",id:"option-2",level:5},{value:"Update DID",id:"update-did",level:3},{value:"Parameters",id:"parameters-1",level:4},{value:"Deactivate DID",id:"deactivate-did",level:3},{value:"Parameters",id:"parameters-2",level:4},{value:"Types",id:"types",level:3},{value:"secret.verificationMethod",id:"secretverificationmethod",level:4},{value:"verificationMethod.id*",id:"verificationmethodid",level:5},{value:"verificationMethod.type*",id:"verificationmethodtype",level:5},{value:"verificationMethod.privateKey",id:"verificationmethodprivatekey",level:5},{value:"options.methodSpecificIdAlgo",id:"optionsmethodspecificidalgo",level:4},{value:"options.network*",id:"optionsnetwork",level:4},{value:"options.versionId",id:"optionsversionid",level:4}],s={toc:p},c="wrapper";function u(e){let{components:t,...n}=e;return(0,a.kt)(c,(0,i.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"cheqd-did-module"},"Cheqd Did Module"),(0,a.kt)("p",null,"In this tutorial we will see how to use the cheqd modules in detail"),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"This section assumes that"),(0,a.kt)("ol",{parentName:"admonition"},(0,a.kt)("li",{parentName:"ol"},"You have ",(0,a.kt)("a",{parentName:"li",href:"../../getting-started"},"set-up your develoment environment"),"."),(0,a.kt)("li",{parentName:"ol"},"You have setup the cheqd module ",(0,a.kt)("a",{parentName:"li",href:"/guides/0.4/getting-started/set-up/cheqd/"},"setup cheqd")))),(0,a.kt)("h2",{id:"did-module"},"DID Module"),(0,a.kt)("p",null,'The cheqd DID module facilitates the Create, Read, Update, and Delete (CRUD) operations for did:cheqd identifiers. To learn more about "did:cheqd," please refer to the ',(0,a.kt)("a",{parentName:"p",href:"https://github.com/cheqd/identity-docs/blob/main/architecture/adr-list/adr-001-cheqd-did-method.md"},"specification")),(0,a.kt)("h3",{id:"create-did"},"Create DID"),(0,a.kt)("p",null,"The DID can be created in two different ways"),(0,a.kt)("h4",{id:"parameters"},"Parameters"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"method"),"*",": ",(0,a.kt)("inlineCode",{parentName:"li"},"cheqd")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"secret")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"options"),"*"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"didDocument"))),(0,a.kt)("h5",{id:"option-1"},"Option 1"),(0,a.kt)("p",null,"Provide a DID Document payload according to the w3c did core specification in the request body. This is possible when the keys corresponding to the verification methods provided in the DID Document are already created in the wallet"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-cheqd.ts section-2",showLineNumbers:!0,"set-up-cheqd.ts":!0,"section-2":!0},"")),(0,a.kt)("h5",{id:"option-2"},"Option 2"),(0,a.kt)("p",null,"If a DID Document is not passed to the registrar, it requires the secret parameter with a verificationMethod to construct the DID Document."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-cheqd.ts section-3",showLineNumbers:!0,"set-up-cheqd.ts":!0,"section-3":!0},"")),(0,a.kt)("h3",{id:"update-did"},"Update DID"),(0,a.kt)("p",null,"To update a DID Document, fetch the body of the DID Document you want to change from the DID Resolver, make the relevant updates and pass it as the parameter"),(0,a.kt)("h4",{id:"parameters-1"},"Parameters"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"did"),"*"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"didDocument"),"*",": The updated DID Document"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"options")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"secret"))),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-cheqd.ts section-4",showLineNumbers:!0,"set-up-cheqd.ts":!0,"section-4":!0},"")),(0,a.kt)("h3",{id:"deactivate-did"},"Deactivate DID"),(0,a.kt)("p",null,"A DID can be deactivated, it can still be resolved"),(0,a.kt)("h4",{id:"parameters-2"},"Parameters"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"did"),"*"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"options"))),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-cheqd.ts section-5",showLineNumbers:!0,"set-up-cheqd.ts":!0,"section-5":!0},"")),(0,a.kt)("h3",{id:"types"},"Types"),(0,a.kt)("hr",null),(0,a.kt)("h4",{id:"secretverificationmethod"},(0,a.kt)("inlineCode",{parentName:"h4"},"secret.verificationMethod")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"verificationMethod")),(0,a.kt)("h5",{id:"verificationmethodid"},(0,a.kt)("inlineCode",{parentName:"h5"},"verificationMethod.id"),"*"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("h5",{id:"verificationmethodtype"},(0,a.kt)("inlineCode",{parentName:"h5"},"verificationMethod.type"),"*"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Default"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"Ed25519VerificationKey2020")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Members"),":"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"Ed25519VerificationKey2020")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"Ed25519VerificationKey2018")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"JsonWebKey2020"))),(0,a.kt)("h5",{id:"verificationmethodprivatekey"},(0,a.kt)("inlineCode",{parentName:"h5"},"verificationMethod.privateKey")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("hr",null),(0,a.kt)("h4",{id:"optionsmethodspecificidalgo"},(0,a.kt)("inlineCode",{parentName:"h4"},"options.methodSpecificIdAlgo")),(0,a.kt)("p",null,"Specifies what type of method specific identifier is needed for your DID"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Default"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"uuid")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Members"),":"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"uuid")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"base58btc"))),(0,a.kt)("hr",null),(0,a.kt)("h4",{id:"optionsnetwork"},(0,a.kt)("inlineCode",{parentName:"h4"},"options.network"),"*"),(0,a.kt)("p",null,"Specifies the cheqd network name to be published"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Default"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"testnet")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Members"),":"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"testnet")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"mainnet"))),(0,a.kt)("hr",null),(0,a.kt)("h4",{id:"optionsversionid"},(0,a.kt)("inlineCode",{parentName:"h4"},"options.versionId")),(0,a.kt)("p",null,"Specifies the version of the DID Document to be published"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/09958099.3cb1e01a.js b/assets/js/09958099.3cb1e01a.js deleted file mode 100644 index 07fd791d..00000000 --- a/assets/js/09958099.3cb1e01a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[2743],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>h});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var d=i.createContext({}),p=function(e){var t=i.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},s=function(e){var t=p(e.components);return i.createElement(d.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},m=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,d=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),c=p(n),m=a,h=c["".concat(d,".").concat(m)]||c[m]||u[m]||r;return n?i.createElement(h,o(o({ref:t},s),{},{components:n})):i.createElement(h,o({ref:t},s))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,o=new Array(r);o[0]=m;var l={};for(var d in t)hasOwnProperty.call(t,d)&&(l[d]=t[d]);l.originalType=e,l[c]="string"==typeof e?e:a,o[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var i=n(7462),a=(n(7294),n(3905));const r={},o="Cheqd Did Module",l={unversionedId:"tutorials/cheqd/index",id:"version-0.4/tutorials/cheqd/index",title:"Cheqd Did Module",description:"In this tutorial we will see how to use the cheqd modules in detail",source:"@site/versioned_docs/version-0.4/tutorials/cheqd/index.md",sourceDirName:"tutorials/cheqd",slug:"/tutorials/cheqd/",permalink:"/guides/tutorials/cheqd/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Create a connection",permalink:"/guides/tutorials/create-a-connection"},next:{title:"Registering a schema and credential definition on an AnonCreds Registry",permalink:"/guides/tutorials/registering-schema-and-credential-definition"}},d={},p=[{value:"DID Module",id:"did-module",level:2},{value:"Create DID",id:"create-did",level:3},{value:"Parameters",id:"parameters",level:4},{value:"Option 1",id:"option-1",level:5},{value:"Option 2",id:"option-2",level:5},{value:"Update DID",id:"update-did",level:3},{value:"Parameters",id:"parameters-1",level:4},{value:"Deactivate DID",id:"deactivate-did",level:3},{value:"Parameters",id:"parameters-2",level:4},{value:"Types",id:"types",level:3},{value:"secret.verificationMethod",id:"secretverificationmethod",level:4},{value:"verificationMethod.id*",id:"verificationmethodid",level:5},{value:"verificationMethod.type*",id:"verificationmethodtype",level:5},{value:"verificationMethod.privateKey",id:"verificationmethodprivatekey",level:5},{value:"options.methodSpecificIdAlgo",id:"optionsmethodspecificidalgo",level:4},{value:"options.network*",id:"optionsnetwork",level:4},{value:"options.versionId",id:"optionsversionid",level:4}],s={toc:p},c="wrapper";function u(e){let{components:t,...n}=e;return(0,a.kt)(c,(0,i.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"cheqd-did-module"},"Cheqd Did Module"),(0,a.kt)("p",null,"In this tutorial we will see how to use the cheqd modules in detail"),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"This section assumes that"),(0,a.kt)("ol",{parentName:"admonition"},(0,a.kt)("li",{parentName:"ol"},"You have ",(0,a.kt)("a",{parentName:"li",href:"../../getting-started"},"set-up your develoment environment"),"."),(0,a.kt)("li",{parentName:"ol"},"You have setup the cheqd module ",(0,a.kt)("a",{parentName:"li",href:"/guides/getting-started/set-up/cheqd/"},"setup cheqd")))),(0,a.kt)("h2",{id:"did-module"},"DID Module"),(0,a.kt)("p",null,'The cheqd DID module facilitates the Create, Read, Update, and Delete (CRUD) operations for did:cheqd identifiers. To learn more about "did:cheqd," please refer to the ',(0,a.kt)("a",{parentName:"p",href:"https://github.com/cheqd/identity-docs/blob/main/architecture/adr-list/adr-001-cheqd-did-method.md"},"specification")),(0,a.kt)("h3",{id:"create-did"},"Create DID"),(0,a.kt)("p",null,"The DID can be created in two different ways"),(0,a.kt)("h4",{id:"parameters"},"Parameters"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"method"),"*",": ",(0,a.kt)("inlineCode",{parentName:"li"},"cheqd")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"secret")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"options"),"*"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"didDocument"))),(0,a.kt)("h5",{id:"option-1"},"Option 1"),(0,a.kt)("p",null,"Provide a DID Document payload according to the w3c did core specification in the request body. This is possible when the keys corresponding to the verification methods provided in the DID Document are already created in the wallet"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-cheqd.ts section-2",showLineNumbers:!0,"set-up-cheqd.ts":!0,"section-2":!0},"")),(0,a.kt)("h5",{id:"option-2"},"Option 2"),(0,a.kt)("p",null,"If a DID Document is not passed to the registrar, it requires the secret parameter with a verificationMethod to construct the DID Document."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-cheqd.ts section-3",showLineNumbers:!0,"set-up-cheqd.ts":!0,"section-3":!0},"")),(0,a.kt)("h3",{id:"update-did"},"Update DID"),(0,a.kt)("p",null,"To update a DID Document, fetch the body of the DID Document you want to change from the DID Resolver, make the relevant updates and pass it as the parameter"),(0,a.kt)("h4",{id:"parameters-1"},"Parameters"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"did"),"*"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"didDocument"),"*",": The updated DID Document"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"options")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"secret"))),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-cheqd.ts section-4",showLineNumbers:!0,"set-up-cheqd.ts":!0,"section-4":!0},"")),(0,a.kt)("h3",{id:"deactivate-did"},"Deactivate DID"),(0,a.kt)("p",null,"A DID can be deactivated, it can still be resolved"),(0,a.kt)("h4",{id:"parameters-2"},"Parameters"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"did"),"*"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"options"))),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-cheqd.ts section-5",showLineNumbers:!0,"set-up-cheqd.ts":!0,"section-5":!0},"")),(0,a.kt)("h3",{id:"types"},"Types"),(0,a.kt)("hr",null),(0,a.kt)("h4",{id:"secretverificationmethod"},(0,a.kt)("inlineCode",{parentName:"h4"},"secret.verificationMethod")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"verificationMethod")),(0,a.kt)("h5",{id:"verificationmethodid"},(0,a.kt)("inlineCode",{parentName:"h5"},"verificationMethod.id"),"*"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("h5",{id:"verificationmethodtype"},(0,a.kt)("inlineCode",{parentName:"h5"},"verificationMethod.type"),"*"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Default"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"Ed25519VerificationKey2020")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Members"),":"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"Ed25519VerificationKey2020")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"Ed25519VerificationKey2018")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"JsonWebKey2020"))),(0,a.kt)("h5",{id:"verificationmethodprivatekey"},(0,a.kt)("inlineCode",{parentName:"h5"},"verificationMethod.privateKey")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("hr",null),(0,a.kt)("h4",{id:"optionsmethodspecificidalgo"},(0,a.kt)("inlineCode",{parentName:"h4"},"options.methodSpecificIdAlgo")),(0,a.kt)("p",null,"Specifies what type of method specific identifier is needed for your DID"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Default"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"uuid")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Members"),":"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"uuid")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"base58btc"))),(0,a.kt)("hr",null),(0,a.kt)("h4",{id:"optionsnetwork"},(0,a.kt)("inlineCode",{parentName:"h4"},"options.network"),"*"),(0,a.kt)("p",null,"Specifies the cheqd network name to be published"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Default"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"testnet")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Members"),":"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"testnet")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"mainnet"))),(0,a.kt)("hr",null),(0,a.kt)("h4",{id:"optionsversionid"},(0,a.kt)("inlineCode",{parentName:"h4"},"options.versionId")),(0,a.kt)("p",null,"Specifies the version of the DID Document to be published"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0a88801c.6008b0ff.js b/assets/js/0a88801c.f6f04a11.js similarity index 65% rename from assets/js/0a88801c.6008b0ff.js rename to assets/js/0a88801c.f6f04a11.js index a5070429..264c3f44 100644 --- a/assets/js/0a88801c.6008b0ff.js +++ b/assets/js/0a88801c.f6f04a11.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[2215],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),d=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=d(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),u=d(n),m=a,h=u["".concat(l,".").concat(m)]||u[m]||p[m]||i;return n?r.createElement(h,s(s({ref:t},c),{},{components:n})):r.createElement(h,s({ref:t},c))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,s=new Array(i);s[0]=m;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[u]="string"==typeof e?e:a,s[1]=o;for(var d=2;d{n.d(t,{Z:()=>y});var r=n(7294),a=n(6010),i=n(3438),s=n(9960),o=n(3919),l=n(5999);const d={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function c(e){let{href:t,children:n}=e;return r.createElement(s.Z,{href:t,className:(0,a.Z)("card padding--lg",d.cardContainer)},n)}function u(e){let{href:t,icon:n,title:i,description:s}=e;return r.createElement(c,{href:t},r.createElement("h2",{className:(0,a.Z)("text--truncate",d.cardTitle),title:i},n," ",i),s&&r.createElement("p",{className:(0,a.Z)("text--truncate",d.cardDescription),title:s},s))}function p(e){let{item:t}=e;const n=(0,i.Wl)(t);return n?r.createElement(u,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,l.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function m(e){let{item:t}=e;const n=(0,o.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",a=(0,i.xz)(t.docId??void 0);return r.createElement(u,{href:t.href,icon:n,title:t.label,description:a?.description})}function h(e){let{item:t}=e;switch(t.type){case"link":return r.createElement(m,{item:t});case"category":return r.createElement(p,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function f(e){let{className:t}=e;const n=(0,i.jA)();return r.createElement(y,{items:n.items,className:t})}function y(e){const{items:t,className:n}=e;if(!t)return r.createElement(f,e);const s=(0,i.MN)(t);return r.createElement("section",{className:(0,a.Z)("row",n)},s.map(((e,t)=>r.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},r.createElement(h,{item:e})))))}},5162:(e,t,n)=>{n.d(t,{Z:()=>s});var r=n(7294),a=n(6010);const i={tabItem:"tabItem_Ymn6"};function s(e){let{children:t,hidden:n,className:s}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(i.tabItem,s),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var r=n(7462),a=n(7294),i=n(6010),s=n(2466),o=n(6550),l=n(1980),d=n(7392),c=n(12);function u(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function p(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??u(n);return function(e){const t=(0,d.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const r=(0,o.k6)(),i=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,l._X)(i),(0,a.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(r.location.search);t.set(i,e),r.replace({...r.location,search:t.toString()})}),[i,r])]}function f(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,i=p(e),[s,o]=(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(!m({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 r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:i}))),[l,d]=h({queryString:n,groupId:r}),[u,f]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,i]=(0,c.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:r}),y=(()=>{const e=l??u;return m({value:e,tabValues:i})?e:null})();(0,a.useLayoutEffect)((()=>{y&&o(y)}),[y]);return{selectedValue:s,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);o(e),d(e),f(e)}),[d,f,i]),tabValues:i}}var y=n(2389);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function b(e){let{className:t,block:n,selectedValue:o,selectValue:l,tabValues:d}=e;const c=[],{blockElementScrollPositionUntilNextRender:u}=(0,s.o5)(),p=e=>{const t=e.currentTarget,n=c.indexOf(t),r=d[n].value;r!==o&&(u(t),l(r))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},d.map((e=>{let{value:t,label:n,attributes:s}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:o===t?0:-1,"aria-selected":o===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:p},s,{className:(0,i.Z)("tabs__item",g.tabItem,s?.className,{"tabs__item--active":o===t})}),n??t)})))}function k(e){let{lazy:t,children:n,selectedValue:r}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function v(e){const t=f(e);return a.createElement("div",{className:(0,i.Z)("tabs-container",g.tabList)},a.createElement(b,(0,r.Z)({},e,t)),a.createElement(k,(0,r.Z)({},e,t)))}function w(e){const t=(0,y.Z)();return a.createElement(v,(0,r.Z)({key:String(t)},e))}},1824:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>d,default:()=>f,frontMatter:()=>l,metadata:()=>c,toc:()=>p});var r=n(7462),a=(n(7294),n(3905)),i=n(4866),s=n(5162),o=n(2991);const l={},d="Indy SDK",c={unversionedId:"getting-started/set-up/indy-sdk/index",id:"version-0.4/getting-started/set-up/indy-sdk/index",title:"Indy SDK",description:"Indy SDK provides a distributed ledger based foundation for self-sovereign identity. It can provide the Wallet and StorageService implementations for the agent, as well as a way to interact with Indy ledgers and an implementation of the legacy (v0.1) AnonCreds Specification",source:"@site/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/index.md",sourceDirName:"getting-started/set-up/indy-sdk",slug:"/getting-started/set-up/indy-sdk/",permalink:"/guides/getting-started/set-up/indy-sdk/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Aries Askar",permalink:"/guides/getting-started/set-up/aries-askar"},next:{title:"Linux",permalink:"/guides/getting-started/set-up/indy-sdk/linux"}},u={},p=[{value:"Installing the Indy SDK",id:"installing-the-indy-sdk",level:3},{value:"Adding the Indy SDK to the Agent",id:"adding-the-indy-sdk-to-the-agent",level:3}],m={toc:p},h="wrapper";function f(e){let{components:t,...n}=e;return(0,a.kt)(h,(0,r.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"indy-sdk"},"Indy SDK"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk"},"Indy SDK")," provides a distributed ledger based foundation for self-sovereign identity. It can provide the ",(0,a.kt)("inlineCode",{parentName:"p"},"Wallet")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"StorageService")," implementations for the agent, as well as a way to interact with Indy ledgers and an implementation of the legacy (v0.1) ",(0,a.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-spec/"},"AnonCreds Specification")),(0,a.kt)("admonition",{type:"caution"},(0,a.kt)("p",{parentName:"admonition"},"The Indy SDK integration in Aries Framework JavaScript is currently in maintenance mode. We recommend new projects to use ",(0,a.kt)("a",{parentName:"p",href:"../aries-askar"},"Aries Askar")," from the start, and also to migrate existing projects to Aries Askar.")),(0,a.kt)("admonition",{type:"caution"},(0,a.kt)("p",{parentName:"admonition"},"The AnonCreds implementation from the Indy SDK only supports the ",(0,a.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-methods-registry/#hyperledger-indy-legacy-anoncreds-method"},"Hyperledger Indy Legacy AnonCreds Method")," (the pre-standardized implementation), and doesn't support the new Ledger ",(0,a.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-spec/"},"Agnostic AnonCreds Specification (v1.0)"),". Use the new AnonCreds Rust implementation, which is also supported by Aries Framework JavaScript, in combination with ",(0,a.kt)("a",{parentName:"p",href:"../aries-askar"},"Aries Askar")," and Indy VDR to replace the bevhaviour of the Indy SDK, and support the new features these libraries have to offer.")),(0,a.kt)("h3",{id:"installing-the-indy-sdk"},"Installing the Indy SDK"),(0,a.kt)("p",null,"When using Aries Framework JavaScript with the Indy SDK, there's a few extra dependencies that need to be installed. We need to install the ",(0,a.kt)("inlineCode",{parentName:"p"},"@aries-framework/indy-sdk")," package, which implements the needed interfaces for the agent. Secondly, we need to install the native Indy SDK library and the bindings for our specific platform. Currently there are bindings for Node.JS and React Native."),(0,a.kt)("p",null,"To start off, install the native Indy SDK library. The setup for this depends on the platform you are using. Follow the instructions for your platform below."),(0,a.kt)(o.Z,{mdxType:"DocCardList"}),(0,a.kt)("p",null,"After the native Indy SDK library is installed, we can add the Indy SDK libraries."),(0,a.kt)(i.Z,{mdxType:"Tabs"},(0,a.kt)(s.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @aries-framework/indy-sdk@^0.4.0 indy-sdk\n")),(0,a.kt)("p",null,"And install the needed types"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add --dev @types/indy-sdk\n"))),(0,a.kt)(s.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @aries-framework/indy-sdk@^0.4.0 indy-sdk-react-native\n")),(0,a.kt)("p",null,"And then install the needed types"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add --dev @types/indy-sdk-react-native@npm:@types/indy-sdk\n")))),(0,a.kt)("h3",{id:"adding-the-indy-sdk-to-the-agent"},"Adding the Indy SDK to the Agent"),(0,a.kt)("p",null,"After installing the dependencies, we can register the Indy SDK Module on the agent."),(0,a.kt)(i.Z,{mdxType:"Tabs"},(0,a.kt)(s.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-indy-sdk.ts section-1",showLineNumbers:!0,"set-up-indy-sdk.ts":!0,"section-1":!0},""))),(0,a.kt)(s.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-indy-sdk-rn.ts section-1",showLineNumbers:!0,"set-up-indy-sdk-rn.ts":!0,"section-1":!0},"")))))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[2215],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),d=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=d(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),u=d(n),m=a,h=u["".concat(l,".").concat(m)]||u[m]||p[m]||i;return n?r.createElement(h,s(s({ref:t},c),{},{components:n})):r.createElement(h,s({ref:t},c))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,s=new Array(i);s[0]=m;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[u]="string"==typeof e?e:a,s[1]=o;for(var d=2;d{n.d(t,{Z:()=>y});var r=n(7294),a=n(6010),i=n(3438),s=n(9960),o=n(3919),l=n(5999);const d={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function c(e){let{href:t,children:n}=e;return r.createElement(s.Z,{href:t,className:(0,a.Z)("card padding--lg",d.cardContainer)},n)}function u(e){let{href:t,icon:n,title:i,description:s}=e;return r.createElement(c,{href:t},r.createElement("h2",{className:(0,a.Z)("text--truncate",d.cardTitle),title:i},n," ",i),s&&r.createElement("p",{className:(0,a.Z)("text--truncate",d.cardDescription),title:s},s))}function p(e){let{item:t}=e;const n=(0,i.Wl)(t);return n?r.createElement(u,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,l.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function m(e){let{item:t}=e;const n=(0,o.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",a=(0,i.xz)(t.docId??void 0);return r.createElement(u,{href:t.href,icon:n,title:t.label,description:a?.description})}function h(e){let{item:t}=e;switch(t.type){case"link":return r.createElement(m,{item:t});case"category":return r.createElement(p,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function f(e){let{className:t}=e;const n=(0,i.jA)();return r.createElement(y,{items:n.items,className:t})}function y(e){const{items:t,className:n}=e;if(!t)return r.createElement(f,e);const s=(0,i.MN)(t);return r.createElement("section",{className:(0,a.Z)("row",n)},s.map(((e,t)=>r.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},r.createElement(h,{item:e})))))}},5162:(e,t,n)=>{n.d(t,{Z:()=>s});var r=n(7294),a=n(6010);const i={tabItem:"tabItem_Ymn6"};function s(e){let{children:t,hidden:n,className:s}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(i.tabItem,s),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var r=n(7462),a=n(7294),i=n(6010),s=n(2466),o=n(6550),l=n(1980),d=n(7392),c=n(12);function u(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function p(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??u(n);return function(e){const t=(0,d.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const r=(0,o.k6)(),i=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,l._X)(i),(0,a.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(r.location.search);t.set(i,e),r.replace({...r.location,search:t.toString()})}),[i,r])]}function f(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,i=p(e),[s,o]=(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(!m({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 r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:i}))),[l,d]=h({queryString:n,groupId:r}),[u,f]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,i]=(0,c.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:r}),y=(()=>{const e=l??u;return m({value:e,tabValues:i})?e:null})();(0,a.useLayoutEffect)((()=>{y&&o(y)}),[y]);return{selectedValue:s,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);o(e),d(e),f(e)}),[d,f,i]),tabValues:i}}var y=n(2389);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function b(e){let{className:t,block:n,selectedValue:o,selectValue:l,tabValues:d}=e;const c=[],{blockElementScrollPositionUntilNextRender:u}=(0,s.o5)(),p=e=>{const t=e.currentTarget,n=c.indexOf(t),r=d[n].value;r!==o&&(u(t),l(r))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},d.map((e=>{let{value:t,label:n,attributes:s}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:o===t?0:-1,"aria-selected":o===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:p},s,{className:(0,i.Z)("tabs__item",g.tabItem,s?.className,{"tabs__item--active":o===t})}),n??t)})))}function k(e){let{lazy:t,children:n,selectedValue:r}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function v(e){const t=f(e);return a.createElement("div",{className:(0,i.Z)("tabs-container",g.tabList)},a.createElement(b,(0,r.Z)({},e,t)),a.createElement(k,(0,r.Z)({},e,t)))}function w(e){const t=(0,y.Z)();return a.createElement(v,(0,r.Z)({key:String(t)},e))}},1824:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>d,default:()=>f,frontMatter:()=>l,metadata:()=>c,toc:()=>p});var r=n(7462),a=(n(7294),n(3905)),i=n(4866),s=n(5162),o=n(2991);const l={},d="Indy SDK",c={unversionedId:"getting-started/set-up/indy-sdk/index",id:"version-0.4/getting-started/set-up/indy-sdk/index",title:"Indy SDK",description:"Indy SDK provides a distributed ledger based foundation for self-sovereign identity. It can provide the Wallet and StorageService implementations for the agent, as well as a way to interact with Indy ledgers and an implementation of the legacy (v0.1) AnonCreds Specification",source:"@site/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/index.md",sourceDirName:"getting-started/set-up/indy-sdk",slug:"/getting-started/set-up/indy-sdk/",permalink:"/guides/0.4/getting-started/set-up/indy-sdk/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Aries Askar",permalink:"/guides/0.4/getting-started/set-up/aries-askar"},next:{title:"Linux",permalink:"/guides/0.4/getting-started/set-up/indy-sdk/linux"}},u={},p=[{value:"Installing the Indy SDK",id:"installing-the-indy-sdk",level:3},{value:"Adding the Indy SDK to the Agent",id:"adding-the-indy-sdk-to-the-agent",level:3}],m={toc:p},h="wrapper";function f(e){let{components:t,...n}=e;return(0,a.kt)(h,(0,r.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"indy-sdk"},"Indy SDK"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk"},"Indy SDK")," provides a distributed ledger based foundation for self-sovereign identity. It can provide the ",(0,a.kt)("inlineCode",{parentName:"p"},"Wallet")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"StorageService")," implementations for the agent, as well as a way to interact with Indy ledgers and an implementation of the legacy (v0.1) ",(0,a.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-spec/"},"AnonCreds Specification")),(0,a.kt)("admonition",{type:"caution"},(0,a.kt)("p",{parentName:"admonition"},"The Indy SDK integration in Aries Framework JavaScript is currently in maintenance mode. We recommend new projects to use ",(0,a.kt)("a",{parentName:"p",href:"../aries-askar"},"Aries Askar")," from the start, and also to migrate existing projects to Aries Askar.")),(0,a.kt)("admonition",{type:"caution"},(0,a.kt)("p",{parentName:"admonition"},"The AnonCreds implementation from the Indy SDK only supports the ",(0,a.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-methods-registry/#hyperledger-indy-legacy-anoncreds-method"},"Hyperledger Indy Legacy AnonCreds Method")," (the pre-standardized implementation), and doesn't support the new Ledger ",(0,a.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-spec/"},"Agnostic AnonCreds Specification (v1.0)"),". Use the new AnonCreds Rust implementation, which is also supported by Aries Framework JavaScript, in combination with ",(0,a.kt)("a",{parentName:"p",href:"../aries-askar"},"Aries Askar")," and Indy VDR to replace the bevhaviour of the Indy SDK, and support the new features these libraries have to offer.")),(0,a.kt)("h3",{id:"installing-the-indy-sdk"},"Installing the Indy SDK"),(0,a.kt)("p",null,"When using Aries Framework JavaScript with the Indy SDK, there's a few extra dependencies that need to be installed. We need to install the ",(0,a.kt)("inlineCode",{parentName:"p"},"@aries-framework/indy-sdk")," package, which implements the needed interfaces for the agent. Secondly, we need to install the native Indy SDK library and the bindings for our specific platform. Currently there are bindings for Node.JS and React Native."),(0,a.kt)("p",null,"To start off, install the native Indy SDK library. The setup for this depends on the platform you are using. Follow the instructions for your platform below."),(0,a.kt)(o.Z,{mdxType:"DocCardList"}),(0,a.kt)("p",null,"After the native Indy SDK library is installed, we can add the Indy SDK libraries."),(0,a.kt)(i.Z,{mdxType:"Tabs"},(0,a.kt)(s.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @aries-framework/indy-sdk@^0.4.0 indy-sdk\n")),(0,a.kt)("p",null,"And install the needed types"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add --dev @types/indy-sdk\n"))),(0,a.kt)(s.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @aries-framework/indy-sdk@^0.4.0 indy-sdk-react-native\n")),(0,a.kt)("p",null,"And then install the needed types"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add --dev @types/indy-sdk-react-native@npm:@types/indy-sdk\n")))),(0,a.kt)("h3",{id:"adding-the-indy-sdk-to-the-agent"},"Adding the Indy SDK to the Agent"),(0,a.kt)("p",null,"After installing the dependencies, we can register the Indy SDK Module on the agent."),(0,a.kt)(i.Z,{mdxType:"Tabs"},(0,a.kt)(s.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-indy-sdk.ts section-1",showLineNumbers:!0,"set-up-indy-sdk.ts":!0,"section-1":!0},""))),(0,a.kt)(s.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-indy-sdk-rn.ts section-1",showLineNumbers:!0,"set-up-indy-sdk-rn.ts":!0,"section-1":!0},"")))))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0c824aea.729d7fe3.js b/assets/js/0c824aea.fae8c22b.js similarity index 58% rename from assets/js/0c824aea.729d7fe3.js rename to assets/js/0c824aea.fae8c22b.js index f86971ee..ed3419b2 100644 --- a/assets/js/0c824aea.729d7fe3.js +++ b/assets/js/0c824aea.fae8c22b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[1350],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,s=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=c(n),m=a,h=d["".concat(l,".").concat(m)]||d[m]||p[m]||s;return n?r.createElement(h,o(o({ref:t},u),{},{components:n})):r.createElement(h,o({ref:t},u))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=n.length,o=new Array(s);o[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[d]="string"==typeof e?e:a,o[1]=i;for(var c=2;c{n.d(t,{Z:()=>g});var r=n(7294),a=n(6010),s=n(3438),o=n(9960),i=n(3919),l=n(5999);const c={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function u(e){let{href:t,children:n}=e;return r.createElement(o.Z,{href:t,className:(0,a.Z)("card padding--lg",c.cardContainer)},n)}function d(e){let{href:t,icon:n,title:s,description:o}=e;return r.createElement(u,{href:t},r.createElement("h2",{className:(0,a.Z)("text--truncate",c.cardTitle),title:s},n," ",s),o&&r.createElement("p",{className:(0,a.Z)("text--truncate",c.cardDescription),title:o},o))}function p(e){let{item:t}=e;const n=(0,s.Wl)(t);return n?r.createElement(d,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,l.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function m(e){let{item:t}=e;const n=(0,i.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",a=(0,s.xz)(t.docId??void 0);return r.createElement(d,{href:t.href,icon:n,title:t.label,description:a?.description})}function h(e){let{item:t}=e;switch(t.type){case"link":return r.createElement(m,{item:t});case"category":return r.createElement(p,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function f(e){let{className:t}=e;const n=(0,s.jA)();return r.createElement(g,{items:n.items,className:t})}function g(e){const{items:t,className:n}=e;if(!t)return r.createElement(f,e);const o=(0,s.MN)(t);return r.createElement("section",{className:(0,a.Z)("row",n)},o.map(((e,t)=>r.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},r.createElement(h,{item:e})))))}},5162:(e,t,n)=>{n.d(t,{Z:()=>o});var r=n(7294),a=n(6010);const s={tabItem:"tabItem_Ymn6"};function o(e){let{children:t,hidden:n,className:o}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(s.tabItem,o),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var r=n(7462),a=n(7294),s=n(6010),o=n(2466),i=n(6550),l=n(1980),c=n(7392),u=n(12);function d(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function p(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??d(n);return function(e){const t=(0,c.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const r=(0,i.k6)(),s=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,l._X)(s),(0,a.useCallback)((e=>{if(!s)return;const t=new URLSearchParams(r.location.search);t.set(s,e),r.replace({...r.location,search:t.toString()})}),[s,r])]}function f(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,s=p(e),[o,i]=(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(!m({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 r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:s}))),[l,c]=h({queryString:n,groupId:r}),[d,f]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,s]=(0,u.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&s.set(e)}),[n,s])]}({groupId:r}),g=(()=>{const e=l??d;return m({value:e,tabValues:s})?e:null})();(0,a.useLayoutEffect)((()=>{g&&i(g)}),[g]);return{selectedValue:o,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:s}))throw new Error(`Can't select invalid tab value=${e}`);i(e),c(e),f(e)}),[c,f,s]),tabValues:s}}var g=n(2389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:n,selectedValue:i,selectValue:l,tabValues:c}=e;const u=[],{blockElementScrollPositionUntilNextRender:d}=(0,o.o5)(),p=e=>{const t=e.currentTarget,n=u.indexOf(t),r=c[n].value;r!==i&&(d(t),l(r))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=u.indexOf(e.currentTarget)+1;t=u[n]??u[0];break}case"ArrowLeft":{const n=u.indexOf(e.currentTarget)-1;t=u[n]??u[u.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.Z)("tabs",{"tabs--block":n},t)},c.map((e=>{let{value:t,label:n,attributes:o}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>u.push(e),onKeyDown:m,onClick:p},o,{className:(0,s.Z)("tabs__item",b.tabItem,o?.className,{"tabs__item--active":i===t})}),n??t)})))}function v(e){let{lazy:t,children:n,selectedValue:r}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function y(e){const t=f(e);return a.createElement("div",{className:(0,s.Z)("tabs-container",b.tabList)},a.createElement(k,(0,r.Z)({},e,t)),a.createElement(v,(0,r.Z)({},e,t)))}function w(e){const t=(0,g.Z)();return a.createElement(y,(0,r.Z)({key:String(t)},e))}},7114:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>d});var r=n(7462),a=(n(7294),n(3905)),s=n(4866),o=n(5162);n(2991);const i={},l="cheqd",c={unversionedId:"getting-started/set-up/cheqd/index",id:"getting-started/set-up/cheqd/index",title:"cheqd",description:"cheqd is a blockchain network, built in the Cosmos ecosystem for Self-Sovereign Identity (SSI). The cheqd Network leverages the cheqd DID method and enables DID-Linked Resources to be written to the network, associated with a DID and controlled using the verification methods in the DID Document.",source:"@site/guides/getting-started/set-up/cheqd/index.md",sourceDirName:"getting-started/set-up/cheqd",slug:"/getting-started/set-up/cheqd/",permalink:"/guides/0.5/getting-started/set-up/cheqd/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Indy VDR",permalink:"/guides/0.5/getting-started/set-up/indy-vdr"},next:{title:"Concepts",permalink:"/guides/0.5/concepts/"}},u={},d=[{value:"Installing cheqd",id:"installing-cheqd",level:3},{value:"React Native",id:"react-native",level:4},{value:"Adding the cheqd to the Agent",id:"adding-the-cheqd-to-the-agent",level:3},{value:"Tutorials",id:"tutorials",level:3}],p={toc:d},m="wrapper";function h(e){let{components:t,...n}=e;return(0,a.kt)(m,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"cheqd"},"cheqd"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/cheqd/sdk"},"cheqd")," is a blockchain network, built in the Cosmos ecosystem for Self-Sovereign Identity (SSI). The cheqd Network leverages the ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cheqd.io/identity/architecture/adr-list/adr-001-cheqd-did-method"},"cheqd DID method")," and enables ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cheqd.io/identity/architecture/adr-list/adr-002-did-linked-resources"},"DID-Linked Resources")," to be written to the network, associated with a DID and controlled using the verification methods in the DID Document."),(0,a.kt)("p",null,"Through this approach, the cheqd Network is able to natively support the ",(0,a.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-spec/"},"Ledger Agnostic AnonCreds Specification (v1.0)")," through its ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cheqd.io/identity/guides/anoncreds"},"AnonCreds Object Method")," (as well as VC-JWT and JSON-LD)."),(0,a.kt)("p",null,"cheqd also has a dedicated token, $CHEQ, used for identity writes to the network, voting in a decentralised governance framework as well as for various payment flows between verifiers, holders and issuers of Verifiable Credentials."),(0,a.kt)("h3",{id:"installing-cheqd"},"Installing cheqd"),(0,a.kt)("p",null,"When using Credo with the cheqd, there's a few extra dependencies that need to be installed. We need to install the ",(0,a.kt)("inlineCode",{parentName:"p"},"@credo-ts/cheqd")," package, which implements the needed interfaces for the agent."),(0,a.kt)("h4",{id:"react-native"},"React Native"),(0,a.kt)("p",null,"To enable react-native support we need to follow the steps below"),(0,a.kt)("p",null,"In the package.json file add the below code snippet, which replaces the cosmjs dependencies with he cosmjs-rn packages"),(0,a.kt)(s.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{label:"NPM",value:"tab1",mdxType:"TabItem"},(0,a.kt)("p",null,"Using ",(0,a.kt)("a",{parentName:"p",href:"https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides"},"NPM ",(0,a.kt)("inlineCode",{parentName:"a"},"overrides"))," we can point the ",(0,a.kt)("inlineCode",{parentName:"p"},"cosmjs")," packages to ",(0,a.kt)("inlineCode",{parentName:"p"},"cosmjs-rn"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'{\n "overrides": {\n "@cosmjs/amino": "npm:@cosmjs-rn/amino@^0.27.1",\n "@cosmjs/encoding": "npm:@cosmjs-rn/encoding@^0.27.1",\n "@cosmjs/math": "npm:@cosmjs-rn/math@^0.27.1",\n "@cosmjs/stargate": "npm:@cosmjs-rn/stargate@^0.27.1",\n "@cosmjs/tendermint-rpc": "npm:@cosmjs-rn/tendermint-rpc@^0.27.1",\n "@cosmjs/utils": "npm:@cosmjs-rn/utils@^0.27.1",\n "@cosmjs/proto-signing": "npm:@cosmjs-rn/proto-signing@^0.27.1",\n "@cosmjs/crypto": "npm:@cosmjs-rn/crypto@^0.27.1"\n }\n}\n'))),(0,a.kt)(o.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,a.kt)("p",null,"Using ",(0,a.kt)("a",{parentName:"p",href:"https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/"},"Yarn ",(0,a.kt)("inlineCode",{parentName:"a"},"resolutions"))," we can point the ",(0,a.kt)("inlineCode",{parentName:"p"},"cosmjs")," packages to ",(0,a.kt)("inlineCode",{parentName:"p"},"cosmjs-rn"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'{\n "resolutions": {\n "@cosmjs/amino": "npm:@cosmjs-rn/amino@^0.27.1",\n "@cosmjs/encoding": "npm:@cosmjs-rn/encoding@^0.27.1",\n "@cosmjs/math": "npm:@cosmjs-rn/math@^0.27.1",\n "@cosmjs/stargate": "npm:@cosmjs-rn/stargate@^0.27.1",\n "@cosmjs/tendermint-rpc": "npm:@cosmjs-rn/tendermint-rpc@^0.27.1",\n "@cosmjs/utils": "npm:@cosmjs-rn/utils@^0.27.1",\n "@cosmjs/proto-signing": "npm:@cosmjs-rn/proto-signing@^0.27.1",\n "@cosmjs/crypto": "npm:@cosmjs-rn/crypto@^0.27.1"\n }\n}\n')))),(0,a.kt)("p",null,"Following that we need to add a buffer polyfill"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add buffer\n")),(0,a.kt)("p",null,"create a shim.js file with the below code snippet"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"import { Buffer } from 'buffer'\nglobal.Buffer = Buffer\n")),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"import shim.js")," file into your file where the App is imported"),(0,a.kt)("h3",{id:"adding-the-cheqd-to-the-agent"},"Adding the cheqd to the Agent"),(0,a.kt)("p",null,"After installing the dependencies, we can register the cheqd Module on the agent by adding the below code snippet to the agent constructor."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-cheqd.ts section-1",showLineNumbers:!0,"set-up-cheqd.ts":!0,"section-1":!0},"")),(0,a.kt)("p",null,"The cosmosPayerSeed can be a 32-bit seed value or a mnemonic, which can be managed using Keplr wallet which can be installed on a mobile or as a browser extension in chrome or safari which allows user's to create accounts, exchange tokens etc. To setup keplr wallet for cheqd follow this ",(0,a.kt)("a",{parentName:"p",href:"https://learn.cheqd.io/getting-set-up-on-cheqd/cheqd-supported-wallets/keplr-wallet"},"tutorial")),(0,a.kt)(s.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{label:"Tutorials",value:"tab1",mdxType:"TabItem"},(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/0.5/tutorials/cheqd/"},"Cheqd DID Module")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/0.5/tutorials/registering-schema-and-credential-definition"},"Register Schema and Credential Definition")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/0.5/tutorials/issue-a-credential"},"Issue a Credential"))))))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[1350],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,s=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=c(n),m=a,h=d["".concat(l,".").concat(m)]||d[m]||p[m]||s;return n?r.createElement(h,o(o({ref:t},u),{},{components:n})):r.createElement(h,o({ref:t},u))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=n.length,o=new Array(s);o[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[d]="string"==typeof e?e:a,o[1]=i;for(var c=2;c{n.d(t,{Z:()=>g});var r=n(7294),a=n(6010),s=n(3438),o=n(9960),i=n(3919),l=n(5999);const c={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function u(e){let{href:t,children:n}=e;return r.createElement(o.Z,{href:t,className:(0,a.Z)("card padding--lg",c.cardContainer)},n)}function d(e){let{href:t,icon:n,title:s,description:o}=e;return r.createElement(u,{href:t},r.createElement("h2",{className:(0,a.Z)("text--truncate",c.cardTitle),title:s},n," ",s),o&&r.createElement("p",{className:(0,a.Z)("text--truncate",c.cardDescription),title:o},o))}function p(e){let{item:t}=e;const n=(0,s.Wl)(t);return n?r.createElement(d,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,l.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function m(e){let{item:t}=e;const n=(0,i.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",a=(0,s.xz)(t.docId??void 0);return r.createElement(d,{href:t.href,icon:n,title:t.label,description:a?.description})}function h(e){let{item:t}=e;switch(t.type){case"link":return r.createElement(m,{item:t});case"category":return r.createElement(p,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function f(e){let{className:t}=e;const n=(0,s.jA)();return r.createElement(g,{items:n.items,className:t})}function g(e){const{items:t,className:n}=e;if(!t)return r.createElement(f,e);const o=(0,s.MN)(t);return r.createElement("section",{className:(0,a.Z)("row",n)},o.map(((e,t)=>r.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},r.createElement(h,{item:e})))))}},5162:(e,t,n)=>{n.d(t,{Z:()=>o});var r=n(7294),a=n(6010);const s={tabItem:"tabItem_Ymn6"};function o(e){let{children:t,hidden:n,className:o}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(s.tabItem,o),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var r=n(7462),a=n(7294),s=n(6010),o=n(2466),i=n(6550),l=n(1980),c=n(7392),u=n(12);function d(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function p(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??d(n);return function(e){const t=(0,c.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const r=(0,i.k6)(),s=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,l._X)(s),(0,a.useCallback)((e=>{if(!s)return;const t=new URLSearchParams(r.location.search);t.set(s,e),r.replace({...r.location,search:t.toString()})}),[s,r])]}function f(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,s=p(e),[o,i]=(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(!m({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 r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:s}))),[l,c]=h({queryString:n,groupId:r}),[d,f]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,s]=(0,u.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&s.set(e)}),[n,s])]}({groupId:r}),g=(()=>{const e=l??d;return m({value:e,tabValues:s})?e:null})();(0,a.useLayoutEffect)((()=>{g&&i(g)}),[g]);return{selectedValue:o,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:s}))throw new Error(`Can't select invalid tab value=${e}`);i(e),c(e),f(e)}),[c,f,s]),tabValues:s}}var g=n(2389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:n,selectedValue:i,selectValue:l,tabValues:c}=e;const u=[],{blockElementScrollPositionUntilNextRender:d}=(0,o.o5)(),p=e=>{const t=e.currentTarget,n=u.indexOf(t),r=c[n].value;r!==i&&(d(t),l(r))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=u.indexOf(e.currentTarget)+1;t=u[n]??u[0];break}case"ArrowLeft":{const n=u.indexOf(e.currentTarget)-1;t=u[n]??u[u.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.Z)("tabs",{"tabs--block":n},t)},c.map((e=>{let{value:t,label:n,attributes:o}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>u.push(e),onKeyDown:m,onClick:p},o,{className:(0,s.Z)("tabs__item",b.tabItem,o?.className,{"tabs__item--active":i===t})}),n??t)})))}function v(e){let{lazy:t,children:n,selectedValue:r}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function y(e){const t=f(e);return a.createElement("div",{className:(0,s.Z)("tabs-container",b.tabList)},a.createElement(k,(0,r.Z)({},e,t)),a.createElement(v,(0,r.Z)({},e,t)))}function w(e){const t=(0,g.Z)();return a.createElement(y,(0,r.Z)({key:String(t)},e))}},7114:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>d});var r=n(7462),a=(n(7294),n(3905)),s=n(4866),o=n(5162);n(2991);const i={},l="cheqd",c={unversionedId:"getting-started/set-up/cheqd/index",id:"getting-started/set-up/cheqd/index",title:"cheqd",description:"cheqd is a blockchain network, built in the Cosmos ecosystem for Self-Sovereign Identity (SSI). The cheqd Network leverages the cheqd DID method and enables DID-Linked Resources to be written to the network, associated with a DID and controlled using the verification methods in the DID Document.",source:"@site/guides/getting-started/set-up/cheqd/index.md",sourceDirName:"getting-started/set-up/cheqd",slug:"/getting-started/set-up/cheqd/",permalink:"/guides/getting-started/set-up/cheqd/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Indy VDR",permalink:"/guides/getting-started/set-up/indy-vdr"},next:{title:"Concepts",permalink:"/guides/concepts/"}},u={},d=[{value:"Installing cheqd",id:"installing-cheqd",level:3},{value:"React Native",id:"react-native",level:4},{value:"Adding the cheqd to the Agent",id:"adding-the-cheqd-to-the-agent",level:3},{value:"Tutorials",id:"tutorials",level:3}],p={toc:d},m="wrapper";function h(e){let{components:t,...n}=e;return(0,a.kt)(m,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"cheqd"},"cheqd"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/cheqd/sdk"},"cheqd")," is a blockchain network, built in the Cosmos ecosystem for Self-Sovereign Identity (SSI). The cheqd Network leverages the ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cheqd.io/identity/architecture/adr-list/adr-001-cheqd-did-method"},"cheqd DID method")," and enables ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cheqd.io/identity/architecture/adr-list/adr-002-did-linked-resources"},"DID-Linked Resources")," to be written to the network, associated with a DID and controlled using the verification methods in the DID Document."),(0,a.kt)("p",null,"Through this approach, the cheqd Network is able to natively support the ",(0,a.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-spec/"},"Ledger Agnostic AnonCreds Specification (v1.0)")," through its ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cheqd.io/identity/guides/anoncreds"},"AnonCreds Object Method")," (as well as VC-JWT and JSON-LD)."),(0,a.kt)("p",null,"cheqd also has a dedicated token, $CHEQ, used for identity writes to the network, voting in a decentralised governance framework as well as for various payment flows between verifiers, holders and issuers of Verifiable Credentials."),(0,a.kt)("h3",{id:"installing-cheqd"},"Installing cheqd"),(0,a.kt)("p",null,"When using Credo with the cheqd, there's a few extra dependencies that need to be installed. We need to install the ",(0,a.kt)("inlineCode",{parentName:"p"},"@credo-ts/cheqd")," package, which implements the needed interfaces for the agent."),(0,a.kt)("h4",{id:"react-native"},"React Native"),(0,a.kt)("p",null,"To enable react-native support we need to follow the steps below"),(0,a.kt)("p",null,"In the package.json file add the below code snippet, which replaces the cosmjs dependencies with he cosmjs-rn packages"),(0,a.kt)(s.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{label:"NPM",value:"tab1",mdxType:"TabItem"},(0,a.kt)("p",null,"Using ",(0,a.kt)("a",{parentName:"p",href:"https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides"},"NPM ",(0,a.kt)("inlineCode",{parentName:"a"},"overrides"))," we can point the ",(0,a.kt)("inlineCode",{parentName:"p"},"cosmjs")," packages to ",(0,a.kt)("inlineCode",{parentName:"p"},"cosmjs-rn"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'{\n "overrides": {\n "@cosmjs/amino": "npm:@cosmjs-rn/amino@^0.27.1",\n "@cosmjs/encoding": "npm:@cosmjs-rn/encoding@^0.27.1",\n "@cosmjs/math": "npm:@cosmjs-rn/math@^0.27.1",\n "@cosmjs/stargate": "npm:@cosmjs-rn/stargate@^0.27.1",\n "@cosmjs/tendermint-rpc": "npm:@cosmjs-rn/tendermint-rpc@^0.27.1",\n "@cosmjs/utils": "npm:@cosmjs-rn/utils@^0.27.1",\n "@cosmjs/proto-signing": "npm:@cosmjs-rn/proto-signing@^0.27.1",\n "@cosmjs/crypto": "npm:@cosmjs-rn/crypto@^0.27.1"\n }\n}\n'))),(0,a.kt)(o.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,a.kt)("p",null,"Using ",(0,a.kt)("a",{parentName:"p",href:"https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/"},"Yarn ",(0,a.kt)("inlineCode",{parentName:"a"},"resolutions"))," we can point the ",(0,a.kt)("inlineCode",{parentName:"p"},"cosmjs")," packages to ",(0,a.kt)("inlineCode",{parentName:"p"},"cosmjs-rn"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'{\n "resolutions": {\n "@cosmjs/amino": "npm:@cosmjs-rn/amino@^0.27.1",\n "@cosmjs/encoding": "npm:@cosmjs-rn/encoding@^0.27.1",\n "@cosmjs/math": "npm:@cosmjs-rn/math@^0.27.1",\n "@cosmjs/stargate": "npm:@cosmjs-rn/stargate@^0.27.1",\n "@cosmjs/tendermint-rpc": "npm:@cosmjs-rn/tendermint-rpc@^0.27.1",\n "@cosmjs/utils": "npm:@cosmjs-rn/utils@^0.27.1",\n "@cosmjs/proto-signing": "npm:@cosmjs-rn/proto-signing@^0.27.1",\n "@cosmjs/crypto": "npm:@cosmjs-rn/crypto@^0.27.1"\n }\n}\n')))),(0,a.kt)("p",null,"Following that we need to add a buffer polyfill"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add buffer\n")),(0,a.kt)("p",null,"create a shim.js file with the below code snippet"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"import { Buffer } from 'buffer'\nglobal.Buffer = Buffer\n")),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"import shim.js")," file into your file where the App is imported"),(0,a.kt)("h3",{id:"adding-the-cheqd-to-the-agent"},"Adding the cheqd to the Agent"),(0,a.kt)("p",null,"After installing the dependencies, we can register the cheqd Module on the agent by adding the below code snippet to the agent constructor."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-cheqd.ts section-1",showLineNumbers:!0,"set-up-cheqd.ts":!0,"section-1":!0},"")),(0,a.kt)("p",null,"The cosmosPayerSeed can be a 32-bit seed value or a mnemonic, which can be managed using Keplr wallet which can be installed on a mobile or as a browser extension in chrome or safari which allows user's to create accounts, exchange tokens etc. To setup keplr wallet for cheqd follow this ",(0,a.kt)("a",{parentName:"p",href:"https://learn.cheqd.io/getting-set-up-on-cheqd/cheqd-supported-wallets/keplr-wallet"},"tutorial")),(0,a.kt)(s.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{label:"Tutorials",value:"tab1",mdxType:"TabItem"},(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/tutorials/cheqd/"},"Cheqd DID Module")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/tutorials/registering-schema-and-credential-definition"},"Register Schema and Credential Definition")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/tutorials/issue-a-credential"},"Issue a Credential"))))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0d8c2653.504e5fea.js b/assets/js/0d8c2653.504e5fea.js deleted file mode 100644 index 4de43d94..00000000 --- a/assets/js/0d8c2653.504e5fea.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4105],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var a=r.createContext({}),d=function(e){var t=r.useContext(a),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=d(e.components);return r.createElement(a.Provider,{value:t},e.children)},u="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},c=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,s=e.originalType,a=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=d(n),c=i,m=u["".concat(a,".").concat(c)]||u[c]||g[c]||s;return n?r.createElement(m,o(o({ref:t},p),{},{components:n})):r.createElement(m,o({ref:t},p))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var s=n.length,o=new Array(s);o[0]=c;var l={};for(var a in t)hasOwnProperty.call(t,a)&&(l[a]=t[a]);l.originalType=e,l[u]="string"==typeof e?e:i,o[1]=l;for(var d=2;d{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>o,default:()=>g,frontMatter:()=>s,metadata:()=>l,toc:()=>d});var r=n(7462),i=(n(7294),n(3905));const s={},o="Postgres Setup for windows",l={unversionedId:"tutorials/indy-sdk-postgres-database-nodejs/windows",id:"version-0.4/tutorials/indy-sdk-postgres-database-nodejs/windows",title:"Postgres Setup for windows",description:"Build Environment Prerequisites",source:"@site/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/windows.md",sourceDirName:"tutorials/indy-sdk-postgres-database-nodejs",slug:"/tutorials/indy-sdk-postgres-database-nodejs/windows",permalink:"/guides/tutorials/indy-sdk-postgres-database-nodejs/windows",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Postgres Setup for macOS",permalink:"/guides/tutorials/indy-sdk-postgres-database-nodejs/macos"},next:{title:"Updating AFJ",permalink:"/guides/updating/"}},a={},d=[{value:"Build Environment Prerequisites",id:"build-environment-prerequisites",level:2},{value:"Step 1: Getting dependencies",id:"step-1-getting-dependencies",level:2},{value:"Step 2: Build Postgres plugin",id:"step-2-build-postgres-plugin",level:2},{value:"Step 2.1: Cloning the indy-sdk",id:"step-21-cloning-the-indy-sdk",level:3},{value:"Step 2.2: Building Postgres plugin",id:"step-22-building-postgres-plugin",level:3},{value:"Step 2.3: Setting the file to PATH",id:"step-23-setting-the-file-to-path",level:3}],p={toc:d},u="wrapper";function g(e){let{components:t,...n}=e;return(0,i.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"postgres-setup-for-windows"},"Postgres Setup for windows"),(0,i.kt)("h2",{id:"build-environment-prerequisites"},"Build Environment Prerequisites"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Download and install Visual Studio Community Edition 2022"),(0,i.kt)("li",{parentName:"ol"},"Install git for windows"),(0,i.kt)("li",{parentName:"ol"},"Download rust for windows ",(0,i.kt)("a",{parentName:"li",href:"https://www.rust-lang.org/en-US/install.html"},"here")),(0,i.kt)("li",{parentName:"ol"},"Make sure you have already setup libindy for windows from ",(0,i.kt)("a",{parentName:"li",href:"../../getting-started/indy-sdk/windows"},"here"))),(0,i.kt)("h2",{id:"step-1-getting-dependencies"},"Step 1: Getting dependencies"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Download the prebuilt dependencies ",(0,i.kt)("a",{parentName:"li",href:"https://repo.sovrin.org/windows/libindy/deps/"},"here")),(0,i.kt)("li",{parentName:"ul"},"Extract them"),(0,i.kt)("li",{parentName:"ul"},"Point path to this directory using environment variables:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"set INDY_PREBUILT_DEPS_DIR=C:\\Users\\{WINDOWS_USER}\\Downloads\\indy-sdk-deps")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"set INDY_CRYPTO_PREBUILT_DEPS_DIR=C:\\Users\\{WINDOWS_USER}\\Downloads\\indy-sdk-deps")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"set MILAGRO_DIR=C:\\Users\\{WINDOWS_USER}\\Downloads\\indy-sdk-deps")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"set LIBZMQ_PREFIX=C:\\Users\\{WINDOWS_USER}\\Downloads\\indy-sdk-deps")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"set SODIUM_LIB_DIR=C:\\Users\\{WINDOWS_USER}\\Downloads\\indy-sdk-deps")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"set OPENSSL_DIR=C:\\Users\\{WINDOWS_USER}\\Downloads\\indy-sdk-deps")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"set PATH=C:\\Users\\{WINDOWS_USER}\\Downloads\\indy-sdk-deps\\lib"))))),(0,i.kt)("h2",{id:"step-2-build-postgres-plugin"},"Step 2: Build Postgres plugin"),(0,i.kt)("p",null,"Building Postgres plugin from the indy-sdk repo with cargo."),(0,i.kt)("h3",{id:"step-21-cloning-the-indy-sdk"},"Step 2.1: Cloning the indy-sdk"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"git clone https://github.com/hyperledger/indy-sdk.git\n\ncd indy-sdk\\experimental\\plugins\\postgres_storage\n")),(0,i.kt)("h3",{id:"step-22-building-postgres-plugin"},"Step 2.2: Building Postgres plugin"),(0,i.kt)("p",null,"If this step throws any errors, it might be because of the environment. Step 1 of this guide provided the dependencies that are required."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"cargo build --release --target x86_64-pc-windows-msvc\n")),(0,i.kt)("p",null,"The library ",(0,i.kt)("strong",{parentName:"p"},"indystrgpostgres.dll")," file will be located at ",(0,i.kt)("inlineCode",{parentName:"p"},"indy-sdk\\experimental\\plugins\\postgres_storage\\target\\x86_64-pc-windows-msvc\\release")),(0,i.kt)("h3",{id:"step-23-setting-the-file-to-path"},"Step 2.3: Setting the file to PATH"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"set LIB_INDY_STRG_POSTGRES=C:\\Users\\{WINDOWS_USER}\\Downloads\\indy-sdklexperimental\\plugins\\postgres_storage\\target\\x86_64-pc-windows-msvc\\release"))),(0,i.kt)("p",null,"or Alternatively you can copy the ",(0,i.kt)("strong",{parentName:"p"},"indystrgpostgres.dll")," file to ",(0,i.kt)("inlineCode",{parentName:"p"},"c:\\\\windows\\\\system32\\\\")))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0d8c2653.669b8614.js b/assets/js/0d8c2653.669b8614.js new file mode 100644 index 00000000..04b2719f --- /dev/null +++ b/assets/js/0d8c2653.669b8614.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4105],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var a=r.createContext({}),d=function(e){var t=r.useContext(a),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=d(e.components);return r.createElement(a.Provider,{value:t},e.children)},u="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},c=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,s=e.originalType,a=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=d(n),c=i,m=u["".concat(a,".").concat(c)]||u[c]||g[c]||s;return n?r.createElement(m,o(o({ref:t},p),{},{components:n})):r.createElement(m,o({ref:t},p))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var s=n.length,o=new Array(s);o[0]=c;var l={};for(var a in t)hasOwnProperty.call(t,a)&&(l[a]=t[a]);l.originalType=e,l[u]="string"==typeof e?e:i,o[1]=l;for(var d=2;d{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>o,default:()=>g,frontMatter:()=>s,metadata:()=>l,toc:()=>d});var r=n(7462),i=(n(7294),n(3905));const s={},o="Postgres Setup for windows",l={unversionedId:"tutorials/indy-sdk-postgres-database-nodejs/windows",id:"version-0.4/tutorials/indy-sdk-postgres-database-nodejs/windows",title:"Postgres Setup for windows",description:"Build Environment Prerequisites",source:"@site/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/windows.md",sourceDirName:"tutorials/indy-sdk-postgres-database-nodejs",slug:"/tutorials/indy-sdk-postgres-database-nodejs/windows",permalink:"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/windows",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Postgres Setup for macOS",permalink:"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/macos"},next:{title:"Updating AFJ",permalink:"/guides/0.4/updating/"}},a={},d=[{value:"Build Environment Prerequisites",id:"build-environment-prerequisites",level:2},{value:"Step 1: Getting dependencies",id:"step-1-getting-dependencies",level:2},{value:"Step 2: Build Postgres plugin",id:"step-2-build-postgres-plugin",level:2},{value:"Step 2.1: Cloning the indy-sdk",id:"step-21-cloning-the-indy-sdk",level:3},{value:"Step 2.2: Building Postgres plugin",id:"step-22-building-postgres-plugin",level:3},{value:"Step 2.3: Setting the file to PATH",id:"step-23-setting-the-file-to-path",level:3}],p={toc:d},u="wrapper";function g(e){let{components:t,...n}=e;return(0,i.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"postgres-setup-for-windows"},"Postgres Setup for windows"),(0,i.kt)("h2",{id:"build-environment-prerequisites"},"Build Environment Prerequisites"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Download and install Visual Studio Community Edition 2022"),(0,i.kt)("li",{parentName:"ol"},"Install git for windows"),(0,i.kt)("li",{parentName:"ol"},"Download rust for windows ",(0,i.kt)("a",{parentName:"li",href:"https://www.rust-lang.org/en-US/install.html"},"here")),(0,i.kt)("li",{parentName:"ol"},"Make sure you have already setup libindy for windows from ",(0,i.kt)("a",{parentName:"li",href:"../../getting-started/indy-sdk/windows"},"here"))),(0,i.kt)("h2",{id:"step-1-getting-dependencies"},"Step 1: Getting dependencies"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Download the prebuilt dependencies ",(0,i.kt)("a",{parentName:"li",href:"https://repo.sovrin.org/windows/libindy/deps/"},"here")),(0,i.kt)("li",{parentName:"ul"},"Extract them"),(0,i.kt)("li",{parentName:"ul"},"Point path to this directory using environment variables:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"set INDY_PREBUILT_DEPS_DIR=C:\\Users\\{WINDOWS_USER}\\Downloads\\indy-sdk-deps")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"set INDY_CRYPTO_PREBUILT_DEPS_DIR=C:\\Users\\{WINDOWS_USER}\\Downloads\\indy-sdk-deps")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"set MILAGRO_DIR=C:\\Users\\{WINDOWS_USER}\\Downloads\\indy-sdk-deps")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"set LIBZMQ_PREFIX=C:\\Users\\{WINDOWS_USER}\\Downloads\\indy-sdk-deps")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"set SODIUM_LIB_DIR=C:\\Users\\{WINDOWS_USER}\\Downloads\\indy-sdk-deps")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"set OPENSSL_DIR=C:\\Users\\{WINDOWS_USER}\\Downloads\\indy-sdk-deps")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"set PATH=C:\\Users\\{WINDOWS_USER}\\Downloads\\indy-sdk-deps\\lib"))))),(0,i.kt)("h2",{id:"step-2-build-postgres-plugin"},"Step 2: Build Postgres plugin"),(0,i.kt)("p",null,"Building Postgres plugin from the indy-sdk repo with cargo."),(0,i.kt)("h3",{id:"step-21-cloning-the-indy-sdk"},"Step 2.1: Cloning the indy-sdk"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"git clone https://github.com/hyperledger/indy-sdk.git\n\ncd indy-sdk\\experimental\\plugins\\postgres_storage\n")),(0,i.kt)("h3",{id:"step-22-building-postgres-plugin"},"Step 2.2: Building Postgres plugin"),(0,i.kt)("p",null,"If this step throws any errors, it might be because of the environment. Step 1 of this guide provided the dependencies that are required."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"cargo build --release --target x86_64-pc-windows-msvc\n")),(0,i.kt)("p",null,"The library ",(0,i.kt)("strong",{parentName:"p"},"indystrgpostgres.dll")," file will be located at ",(0,i.kt)("inlineCode",{parentName:"p"},"indy-sdk\\experimental\\plugins\\postgres_storage\\target\\x86_64-pc-windows-msvc\\release")),(0,i.kt)("h3",{id:"step-23-setting-the-file-to-path"},"Step 2.3: Setting the file to PATH"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"set LIB_INDY_STRG_POSTGRES=C:\\Users\\{WINDOWS_USER}\\Downloads\\indy-sdklexperimental\\plugins\\postgres_storage\\target\\x86_64-pc-windows-msvc\\release"))),(0,i.kt)("p",null,"or Alternatively you can copy the ",(0,i.kt)("strong",{parentName:"p"},"indystrgpostgres.dll")," file to ",(0,i.kt)("inlineCode",{parentName:"p"},"c:\\\\windows\\\\system32\\\\")))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0ecb752f.353d2948.js b/assets/js/0ecb752f.353d2948.js new file mode 100644 index 00000000..be116fb5 --- /dev/null +++ b/assets/js/0ecb752f.353d2948.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7824],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var d=a.createContext({}),l=function(e){var t=a.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return a.createElement(d.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,d=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),c=l(n),h=r,m=c["".concat(d,".").concat(h)]||c[h]||u[h]||i;return n?a.createElement(m,o(o({ref:t},p),{},{components:n})):a.createElement(m,o({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=h;var s={};for(var d in t)hasOwnProperty.call(t,d)&&(s[d]=t[d]);s.originalType=e,s[c]="string"==typeof e?e:r,o[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var a=n(7462),r=(n(7294),n(3905));const i={},o="Migrating from an Indy SDK Wallet to Aries Askar",s={unversionedId:"updating/update-indy-sdk-to-askar",id:"updating/update-indy-sdk-to-askar",title:"Migrating from an Indy SDK Wallet to Aries Askar",description:"This documentation explains the process of migrating your Indy SDK wallet to Aries Askar.",source:"@site/guides/updating/update-indy-sdk-to-askar.md",sourceDirName:"updating",slug:"/updating/update-indy-sdk-to-askar",permalink:"/guides/updating/update-indy-sdk-to-askar",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Update Assistant",permalink:"/guides/updating/update-assistant"},next:{title:"Migrating from Credo 0.1.0 to 0.2.x",permalink:"/guides/updating/versions/0.1-to-0.2"}},d={},l=[{value:"What does the migration do internally?",id:"what-does-the-migration-do-internally",level:2},{value:"Create a backup",id:"create-a-backup",level:3},{value:"Migrate the database to an Aries Askar structure",id:"migrate-the-database-to-an-aries-askar-structure",level:3},{value:"Try to open the wallet in the new Aries Askar structure",id:"try-to-open-the-wallet-in-the-new-aries-askar-structure",level:3},{value:"Update the keys",id:"update-the-keys",level:3},{value:"Update the DIDs",id:"update-the-dids",level:3},{value:"Update the credential definitions",id:"update-the-credential-definitions",level:3},{value:"Update the link secret(s) (master secret)",id:"update-the-link-secrets-master-secret",level:3},{value:"Update the credentials",id:"update-the-credentials",level:3},{value:"All the other records",id:"all-the-other-records",level:3},{value:"How to update",id:"how-to-update",level:2},{value:"add the required dependencies",id:"add-the-required-dependencies",level:3},{value:"Getting the database path",id:"getting-the-database-path",level:3},{value:"Android",id:"android",level:4},{value:"iOS",id:"ios",level:4}],p={toc:l},c="wrapper";function u(e){let{components:t,...n}=e;return(0,r.kt)(c,(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"migrating-from-an-indy-sdk-wallet-to-aries-askar"},"Migrating from an Indy SDK Wallet to Aries Askar"),(0,r.kt)("p",null,"This documentation explains the process of migrating your Indy SDK wallet to ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-askar"},"Aries Askar"),"."),(0,r.kt)("admonition",{type:"danger"},(0,r.kt)("p",{parentName:"admonition"},"While the migration script technically works on node.js, it is strongly advised not to use it, yet. The migration of issuer records (such as Schemas and Credential Definitions) is not implemented yet. When a credential definition is detected it will revert the migration process and no harm is done.")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Postgres is not supported. If you are using postgres with Indy SDK and need to update to Aries Askar, please open an issue on ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts"},"GitHub"),".")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"The migration script is supported to run on 0.3.x before migrating from 0.3.x to 0.4.x. Please refer to ",(0,r.kt)("a",{parentName:"p",href:"/guides/updating/versions/0.3-to-0.4"},"Migrating from Credo 0.3.x to 0.4.x")," to get to 0.4.x afterwards."),(0,r.kt)("p",{parentName:"admonition"},"It is important to note that this script must be ran before you update from 0.3.x to 0.4.x.")),(0,r.kt)("h2",{id:"what-does-the-migration-do-internally"},"What does the migration do internally?"),(0,r.kt)("p",null,"The migration script does the following to make sure everything is migrated properly, and if anything goes wrong, it will revert back to a working state."),(0,r.kt)("h3",{id:"create-a-backup"},"Create a backup"),(0,r.kt)("p",null,"Because undefined behavior might occur, we create a backup in the new ",(0,r.kt)("inlineCode",{parentName:"p"},"tmp")," directory from Credo. if some error occurs, it will be reverted back to the backed-up state and if no error occurs, it will delete the backup from the temporary directory."),(0,r.kt)("h3",{id:"migrate-the-database-to-an-aries-askar-structure"},"Migrate the database to an Aries Askar structure"),(0,r.kt)("p",null,"The Indy-sdk and Aries Askar have different database structures. So first of all we need to change some table names, decrypt all the items with the old Indy keys, encrypt the items with the new Aries Askar keys and store them inside the new structure."),(0,r.kt)("h3",{id:"try-to-open-the-wallet-in-the-new-aries-askar-structure"},"Try to open the wallet in the new Aries Askar structure"),(0,r.kt)("p",null,"When the wallet is correctly transformed, the wallet will be attempted to be opened."),(0,r.kt)("h3",{id:"update-the-keys"},"Update the keys"),(0,r.kt)("p",null,"Aries Askar has a specific way to store keys and every key, defined by the category of ",(0,r.kt)("inlineCode",{parentName:"p"},"Indy::Key")," will be migrated."),(0,r.kt)("h3",{id:"update-the-dids"},"Update the DIDs"),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"This update script does not transform did records. This is fine for something like ",(0,r.kt)("inlineCode",{parentName:"p"},"did:peer"),", but will cause issues with ",(0,r.kt)("inlineCode",{parentName:"p"},"indy")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"sov")," DIDs. For more information, please check out the ",(0,r.kt)("a",{parentName:"p",href:"/guides/updating/versions/0.3-to-0.4#removal-of-publicdidseed-and-publicdid"},"Migrating from Credo 0.3.x to 0.4.x"))),(0,r.kt)("h3",{id:"update-the-credential-definitions"},"Update the credential definitions"),(0,r.kt)("admonition",{type:"danger"},(0,r.kt)("p",{parentName:"admonition"},"Updating of credential definitions is not yet supported. This is why it is strongly advised not to run this script in a node.js environment.")),(0,r.kt)("h3",{id:"update-the-link-secrets-master-secret"},"Update the link secret(s) (master secret)"),(0,r.kt)("p",null,"The link secrets, identified by the category ",(0,r.kt)("inlineCode",{parentName:"p"},"Indy::MasterSecret"),", are updated next. They are stored inside a new ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsLinkSecretRecord"),"."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Since we have to set a default link secret, some additional logic is added to detect this. You can either supply a ",(0,r.kt)("inlineCode",{parentName:"p"},"defaultLinkSercetId")," as a constructor parameter or it will be based on your ",(0,r.kt)("inlineCode",{parentName:"p"},"walletId"),"."),(0,r.kt)("p",{parentName:"admonition"},"If there is no Indy record with the ",(0,r.kt)("inlineCode",{parentName:"p"},"defaultLinkSecretId")," or the ",(0,r.kt)("inlineCode",{parentName:"p"},"walletId"),", an error will be thrown and the migration will be restored.")),(0,r.kt)("h3",{id:"update-the-credentials"},"Update the credentials"),(0,r.kt)("p",null,"The credentials, identified by the category ",(0,r.kt)("inlineCode",{parentName:"p"},"Indy::Credential")," are updated last. They are stored in the new ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsCredentialRecord")," as a one-to-one copy. This means that they now support more tags and will make querying a lot easier."),(0,r.kt)("h3",{id:"all-the-other-records"},"All the other records"),(0,r.kt)("p",null,"All the other records will be transferred without any updates as they are not Indy specific."),(0,r.kt)("h2",{id:"how-to-update"},"How to update"),(0,r.kt)("p",null,"Updating does not require a lot of code, but must be done with caution."),(0,r.kt)("p",null,"It is very important to note that the migration script only has to be run once. If it runs for a second time, it will error saying that the database is already migrated. Also, when the migration is finished, it is common practice to store this state in your persistent app storage. This script does not provide a way to detect if an update has happened, so storing this value will prevent the script from running every time. For more information regarding this topic, please check out ",(0,r.kt)("a",{parentName:"p",href:"/guides/updating/update-assistant#storing-the-agent-storage-version-outside-of-the-agent-storage"},"Update Assistant"),"."),(0,r.kt)("h3",{id:"add-the-required-dependencies"},"add the required dependencies"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @hyperledger/aries-askar-react-native @credo-ts/indy-sdk-to-askar-migration react-native-fs\n")),(0,r.kt)("p",null,"Below is the minimal code required for the migration to work. It is recommended to turn the logger on as it gives a lot of information regarding the migration."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"The agent is not allowed to be initialized to run this script. This makes sure nothing else happens during the migration.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript"},"import { agentDependencies } from '@credo-ts/react-native'\nimport { AskarModule } from '@credo-ts/askar'\nimport { IndySdkToAskarMigrationUpdater } from '@credo-ts/indy-sdk-to-askar-migration'\nimport { ariesAskar } from '@hyperledger/aries-askar-react-native'\n\nconst oldAgent = new Agent({\n config: {\n /* ... */\n },\n modules: {\n ariesAskar: new AskarModule({\n ariesAskar,\n }),\n },\n dependencies: agentDependencies,\n})\n\nconst dbPath = '' // see section below\n\nconst updater = await IndySdkToAskarMigrationUpdater.initialize({ dbPath, agent })\nawait updater.update()\n")),(0,r.kt)("h3",{id:"getting-the-database-path"},"Getting the database path"),(0,r.kt)("h4",{id:"android"},"Android"),(0,r.kt)("p",null,"On android, the database is commonly located under the ",(0,r.kt)("inlineCode",{parentName:"p"},"ExternalDirectoryPath"),"."),(0,r.kt)("p",null,"If you did not follow the default indy-sdk for React Native setup, your path might differ. Check out ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk-react-native#5-load-indy-library"},"step 5 of the Android setup for Indy SDK React Native")," for the default behavior."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript"},"import fs from 'react-native-fs'\n\nconst base = fs.ExternalDirectoryPath\nconst indyClient = '.indy_client'\nconst wallet = 'wallet'\nconst walletId = agent.config.walletConfig.id\nconst file = 'sqlite.db'\n\nconst dbPath = `${base}/${indyClient}/${wallet}/${walletId}/${file}`\n")),(0,r.kt)("h4",{id:"ios"},"iOS"),(0,r.kt)("p",null,"On iOS, the database is commonly located under the ",(0,r.kt)("inlineCode",{parentName:"p"},"DocumentDirectoryPath"),"."),(0,r.kt)("p",null,"For iOS this can only change if your phone does not have the ",(0,r.kt)("inlineCode",{parentName:"p"},"HOME")," environment variable set. This is not usual behavior, and if ",(0,r.kt)("inlineCode",{parentName:"p"},"HOME")," is not set, the ",(0,r.kt)("inlineCode",{parentName:"p"},"base")," in the code section below will be ",(0,r.kt)("inlineCode",{parentName:"p"},"/home/indy/Documents"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript"},"import fs from 'react-native-fs'\n\nconst base = fs.DocumentDirectoryPath\nconst indyClient = '.indy_client'\nconst wallet = 'wallet'\nconst walletId = agent.config.walletConfig.id\nconst file = 'sqlite.db'\n\nconst dbPath = `${base}/${indyClient}/${wallet}/${walletId}/${file}`\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0ecb752f.50e94dea.js b/assets/js/0ecb752f.50e94dea.js deleted file mode 100644 index e88aaab8..00000000 --- a/assets/js/0ecb752f.50e94dea.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7824],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var d=a.createContext({}),l=function(e){var t=a.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return a.createElement(d.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,d=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),c=l(n),h=r,m=c["".concat(d,".").concat(h)]||c[h]||u[h]||i;return n?a.createElement(m,o(o({ref:t},p),{},{components:n})):a.createElement(m,o({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=h;var s={};for(var d in t)hasOwnProperty.call(t,d)&&(s[d]=t[d]);s.originalType=e,s[c]="string"==typeof e?e:r,o[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var a=n(7462),r=(n(7294),n(3905));const i={},o="Migrating from an Indy SDK Wallet to Aries Askar",s={unversionedId:"updating/update-indy-sdk-to-askar",id:"updating/update-indy-sdk-to-askar",title:"Migrating from an Indy SDK Wallet to Aries Askar",description:"This documentation explains the process of migrating your Indy SDK wallet to Aries Askar.",source:"@site/guides/updating/update-indy-sdk-to-askar.md",sourceDirName:"updating",slug:"/updating/update-indy-sdk-to-askar",permalink:"/guides/0.5/updating/update-indy-sdk-to-askar",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Update Assistant",permalink:"/guides/0.5/updating/update-assistant"},next:{title:"Migrating from Credo 0.1.0 to 0.2.x",permalink:"/guides/0.5/updating/versions/0.1-to-0.2"}},d={},l=[{value:"What does the migration do internally?",id:"what-does-the-migration-do-internally",level:2},{value:"Create a backup",id:"create-a-backup",level:3},{value:"Migrate the database to an Aries Askar structure",id:"migrate-the-database-to-an-aries-askar-structure",level:3},{value:"Try to open the wallet in the new Aries Askar structure",id:"try-to-open-the-wallet-in-the-new-aries-askar-structure",level:3},{value:"Update the keys",id:"update-the-keys",level:3},{value:"Update the DIDs",id:"update-the-dids",level:3},{value:"Update the credential definitions",id:"update-the-credential-definitions",level:3},{value:"Update the link secret(s) (master secret)",id:"update-the-link-secrets-master-secret",level:3},{value:"Update the credentials",id:"update-the-credentials",level:3},{value:"All the other records",id:"all-the-other-records",level:3},{value:"How to update",id:"how-to-update",level:2},{value:"add the required dependencies",id:"add-the-required-dependencies",level:3},{value:"Getting the database path",id:"getting-the-database-path",level:3},{value:"Android",id:"android",level:4},{value:"iOS",id:"ios",level:4}],p={toc:l},c="wrapper";function u(e){let{components:t,...n}=e;return(0,r.kt)(c,(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"migrating-from-an-indy-sdk-wallet-to-aries-askar"},"Migrating from an Indy SDK Wallet to Aries Askar"),(0,r.kt)("p",null,"This documentation explains the process of migrating your Indy SDK wallet to ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-askar"},"Aries Askar"),"."),(0,r.kt)("admonition",{type:"danger"},(0,r.kt)("p",{parentName:"admonition"},"While the migration script technically works on node.js, it is strongly advised not to use it, yet. The migration of issuer records (such as Schemas and Credential Definitions) is not implemented yet. When a credential definition is detected it will revert the migration process and no harm is done.")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Postgres is not supported. If you are using postgres with Indy SDK and need to update to Aries Askar, please open an issue on ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts"},"GitHub"),".")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"The migration script is supported to run on 0.3.x before migrating from 0.3.x to 0.4.x. Please refer to ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.5/updating/versions/0.3-to-0.4"},"Migrating from Credo 0.3.x to 0.4.x")," to get to 0.4.x afterwards."),(0,r.kt)("p",{parentName:"admonition"},"It is important to note that this script must be ran before you update from 0.3.x to 0.4.x.")),(0,r.kt)("h2",{id:"what-does-the-migration-do-internally"},"What does the migration do internally?"),(0,r.kt)("p",null,"The migration script does the following to make sure everything is migrated properly, and if anything goes wrong, it will revert back to a working state."),(0,r.kt)("h3",{id:"create-a-backup"},"Create a backup"),(0,r.kt)("p",null,"Because undefined behavior might occur, we create a backup in the new ",(0,r.kt)("inlineCode",{parentName:"p"},"tmp")," directory from Credo. if some error occurs, it will be reverted back to the backed-up state and if no error occurs, it will delete the backup from the temporary directory."),(0,r.kt)("h3",{id:"migrate-the-database-to-an-aries-askar-structure"},"Migrate the database to an Aries Askar structure"),(0,r.kt)("p",null,"The Indy-sdk and Aries Askar have different database structures. So first of all we need to change some table names, decrypt all the items with the old Indy keys, encrypt the items with the new Aries Askar keys and store them inside the new structure."),(0,r.kt)("h3",{id:"try-to-open-the-wallet-in-the-new-aries-askar-structure"},"Try to open the wallet in the new Aries Askar structure"),(0,r.kt)("p",null,"When the wallet is correctly transformed, the wallet will be attempted to be opened."),(0,r.kt)("h3",{id:"update-the-keys"},"Update the keys"),(0,r.kt)("p",null,"Aries Askar has a specific way to store keys and every key, defined by the category of ",(0,r.kt)("inlineCode",{parentName:"p"},"Indy::Key")," will be migrated."),(0,r.kt)("h3",{id:"update-the-dids"},"Update the DIDs"),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"This update script does not transform did records. This is fine for something like ",(0,r.kt)("inlineCode",{parentName:"p"},"did:peer"),", but will cause issues with ",(0,r.kt)("inlineCode",{parentName:"p"},"indy")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"sov")," DIDs. For more information, please check out the ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.5/updating/versions/0.3-to-0.4#removal-of-publicdidseed-and-publicdid"},"Migrating from Credo 0.3.x to 0.4.x"))),(0,r.kt)("h3",{id:"update-the-credential-definitions"},"Update the credential definitions"),(0,r.kt)("admonition",{type:"danger"},(0,r.kt)("p",{parentName:"admonition"},"Updating of credential definitions is not yet supported. This is why it is strongly advised not to run this script in a node.js environment.")),(0,r.kt)("h3",{id:"update-the-link-secrets-master-secret"},"Update the link secret(s) (master secret)"),(0,r.kt)("p",null,"The link secrets, identified by the category ",(0,r.kt)("inlineCode",{parentName:"p"},"Indy::MasterSecret"),", are updated next. They are stored inside a new ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsLinkSecretRecord"),"."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Since we have to set a default link secret, some additional logic is added to detect this. You can either supply a ",(0,r.kt)("inlineCode",{parentName:"p"},"defaultLinkSercetId")," as a constructor parameter or it will be based on your ",(0,r.kt)("inlineCode",{parentName:"p"},"walletId"),"."),(0,r.kt)("p",{parentName:"admonition"},"If there is no Indy record with the ",(0,r.kt)("inlineCode",{parentName:"p"},"defaultLinkSecretId")," or the ",(0,r.kt)("inlineCode",{parentName:"p"},"walletId"),", an error will be thrown and the migration will be restored.")),(0,r.kt)("h3",{id:"update-the-credentials"},"Update the credentials"),(0,r.kt)("p",null,"The credentials, identified by the category ",(0,r.kt)("inlineCode",{parentName:"p"},"Indy::Credential")," are updated last. They are stored in the new ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsCredentialRecord")," as a one-to-one copy. This means that they now support more tags and will make querying a lot easier."),(0,r.kt)("h3",{id:"all-the-other-records"},"All the other records"),(0,r.kt)("p",null,"All the other records will be transferred without any updates as they are not Indy specific."),(0,r.kt)("h2",{id:"how-to-update"},"How to update"),(0,r.kt)("p",null,"Updating does not require a lot of code, but must be done with caution."),(0,r.kt)("p",null,"It is very important to note that the migration script only has to be run once. If it runs for a second time, it will error saying that the database is already migrated. Also, when the migration is finished, it is common practice to store this state in your persistent app storage. This script does not provide a way to detect if an update has happened, so storing this value will prevent the script from running every time. For more information regarding this topic, please check out ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.5/updating/update-assistant#storing-the-agent-storage-version-outside-of-the-agent-storage"},"Update Assistant"),"."),(0,r.kt)("h3",{id:"add-the-required-dependencies"},"add the required dependencies"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @hyperledger/aries-askar-react-native @credo-ts/indy-sdk-to-askar-migration react-native-fs\n")),(0,r.kt)("p",null,"Below is the minimal code required for the migration to work. It is recommended to turn the logger on as it gives a lot of information regarding the migration."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"The agent is not allowed to be initialized to run this script. This makes sure nothing else happens during the migration.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript"},"import { agentDependencies } from '@credo-ts/react-native'\nimport { AskarModule } from '@credo-ts/askar'\nimport { IndySdkToAskarMigrationUpdater } from '@credo-ts/indy-sdk-to-askar-migration'\nimport { ariesAskar } from '@hyperledger/aries-askar-react-native'\n\nconst oldAgent = new Agent({\n config: {\n /* ... */\n },\n modules: {\n ariesAskar: new AskarModule({\n ariesAskar,\n }),\n },\n dependencies: agentDependencies,\n})\n\nconst dbPath = '' // see section below\n\nconst updater = await IndySdkToAskarMigrationUpdater.initialize({ dbPath, agent })\nawait updater.update()\n")),(0,r.kt)("h3",{id:"getting-the-database-path"},"Getting the database path"),(0,r.kt)("h4",{id:"android"},"Android"),(0,r.kt)("p",null,"On android, the database is commonly located under the ",(0,r.kt)("inlineCode",{parentName:"p"},"ExternalDirectoryPath"),"."),(0,r.kt)("p",null,"If you did not follow the default indy-sdk for React Native setup, your path might differ. Check out ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk-react-native#5-load-indy-library"},"step 5 of the Android setup for Indy SDK React Native")," for the default behavior."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript"},"import fs from 'react-native-fs'\n\nconst base = fs.ExternalDirectoryPath\nconst indyClient = '.indy_client'\nconst wallet = 'wallet'\nconst walletId = agent.config.walletConfig.id\nconst file = 'sqlite.db'\n\nconst dbPath = `${base}/${indyClient}/${wallet}/${walletId}/${file}`\n")),(0,r.kt)("h4",{id:"ios"},"iOS"),(0,r.kt)("p",null,"On iOS, the database is commonly located under the ",(0,r.kt)("inlineCode",{parentName:"p"},"DocumentDirectoryPath"),"."),(0,r.kt)("p",null,"For iOS this can only change if your phone does not have the ",(0,r.kt)("inlineCode",{parentName:"p"},"HOME")," environment variable set. This is not usual behavior, and if ",(0,r.kt)("inlineCode",{parentName:"p"},"HOME")," is not set, the ",(0,r.kt)("inlineCode",{parentName:"p"},"base")," in the code section below will be ",(0,r.kt)("inlineCode",{parentName:"p"},"/home/indy/Documents"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript"},"import fs from 'react-native-fs'\n\nconst base = fs.DocumentDirectoryPath\nconst indyClient = '.indy_client'\nconst wallet = 'wallet'\nconst walletId = agent.config.walletConfig.id\nconst file = 'sqlite.db'\n\nconst dbPath = `${base}/${indyClient}/${wallet}/${walletId}/${file}`\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0f95bd9e.8fa52356.js b/assets/js/0f95bd9e.8fa52356.js new file mode 100644 index 00000000..979495b9 --- /dev/null +++ b/assets/js/0f95bd9e.8fa52356.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7885],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(n),h=a,m=u["".concat(l,".").concat(h)]||u[h]||d[h]||o;return n?r.createElement(m,i(i({ref:t},p),{},{components:n})):r.createElement(m,i({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var r=n(7462),a=(n(7294),n(3905));const o={},i="Agents",s={unversionedId:"concepts/agents",id:"concepts/agents",title:"Agents",description:"When working with any Credo implementation, you will interact with an Credo",source:"@site/guides/concepts/agents.md",sourceDirName:"concepts",slug:"/concepts/agents",permalink:"/guides/concepts/agents",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Concepts",permalink:"/guides/concepts/"},next:{title:"DIDs and DIDComm",permalink:"/guides/concepts/did-and-didcomm"}},l={},c=[{value:"Characteristics",id:"characteristics",level:3},{value:"Categories",id:"categories",level:3},{value:"Examples",id:"examples",level:3},{value:"Useful resources",id:"useful-resources",level:3}],p={toc:c},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"agents"},"Agents"),(0,a.kt)("p",null,"When working with any Credo implementation, you will interact with an Credo\nagent. This will be either directly or via a REST API, like ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts-ext/tree/main/packages/rest"},"the Credo REST\nAPI"),"."),(0,a.kt)("h3",{id:"characteristics"},"Characteristics"),(0,a.kt)("p",null,"An Credo agent has three essential characteristics:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"It acts as a fiduciary on behalf of a single identity owner (or, for agents\nof things like IoT devices, pets, and similar things, a single controller)."),(0,a.kt)("li",{parentName:"ol"},"It holds cryptographic keys that uniquely embody its delegated\nauthorization."),(0,a.kt)("li",{parentName:"ol"},"It interacts using interoperable DIDComm protocols, more on that later.")),(0,a.kt)("p",null,"What this means is that an Credo agent will act your behalf to issue create\nconnections, issue credentials, send messages etc. It also have a cryptographic\ntoolkit with which it can uniquely, securely and verifiably operate. And lastly\nit interacts with other entities, this could be another agent, via ",(0,a.kt)("a",{parentName:"p",href:"https://identity.foundation/didcomm-messaging/spec/"},"DIDComm\nprotocols")," later on. The\nCredo agent in the context of the Credo ecosystem is your entry-point\nto all of the functionality."),(0,a.kt)("h3",{id:"categories"},"Categories"),(0,a.kt)("p",null,'There are many categories of Credo agents and we will group them into two\ncategories; a mobile agent and a cloud agent. These agents are grouped based on\ntheir "location", e.g. a mobile wallet or server. Some other categories are a\nstatic, thin, thick and rich Credo agents. These agents are grouped based on\ntheir complexity instead of their "location". The Credo ecosystem\nallows you to create a mobile agent and a cloud agent. It also allows any of\nthe complexity categorized agents.'),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("p",null,"Some examples of things that are Credo agent-like (since the definition can be\nbit loose, these examples might help to get a clearer picture):"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"A mobile wallet")),(0,a.kt)("p",null,"A mobile wallet, like\n",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-mobile-agent-react-native"},"aries-mobile-agent-react-native"),"\n, can be used to create connections, send basic messages, hold credentials,\netc. In the real world this could be an application that contains data like an\nofficial drivers license."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"An Identity hub")),(0,a.kt)("p",null,"An ",(0,a.kt)("a",{parentName:"p",href:"https://didproject.azurewebsites.net/docs/hub-overview.html"},"Identity Hub"),"\nis a personal data store that gives complete control to their owner. It allows\nfor secure sensitive data storage and sharing. Since everyone has multiple\ndevices these can be used as a more central point for your data."),(0,a.kt)("h3",{id:"useful-resources"},"Useful resources"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0004-agents/README.md"},"Hyperledger Aries RFC - 004:\nAgents"))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0f95bd9e.e27914e3.js b/assets/js/0f95bd9e.e27914e3.js deleted file mode 100644 index 5afb516b..00000000 --- a/assets/js/0f95bd9e.e27914e3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7885],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(n),h=a,m=u["".concat(l,".").concat(h)]||u[h]||d[h]||o;return n?r.createElement(m,i(i({ref:t},p),{},{components:n})):r.createElement(m,i({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var r=n(7462),a=(n(7294),n(3905));const o={},i="Agents",s={unversionedId:"concepts/agents",id:"concepts/agents",title:"Agents",description:"When working with any Credo implementation, you will interact with an Credo",source:"@site/guides/concepts/agents.md",sourceDirName:"concepts",slug:"/concepts/agents",permalink:"/guides/0.5/concepts/agents",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Concepts",permalink:"/guides/0.5/concepts/"},next:{title:"DIDs and DIDComm",permalink:"/guides/0.5/concepts/did-and-didcomm"}},l={},c=[{value:"Characteristics",id:"characteristics",level:3},{value:"Categories",id:"categories",level:3},{value:"Examples",id:"examples",level:3},{value:"Useful resources",id:"useful-resources",level:3}],p={toc:c},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"agents"},"Agents"),(0,a.kt)("p",null,"When working with any Credo implementation, you will interact with an Credo\nagent. This will be either directly or via a REST API, like ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts-ext/tree/main/packages/rest"},"the Credo REST\nAPI"),"."),(0,a.kt)("h3",{id:"characteristics"},"Characteristics"),(0,a.kt)("p",null,"An Credo agent has three essential characteristics:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"It acts as a fiduciary on behalf of a single identity owner (or, for agents\nof things like IoT devices, pets, and similar things, a single controller)."),(0,a.kt)("li",{parentName:"ol"},"It holds cryptographic keys that uniquely embody its delegated\nauthorization."),(0,a.kt)("li",{parentName:"ol"},"It interacts using interoperable DIDComm protocols, more on that later.")),(0,a.kt)("p",null,"What this means is that an Credo agent will act your behalf to issue create\nconnections, issue credentials, send messages etc. It also have a cryptographic\ntoolkit with which it can uniquely, securely and verifiably operate. And lastly\nit interacts with other entities, this could be another agent, via ",(0,a.kt)("a",{parentName:"p",href:"https://identity.foundation/didcomm-messaging/spec/"},"DIDComm\nprotocols")," later on. The\nCredo agent in the context of the Credo ecosystem is your entry-point\nto all of the functionality."),(0,a.kt)("h3",{id:"categories"},"Categories"),(0,a.kt)("p",null,'There are many categories of Credo agents and we will group them into two\ncategories; a mobile agent and a cloud agent. These agents are grouped based on\ntheir "location", e.g. a mobile wallet or server. Some other categories are a\nstatic, thin, thick and rich Credo agents. These agents are grouped based on\ntheir complexity instead of their "location". The Credo ecosystem\nallows you to create a mobile agent and a cloud agent. It also allows any of\nthe complexity categorized agents.'),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("p",null,"Some examples of things that are Credo agent-like (since the definition can be\nbit loose, these examples might help to get a clearer picture):"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"A mobile wallet")),(0,a.kt)("p",null,"A mobile wallet, like\n",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-mobile-agent-react-native"},"aries-mobile-agent-react-native"),"\n, can be used to create connections, send basic messages, hold credentials,\netc. In the real world this could be an application that contains data like an\nofficial drivers license."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"An Identity hub")),(0,a.kt)("p",null,"An ",(0,a.kt)("a",{parentName:"p",href:"https://didproject.azurewebsites.net/docs/hub-overview.html"},"Identity Hub"),"\nis a personal data store that gives complete control to their owner. It allows\nfor secure sensitive data storage and sharing. Since everyone has multiple\ndevices these can be used as a more central point for your data."),(0,a.kt)("h3",{id:"useful-resources"},"Useful resources"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0004-agents/README.md"},"Hyperledger Aries RFC - 004:\nAgents"))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/14973ffc.3812a945.js b/assets/js/14973ffc.99604b3e.js similarity index 77% rename from assets/js/14973ffc.3812a945.js rename to assets/js/14973ffc.99604b3e.js index 9cdd486d..2cdea11e 100644 --- a/assets/js/14973ffc.3812a945.js +++ b/assets/js/14973ffc.99604b3e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[5554],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var u=n.createContext({}),i=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=i(e.components);return n.createElement(u.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,u=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=i(r),m=a,f=p["".concat(u,".").concat(m)]||p[m]||d[m]||o;return r?n.createElement(f,l(l({ref:t},c),{},{components:r})):n.createElement(f,l({ref:t},c))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=m;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s[p]="string"==typeof e?e:a,l[1]=s;for(var i=2;i{r.d(t,{Z:()=>l});var n=r(7294),a=r(6010);const o={tabItem:"tabItem_Ymn6"};function l(e){let{children:t,hidden:r,className:l}=e;return n.createElement("div",{role:"tabpanel",className:(0,a.Z)(o.tabItem,l),hidden:r},t)}},4866:(e,t,r)=>{r.d(t,{Z:()=>x});var n=r(7462),a=r(7294),o=r(6010),l=r(2466),s=r(6550),u=r(1980),i=r(7392),c=r(12);function p(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:r,attributes:n,default:a}}=e;return{value:t,label:r,attributes:n,default:a}}))}function d(e){const{values:t,children:r}=e;return(0,a.useMemo)((()=>{const e=t??p(r);return function(e){const t=(0,i.l)(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,r])}function m(e){let{value:t,tabValues:r}=e;return r.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:r}=e;const n=(0,s.k6)(),o=function(e){let{queryString:t=!1,groupId:r}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!r)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 r??null}({queryString:t,groupId:r});return[(0,u._X)(o),(0,a.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(n.location.search);t.set(o,e),n.replace({...n.location,search:t.toString()})}),[o,n])]}function b(e){const{defaultValue:t,queryString:r=!1,groupId:n}=e,o=d(e),[l,s]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:r}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=r.find((e=>e.default))??r[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:o}))),[u,i]=f({queryString:r,groupId:n}),[p,b]=function(e){let{groupId:t}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,o]=(0,c.Nk)(r);return[n,(0,a.useCallback)((e=>{r&&o.set(e)}),[r,o])]}({groupId:n}),h=(()=>{const e=u??p;return m({value:e,tabValues:o})?e:null})();(0,a.useLayoutEffect)((()=>{h&&s(h)}),[h]);return{selectedValue:l,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);s(e),i(e),b(e)}),[i,b,o]),tabValues:o}}var h=r(2389);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function g(e){let{className:t,block:r,selectedValue:s,selectValue:u,tabValues:i}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,l.o5)(),d=e=>{const t=e.currentTarget,r=c.indexOf(t),n=i[r].value;n!==s&&(p(t),u(n))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const r=c.indexOf(e.currentTarget)+1;t=c[r]??c[0];break}case"ArrowLeft":{const r=c.indexOf(e.currentTarget)-1;t=c[r]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":r},t)},i.map((e=>{let{value:t,label:r,attributes:l}=e;return a.createElement("li",(0,n.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},l,{className:(0,o.Z)("tabs__item",v.tabItem,l?.className,{"tabs__item--active":s===t})}),r??t)})))}function y(e){let{lazy:t,children:r,selectedValue:n}=e;if(r=Array.isArray(r)?r:[r],t){const e=r.find((e=>e.props.value===n));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},r.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==n}))))}function k(e){const t=b(e);return a.createElement("div",{className:(0,o.Z)("tabs-container",v.tabList)},a.createElement(g,(0,n.Z)({},e,t)),a.createElement(y,(0,n.Z)({},e,t)))}function x(e){const t=(0,h.Z)();return a.createElement(k,(0,n.Z)({key:String(t)},e))}},4814:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>u,default:()=>f,frontMatter:()=>s,metadata:()=>i,toc:()=>p});var n=r(7462),a=(r(7294),r(3905)),o=r(4866),l=r(5162);const s={},u="Redux Store",i={unversionedId:"extensions/redux-store",id:"version-0.4/extensions/redux-store",title:"Redux Store",description:"The Redux Store is an implementation of state management that can be used to build React & React Native SSI clients using AFJ.",source:"@site/versioned_docs/version-0.4/extensions/redux-store.md",sourceDirName:"extensions",slug:"/extensions/redux-store",permalink:"/guides/extensions/redux-store",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"React Hooks",permalink:"/guides/extensions/react-hooks"},next:{title:"Push Notifications",permalink:"/guides/extensions/push-notifications"}},c={},p=[{value:"Installation",id:"installation",level:2},{value:"npm",id:"npm",level:2},{value:"Yarn",id:"yarn",level:2}],d={toc:p},m="wrapper";function f(e){let{components:t,...r}=e;return(0,a.kt)(m,(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"redux-store"},"Redux Store"),(0,a.kt)("p",null,"The Redux Store is an implementation of state management that can be used to build React & React Native SSI clients using AFJ."),(0,a.kt)("p",null,"The Redux Store allows you to integrate state management for the most important parts of using AFJ in a client application (mediation, connections, credentials and proofs), allowing you to sync UI state with the state of the agent as it interacts with other agents through the framework."),(0,a.kt)("admonition",{type:"note"},(0,a.kt)("p",{parentName:"admonition"},"This document is for version ",(0,a.kt)("strong",{parentName:"p"},(0,a.kt)("inlineCode",{parentName:"strong"},"0.4.x"))," of the ",(0,a.kt)("inlineCode",{parentName:"p"},"@aries-framework/redux-store")," package, that works with ",(0,a.kt)("inlineCode",{parentName:"p"},"@aries-framework/core")," version ",(0,a.kt)("strong",{parentName:"p"},(0,a.kt)("inlineCode",{parentName:"strong"},"0.4.x")),". Extension packages (such as Redux Store) are versioned separately from the core packages.")),(0,a.kt)("h2",{id:"installation"},"Installation"),(0,a.kt)("p",null,"To add the Redux Store package to your existing project simply run:"),(0,a.kt)(o.Z,{mdxType:"Tabs"},(0,a.kt)(l.Z,{label:"npm",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"npm i @aries-framework/redux-store\n"))),(0,a.kt)(l.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/redux-store\n")))))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[5554],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var u=n.createContext({}),i=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=i(e.components);return n.createElement(u.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,u=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=i(r),m=a,f=p["".concat(u,".").concat(m)]||p[m]||d[m]||o;return r?n.createElement(f,l(l({ref:t},c),{},{components:r})):n.createElement(f,l({ref:t},c))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=m;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s[p]="string"==typeof e?e:a,l[1]=s;for(var i=2;i{r.d(t,{Z:()=>l});var n=r(7294),a=r(6010);const o={tabItem:"tabItem_Ymn6"};function l(e){let{children:t,hidden:r,className:l}=e;return n.createElement("div",{role:"tabpanel",className:(0,a.Z)(o.tabItem,l),hidden:r},t)}},4866:(e,t,r)=>{r.d(t,{Z:()=>x});var n=r(7462),a=r(7294),o=r(6010),l=r(2466),s=r(6550),u=r(1980),i=r(7392),c=r(12);function p(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:r,attributes:n,default:a}}=e;return{value:t,label:r,attributes:n,default:a}}))}function d(e){const{values:t,children:r}=e;return(0,a.useMemo)((()=>{const e=t??p(r);return function(e){const t=(0,i.l)(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,r])}function m(e){let{value:t,tabValues:r}=e;return r.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:r}=e;const n=(0,s.k6)(),o=function(e){let{queryString:t=!1,groupId:r}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!r)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 r??null}({queryString:t,groupId:r});return[(0,u._X)(o),(0,a.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(n.location.search);t.set(o,e),n.replace({...n.location,search:t.toString()})}),[o,n])]}function b(e){const{defaultValue:t,queryString:r=!1,groupId:n}=e,o=d(e),[l,s]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:r}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=r.find((e=>e.default))??r[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:o}))),[u,i]=f({queryString:r,groupId:n}),[p,b]=function(e){let{groupId:t}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,o]=(0,c.Nk)(r);return[n,(0,a.useCallback)((e=>{r&&o.set(e)}),[r,o])]}({groupId:n}),h=(()=>{const e=u??p;return m({value:e,tabValues:o})?e:null})();(0,a.useLayoutEffect)((()=>{h&&s(h)}),[h]);return{selectedValue:l,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);s(e),i(e),b(e)}),[i,b,o]),tabValues:o}}var h=r(2389);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function g(e){let{className:t,block:r,selectedValue:s,selectValue:u,tabValues:i}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,l.o5)(),d=e=>{const t=e.currentTarget,r=c.indexOf(t),n=i[r].value;n!==s&&(p(t),u(n))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const r=c.indexOf(e.currentTarget)+1;t=c[r]??c[0];break}case"ArrowLeft":{const r=c.indexOf(e.currentTarget)-1;t=c[r]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":r},t)},i.map((e=>{let{value:t,label:r,attributes:l}=e;return a.createElement("li",(0,n.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},l,{className:(0,o.Z)("tabs__item",v.tabItem,l?.className,{"tabs__item--active":s===t})}),r??t)})))}function y(e){let{lazy:t,children:r,selectedValue:n}=e;if(r=Array.isArray(r)?r:[r],t){const e=r.find((e=>e.props.value===n));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},r.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==n}))))}function k(e){const t=b(e);return a.createElement("div",{className:(0,o.Z)("tabs-container",v.tabList)},a.createElement(g,(0,n.Z)({},e,t)),a.createElement(y,(0,n.Z)({},e,t)))}function x(e){const t=(0,h.Z)();return a.createElement(k,(0,n.Z)({key:String(t)},e))}},4814:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>u,default:()=>f,frontMatter:()=>s,metadata:()=>i,toc:()=>p});var n=r(7462),a=(r(7294),r(3905)),o=r(4866),l=r(5162);const s={},u="Redux Store",i={unversionedId:"extensions/redux-store",id:"version-0.4/extensions/redux-store",title:"Redux Store",description:"The Redux Store is an implementation of state management that can be used to build React & React Native SSI clients using AFJ.",source:"@site/versioned_docs/version-0.4/extensions/redux-store.md",sourceDirName:"extensions",slug:"/extensions/redux-store",permalink:"/guides/0.4/extensions/redux-store",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"React Hooks",permalink:"/guides/0.4/extensions/react-hooks"},next:{title:"Push Notifications",permalink:"/guides/0.4/extensions/push-notifications"}},c={},p=[{value:"Installation",id:"installation",level:2},{value:"npm",id:"npm",level:2},{value:"Yarn",id:"yarn",level:2}],d={toc:p},m="wrapper";function f(e){let{components:t,...r}=e;return(0,a.kt)(m,(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"redux-store"},"Redux Store"),(0,a.kt)("p",null,"The Redux Store is an implementation of state management that can be used to build React & React Native SSI clients using AFJ."),(0,a.kt)("p",null,"The Redux Store allows you to integrate state management for the most important parts of using AFJ in a client application (mediation, connections, credentials and proofs), allowing you to sync UI state with the state of the agent as it interacts with other agents through the framework."),(0,a.kt)("admonition",{type:"note"},(0,a.kt)("p",{parentName:"admonition"},"This document is for version ",(0,a.kt)("strong",{parentName:"p"},(0,a.kt)("inlineCode",{parentName:"strong"},"0.4.x"))," of the ",(0,a.kt)("inlineCode",{parentName:"p"},"@aries-framework/redux-store")," package, that works with ",(0,a.kt)("inlineCode",{parentName:"p"},"@aries-framework/core")," version ",(0,a.kt)("strong",{parentName:"p"},(0,a.kt)("inlineCode",{parentName:"strong"},"0.4.x")),". Extension packages (such as Redux Store) are versioned separately from the core packages.")),(0,a.kt)("h2",{id:"installation"},"Installation"),(0,a.kt)("p",null,"To add the Redux Store package to your existing project simply run:"),(0,a.kt)(o.Z,{mdxType:"Tabs"},(0,a.kt)(l.Z,{label:"npm",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"npm i @aries-framework/redux-store\n"))),(0,a.kt)(l.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/redux-store\n")))))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/14e53ecf.d02e9688.js b/assets/js/14e53ecf.d02e9688.js deleted file mode 100644 index acffcddf..00000000 --- a/assets/js/14e53ecf.d02e9688.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[1904],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>h});var a=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function o(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var s=a.createContext({}),l=function(e){var n=a.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},p=function(e){var n=l(e.components);return a.createElement(s.Provider,{value:n},e.children)},c="mdxType",m={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},u=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,p=d(e,["components","mdxType","originalType","parentName"]),c=l(t),u=r,h=c["".concat(s,".").concat(u)]||c[u]||m[u]||i;return t?a.createElement(h,o(o({ref:n},p),{},{components:t})):a.createElement(h,o({ref:n},p))}));function h(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var i=t.length,o=new Array(i);o[0]=u;var d={};for(var s in n)hasOwnProperty.call(n,s)&&(d[s]=n[s]);d.originalType=e,d[c]="string"==typeof e?e:r,o[1]=d;for(var l=2;l{t.d(n,{Z:()=>o});var a=t(7294),r=t(6010);const i={tabItem:"tabItem_Ymn6"};function o(e){let{children:n,hidden:t,className:o}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(i.tabItem,o),hidden:t},n)}},4866:(e,n,t)=>{t.d(n,{Z:()=>w});var a=t(7462),r=t(7294),i=t(6010),o=t(2466),d=t(6550),s=t(1980),l=t(7392),p=t(12);function c(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:n,label:t,attributes:a,default:r}}=e;return{value:n,label:t,attributes:a,default:r}}))}function m(e){const{values:n,children:t}=e;return(0,r.useMemo)((()=>{const e=n??c(t);return function(e){const n=(0,l.l)(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 u(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function h(e){let{queryString:n=!1,groupId:t}=e;const a=(0,d.k6)(),i=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,s._X)(i),(0,r.useCallback)((e=>{if(!i)return;const n=new URLSearchParams(a.location.search);n.set(i,e),a.replace({...a.location,search:n.toString()})}),[i,a])]}function k(e){const{defaultValue:n,queryString:t=!1,groupId:a}=e,i=m(e),[o,d]=(0,r.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(!u({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 a=t.find((e=>e.default))??t[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:n,tabValues:i}))),[s,l]=h({queryString:t,groupId:a}),[c,k]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[a,i]=(0,p.Nk)(t);return[a,(0,r.useCallback)((e=>{t&&i.set(e)}),[t,i])]}({groupId:a}),g=(()=>{const e=s??c;return u({value:e,tabValues:i})?e:null})();(0,r.useLayoutEffect)((()=>{g&&d(g)}),[g]);return{selectedValue:o,selectValue:(0,r.useCallback)((e=>{if(!u({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);d(e),l(e),k(e)}),[l,k,i]),tabValues:i}}var g=t(2389);const f={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){let{className:n,block:t,selectedValue:d,selectValue:s,tabValues:l}=e;const p=[],{blockElementScrollPositionUntilNextRender:c}=(0,o.o5)(),m=e=>{const n=e.currentTarget,t=p.indexOf(n),a=l[t].value;a!==d&&(c(n),s(a))},u=e=>{let n=null;switch(e.key){case"Enter":m(e);break;case"ArrowRight":{const t=p.indexOf(e.currentTarget)+1;n=p[t]??p[0];break}case"ArrowLeft":{const t=p.indexOf(e.currentTarget)-1;n=p[t]??p[p.length-1];break}}n?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":t},n)},l.map((e=>{let{value:n,label:t,attributes:o}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:d===n?0:-1,"aria-selected":d===n,key:n,ref:e=>p.push(e),onKeyDown:u,onClick:m},o,{className:(0,i.Z)("tabs__item",f.tabItem,o?.className,{"tabs__item--active":d===n})}),t??n)})))}function v(e){let{lazy:n,children:t,selectedValue:a}=e;if(t=Array.isArray(t)?t:[t],n){const e=t.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},t.map(((e,n)=>(0,r.cloneElement)(e,{key:n,hidden:e.props.value!==a}))))}function b(e){const n=k(e);return r.createElement("div",{className:(0,i.Z)("tabs-container",f.tabList)},r.createElement(y,(0,a.Z)({},e,n)),r.createElement(v,(0,a.Z)({},e,n)))}function w(e){const n=(0,g.Z)();return r.createElement(b,(0,a.Z)({key:String(n)},e))}},3635:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>s,default:()=>h,frontMatter:()=>d,metadata:()=>l,toc:()=>c});var a=t(7462),r=(t(7294),t(3905)),i=t(4866),o=t(5162);const d={},s="Migrating from Credo 0.3.x to 0.4.x",l={unversionedId:"updating/versions/0.3-to-0.4",id:"updating/versions/0.3-to-0.4",title:"Migrating from Credo 0.3.x to 0.4.x",description:"This document describes everything you need to know for updating Credo 0.3.x to 0.4.x. If you're not aware of how updating in Credo works make sure to first read the guide on Updating Credo.",source:"@site/guides/updating/versions/0.3-to-0.4.md",sourceDirName:"updating/versions",slug:"/updating/versions/0.3-to-0.4",permalink:"/guides/0.5/updating/versions/0.3-to-0.4",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Migrating from Credo 0.2.x to 0.3.x",permalink:"/guides/0.5/updating/versions/0.2-to-0.3"},next:{title:"The Credo Ecosystem",permalink:"/guides/0.5/ecosystem/"}},p={},c=[{value:"React Native",id:"react-native",level:4},{value:"Node",id:"node",level:4},{value:"Breaking Code Changes",id:"breaking-code-changes",level:2},{value:"Agent Creation",id:"agent-creation",level:3},{value:"0.3.x",id:"03x",level:5},{value:"0.4.x",id:"04x",level:5},{value:"Indy Network Configuration",id:"indy-network-configuration",level:3},{value:"0.3.x",id:"03x-1",level:5},{value:"0.4.x",id:"04x-1",level:5},{value:"Changes to wallet",id:"changes-to-wallet",level:3},{value:"Did Resolver and Registrar",id:"did-resolver-and-registrar",level:3},{value:"0.3.x",id:"03x-2",level:5},{value:"0.4.x",id:"04x-2",level:5},{value:"Removal of publicDidSeed and publicDid",id:"removal-of-publicdidseed-and-publicdid",level:3},{value:"0.3.x",id:"03x-3",level:5},{value:"0.4.x",id:"04x-3",level:5},{value:"More Granular Usage of Legacy did:sov Prefix in DIDComm Messages",id:"more-granular-usage-of-legacy-didsov-prefix-in-didcomm-messages",level:3},{value:"0.3.x",id:"03x-4",level:5},{value:"0.4.x",id:"04x-4",level:5},{value:"Removal of injectionContainer property from the agent",id:"removal-of-injectioncontainer-property-from-the-agent",level:3},{value:"connection has been updated to connectionId in TransportSession",id:"connection-has-been-updated-to-connectionid-in-transportsession",level:3},{value:"Replacement of Ledger Module with new AnonCreds Module",id:"replacement-of-ledger-module-with-new-anoncreds-module",level:3},{value:"0.3.x",id:"03x-5",level:5},{value:"0.4.x",id:"04x-5",level:5},{value:"Changes to the Credentials and Proofs modules",id:"changes-to-the-credentials-and-proofs-modules",level:3},{value:"Changes to the AnonCreds Credential and Proof Format",id:"changes-to-the-anoncreds-credential-and-proof-format",level:3},{value:"0.3.x",id:"03x-6",level:5},{value:"0.4.x",id:"04x-6",level:5},{value:"Removal of AnonCreds Master Secret management from Wallet",id:"removal-of-anoncreds-master-secret-management-from-wallet",level:3},{value:"Default Outbound DIDComm Content Type now application/didcomm-envelope-enc",id:"default-outbound-didcomm-content-type-now-applicationdidcomm-envelope-enc",level:3},{value:"0.3.x",id:"03x-7",level:5},{value:"0.4.x",id:"04x-7",level:5},{value:"Generalizing Indy properties in CredentialExchangeRecord",id:"generalizing-indy-properties-in-credentialexchangerecord",level:3},{value:"credentialRecordType",id:"credentialrecordtype",level:4},{value:"0.3.x",id:"03x-8",level:5},{value:"0.4.x",id:"04x-8",level:5},{value:"Metadata",id:"metadata",level:4},{value:"0.3.x",id:"03x-9",level:5},{value:"0.4.x",id:"04x-9",level:5},{value:"More paths in FileSystem",id:"more-paths-in-filesystem",level:3},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:2}],m={toc:c},u="wrapper";function h(e){let{components:n,...t}=e;return(0,r.kt)(u,(0,a.Z)({},m,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"migrating-from-credo-03x-to-04x"},"Migrating from Credo 0.3.x to 0.4.x"),(0,r.kt)("p",null,"This document describes everything you need to know for updating Credo 0.3.x to 0.4.x. If you're not aware of how updating in Credo works make sure to first read the guide on ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.5/updating/"},"Updating Credo"),"."),(0,r.kt)("p",null,"First of all, update you dependencies to the 0.4.x versions. This will also update the needed peer dependencies. ",(0,r.kt)("strong",{parentName:"p"},"Extension packages are not updated with this command"),". You need to update these manually, and make sure they're up to date with the latest version of Credo."),(0,r.kt)("p",null,"Credo 0.4.0 is a major release that introduces a lot of new features and changes to the public API. Specifically, this release removed the dependency on the Indy SDK from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/core")," package. Agent setup is more flexible, but it also means the setup is more complex. Follow the mentioned steps in this document carefully to make the upgrade as smooth as possible."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"The migration guide only covers how to migrate from 0.3.x to 0.4.x while keeping the same behavior and dependencies. Credo 0.4.0 introduced a lot of new features and adds support for ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-askar"},"Aries Askar"),", ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-vdr"},"Indy VDR")," and ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/anoncreds-rs"},"AnonCreds RS")," as a replacement for the Indy SDK."),(0,r.kt)("p",{parentName:"admonition"},"Migrating to these new components requires additional migration steps, which need to be closely followed to prevent loss of data. These can be found at the ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.5/updating/update-indy-sdk-to-askar"},"Update Indy SDK to Askar guide"),"."),(0,r.kt)("p",{parentName:"admonition"},"As noted in the ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.5/updating/update-indy-sdk-to-askar"},"Update Indy SDK to Askar guide"),", it is very important that the 0.3.x to 0.4.x update is started after migrating from the Indy SDK to Aries Askar.")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Multi-tenancy is not covered in the 0.3.x to 0.4.x migration guide. If you're using multi-tenancy in 0.3.x and want to migrate to 0.4.x, please open an issue on ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts"},"Github"),".")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"The following APIs, modules and features are experimental and therefore not covered by the semver versioning in Credo. If you're using any of these features, make sure to use an exact version of Credo (",(0,r.kt)("inlineCode",{parentName:"p"},"0.4.0"),") instead of a range (",(0,r.kt)("inlineCode",{parentName:"p"},"^0.4.0"),"):"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},"Implementing your own ",(0,r.kt)("inlineCode",{parentName:"li"},"AnonCredsRegistry")," and AnonCreds service implementation. Using the default implementations (Indy SDK, AnonCreds RS) is fine."),(0,r.kt)("li",{parentName:"ul"},"Using the shared component libraries from ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/aries-askar"),", ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/indy-vdr")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/anoncreds-rs")),(0,r.kt)("li",{parentName:"ul"},"Using OpenID4VC from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/openid4vc-client")," module"),(0,r.kt)("li",{parentName:"ul"},"W3C JWT Verifiable Credentials"),(0,r.kt)("li",{parentName:"ul"},"Using multi-tenancy from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/tenants")," module"))),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"React Native",value:"tab1",mdxType:"TabItem"},(0,r.kt)("p",null,"First install the updated dependencies. Make sure to also install the new ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/indy-sdk")," package, which is a wrapper around the Indy SDK and install the ",(0,r.kt)("inlineCode",{parentName:"p"},"indy-sdk-react-native")," package."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/react-native@^0.4.0 @aries-framework/core@^0.4.0 @aries-framework/indy-sdk@^0.4.0 @aries-framework/anoncreds@^0.4.0 indy-sdk-react-native@^0.3.1\n\n# or NPM\nnpn install @aries-framework/react-native@^0.4.0 @aries-framework/core@^0.4.0 @aries-framework/indy-sdk@^0.4.0 @aries-framework/anoncreds@^0.4.0 indy-sdk-react-native@^0.3.1\n")),(0,r.kt)("p",null,"We also need to install types for the ",(0,r.kt)("inlineCode",{parentName:"p"},"indy-sdk-react-native")," package, which we take from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@types/indy-sdk")," package."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add --dev @types/indy-sdk-react-native@npm:@types/indy-sdk\n\n# or NPM\nnpm install --save-dev @types/indy-sdk-react-native@npm:@types/indy-sdk\n"))),(0,r.kt)(o.Z,{label:"Node",value:"tab2",mdxType:"TabItem"},(0,r.kt)("p",null,"First install the updated dependencies. Make sure to also install the new ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/indy-sdk")," package, which is a wrapper around the Indy SDK and install the ",(0,r.kt)("inlineCode",{parentName:"p"},"indy-sdk")," package itself."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/node@^0.4.0 @aries-framework/core@^0.4.0 @aries-framework/indy-sdk@^0.4.0 @aries-framework/anoncreds@^0.4.0 indy-sdk\n\n# or NPM\nnpm install @aries-framework/node@^0.4.0 @aries-framework/core@^0.4.0 @aries-framework/indy-sdk@^0.4.0 @aries-framework/anoncreds@^0.4.0 indy-sdk\n")),(0,r.kt)("p",null,"We also need to install types for the ",(0,r.kt)("inlineCode",{parentName:"p"},"indy-sdk")," package, which are available in the ",(0,r.kt)("inlineCode",{parentName:"p"},"@types/indy-sdk")," package."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add --dev @types/indy-sdk\n\n# or NPM\nnpm install --save-dev @types/indy-sdk\n")))),(0,r.kt)("h2",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,r.kt)("p",null,"This section will list all breaking changes made to the public API of Credo between version 0.3.x and 0.4.0."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here, but it is possible some breaking changes are not documented here (feel free to open a pull request).")),(0,r.kt)("h3",{id:"agent-creation"},"Agent Creation"),(0,r.kt)("p",null,"With the dependency on the Indy SDK removed from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/core")," package, we now need to register the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," to still leverage the functionality the Indy SDK provides."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\nimport { IndySdkModule } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n // Register the IndySdkModule and provide the indySdk dependency\n indySdk: new IndySdkModule({\n indySdk,\n }),\n },\n})\n")))),(0,r.kt)("h3",{id:"indy-network-configuration"},"Indy Network Configuration"),(0,r.kt)("p",null,"With the Indy SDK being extracted out of core, the ",(0,r.kt)("inlineCode",{parentName:"p"},"indyLedger")," configuration option is no longer available on the ",(0,r.kt)("inlineCode",{parentName:"p"},"AgentConfig")," interface. Instead, the ",(0,r.kt)("inlineCode",{parentName:"p"},"networks")," configuration option is now available on the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," configuration."),(0,r.kt)("p",null,"In addition the ",(0,r.kt)("inlineCode",{parentName:"p"},"connectToIndyLedgersOnStartup")," property has been removed in favor of a per-network ",(0,r.kt)("inlineCode",{parentName:"p"},"connectOnStartup")," property that allows more fine-grained control over which networks to connect to on startup."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n connectToIndyLedgersOnStartup: true,\n indyLedgers: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\nimport { IndySdkModule } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n // Register the IndySdkModule and provide the indySdk dependency\n indySdk: new IndySdkModule({\n indySdk,\n\n // add networks as a replacement for indyLedgers\n networks: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n // new connectOnStartup property\n connectOnStartup: true,\n },\n ],\n }),\n },\n})\n")))),(0,r.kt)("h3",{id:"changes-to-wallet"},"Changes to wallet"),(0,r.kt)("p",null,"Throughout the framework it was possible to provide a ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," for deterministic key generation. Recently it was discovered that the ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," property in the Indy SDK was not actually used as a seed, but directly as the private key."),(0,r.kt)("p",null,"Therefore a new ",(0,r.kt)("inlineCode",{parentName:"p"},"privateKey")," property was added to the ",(0,r.kt)("inlineCode",{parentName:"p"},"Wallet")," interface in addition to the ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," property. When using the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," this now means you can ",(0,r.kt)("strong",{parentName:"p"},"only")," provide the ",(0,r.kt)("inlineCode",{parentName:"p"},"privateKey")," property. The ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," property is no longer supported ",(0,r.kt)("strong",{parentName:"p"},"by the ",(0,r.kt)("inlineCode",{parentName:"strong"},"IndySdkModule")),"."),(0,r.kt)("p",null,"The type of the ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," property has also been changed to ",(0,r.kt)("inlineCode",{parentName:"p"},"Buffer")," to make it more consistent with ",(0,r.kt)("inlineCode",{parentName:"p"},"privateKey")," property, and remove the ambiguity of what the encoding of the string variant of the ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," property should be."),(0,r.kt)("h3",{id:"did-resolver-and-registrar"},"Did Resolver and Registrar"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"did:sov")," resolver and registrar were registered by default in 0.3.x of the agent. In 0.4.0 they've been moved to the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/indy-sdk")," package and are thus not registered by default on the DIDs module anymore. In addition, the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkSovDidRegistrar")," has been replaced in favor of the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkIndyDidRegistrar")," which provides similar behavior, but leverages the new ",(0,r.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/indy-did-method/#indy-did-method-identifiers"},(0,r.kt)("inlineCode",{parentName:"a"},"did:indy")," method"),", which removes ambiguity about which network to use. You can still use the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkSovDidResolver")," to resolve ",(0,r.kt)("inlineCode",{parentName:"p"},"did:sov")," DIDs."),(0,r.kt)("p",null,"Note that the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," MUST be registered when using the Indy SDK did resolvers and registrars (see ",(0,r.kt)("a",{parentName:"p",href:"#agent-creation"},"Agent Creation"),"). The networks supported by the resolvers and registrar is determined by the ",(0,r.kt)("inlineCode",{parentName:"p"},"networks")," registered on the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," (see ",(0,r.kt)("a",{parentName:"p",href:"#indy-network-configuration"},"Indy Network Configuration"),")."),(0,r.kt)("p",null,"Also note that by default the ",(0,r.kt)("inlineCode",{parentName:"p"},"WebDidResolver"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"KeyDidResolver")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"PeerDidResolver")," are registered, and setting the ",(0,r.kt)("inlineCode",{parentName:"p"},"resolvers")," property on the ",(0,r.kt)("inlineCode",{parentName:"p"},"DidsModule")," configuration will override the default resolvers (an exception is the ",(0,r.kt)("inlineCode",{parentName:"p"},"PeerDidResolver")," as it is required for creating connections, and thus will always be registered)."),(0,r.kt)("p",null,"The same thing is true for the ",(0,r.kt)("inlineCode",{parentName:"p"},"registrars"),", for which the ",(0,r.kt)("inlineCode",{parentName:"p"},"KeyDidRegistrar")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"PeerDidRegistrar")," are registered by default. If defining the ",(0,r.kt)("inlineCode",{parentName:"p"},"resolvers")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"registrars"),", make sure to include the default registrars if you want to keep the previous behavior."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent, DidsModule } from '@aries-framework/core'\nimport { IndySdkModule } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n // note that the IndySdkModule MUST be registered for the resolvers and registrars to work\n // they are left out for brevity and can bee\n dids: new DidsModule({\n registrars: [new IndySdkIndyDidRegistrar()],\n resolvers: [new IndySdkSovDidResolver(), new IndySdkIndyDidResolver()],\n }),\n },\n})\n")))),(0,r.kt)("h3",{id:"removal-of-publicdidseed-and-publicdid"},"Removal of ",(0,r.kt)("inlineCode",{parentName:"h3"},"publicDidSeed")," and ",(0,r.kt)("inlineCode",{parentName:"h3"},"publicDid")),(0,r.kt)("p",null,"To make Credo more generic, and less focused on Hyperledger Indy, and Indy dids, the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDidSeed")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDid")," properties have been removed from the agent configuration, the agent class, and the ",(0,r.kt)("inlineCode",{parentName:"p"},"Wallet")," interface."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDid")," property was used as the did to register items in the ledger module. The approach had some limitations:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"An agent could only have a single ",(0,r.kt)("inlineCode",{parentName:"li"},"publicDid")," property. This means that if you wanted to write to multiple ledgers you would have to create multiple agents"),(0,r.kt)("li",{parentName:"ul"},"The property assumed only Indy ledgers would be used, and didn't take into account the possibility of other ledgers.")),(0,r.kt)("p",null,"Credo now provides generic APIs that can work with any ledger, and thus the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDid")," property is no longer needed. Different sections of this migration guide will explain the different parts of how to use the new APIs, this section just focuses on how to replace the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDid")," property."),(0,r.kt)("p",null,"The most common use case for the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDid")," property was for registering an endorser did that can endorse (read: pay for) transactions on the ledger. This can now be done by importing the did into agent, after which it can be used by the AnonCreds module to register schemas and credential definitions, and the did registrar to register DIDs."),(0,r.kt)("p",null,"There's a ",(0,r.kt)("strong",{parentName:"p"},"one-time import")," that needs to be done to import the did into the agent using the ",(0,r.kt)("inlineCode",{parentName:"p"},"DidsApi.import")," method. If you've previously used the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDidSeed")," property, providing the private key is optional, as it is already stored in the wallet. Note that the ",(0,r.kt)("inlineCode",{parentName:"p"},"privateKey")," is the same as the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDidSeed"),", see ",(0,r.kt)("a",{parentName:"p",href:"#changes-to-wallet"},"Changes to Wallet")," for context). The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," method will resolve the did passed to the ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," method (so make sure to register the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkIndyDidResolver"),"). It is recommended to import the endorser did as an ",(0,r.kt)("inlineCode",{parentName:"p"},"did:indy")," did rather than a ",(0,r.kt)("inlineCode",{parentName:"p"},"did:sov")," did, as the ",(0,r.kt)("inlineCode",{parentName:"p"},"did:sov")," method is deprecated for creation. The ",(0,r.kt)("inlineCode",{parentName:"p"},"did:indy")," did can be constructed by replacing ",(0,r.kt)("inlineCode",{parentName:"p"},"sov")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"indy:"),", where ",(0,r.kt)("inlineCode",{parentName:"p"},"")," should be replaced with a namespace as registered in the ",(0,r.kt)("inlineCode",{parentName:"p"},"networks")," property of the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," (see ",(0,r.kt)("a",{parentName:"p",href:"#indy-network-configuration"},"Indy Network Configuration"),")."),(0,r.kt)("p",null,"An initial list of namespace identifiers can be found in an ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-did-networks/issues/3"},"issue in the Indy Did Networks Repository"),". In the future this list will be maintained in the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-did-networks"},"Indy DID Networks repository")," itself."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n publicDidSeed: '01eafa4de4e22ed4fc2ee522b6ce2731',\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent, DidsModule, KeyType, TypedArrayEncoder } from '@aries-framework/core'\nimport { IndySdkModule, IndySdkIndyDidResolver } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n indySdk: new IndySdkModule({\n indySdk,\n networks: [\n {\n id: 'Sovrin Mainnet',\n // Important: make sure to pick the correct indy namespace for the network you're connecting to\n // See: https://github.com/hyperledger/indy-did-networks/issues/3\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n }),\n dids: new DidsModule({\n // Important: Make sure to register the IndySdkIndyDidResolver\n resolvers: [new IndySdkIndyDidResolver()],\n }),\n },\n})\n\n// Important: the `import` method only has to be called once, and the agent MUST be initialized before calling it.\n// The private key is optional if you've used the publicDidSeed property before (as the key will already be in the wallet),\nawait agent.initialize()\nawait agent.dids.import({\n did: 'did:indy:sovrin:KEPUoXHcswsfsHkXGfmXB7',\n privateKeys: [\n {\n keyType: KeyType.Ed25519,\n privateKey: TypedArrayEncoder.fromString('01eafa4de4e22ed4fc2ee522b6ce2731'),\n },\n ],\n})\n")))),(0,r.kt)("h3",{id:"more-granular-usage-of-legacy-didsov-prefix-in-didcomm-messages"},"More Granular Usage of Legacy ",(0,r.kt)("inlineCode",{parentName:"h3"},"did:sov")," Prefix in DIDComm Messages"),(0,r.kt)("p",null,"Credo 0.3.0 used the ",(0,r.kt)("inlineCode",{parentName:"p"},"useLegacyDidSovPrefix")," to use the legacy ",(0,r.kt)("inlineCode",{parentName:"p"},"did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/")," as the prefix in the ",(0,r.kt)("inlineCode",{parentName:"p"},"@type")," of DIDComm message instead of the new ",(0,r.kt)("inlineCode",{parentName:"p"},"https://didcomm.org")," prefix. Over time it has proven that this approach leads to undesired behavior as all messages (even protocols that were defined after the new prefix was the default) would use the legacy prefix. However, due to not all implementations having support for new prefix, disabling the legacy prefixes proved to be a problem."),(0,r.kt)("p",null,"Therefore, in Credo 0.4.0 the ",(0,r.kt)("inlineCode",{parentName:"p"},"useLegacyDidSovPrefix")," property has been replaced with the ",(0,r.kt)("inlineCode",{parentName:"p"},"useDidSovPrefixWhereAllowed")," property. This property will only use the legacy prefix for protocols that were defined before the new prefix was the default. This means that protocols that were defined after the new prefix was the default will use the new prefix independent of the value of the ",(0,r.kt)("inlineCode",{parentName:"p"},"useDidSovPrefixWhereAllowed")," property. We hope this will allow us to slowly migrate away from the legacy prefix as new protocols are defined without breaking backwards compatibility."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n useLegacyDidSovPrefix: true,\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n useDidSovPrefixWhereAllowed: true,\n },\n dependencies: agentDependencies,\n})\n")))),(0,r.kt)("h3",{id:"removal-of-injectioncontainer-property-from-the-agent"},"Removal of ",(0,r.kt)("inlineCode",{parentName:"h3"},"injectionContainer")," property from the agent"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"injectionContainer")," property on the ",(0,r.kt)("inlineCode",{parentName:"p"},"Agent")," has been replaced by the ",(0,r.kt)("inlineCode",{parentName:"p"},"dependencyManager")," property. The ",(0,r.kt)("inlineCode",{parentName:"p"},"dependencyManager")," property is an instance of the ",(0,r.kt)("inlineCode",{parentName:"p"},"DependencyManager")," class and wraps the injection container from ",(0,r.kt)("inlineCode",{parentName:"p"},"tsyringe"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"DependencyManager")," ",(0,r.kt)("em",{parentName:"p"},"should")," provide all functionality that is needed, and it is recommended to not use the injection directly. If you need to use the injection container directly, you can access it via the ",(0,r.kt)("inlineCode",{parentName:"p"},"container")," property on the ",(0,r.kt)("inlineCode",{parentName:"p"},"DependencyManager")," instance, but please raise an issue to discuss if the functionality you need should be added to the ",(0,r.kt)("inlineCode",{parentName:"p"},"DependencyManager")," class."),(0,r.kt)("h3",{id:"connection-has-been-updated-to-connectionid-in-transportsession"},(0,r.kt)("inlineCode",{parentName:"h3"},"connection")," has been updated to ",(0,r.kt)("inlineCode",{parentName:"h3"},"connectionId")," in ",(0,r.kt)("inlineCode",{parentName:"h3"},"TransportSession")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"connection")," property on the ",(0,r.kt)("inlineCode",{parentName:"p"},"TransportSession")," has been changed to ",(0,r.kt)("inlineCode",{parentName:"p"},"connectionId")," and now only holds a reference to the connection id instead of the connection record itself."),(0,r.kt)("p",null,"Accessing the connection on a transport session is an advanced case that is mostly only relevant when implementing a custom transport. If you are using the default transports, you should not be affected by this change."),(0,r.kt)("h3",{id:"replacement-of-ledger-module-with-new-anoncreds-module"},"Replacement of Ledger Module with new AnonCreds Module"),(0,r.kt)("p",null,"The ledger module has been available in Credo since the very beginning, and was due for a big overhaul. With the addition of the dids module a while ago we already had a replacement for the ",(0,r.kt)("inlineCode",{parentName:"p"},"registerPublicDid")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"getPublicDid")," methods on the ledger module. The other methods of the ledger module have been replaced by the AnonCreds module."),(0,r.kt)("p",null,"In Credo 0.4.0 AnonCreds credential support is not part of the core framework anymore, and needs to be manually registered on the agent. The first part is enabling the AnonCreds module, which allows to manage AnonCreds objects, interact with the ledger, and issuer, hold and verify AnonCreds credentials and is explained in this section. The second part is actually allowing AnonCreds credentials to be exchanged in the Issue Credential and Present Proof protocols, which is explained in the ",(0,r.kt)("a",{parentName:"p",href:"#manually-register-anoncreds-support-in-credentials-and-proofs-modules"},"Manually Register AnonCreds Support in Credentials and Proofs Modules")," section."),(0,r.kt)("p",null,"There's a few important takeaways based on the code example below:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"The ",(0,r.kt)("inlineCode",{parentName:"li"},"anoncreds")," module can be accessed under the ",(0,r.kt)("inlineCode",{parentName:"li"},"agent.modules.anoncreds")," property."),(0,r.kt)("li",{parentName:"ul"},"The interfaces are set up as generically as possible based on the ",(0,r.kt)("a",{parentName:"li",href:"https://identity.foundation/did-registration/"},"DID Registration")," and ",(0,r.kt)("a",{parentName:"li",href:"https://w3c-ccg.github.io/did-resolution/"},"DID Resolution")," specifications."),(0,r.kt)("li",{parentName:"ul"},"AnonCreds registries need to be manually registered so it's important to register the ",(0,r.kt)("inlineCode",{parentName:"li"},"IndySdkAnonCredsRegistry")," on the ",(0,r.kt)("inlineCode",{parentName:"li"},"AnonCredsModule"),"."),(0,r.kt)("li",{parentName:"ul"},"It is now required to pass an ",(0,r.kt)("inlineCode",{parentName:"li"},"issuerId")," when registering AnonCreds objects, according to the ",(0,r.kt)("a",{parentName:"li",href:"https://hyperledger.github.io/anoncreds-spec/"},"AnonCreds Specification"),". Only ",(0,r.kt)("inlineCode",{parentName:"li"},"did:indy")," issuer identifiers are allowed (based on the ",(0,r.kt)("a",{parentName:"li",href:"https://hyperledger.github.io/anoncreds-methods-registry/#didindy-anoncreds-method"},(0,r.kt)("inlineCode",{parentName:"a"},"did:indy")," AnonCreds Method"),"), so the network can be inferred from the issuer identifier.")),(0,r.kt)("p",null,"As will be explained in the ",(0,r.kt)("a",{parentName:"p",href:"#manually-register-anoncreds-support-in-credentials-and-proofs-modules"},"Manually Register AnonCreds Support in Credentials and Proofs Modules"),", you can still use the unqualified issuer identifiers (best known as the ",(0,r.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-methods-registry/#hyperledger-indy-legacy-anoncreds-method"},"Hyperledger Indy Legacy AnonCreds Method"),") in credential and proof exchanges."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n publicDidSeed: '01eafa4de4e22ed4fc2ee522b6ce2731',\n indyLedgers: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n },\n dependencies: agentDependencies,\n})\n\nawait agent.initialize()\n\nconst schema = await agent.ledger.registerSchema({\n attributes: ['name'],\n name: 'Example Schema',\n version: '1.0.1',\n})\n\nconst credentialDefinition = await agent.ledger.registerCredentialDefinition({\n schema,\n supportRevocation: false,\n tag: 'default',\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { AnonCredsModule } from '@aries-framework/anoncreds'\nimport { Agent, DidsModule, KeyType, TypedArrayEncoder } from '@aries-framework/core'\nimport { IndySdkAnonCredsRegistry, IndySdkModule, IndySdkIndyDidResolver } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n indySdk: new IndySdkModule({\n indySdk,\n networks: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n }),\n // Important: register the IndySdkAnonCredsRegistry so that the anoncreds module can resolver/register anoncreds objects based on the networks configured in the IndySdkModule\n anoncreds: new AnonCredsModule({\n registries: [new IndySdkAnonCredsRegistry()],\n }),\n // Important: register the IndySdkIndyDidResolver so that the anoncreds module can resolve DIDs based on the networks configured in the IndySdkModule\n dids: new DidsModule({\n resolvers: [new IndySdkIndyDidResolver()],\n }),\n },\n})\n\n// Agent MUST be initialized before the anoncreds module can be used\nawait agent.initialize()\n\n// Important: the issuerId (did) MUST be available to the dids module in the agent. You can either create the did using the dids module, or import it as described in this migration guide.\nconst schemaResult = await agent.modules.anoncreds.registerSchema({\n schema: {\n attrNames: ['name'],\n issuerId: 'did:indy:sovrin:KEPUoXHcswsfsHkXGfmXB7',\n name: 'Example Schema',\n version: '1.0.0',\n },\n options: {},\n})\n\n// The resolver and registrar follow the same pattern as the Did Registration\n// and Did Resolver interfaces as used by the did module.\nif (schemaResult.schemaState.state !== 'finished') {\n console.error(schemaResult)\n throw new Error(`Error creating schema`)\n}\n\nconst credentialDefinitionResult = await agent.modules.anoncreds.registerCredentialDefinition({\n credentialDefinition: {\n issuerId: 'did:indy:sovrin:KEPUoXHcswsfsHkXGfmXB7',\n schemaId: schemaResult.schemaState.schemaId,\n tag: 'default',\n },\n options: {},\n})\n")))),(0,r.kt)("h3",{id:"changes-to-the-credentials-and-proofs-modules"},"Changes to the Credentials and Proofs modules"),(0,r.kt)("p",null,"A lot of small, and some bigger changes have been made to the Credentials, and primarily, the Proofs modules. These changes have been made to make the modules more consistent and generic so that they can be used in a wider range of use cases, removing any focus on AnonCreds and Indy credentials."),(0,r.kt)("p",null,"Changes to the Proofs module include:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"getRequestedCredentialsForProofRequest")," has been renamed to ",(0,r.kt)("inlineCode",{parentName:"li"},"getCredentialsForRequest")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"autoSelectCredentialsForProofRequest")," has been renamed to ",(0,r.kt)("inlineCode",{parentName:"li"},"selectCredentialsForRequest")),(0,r.kt)("li",{parentName:"ul"},"The ",(0,r.kt)("inlineCode",{parentName:"li"},"config")," parameter for both methods has been removed and those have been replaced by proof format specific configuration options. In this case, the ",(0,r.kt)("inlineCode",{parentName:"li"},"config.filterByNonRevocationRequirements")," has been added as ",(0,r.kt)("inlineCode",{parentName:"li"},"proofFormats.indy.filterByNonRevocationRequirements")," (if the ",(0,r.kt)("inlineCode",{parentName:"li"},"indy")," format is registered as explained in the next section). The ",(0,r.kt)("inlineCode",{parentName:"li"},"config.filterByPresentationPreview")," has been removed as the presentation preview was only present in the present proof V1 protocol, and due to it's limited applicability (the holder starts with a proposal) we've decided to remove this method for now. You can still filter the credentials yourself by using the ",(0,r.kt)("inlineCode",{parentName:"li"},"getCredentialsForRequest")," method."),(0,r.kt)("li",{parentName:"ul"},"Interfaces have been renamed to be more consistent with the method names. Please refer to the ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/openwallet-foundation/credo-ts/blob/v0.4.0/packages/core/src/modules/credentials/CredentialsApiOptions.ts"},(0,r.kt)("inlineCode",{parentName:"a"},"CredentialsApiOptions"))," and ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/openwallet-foundation/credo-ts/blob/v0.4.0/packages/core/src/modules/proofs/ProofsApiOptions.ts"},(0,r.kt)("inlineCode",{parentName:"a"},"ProofsApiOptions"))," for the interface names that can be imported.")),(0,r.kt)("p",null,"If you encounter any other breaking changes in the Proofs and Credentials modules, please open an issue in the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts-docs"},"Credo Docs")," repository."),(0,r.kt)("h3",{id:"changes-to-the-anoncreds-credential-and-proof-format"},"Changes to the AnonCreds Credential and Proof Format"),(0,r.kt)("p",null,"With the 0.4.0 release, Credo now provides a pluggable AnonCreds interface, and requires support AnonCreds credentials to be explicitly registered on the agent. This is also the case for registering the credential and proof formats."),(0,r.kt)("p",null,"In 0.3.x, the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndyProofFormatService")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"IndyCredentialFormatService")," were registered by default. In 0.4.x, these services are no longer registered by default and they should be imported from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/anoncreds")," package as ",(0,r.kt)("inlineCode",{parentName:"p"},"LegacyIndyProofFormatService")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"LegacyIndyCredentialFormatService")," and are based on ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0592-indy-attachments/README.md"},"Aries RFC 0592"),". In a future version the new ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsCredentialFormatService")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsProofFormatService")," will be added to the AnonCreds package, which are based on ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/pull/771"},"Aries RFC 0771")," and allow for AnonCreds credentials to be exchanged based on the new ledger agnostic ",(0,r.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-spec/"},"AnonCreds Specification"),"."),(0,r.kt)("p",null,"In addition, the ",(0,r.kt)("inlineCode",{parentName:"p"},"V1CredentialProtocol")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"V1ProofProtocol")," have been extracted into the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/anoncreds")," package, as they only support exchange of (legacy Indy) AnonCreds credentials."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n indyLedgers: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import {\n AnonCredsModule,\n LegacyIndyCredentialFormatService,\n LegacyIndyProofFormatService,\n V1CredentialProtocol,\n V1ProofProtocol,\n} from '@aries-framework/anoncreds'\nimport { Agent, CredentialsModule, ProofsModule, V2CredentialProtocol, V2ProofProtocol } from '@aries-framework/core'\nimport { IndySdkAnonCredsRegistry, IndySdkModule } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst legacyIndyCredentialFormat = new LegacyIndyCredentialFormatService()\nconst legacyIndyProofFormat = new LegacyIndyProofFormatService()\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n indySdk: new IndySdkModule({\n indySdk,\n networks: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n }),\n // Important: the AnonCreds module MUST be registered with a registry that can resolve\n // legacy unqualified Indy anoncreds identifiers\n anoncreds: new AnonCredsModule({\n registries: [new IndySdkAnonCredsRegistry()],\n }),\n // Define the proofs module with support for both v1 and v2 of the proof protocols\n // both of which support the legacy Indy proof format\n proofs: new ProofsModule({\n proofProtocols: [\n new V1ProofProtocol({\n indyProofFormat: legacyIndyProofFormat,\n }),\n new V2ProofProtocol({\n proofFormats: [legacyIndyProofFormat],\n }),\n ],\n }),\n // Define the credentials module with support for both v1 and v2 of the credential protocols\n // both of which support the legacy Indy proof format\n credentials: new CredentialsModule({\n credentialProtocols: [\n new V1CredentialProtocol({\n indyCredentialFormat: legacyIndyCredentialFormat,\n }),\n new V2CredentialProtocol({\n credentialFormats: [legacyIndyCredentialFormat],\n }),\n ],\n }),\n },\n})\n")))),(0,r.kt)("h3",{id:"removal-of-anoncreds-master-secret-management-from-wallet"},"Removal of AnonCreds Master Secret management from ",(0,r.kt)("inlineCode",{parentName:"h3"},"Wallet")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"Wallet")," class no longer manages the creation and deletion of AnonCreds master secrets (which are now called Link Secrets in AnonCreds module and specification). If you haven't provided a custom ",(0,r.kt)("inlineCode",{parentName:"p"},"masterSecretId")," to the ",(0,r.kt)("inlineCode",{parentName:"p"},"walletConfig")," before, the storage migration script should have automatically created an ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsLinkSecretRecord")," for you based on the ",(0,r.kt)("inlineCode",{parentName:"p"},"walletConfig.id"),"."),(0,r.kt)("p",null,"For new agents however, you now need to explicitly create a link secret before you can create requests for AnonCreds credential offers. You can do this using the ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsApi.createLinkSecret")," method."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"If you previously used a custom ",(0,r.kt)("inlineCode",{parentName:"p"},"masterSecretId")," in the ",(0,r.kt)("inlineCode",{parentName:"p"},"walletConfig")," the migration script will have created an incorrect ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsLinkSecretRecord")," based on the ",(0,r.kt)("inlineCode",{parentName:"p"},"walletConfig.id"),". You will need to manually override the link secret record with the correct ",(0,r.kt)("inlineCode",{parentName:"p"},"linkSecretId"),"."),(0,r.kt)("p",{parentName:"admonition"},"You ",(0,r.kt)("strong",{parentName:"p"},"ONLY")," need to do this if you're not migrating from Indy SDK to Askar, as in that case the migration script will have created the correct ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsLinkSecretRecord")," for you."),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { AnonCredsLinkSecretRepository } from '@aries-framework/anoncreds'\n\nconst linkSecretRepository = agent.dependencyManager.resolve(AnonCredsLinkSecretRepository)\nconst defaultLinkSecret = await linkSecretRepository.findDefault(agent.context)\n\nif (defaultLinkSecret) {\n defaultLinkSecret.linkSecretId = 'my-custom-link-secret-id'\n await linkSecretRepository.update(agent.context, defaultLinkSecret)\n}\n"))),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { AnonCredsModule } from '@aries-framework/anoncreds'\nimport { Agent } from '@aries-framework/core'\nimport { IndySdkAnonCredsRegistry, IndySdkModule } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n indySdk: new IndySdkModule({\n indySdk,\n }),\n anoncreds: new AnonCredsModule({\n registries: [new IndySdkAnonCredsRegistry()],\n }),\n },\n})\n\n// the agent MUST be initialized before calling it.\nawait agent.wallet.initialize({\n id: 'wallet-id',\n key: 'wallet-key',\n})\n\nawait agent.modules.anoncreds.createLinkSecret({\n // first one will be set to default automatically\n setAsDefault: true,\n\n // will be generated if not provided.\n // linkSecretId: 'link-secret-id'\n})\n")),(0,r.kt)("h3",{id:"default-outbound-didcomm-content-type-now-applicationdidcomm-envelope-enc"},"Default Outbound DIDComm Content Type now ",(0,r.kt)("inlineCode",{parentName:"h3"},"application/didcomm-envelope-enc")),(0,r.kt)("p",null,"The default outbound DIDComm content type has been changed from ",(0,r.kt)("inlineCode",{parentName:"p"},"DidCommMimeType.V0")," (",(0,r.kt)("inlineCode",{parentName:"p"},"application/ssi-agent-wire"),") to ",(0,r.kt)("inlineCode",{parentName:"p"},"DidCommMimeType.V1")," (",(0,r.kt)("inlineCode",{parentName:"p"},"application/didcomm-envelope-enc"),"). V1 is the default for DIDComm V1 (as ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0044-didcomm-file-and-mime-types/README.md#detecting-didcomm-versions"},"defined in Aries RFC 0044"),"). In the past, V0 resulted in better interoperability, but since it has been the default for so long it makes sense to change the default behavior."),(0,r.kt)("p",null,"It is advised to use the default value as configured by the agent (V1). If you want to keep the old behavior, you can ",(0,r.kt)("a",{parentName:"p",href:"/guides/tutorials/agent-config#didcommmimetype"},"configure the ",(0,r.kt)("inlineCode",{parentName:"a"},"didCommMimeType")," property in the agent configuration"),"."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent, DidCommMimeType } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n didCommMimeType: DidCommMimeType.V0,\n },\n dependencies: agentDependencies,\n})\n")))),(0,r.kt)("h3",{id:"generalizing-indy-properties-in-credentialexchangerecord"},"Generalizing Indy properties in ",(0,r.kt)("inlineCode",{parentName:"h3"},"CredentialExchangeRecord")),(0,r.kt)("p",null,"With AnonCreds credentials now being generalized to support multiple ledgers, the properties specific to Hyperledger Indy have now been generalized into a generic AnonCreds properties."),(0,r.kt)("h4",{id:"credentialrecordtype"},(0,r.kt)("inlineCode",{parentName:"h4"},"credentialRecordType")),(0,r.kt)("p",null,"First off, the ",(0,r.kt)("inlineCode",{parentName:"p"},"credentialRecordType")," that was used to reference stored AnonCreds credentials has been renamed from ",(0,r.kt)("inlineCode",{parentName:"p"},"indy")," to ",(0,r.kt)("inlineCode",{parentName:"p"},"anoncreds"),". The migration script takes care of the update to the storage, but you need to make sure to update all places that expect a ",(0,r.kt)("inlineCode",{parentName:"p"},"credentialRecordType")," of ",(0,r.kt)("inlineCode",{parentName:"p"},"indy")," to be defined."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="CredentialExchangeRecord"',title:'"CredentialExchangeRecord"'},'{\n "credentials": [\n {\n "credentialRecordType": "indy",\n "credentialRecordId": "credential-id"\n }\n ]\n}\n'))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="CredentialExchangeRecord"',title:'"CredentialExchangeRecord"'},'{\n "credentials": [\n {\n "credentialRecordType": "anoncreds",\n "credentialRecordId": "credential-id"\n }\n ]\n}\n')))),(0,r.kt)("h4",{id:"metadata"},"Metadata"),(0,r.kt)("p",null,"Second, the metadata keys and values have been renamed to be AnonCreds specific rather than Indy specific. The ",(0,r.kt)("inlineCode",{parentName:"p"},"CredentialMetadataKeys")," have been replaced by the ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsCredentialMetadataKey")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsCredentialRequestMetadataKey")," constants which can be imported from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/anoncreds")," package."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="CredentialExchangeRecord"',title:'"CredentialExchangeRecord"'},'{\n "metadata": {\n "_internal/indyCredential": {\n "schemaId": "schema-id",\n "credentialDefinitionId": "cred-def-id",\n "indyRevocationRegistryId": "rev-reg-id",\n "indyCredentialRevocationId": "cred-rev-id"\n },\n "_internal/indyRequest": {\n "master_secret_blinding_data": {\n "v_prime": "string",\n "vr_prime": "string"\n },\n "master_secret_name": "string",\n "nonce": "string"\n }\n }\n}\n'))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="CredentialExchangeRecord"',title:'"CredentialExchangeRecord"'},'{\n "metadata": {\n "_anoncreds/credential": {\n "schemaId": "schema-id",\n "credentialDefinitionId": "cred-def-id",\n "revocationRegistryId": "rev-reg-id",\n "credentialRevocationId": "cred-rev-id"\n },\n "_anoncreds/credentialRequest": {\n "master_secret_blinding_data": {\n "v_prime": "string",\n "vr_prime": "string"\n },\n "master_secret_name": "string",\n "nonce": "string"\n }\n }\n}\n')))),(0,r.kt)("h3",{id:"more-paths-in-filesystem"},"More paths in ",(0,r.kt)("inlineCode",{parentName:"h3"},"FileSystem")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"FileSystem")," interface has been extended to support multiple base paths. The previous interface had a single ",(0,r.kt)("inlineCode",{parentName:"p"},"basePath")," property which was used for storing of files across the framework."),(0,r.kt)("p",null,"With the different lifetimes of different objects, the ",(0,r.kt)("inlineCode",{parentName:"p"},"FileSystem")," interface has been extended to now support three different base paths:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"cachePath")," - files used for caching purposes. It's okay if the files are cleared from time to time."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"dataPath")," - files that are used for long-term reliable storage purposes. These files will never be cleared."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"tempPath")," - files that are used for temporary storage purposes. It's okay if the files are cleared from time to time.")),(0,r.kt)("p",null,"If you're using the framework, you don't need to worry about this change. The agent may need to download some objects again after the update. If you've made a custom implementation of the ",(0,r.kt)("inlineCode",{parentName:"p"},"FileSystem"),", make sure to support all three base paths, and make sure to correctly handle the life-cycle of the files. Items stored under the ",(0,r.kt)("inlineCode",{parentName:"p"},"dataPath")," ",(0,r.kt)("strong",{parentName:"p"},"should never be cleared"),"."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Indy SDK SQLite wallets do not use the paths defined by the ",(0,r.kt)("inlineCode",{parentName:"p"},"FileSystem")," interface, and thus will not be influenced by this change. When upgrading to Aries Askar, the ",(0,r.kt)("inlineCode",{parentName:"p"},"dataPath")," will be used as the base path for storing the SQLite wallet data.")),(0,r.kt)("h2",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,r.kt)("p",null,"The 0.4.0 release introduces some breaking changes to the storage format."),(0,r.kt)("p",null,"Below all breaking storage changes are explained in as much detail as possible. The update assistant provides all tools to migrate without a hassle, but it is important to know what has changed. All examples only show the keys that have changed, unrelated keys in records have been omitted."),(0,r.kt)("p",null,"See the ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.5/updating/update-assistant"},"Update Assistant")," documentation for a guide on how to use the update assistant."),(0,r.kt)("p",null,"There are no configuration parameters to be provided to the update assistant to migrate from 0.3.x to 0.4.x."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"TODO")))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/14e53ecf.ede4ee2a.js b/assets/js/14e53ecf.ede4ee2a.js new file mode 100644 index 00000000..cd7729fc --- /dev/null +++ b/assets/js/14e53ecf.ede4ee2a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[1904],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>h});var a=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function o(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var s=a.createContext({}),l=function(e){var n=a.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},p=function(e){var n=l(e.components);return a.createElement(s.Provider,{value:n},e.children)},c="mdxType",m={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},u=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,p=d(e,["components","mdxType","originalType","parentName"]),c=l(t),u=r,h=c["".concat(s,".").concat(u)]||c[u]||m[u]||i;return t?a.createElement(h,o(o({ref:n},p),{},{components:t})):a.createElement(h,o({ref:n},p))}));function h(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var i=t.length,o=new Array(i);o[0]=u;var d={};for(var s in n)hasOwnProperty.call(n,s)&&(d[s]=n[s]);d.originalType=e,d[c]="string"==typeof e?e:r,o[1]=d;for(var l=2;l{t.d(n,{Z:()=>o});var a=t(7294),r=t(6010);const i={tabItem:"tabItem_Ymn6"};function o(e){let{children:n,hidden:t,className:o}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(i.tabItem,o),hidden:t},n)}},4866:(e,n,t)=>{t.d(n,{Z:()=>w});var a=t(7462),r=t(7294),i=t(6010),o=t(2466),d=t(6550),s=t(1980),l=t(7392),p=t(12);function c(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:n,label:t,attributes:a,default:r}}=e;return{value:n,label:t,attributes:a,default:r}}))}function m(e){const{values:n,children:t}=e;return(0,r.useMemo)((()=>{const e=n??c(t);return function(e){const n=(0,l.l)(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 u(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function h(e){let{queryString:n=!1,groupId:t}=e;const a=(0,d.k6)(),i=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,s._X)(i),(0,r.useCallback)((e=>{if(!i)return;const n=new URLSearchParams(a.location.search);n.set(i,e),a.replace({...a.location,search:n.toString()})}),[i,a])]}function k(e){const{defaultValue:n,queryString:t=!1,groupId:a}=e,i=m(e),[o,d]=(0,r.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(!u({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 a=t.find((e=>e.default))??t[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:n,tabValues:i}))),[s,l]=h({queryString:t,groupId:a}),[c,k]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[a,i]=(0,p.Nk)(t);return[a,(0,r.useCallback)((e=>{t&&i.set(e)}),[t,i])]}({groupId:a}),g=(()=>{const e=s??c;return u({value:e,tabValues:i})?e:null})();(0,r.useLayoutEffect)((()=>{g&&d(g)}),[g]);return{selectedValue:o,selectValue:(0,r.useCallback)((e=>{if(!u({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);d(e),l(e),k(e)}),[l,k,i]),tabValues:i}}var g=t(2389);const f={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){let{className:n,block:t,selectedValue:d,selectValue:s,tabValues:l}=e;const p=[],{blockElementScrollPositionUntilNextRender:c}=(0,o.o5)(),m=e=>{const n=e.currentTarget,t=p.indexOf(n),a=l[t].value;a!==d&&(c(n),s(a))},u=e=>{let n=null;switch(e.key){case"Enter":m(e);break;case"ArrowRight":{const t=p.indexOf(e.currentTarget)+1;n=p[t]??p[0];break}case"ArrowLeft":{const t=p.indexOf(e.currentTarget)-1;n=p[t]??p[p.length-1];break}}n?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":t},n)},l.map((e=>{let{value:n,label:t,attributes:o}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:d===n?0:-1,"aria-selected":d===n,key:n,ref:e=>p.push(e),onKeyDown:u,onClick:m},o,{className:(0,i.Z)("tabs__item",f.tabItem,o?.className,{"tabs__item--active":d===n})}),t??n)})))}function v(e){let{lazy:n,children:t,selectedValue:a}=e;if(t=Array.isArray(t)?t:[t],n){const e=t.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},t.map(((e,n)=>(0,r.cloneElement)(e,{key:n,hidden:e.props.value!==a}))))}function b(e){const n=k(e);return r.createElement("div",{className:(0,i.Z)("tabs-container",f.tabList)},r.createElement(y,(0,a.Z)({},e,n)),r.createElement(v,(0,a.Z)({},e,n)))}function w(e){const n=(0,g.Z)();return r.createElement(b,(0,a.Z)({key:String(n)},e))}},3635:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>s,default:()=>h,frontMatter:()=>d,metadata:()=>l,toc:()=>c});var a=t(7462),r=(t(7294),t(3905)),i=t(4866),o=t(5162);const d={},s="Migrating from Credo 0.3.x to 0.4.x",l={unversionedId:"updating/versions/0.3-to-0.4",id:"updating/versions/0.3-to-0.4",title:"Migrating from Credo 0.3.x to 0.4.x",description:"This document describes everything you need to know for updating Credo 0.3.x to 0.4.x. If you're not aware of how updating in Credo works make sure to first read the guide on Updating Credo.",source:"@site/guides/updating/versions/0.3-to-0.4.md",sourceDirName:"updating/versions",slug:"/updating/versions/0.3-to-0.4",permalink:"/guides/updating/versions/0.3-to-0.4",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Migrating from Credo 0.2.x to 0.3.x",permalink:"/guides/updating/versions/0.2-to-0.3"},next:{title:"The Credo Ecosystem",permalink:"/guides/ecosystem/"}},p={},c=[{value:"React Native",id:"react-native",level:4},{value:"Node",id:"node",level:4},{value:"Breaking Code Changes",id:"breaking-code-changes",level:2},{value:"Agent Creation",id:"agent-creation",level:3},{value:"0.3.x",id:"03x",level:5},{value:"0.4.x",id:"04x",level:5},{value:"Indy Network Configuration",id:"indy-network-configuration",level:3},{value:"0.3.x",id:"03x-1",level:5},{value:"0.4.x",id:"04x-1",level:5},{value:"Changes to wallet",id:"changes-to-wallet",level:3},{value:"Did Resolver and Registrar",id:"did-resolver-and-registrar",level:3},{value:"0.3.x",id:"03x-2",level:5},{value:"0.4.x",id:"04x-2",level:5},{value:"Removal of publicDidSeed and publicDid",id:"removal-of-publicdidseed-and-publicdid",level:3},{value:"0.3.x",id:"03x-3",level:5},{value:"0.4.x",id:"04x-3",level:5},{value:"More Granular Usage of Legacy did:sov Prefix in DIDComm Messages",id:"more-granular-usage-of-legacy-didsov-prefix-in-didcomm-messages",level:3},{value:"0.3.x",id:"03x-4",level:5},{value:"0.4.x",id:"04x-4",level:5},{value:"Removal of injectionContainer property from the agent",id:"removal-of-injectioncontainer-property-from-the-agent",level:3},{value:"connection has been updated to connectionId in TransportSession",id:"connection-has-been-updated-to-connectionid-in-transportsession",level:3},{value:"Replacement of Ledger Module with new AnonCreds Module",id:"replacement-of-ledger-module-with-new-anoncreds-module",level:3},{value:"0.3.x",id:"03x-5",level:5},{value:"0.4.x",id:"04x-5",level:5},{value:"Changes to the Credentials and Proofs modules",id:"changes-to-the-credentials-and-proofs-modules",level:3},{value:"Changes to the AnonCreds Credential and Proof Format",id:"changes-to-the-anoncreds-credential-and-proof-format",level:3},{value:"0.3.x",id:"03x-6",level:5},{value:"0.4.x",id:"04x-6",level:5},{value:"Removal of AnonCreds Master Secret management from Wallet",id:"removal-of-anoncreds-master-secret-management-from-wallet",level:3},{value:"Default Outbound DIDComm Content Type now application/didcomm-envelope-enc",id:"default-outbound-didcomm-content-type-now-applicationdidcomm-envelope-enc",level:3},{value:"0.3.x",id:"03x-7",level:5},{value:"0.4.x",id:"04x-7",level:5},{value:"Generalizing Indy properties in CredentialExchangeRecord",id:"generalizing-indy-properties-in-credentialexchangerecord",level:3},{value:"credentialRecordType",id:"credentialrecordtype",level:4},{value:"0.3.x",id:"03x-8",level:5},{value:"0.4.x",id:"04x-8",level:5},{value:"Metadata",id:"metadata",level:4},{value:"0.3.x",id:"03x-9",level:5},{value:"0.4.x",id:"04x-9",level:5},{value:"More paths in FileSystem",id:"more-paths-in-filesystem",level:3},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:2}],m={toc:c},u="wrapper";function h(e){let{components:n,...t}=e;return(0,r.kt)(u,(0,a.Z)({},m,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"migrating-from-credo-03x-to-04x"},"Migrating from Credo 0.3.x to 0.4.x"),(0,r.kt)("p",null,"This document describes everything you need to know for updating Credo 0.3.x to 0.4.x. If you're not aware of how updating in Credo works make sure to first read the guide on ",(0,r.kt)("a",{parentName:"p",href:"/guides/updating/"},"Updating Credo"),"."),(0,r.kt)("p",null,"First of all, update you dependencies to the 0.4.x versions. This will also update the needed peer dependencies. ",(0,r.kt)("strong",{parentName:"p"},"Extension packages are not updated with this command"),". You need to update these manually, and make sure they're up to date with the latest version of Credo."),(0,r.kt)("p",null,"Credo 0.4.0 is a major release that introduces a lot of new features and changes to the public API. Specifically, this release removed the dependency on the Indy SDK from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/core")," package. Agent setup is more flexible, but it also means the setup is more complex. Follow the mentioned steps in this document carefully to make the upgrade as smooth as possible."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"The migration guide only covers how to migrate from 0.3.x to 0.4.x while keeping the same behavior and dependencies. Credo 0.4.0 introduced a lot of new features and adds support for ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-askar"},"Aries Askar"),", ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-vdr"},"Indy VDR")," and ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/anoncreds-rs"},"AnonCreds RS")," as a replacement for the Indy SDK."),(0,r.kt)("p",{parentName:"admonition"},"Migrating to these new components requires additional migration steps, which need to be closely followed to prevent loss of data. These can be found at the ",(0,r.kt)("a",{parentName:"p",href:"/guides/updating/update-indy-sdk-to-askar"},"Update Indy SDK to Askar guide"),"."),(0,r.kt)("p",{parentName:"admonition"},"As noted in the ",(0,r.kt)("a",{parentName:"p",href:"/guides/updating/update-indy-sdk-to-askar"},"Update Indy SDK to Askar guide"),", it is very important that the 0.3.x to 0.4.x update is started after migrating from the Indy SDK to Aries Askar.")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Multi-tenancy is not covered in the 0.3.x to 0.4.x migration guide. If you're using multi-tenancy in 0.3.x and want to migrate to 0.4.x, please open an issue on ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts"},"Github"),".")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"The following APIs, modules and features are experimental and therefore not covered by the semver versioning in Credo. If you're using any of these features, make sure to use an exact version of Credo (",(0,r.kt)("inlineCode",{parentName:"p"},"0.4.0"),") instead of a range (",(0,r.kt)("inlineCode",{parentName:"p"},"^0.4.0"),"):"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},"Implementing your own ",(0,r.kt)("inlineCode",{parentName:"li"},"AnonCredsRegistry")," and AnonCreds service implementation. Using the default implementations (Indy SDK, AnonCreds RS) is fine."),(0,r.kt)("li",{parentName:"ul"},"Using the shared component libraries from ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/aries-askar"),", ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/indy-vdr")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/anoncreds-rs")),(0,r.kt)("li",{parentName:"ul"},"Using OpenID4VC from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/openid4vc-client")," module"),(0,r.kt)("li",{parentName:"ul"},"W3C JWT Verifiable Credentials"),(0,r.kt)("li",{parentName:"ul"},"Using multi-tenancy from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/tenants")," module"))),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"React Native",value:"tab1",mdxType:"TabItem"},(0,r.kt)("p",null,"First install the updated dependencies. Make sure to also install the new ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/indy-sdk")," package, which is a wrapper around the Indy SDK and install the ",(0,r.kt)("inlineCode",{parentName:"p"},"indy-sdk-react-native")," package."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/react-native@^0.4.0 @aries-framework/core@^0.4.0 @aries-framework/indy-sdk@^0.4.0 @aries-framework/anoncreds@^0.4.0 indy-sdk-react-native@^0.3.1\n\n# or NPM\nnpn install @aries-framework/react-native@^0.4.0 @aries-framework/core@^0.4.0 @aries-framework/indy-sdk@^0.4.0 @aries-framework/anoncreds@^0.4.0 indy-sdk-react-native@^0.3.1\n")),(0,r.kt)("p",null,"We also need to install types for the ",(0,r.kt)("inlineCode",{parentName:"p"},"indy-sdk-react-native")," package, which we take from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@types/indy-sdk")," package."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add --dev @types/indy-sdk-react-native@npm:@types/indy-sdk\n\n# or NPM\nnpm install --save-dev @types/indy-sdk-react-native@npm:@types/indy-sdk\n"))),(0,r.kt)(o.Z,{label:"Node",value:"tab2",mdxType:"TabItem"},(0,r.kt)("p",null,"First install the updated dependencies. Make sure to also install the new ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/indy-sdk")," package, which is a wrapper around the Indy SDK and install the ",(0,r.kt)("inlineCode",{parentName:"p"},"indy-sdk")," package itself."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/node@^0.4.0 @aries-framework/core@^0.4.0 @aries-framework/indy-sdk@^0.4.0 @aries-framework/anoncreds@^0.4.0 indy-sdk\n\n# or NPM\nnpm install @aries-framework/node@^0.4.0 @aries-framework/core@^0.4.0 @aries-framework/indy-sdk@^0.4.0 @aries-framework/anoncreds@^0.4.0 indy-sdk\n")),(0,r.kt)("p",null,"We also need to install types for the ",(0,r.kt)("inlineCode",{parentName:"p"},"indy-sdk")," package, which are available in the ",(0,r.kt)("inlineCode",{parentName:"p"},"@types/indy-sdk")," package."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add --dev @types/indy-sdk\n\n# or NPM\nnpm install --save-dev @types/indy-sdk\n")))),(0,r.kt)("h2",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,r.kt)("p",null,"This section will list all breaking changes made to the public API of Credo between version 0.3.x and 0.4.0."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here, but it is possible some breaking changes are not documented here (feel free to open a pull request).")),(0,r.kt)("h3",{id:"agent-creation"},"Agent Creation"),(0,r.kt)("p",null,"With the dependency on the Indy SDK removed from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/core")," package, we now need to register the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," to still leverage the functionality the Indy SDK provides."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\nimport { IndySdkModule } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n // Register the IndySdkModule and provide the indySdk dependency\n indySdk: new IndySdkModule({\n indySdk,\n }),\n },\n})\n")))),(0,r.kt)("h3",{id:"indy-network-configuration"},"Indy Network Configuration"),(0,r.kt)("p",null,"With the Indy SDK being extracted out of core, the ",(0,r.kt)("inlineCode",{parentName:"p"},"indyLedger")," configuration option is no longer available on the ",(0,r.kt)("inlineCode",{parentName:"p"},"AgentConfig")," interface. Instead, the ",(0,r.kt)("inlineCode",{parentName:"p"},"networks")," configuration option is now available on the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," configuration."),(0,r.kt)("p",null,"In addition the ",(0,r.kt)("inlineCode",{parentName:"p"},"connectToIndyLedgersOnStartup")," property has been removed in favor of a per-network ",(0,r.kt)("inlineCode",{parentName:"p"},"connectOnStartup")," property that allows more fine-grained control over which networks to connect to on startup."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n connectToIndyLedgersOnStartup: true,\n indyLedgers: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\nimport { IndySdkModule } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n // Register the IndySdkModule and provide the indySdk dependency\n indySdk: new IndySdkModule({\n indySdk,\n\n // add networks as a replacement for indyLedgers\n networks: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n // new connectOnStartup property\n connectOnStartup: true,\n },\n ],\n }),\n },\n})\n")))),(0,r.kt)("h3",{id:"changes-to-wallet"},"Changes to wallet"),(0,r.kt)("p",null,"Throughout the framework it was possible to provide a ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," for deterministic key generation. Recently it was discovered that the ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," property in the Indy SDK was not actually used as a seed, but directly as the private key."),(0,r.kt)("p",null,"Therefore a new ",(0,r.kt)("inlineCode",{parentName:"p"},"privateKey")," property was added to the ",(0,r.kt)("inlineCode",{parentName:"p"},"Wallet")," interface in addition to the ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," property. When using the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," this now means you can ",(0,r.kt)("strong",{parentName:"p"},"only")," provide the ",(0,r.kt)("inlineCode",{parentName:"p"},"privateKey")," property. The ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," property is no longer supported ",(0,r.kt)("strong",{parentName:"p"},"by the ",(0,r.kt)("inlineCode",{parentName:"strong"},"IndySdkModule")),"."),(0,r.kt)("p",null,"The type of the ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," property has also been changed to ",(0,r.kt)("inlineCode",{parentName:"p"},"Buffer")," to make it more consistent with ",(0,r.kt)("inlineCode",{parentName:"p"},"privateKey")," property, and remove the ambiguity of what the encoding of the string variant of the ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," property should be."),(0,r.kt)("h3",{id:"did-resolver-and-registrar"},"Did Resolver and Registrar"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"did:sov")," resolver and registrar were registered by default in 0.3.x of the agent. In 0.4.0 they've been moved to the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/indy-sdk")," package and are thus not registered by default on the DIDs module anymore. In addition, the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkSovDidRegistrar")," has been replaced in favor of the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkIndyDidRegistrar")," which provides similar behavior, but leverages the new ",(0,r.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/indy-did-method/#indy-did-method-identifiers"},(0,r.kt)("inlineCode",{parentName:"a"},"did:indy")," method"),", which removes ambiguity about which network to use. You can still use the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkSovDidResolver")," to resolve ",(0,r.kt)("inlineCode",{parentName:"p"},"did:sov")," DIDs."),(0,r.kt)("p",null,"Note that the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," MUST be registered when using the Indy SDK did resolvers and registrars (see ",(0,r.kt)("a",{parentName:"p",href:"#agent-creation"},"Agent Creation"),"). The networks supported by the resolvers and registrar is determined by the ",(0,r.kt)("inlineCode",{parentName:"p"},"networks")," registered on the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," (see ",(0,r.kt)("a",{parentName:"p",href:"#indy-network-configuration"},"Indy Network Configuration"),")."),(0,r.kt)("p",null,"Also note that by default the ",(0,r.kt)("inlineCode",{parentName:"p"},"WebDidResolver"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"KeyDidResolver")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"PeerDidResolver")," are registered, and setting the ",(0,r.kt)("inlineCode",{parentName:"p"},"resolvers")," property on the ",(0,r.kt)("inlineCode",{parentName:"p"},"DidsModule")," configuration will override the default resolvers (an exception is the ",(0,r.kt)("inlineCode",{parentName:"p"},"PeerDidResolver")," as it is required for creating connections, and thus will always be registered)."),(0,r.kt)("p",null,"The same thing is true for the ",(0,r.kt)("inlineCode",{parentName:"p"},"registrars"),", for which the ",(0,r.kt)("inlineCode",{parentName:"p"},"KeyDidRegistrar")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"PeerDidRegistrar")," are registered by default. If defining the ",(0,r.kt)("inlineCode",{parentName:"p"},"resolvers")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"registrars"),", make sure to include the default registrars if you want to keep the previous behavior."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent, DidsModule } from '@aries-framework/core'\nimport { IndySdkModule } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n // note that the IndySdkModule MUST be registered for the resolvers and registrars to work\n // they are left out for brevity and can bee\n dids: new DidsModule({\n registrars: [new IndySdkIndyDidRegistrar()],\n resolvers: [new IndySdkSovDidResolver(), new IndySdkIndyDidResolver()],\n }),\n },\n})\n")))),(0,r.kt)("h3",{id:"removal-of-publicdidseed-and-publicdid"},"Removal of ",(0,r.kt)("inlineCode",{parentName:"h3"},"publicDidSeed")," and ",(0,r.kt)("inlineCode",{parentName:"h3"},"publicDid")),(0,r.kt)("p",null,"To make Credo more generic, and less focused on Hyperledger Indy, and Indy dids, the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDidSeed")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDid")," properties have been removed from the agent configuration, the agent class, and the ",(0,r.kt)("inlineCode",{parentName:"p"},"Wallet")," interface."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDid")," property was used as the did to register items in the ledger module. The approach had some limitations:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"An agent could only have a single ",(0,r.kt)("inlineCode",{parentName:"li"},"publicDid")," property. This means that if you wanted to write to multiple ledgers you would have to create multiple agents"),(0,r.kt)("li",{parentName:"ul"},"The property assumed only Indy ledgers would be used, and didn't take into account the possibility of other ledgers.")),(0,r.kt)("p",null,"Credo now provides generic APIs that can work with any ledger, and thus the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDid")," property is no longer needed. Different sections of this migration guide will explain the different parts of how to use the new APIs, this section just focuses on how to replace the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDid")," property."),(0,r.kt)("p",null,"The most common use case for the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDid")," property was for registering an endorser did that can endorse (read: pay for) transactions on the ledger. This can now be done by importing the did into agent, after which it can be used by the AnonCreds module to register schemas and credential definitions, and the did registrar to register DIDs."),(0,r.kt)("p",null,"There's a ",(0,r.kt)("strong",{parentName:"p"},"one-time import")," that needs to be done to import the did into the agent using the ",(0,r.kt)("inlineCode",{parentName:"p"},"DidsApi.import")," method. If you've previously used the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDidSeed")," property, providing the private key is optional, as it is already stored in the wallet. Note that the ",(0,r.kt)("inlineCode",{parentName:"p"},"privateKey")," is the same as the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDidSeed"),", see ",(0,r.kt)("a",{parentName:"p",href:"#changes-to-wallet"},"Changes to Wallet")," for context). The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," method will resolve the did passed to the ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," method (so make sure to register the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkIndyDidResolver"),"). It is recommended to import the endorser did as an ",(0,r.kt)("inlineCode",{parentName:"p"},"did:indy")," did rather than a ",(0,r.kt)("inlineCode",{parentName:"p"},"did:sov")," did, as the ",(0,r.kt)("inlineCode",{parentName:"p"},"did:sov")," method is deprecated for creation. The ",(0,r.kt)("inlineCode",{parentName:"p"},"did:indy")," did can be constructed by replacing ",(0,r.kt)("inlineCode",{parentName:"p"},"sov")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"indy:"),", where ",(0,r.kt)("inlineCode",{parentName:"p"},"")," should be replaced with a namespace as registered in the ",(0,r.kt)("inlineCode",{parentName:"p"},"networks")," property of the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," (see ",(0,r.kt)("a",{parentName:"p",href:"#indy-network-configuration"},"Indy Network Configuration"),")."),(0,r.kt)("p",null,"An initial list of namespace identifiers can be found in an ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-did-networks/issues/3"},"issue in the Indy Did Networks Repository"),". In the future this list will be maintained in the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-did-networks"},"Indy DID Networks repository")," itself."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n publicDidSeed: '01eafa4de4e22ed4fc2ee522b6ce2731',\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent, DidsModule, KeyType, TypedArrayEncoder } from '@aries-framework/core'\nimport { IndySdkModule, IndySdkIndyDidResolver } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n indySdk: new IndySdkModule({\n indySdk,\n networks: [\n {\n id: 'Sovrin Mainnet',\n // Important: make sure to pick the correct indy namespace for the network you're connecting to\n // See: https://github.com/hyperledger/indy-did-networks/issues/3\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n }),\n dids: new DidsModule({\n // Important: Make sure to register the IndySdkIndyDidResolver\n resolvers: [new IndySdkIndyDidResolver()],\n }),\n },\n})\n\n// Important: the `import` method only has to be called once, and the agent MUST be initialized before calling it.\n// The private key is optional if you've used the publicDidSeed property before (as the key will already be in the wallet),\nawait agent.initialize()\nawait agent.dids.import({\n did: 'did:indy:sovrin:KEPUoXHcswsfsHkXGfmXB7',\n privateKeys: [\n {\n keyType: KeyType.Ed25519,\n privateKey: TypedArrayEncoder.fromString('01eafa4de4e22ed4fc2ee522b6ce2731'),\n },\n ],\n})\n")))),(0,r.kt)("h3",{id:"more-granular-usage-of-legacy-didsov-prefix-in-didcomm-messages"},"More Granular Usage of Legacy ",(0,r.kt)("inlineCode",{parentName:"h3"},"did:sov")," Prefix in DIDComm Messages"),(0,r.kt)("p",null,"Credo 0.3.0 used the ",(0,r.kt)("inlineCode",{parentName:"p"},"useLegacyDidSovPrefix")," to use the legacy ",(0,r.kt)("inlineCode",{parentName:"p"},"did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/")," as the prefix in the ",(0,r.kt)("inlineCode",{parentName:"p"},"@type")," of DIDComm message instead of the new ",(0,r.kt)("inlineCode",{parentName:"p"},"https://didcomm.org")," prefix. Over time it has proven that this approach leads to undesired behavior as all messages (even protocols that were defined after the new prefix was the default) would use the legacy prefix. However, due to not all implementations having support for new prefix, disabling the legacy prefixes proved to be a problem."),(0,r.kt)("p",null,"Therefore, in Credo 0.4.0 the ",(0,r.kt)("inlineCode",{parentName:"p"},"useLegacyDidSovPrefix")," property has been replaced with the ",(0,r.kt)("inlineCode",{parentName:"p"},"useDidSovPrefixWhereAllowed")," property. This property will only use the legacy prefix for protocols that were defined before the new prefix was the default. This means that protocols that were defined after the new prefix was the default will use the new prefix independent of the value of the ",(0,r.kt)("inlineCode",{parentName:"p"},"useDidSovPrefixWhereAllowed")," property. We hope this will allow us to slowly migrate away from the legacy prefix as new protocols are defined without breaking backwards compatibility."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n useLegacyDidSovPrefix: true,\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n useDidSovPrefixWhereAllowed: true,\n },\n dependencies: agentDependencies,\n})\n")))),(0,r.kt)("h3",{id:"removal-of-injectioncontainer-property-from-the-agent"},"Removal of ",(0,r.kt)("inlineCode",{parentName:"h3"},"injectionContainer")," property from the agent"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"injectionContainer")," property on the ",(0,r.kt)("inlineCode",{parentName:"p"},"Agent")," has been replaced by the ",(0,r.kt)("inlineCode",{parentName:"p"},"dependencyManager")," property. The ",(0,r.kt)("inlineCode",{parentName:"p"},"dependencyManager")," property is an instance of the ",(0,r.kt)("inlineCode",{parentName:"p"},"DependencyManager")," class and wraps the injection container from ",(0,r.kt)("inlineCode",{parentName:"p"},"tsyringe"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"DependencyManager")," ",(0,r.kt)("em",{parentName:"p"},"should")," provide all functionality that is needed, and it is recommended to not use the injection directly. If you need to use the injection container directly, you can access it via the ",(0,r.kt)("inlineCode",{parentName:"p"},"container")," property on the ",(0,r.kt)("inlineCode",{parentName:"p"},"DependencyManager")," instance, but please raise an issue to discuss if the functionality you need should be added to the ",(0,r.kt)("inlineCode",{parentName:"p"},"DependencyManager")," class."),(0,r.kt)("h3",{id:"connection-has-been-updated-to-connectionid-in-transportsession"},(0,r.kt)("inlineCode",{parentName:"h3"},"connection")," has been updated to ",(0,r.kt)("inlineCode",{parentName:"h3"},"connectionId")," in ",(0,r.kt)("inlineCode",{parentName:"h3"},"TransportSession")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"connection")," property on the ",(0,r.kt)("inlineCode",{parentName:"p"},"TransportSession")," has been changed to ",(0,r.kt)("inlineCode",{parentName:"p"},"connectionId")," and now only holds a reference to the connection id instead of the connection record itself."),(0,r.kt)("p",null,"Accessing the connection on a transport session is an advanced case that is mostly only relevant when implementing a custom transport. If you are using the default transports, you should not be affected by this change."),(0,r.kt)("h3",{id:"replacement-of-ledger-module-with-new-anoncreds-module"},"Replacement of Ledger Module with new AnonCreds Module"),(0,r.kt)("p",null,"The ledger module has been available in Credo since the very beginning, and was due for a big overhaul. With the addition of the dids module a while ago we already had a replacement for the ",(0,r.kt)("inlineCode",{parentName:"p"},"registerPublicDid")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"getPublicDid")," methods on the ledger module. The other methods of the ledger module have been replaced by the AnonCreds module."),(0,r.kt)("p",null,"In Credo 0.4.0 AnonCreds credential support is not part of the core framework anymore, and needs to be manually registered on the agent. The first part is enabling the AnonCreds module, which allows to manage AnonCreds objects, interact with the ledger, and issuer, hold and verify AnonCreds credentials and is explained in this section. The second part is actually allowing AnonCreds credentials to be exchanged in the Issue Credential and Present Proof protocols, which is explained in the ",(0,r.kt)("a",{parentName:"p",href:"#manually-register-anoncreds-support-in-credentials-and-proofs-modules"},"Manually Register AnonCreds Support in Credentials and Proofs Modules")," section."),(0,r.kt)("p",null,"There's a few important takeaways based on the code example below:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"The ",(0,r.kt)("inlineCode",{parentName:"li"},"anoncreds")," module can be accessed under the ",(0,r.kt)("inlineCode",{parentName:"li"},"agent.modules.anoncreds")," property."),(0,r.kt)("li",{parentName:"ul"},"The interfaces are set up as generically as possible based on the ",(0,r.kt)("a",{parentName:"li",href:"https://identity.foundation/did-registration/"},"DID Registration")," and ",(0,r.kt)("a",{parentName:"li",href:"https://w3c-ccg.github.io/did-resolution/"},"DID Resolution")," specifications."),(0,r.kt)("li",{parentName:"ul"},"AnonCreds registries need to be manually registered so it's important to register the ",(0,r.kt)("inlineCode",{parentName:"li"},"IndySdkAnonCredsRegistry")," on the ",(0,r.kt)("inlineCode",{parentName:"li"},"AnonCredsModule"),"."),(0,r.kt)("li",{parentName:"ul"},"It is now required to pass an ",(0,r.kt)("inlineCode",{parentName:"li"},"issuerId")," when registering AnonCreds objects, according to the ",(0,r.kt)("a",{parentName:"li",href:"https://hyperledger.github.io/anoncreds-spec/"},"AnonCreds Specification"),". Only ",(0,r.kt)("inlineCode",{parentName:"li"},"did:indy")," issuer identifiers are allowed (based on the ",(0,r.kt)("a",{parentName:"li",href:"https://hyperledger.github.io/anoncreds-methods-registry/#didindy-anoncreds-method"},(0,r.kt)("inlineCode",{parentName:"a"},"did:indy")," AnonCreds Method"),"), so the network can be inferred from the issuer identifier.")),(0,r.kt)("p",null,"As will be explained in the ",(0,r.kt)("a",{parentName:"p",href:"#manually-register-anoncreds-support-in-credentials-and-proofs-modules"},"Manually Register AnonCreds Support in Credentials and Proofs Modules"),", you can still use the unqualified issuer identifiers (best known as the ",(0,r.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-methods-registry/#hyperledger-indy-legacy-anoncreds-method"},"Hyperledger Indy Legacy AnonCreds Method"),") in credential and proof exchanges."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n publicDidSeed: '01eafa4de4e22ed4fc2ee522b6ce2731',\n indyLedgers: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n },\n dependencies: agentDependencies,\n})\n\nawait agent.initialize()\n\nconst schema = await agent.ledger.registerSchema({\n attributes: ['name'],\n name: 'Example Schema',\n version: '1.0.1',\n})\n\nconst credentialDefinition = await agent.ledger.registerCredentialDefinition({\n schema,\n supportRevocation: false,\n tag: 'default',\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { AnonCredsModule } from '@aries-framework/anoncreds'\nimport { Agent, DidsModule, KeyType, TypedArrayEncoder } from '@aries-framework/core'\nimport { IndySdkAnonCredsRegistry, IndySdkModule, IndySdkIndyDidResolver } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n indySdk: new IndySdkModule({\n indySdk,\n networks: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n }),\n // Important: register the IndySdkAnonCredsRegistry so that the anoncreds module can resolver/register anoncreds objects based on the networks configured in the IndySdkModule\n anoncreds: new AnonCredsModule({\n registries: [new IndySdkAnonCredsRegistry()],\n }),\n // Important: register the IndySdkIndyDidResolver so that the anoncreds module can resolve DIDs based on the networks configured in the IndySdkModule\n dids: new DidsModule({\n resolvers: [new IndySdkIndyDidResolver()],\n }),\n },\n})\n\n// Agent MUST be initialized before the anoncreds module can be used\nawait agent.initialize()\n\n// Important: the issuerId (did) MUST be available to the dids module in the agent. You can either create the did using the dids module, or import it as described in this migration guide.\nconst schemaResult = await agent.modules.anoncreds.registerSchema({\n schema: {\n attrNames: ['name'],\n issuerId: 'did:indy:sovrin:KEPUoXHcswsfsHkXGfmXB7',\n name: 'Example Schema',\n version: '1.0.0',\n },\n options: {},\n})\n\n// The resolver and registrar follow the same pattern as the Did Registration\n// and Did Resolver interfaces as used by the did module.\nif (schemaResult.schemaState.state !== 'finished') {\n console.error(schemaResult)\n throw new Error(`Error creating schema`)\n}\n\nconst credentialDefinitionResult = await agent.modules.anoncreds.registerCredentialDefinition({\n credentialDefinition: {\n issuerId: 'did:indy:sovrin:KEPUoXHcswsfsHkXGfmXB7',\n schemaId: schemaResult.schemaState.schemaId,\n tag: 'default',\n },\n options: {},\n})\n")))),(0,r.kt)("h3",{id:"changes-to-the-credentials-and-proofs-modules"},"Changes to the Credentials and Proofs modules"),(0,r.kt)("p",null,"A lot of small, and some bigger changes have been made to the Credentials, and primarily, the Proofs modules. These changes have been made to make the modules more consistent and generic so that they can be used in a wider range of use cases, removing any focus on AnonCreds and Indy credentials."),(0,r.kt)("p",null,"Changes to the Proofs module include:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"getRequestedCredentialsForProofRequest")," has been renamed to ",(0,r.kt)("inlineCode",{parentName:"li"},"getCredentialsForRequest")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"autoSelectCredentialsForProofRequest")," has been renamed to ",(0,r.kt)("inlineCode",{parentName:"li"},"selectCredentialsForRequest")),(0,r.kt)("li",{parentName:"ul"},"The ",(0,r.kt)("inlineCode",{parentName:"li"},"config")," parameter for both methods has been removed and those have been replaced by proof format specific configuration options. In this case, the ",(0,r.kt)("inlineCode",{parentName:"li"},"config.filterByNonRevocationRequirements")," has been added as ",(0,r.kt)("inlineCode",{parentName:"li"},"proofFormats.indy.filterByNonRevocationRequirements")," (if the ",(0,r.kt)("inlineCode",{parentName:"li"},"indy")," format is registered as explained in the next section). The ",(0,r.kt)("inlineCode",{parentName:"li"},"config.filterByPresentationPreview")," has been removed as the presentation preview was only present in the present proof V1 protocol, and due to it's limited applicability (the holder starts with a proposal) we've decided to remove this method for now. You can still filter the credentials yourself by using the ",(0,r.kt)("inlineCode",{parentName:"li"},"getCredentialsForRequest")," method."),(0,r.kt)("li",{parentName:"ul"},"Interfaces have been renamed to be more consistent with the method names. Please refer to the ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/openwallet-foundation/credo-ts/blob/v0.4.0/packages/core/src/modules/credentials/CredentialsApiOptions.ts"},(0,r.kt)("inlineCode",{parentName:"a"},"CredentialsApiOptions"))," and ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/openwallet-foundation/credo-ts/blob/v0.4.0/packages/core/src/modules/proofs/ProofsApiOptions.ts"},(0,r.kt)("inlineCode",{parentName:"a"},"ProofsApiOptions"))," for the interface names that can be imported.")),(0,r.kt)("p",null,"If you encounter any other breaking changes in the Proofs and Credentials modules, please open an issue in the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts-docs"},"Credo Docs")," repository."),(0,r.kt)("h3",{id:"changes-to-the-anoncreds-credential-and-proof-format"},"Changes to the AnonCreds Credential and Proof Format"),(0,r.kt)("p",null,"With the 0.4.0 release, Credo now provides a pluggable AnonCreds interface, and requires support AnonCreds credentials to be explicitly registered on the agent. This is also the case for registering the credential and proof formats."),(0,r.kt)("p",null,"In 0.3.x, the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndyProofFormatService")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"IndyCredentialFormatService")," were registered by default. In 0.4.x, these services are no longer registered by default and they should be imported from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/anoncreds")," package as ",(0,r.kt)("inlineCode",{parentName:"p"},"LegacyIndyProofFormatService")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"LegacyIndyCredentialFormatService")," and are based on ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0592-indy-attachments/README.md"},"Aries RFC 0592"),". In a future version the new ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsCredentialFormatService")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsProofFormatService")," will be added to the AnonCreds package, which are based on ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/pull/771"},"Aries RFC 0771")," and allow for AnonCreds credentials to be exchanged based on the new ledger agnostic ",(0,r.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-spec/"},"AnonCreds Specification"),"."),(0,r.kt)("p",null,"In addition, the ",(0,r.kt)("inlineCode",{parentName:"p"},"V1CredentialProtocol")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"V1ProofProtocol")," have been extracted into the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/anoncreds")," package, as they only support exchange of (legacy Indy) AnonCreds credentials."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n indyLedgers: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import {\n AnonCredsModule,\n LegacyIndyCredentialFormatService,\n LegacyIndyProofFormatService,\n V1CredentialProtocol,\n V1ProofProtocol,\n} from '@aries-framework/anoncreds'\nimport { Agent, CredentialsModule, ProofsModule, V2CredentialProtocol, V2ProofProtocol } from '@aries-framework/core'\nimport { IndySdkAnonCredsRegistry, IndySdkModule } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst legacyIndyCredentialFormat = new LegacyIndyCredentialFormatService()\nconst legacyIndyProofFormat = new LegacyIndyProofFormatService()\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n indySdk: new IndySdkModule({\n indySdk,\n networks: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n }),\n // Important: the AnonCreds module MUST be registered with a registry that can resolve\n // legacy unqualified Indy anoncreds identifiers\n anoncreds: new AnonCredsModule({\n registries: [new IndySdkAnonCredsRegistry()],\n }),\n // Define the proofs module with support for both v1 and v2 of the proof protocols\n // both of which support the legacy Indy proof format\n proofs: new ProofsModule({\n proofProtocols: [\n new V1ProofProtocol({\n indyProofFormat: legacyIndyProofFormat,\n }),\n new V2ProofProtocol({\n proofFormats: [legacyIndyProofFormat],\n }),\n ],\n }),\n // Define the credentials module with support for both v1 and v2 of the credential protocols\n // both of which support the legacy Indy proof format\n credentials: new CredentialsModule({\n credentialProtocols: [\n new V1CredentialProtocol({\n indyCredentialFormat: legacyIndyCredentialFormat,\n }),\n new V2CredentialProtocol({\n credentialFormats: [legacyIndyCredentialFormat],\n }),\n ],\n }),\n },\n})\n")))),(0,r.kt)("h3",{id:"removal-of-anoncreds-master-secret-management-from-wallet"},"Removal of AnonCreds Master Secret management from ",(0,r.kt)("inlineCode",{parentName:"h3"},"Wallet")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"Wallet")," class no longer manages the creation and deletion of AnonCreds master secrets (which are now called Link Secrets in AnonCreds module and specification). If you haven't provided a custom ",(0,r.kt)("inlineCode",{parentName:"p"},"masterSecretId")," to the ",(0,r.kt)("inlineCode",{parentName:"p"},"walletConfig")," before, the storage migration script should have automatically created an ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsLinkSecretRecord")," for you based on the ",(0,r.kt)("inlineCode",{parentName:"p"},"walletConfig.id"),"."),(0,r.kt)("p",null,"For new agents however, you now need to explicitly create a link secret before you can create requests for AnonCreds credential offers. You can do this using the ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsApi.createLinkSecret")," method."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"If you previously used a custom ",(0,r.kt)("inlineCode",{parentName:"p"},"masterSecretId")," in the ",(0,r.kt)("inlineCode",{parentName:"p"},"walletConfig")," the migration script will have created an incorrect ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsLinkSecretRecord")," based on the ",(0,r.kt)("inlineCode",{parentName:"p"},"walletConfig.id"),". You will need to manually override the link secret record with the correct ",(0,r.kt)("inlineCode",{parentName:"p"},"linkSecretId"),"."),(0,r.kt)("p",{parentName:"admonition"},"You ",(0,r.kt)("strong",{parentName:"p"},"ONLY")," need to do this if you're not migrating from Indy SDK to Askar, as in that case the migration script will have created the correct ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsLinkSecretRecord")," for you."),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { AnonCredsLinkSecretRepository } from '@aries-framework/anoncreds'\n\nconst linkSecretRepository = agent.dependencyManager.resolve(AnonCredsLinkSecretRepository)\nconst defaultLinkSecret = await linkSecretRepository.findDefault(agent.context)\n\nif (defaultLinkSecret) {\n defaultLinkSecret.linkSecretId = 'my-custom-link-secret-id'\n await linkSecretRepository.update(agent.context, defaultLinkSecret)\n}\n"))),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { AnonCredsModule } from '@aries-framework/anoncreds'\nimport { Agent } from '@aries-framework/core'\nimport { IndySdkAnonCredsRegistry, IndySdkModule } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n indySdk: new IndySdkModule({\n indySdk,\n }),\n anoncreds: new AnonCredsModule({\n registries: [new IndySdkAnonCredsRegistry()],\n }),\n },\n})\n\n// the agent MUST be initialized before calling it.\nawait agent.wallet.initialize({\n id: 'wallet-id',\n key: 'wallet-key',\n})\n\nawait agent.modules.anoncreds.createLinkSecret({\n // first one will be set to default automatically\n setAsDefault: true,\n\n // will be generated if not provided.\n // linkSecretId: 'link-secret-id'\n})\n")),(0,r.kt)("h3",{id:"default-outbound-didcomm-content-type-now-applicationdidcomm-envelope-enc"},"Default Outbound DIDComm Content Type now ",(0,r.kt)("inlineCode",{parentName:"h3"},"application/didcomm-envelope-enc")),(0,r.kt)("p",null,"The default outbound DIDComm content type has been changed from ",(0,r.kt)("inlineCode",{parentName:"p"},"DidCommMimeType.V0")," (",(0,r.kt)("inlineCode",{parentName:"p"},"application/ssi-agent-wire"),") to ",(0,r.kt)("inlineCode",{parentName:"p"},"DidCommMimeType.V1")," (",(0,r.kt)("inlineCode",{parentName:"p"},"application/didcomm-envelope-enc"),"). V1 is the default for DIDComm V1 (as ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0044-didcomm-file-and-mime-types/README.md#detecting-didcomm-versions"},"defined in Aries RFC 0044"),"). In the past, V0 resulted in better interoperability, but since it has been the default for so long it makes sense to change the default behavior."),(0,r.kt)("p",null,"It is advised to use the default value as configured by the agent (V1). If you want to keep the old behavior, you can ",(0,r.kt)("a",{parentName:"p",href:"/guides/tutorials/agent-config#didcommmimetype"},"configure the ",(0,r.kt)("inlineCode",{parentName:"a"},"didCommMimeType")," property in the agent configuration"),"."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent, DidCommMimeType } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n didCommMimeType: DidCommMimeType.V0,\n },\n dependencies: agentDependencies,\n})\n")))),(0,r.kt)("h3",{id:"generalizing-indy-properties-in-credentialexchangerecord"},"Generalizing Indy properties in ",(0,r.kt)("inlineCode",{parentName:"h3"},"CredentialExchangeRecord")),(0,r.kt)("p",null,"With AnonCreds credentials now being generalized to support multiple ledgers, the properties specific to Hyperledger Indy have now been generalized into a generic AnonCreds properties."),(0,r.kt)("h4",{id:"credentialrecordtype"},(0,r.kt)("inlineCode",{parentName:"h4"},"credentialRecordType")),(0,r.kt)("p",null,"First off, the ",(0,r.kt)("inlineCode",{parentName:"p"},"credentialRecordType")," that was used to reference stored AnonCreds credentials has been renamed from ",(0,r.kt)("inlineCode",{parentName:"p"},"indy")," to ",(0,r.kt)("inlineCode",{parentName:"p"},"anoncreds"),". The migration script takes care of the update to the storage, but you need to make sure to update all places that expect a ",(0,r.kt)("inlineCode",{parentName:"p"},"credentialRecordType")," of ",(0,r.kt)("inlineCode",{parentName:"p"},"indy")," to be defined."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="CredentialExchangeRecord"',title:'"CredentialExchangeRecord"'},'{\n "credentials": [\n {\n "credentialRecordType": "indy",\n "credentialRecordId": "credential-id"\n }\n ]\n}\n'))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="CredentialExchangeRecord"',title:'"CredentialExchangeRecord"'},'{\n "credentials": [\n {\n "credentialRecordType": "anoncreds",\n "credentialRecordId": "credential-id"\n }\n ]\n}\n')))),(0,r.kt)("h4",{id:"metadata"},"Metadata"),(0,r.kt)("p",null,"Second, the metadata keys and values have been renamed to be AnonCreds specific rather than Indy specific. The ",(0,r.kt)("inlineCode",{parentName:"p"},"CredentialMetadataKeys")," have been replaced by the ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsCredentialMetadataKey")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsCredentialRequestMetadataKey")," constants which can be imported from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/anoncreds")," package."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="CredentialExchangeRecord"',title:'"CredentialExchangeRecord"'},'{\n "metadata": {\n "_internal/indyCredential": {\n "schemaId": "schema-id",\n "credentialDefinitionId": "cred-def-id",\n "indyRevocationRegistryId": "rev-reg-id",\n "indyCredentialRevocationId": "cred-rev-id"\n },\n "_internal/indyRequest": {\n "master_secret_blinding_data": {\n "v_prime": "string",\n "vr_prime": "string"\n },\n "master_secret_name": "string",\n "nonce": "string"\n }\n }\n}\n'))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="CredentialExchangeRecord"',title:'"CredentialExchangeRecord"'},'{\n "metadata": {\n "_anoncreds/credential": {\n "schemaId": "schema-id",\n "credentialDefinitionId": "cred-def-id",\n "revocationRegistryId": "rev-reg-id",\n "credentialRevocationId": "cred-rev-id"\n },\n "_anoncreds/credentialRequest": {\n "master_secret_blinding_data": {\n "v_prime": "string",\n "vr_prime": "string"\n },\n "master_secret_name": "string",\n "nonce": "string"\n }\n }\n}\n')))),(0,r.kt)("h3",{id:"more-paths-in-filesystem"},"More paths in ",(0,r.kt)("inlineCode",{parentName:"h3"},"FileSystem")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"FileSystem")," interface has been extended to support multiple base paths. The previous interface had a single ",(0,r.kt)("inlineCode",{parentName:"p"},"basePath")," property which was used for storing of files across the framework."),(0,r.kt)("p",null,"With the different lifetimes of different objects, the ",(0,r.kt)("inlineCode",{parentName:"p"},"FileSystem")," interface has been extended to now support three different base paths:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"cachePath")," - files used for caching purposes. It's okay if the files are cleared from time to time."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"dataPath")," - files that are used for long-term reliable storage purposes. These files will never be cleared."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"tempPath")," - files that are used for temporary storage purposes. It's okay if the files are cleared from time to time.")),(0,r.kt)("p",null,"If you're using the framework, you don't need to worry about this change. The agent may need to download some objects again after the update. If you've made a custom implementation of the ",(0,r.kt)("inlineCode",{parentName:"p"},"FileSystem"),", make sure to support all three base paths, and make sure to correctly handle the life-cycle of the files. Items stored under the ",(0,r.kt)("inlineCode",{parentName:"p"},"dataPath")," ",(0,r.kt)("strong",{parentName:"p"},"should never be cleared"),"."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Indy SDK SQLite wallets do not use the paths defined by the ",(0,r.kt)("inlineCode",{parentName:"p"},"FileSystem")," interface, and thus will not be influenced by this change. When upgrading to Aries Askar, the ",(0,r.kt)("inlineCode",{parentName:"p"},"dataPath")," will be used as the base path for storing the SQLite wallet data.")),(0,r.kt)("h2",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,r.kt)("p",null,"The 0.4.0 release introduces some breaking changes to the storage format."),(0,r.kt)("p",null,"Below all breaking storage changes are explained in as much detail as possible. The update assistant provides all tools to migrate without a hassle, but it is important to know what has changed. All examples only show the keys that have changed, unrelated keys in records have been omitted."),(0,r.kt)("p",null,"See the ",(0,r.kt)("a",{parentName:"p",href:"/guides/updating/update-assistant"},"Update Assistant")," documentation for a guide on how to use the update assistant."),(0,r.kt)("p",null,"There are no configuration parameters to be provided to the update assistant to migrate from 0.3.x to 0.4.x."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"TODO")))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/17b50570.0650230e.js b/assets/js/17b50570.0650230e.js new file mode 100644 index 00000000..9dde95eb --- /dev/null +++ b/assets/js/17b50570.0650230e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[9593],{6514:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"0.4","label":"v0.4.x","banner":"unmaintained","badge":true,"noIndex":false,"className":"docs-version-0.4","isLast":false,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Intro","href":"/guides/0.4/","docId":"index"},{"type":"category","label":"Getting started","items":[{"type":"link","label":"Prerequisites","href":"/guides/0.4/getting-started/prerequisites","docId":"getting-started/prerequisites"},{"type":"category","label":"Agent Setup","items":[{"type":"link","label":"Aries Askar","href":"/guides/0.4/getting-started/set-up/aries-askar","docId":"getting-started/set-up/aries-askar"},{"type":"category","label":"Indy SDK","items":[{"type":"link","label":"Linux","href":"/guides/0.4/getting-started/set-up/indy-sdk/linux","docId":"getting-started/set-up/indy-sdk/linux"},{"type":"link","label":"Windows","href":"/guides/0.4/getting-started/set-up/indy-sdk/windows","docId":"getting-started/set-up/indy-sdk/windows"},{"type":"link","label":"macOS (Intel)","href":"/guides/0.4/getting-started/set-up/indy-sdk/macos-intel","docId":"getting-started/set-up/indy-sdk/macos-intel"},{"type":"link","label":"macOS (ARM)","href":"/guides/0.4/getting-started/set-up/indy-sdk/macos-arm","docId":"getting-started/set-up/indy-sdk/macos-arm"},{"type":"link","label":"React Native","href":"/guides/0.4/getting-started/set-up/indy-sdk/react-native","docId":"getting-started/set-up/indy-sdk/react-native"}],"collapsed":true,"collapsible":true,"href":"/guides/0.4/getting-started/set-up/indy-sdk/"},{"type":"link","label":"AnonCreds RS","href":"/guides/0.4/getting-started/set-up/anoncreds-rs","docId":"getting-started/set-up/anoncreds-rs"},{"type":"link","label":"Indy VDR","href":"/guides/0.4/getting-started/set-up/indy-vdr","docId":"getting-started/set-up/indy-vdr"},{"type":"link","label":"cheqd","href":"/guides/0.4/getting-started/set-up/cheqd/","docId":"getting-started/set-up/cheqd/index"}],"collapsed":true,"collapsible":true,"href":"/guides/0.4/getting-started/set-up/"}],"collapsed":true,"collapsible":true,"href":"/guides/0.4/getting-started/"},{"type":"category","label":"Concepts","items":[{"type":"link","label":"Agents","href":"/guides/0.4/concepts/agents","docId":"concepts/agents"},{"type":"link","label":"DIDs and DIDComm","href":"/guides/0.4/concepts/did-and-didcomm","docId":"concepts/did-and-didcomm"},{"type":"link","label":"Platform and Environment","href":"/guides/0.4/concepts/platform-and-environment","docId":"concepts/platform-and-environment"}],"collapsed":true,"collapsible":true,"href":"/guides/0.4/concepts/"},{"type":"category","label":"Tutorials","items":[{"type":"category","label":"Agent Config","items":[{"type":"link","label":"Logging","href":"/guides/0.4/tutorials/agent-config/logging","docId":"tutorials/agent-config/logging"}],"collapsed":true,"collapsible":true,"href":"/guides/0.4/tutorials/agent-config/"},{"type":"link","label":"Create a connection","href":"/guides/0.4/tutorials/create-a-connection","docId":"tutorials/create-a-connection"},{"type":"link","label":"Cheqd Did Module","href":"/guides/0.4/tutorials/cheqd/","docId":"tutorials/cheqd/index"},{"type":"link","label":"Registering a schema and credential definition on an AnonCreds Registry","href":"/guides/0.4/tutorials/registering-schema-and-credential-definition","docId":"tutorials/registering-schema-and-credential-definition"},{"type":"link","label":"Issue a credential","href":"/guides/0.4/tutorials/issue-a-credential","docId":"tutorials/issue-a-credential"},{"type":"link","label":"Mediation","href":"/guides/0.4/tutorials/mediation","docId":"tutorials/mediation"},{"type":"category","label":"Using PostgreSQL with the Indy SDK","items":[{"type":"link","label":"Postgres Setup for Linux","href":"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/linux","docId":"tutorials/indy-sdk-postgres-database-nodejs/linux"},{"type":"link","label":"Postgres Setup for macOS","href":"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/macos","docId":"tutorials/indy-sdk-postgres-database-nodejs/macos"},{"type":"link","label":"Postgres Setup for windows","href":"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/windows","docId":"tutorials/indy-sdk-postgres-database-nodejs/windows"}],"collapsed":true,"collapsible":true,"href":"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/"}],"collapsed":true,"collapsible":true,"href":"/guides/0.4/tutorials/"},{"type":"category","label":"Updating","items":[{"type":"link","label":"Update Assistant","href":"/guides/0.4/updating/update-assistant","docId":"updating/update-assistant"},{"type":"link","label":"Migrating from an Indy SDK Wallet to Aries Askar","href":"/guides/0.4/updating/update-indy-sdk-to-askar","docId":"updating/update-indy-sdk-to-askar"},{"type":"link","label":"Migrating from AFJ 0.1.0 to 0.2.x","href":"/guides/0.4/updating/versions/0.1-to-0.2","docId":"updating/versions/0.1-to-0.2"},{"type":"link","label":"Migrating from AFJ 0.2.x to 0.3.x","href":"/guides/0.4/updating/versions/0.2-to-0.3","docId":"updating/versions/0.2-to-0.3"},{"type":"link","label":"Migrating from AFJ 0.3.x to 0.4.x","href":"/guides/0.4/updating/versions/0.3-to-0.4","docId":"updating/versions/0.3-to-0.4"}],"collapsed":true,"collapsible":true,"href":"/guides/0.4/updating/"},{"type":"link","label":"The Aries JavaScript Ecosystem","href":"/guides/0.4/ecosystem/","docId":"ecosystem/index"},{"type":"category","label":"Extensions","items":[{"type":"link","label":"REST API","href":"/guides/0.4/extensions/rest","docId":"extensions/rest"},{"type":"link","label":"React Hooks","href":"/guides/0.4/extensions/react-hooks","docId":"extensions/react-hooks"},{"type":"link","label":"Redux Store","href":"/guides/0.4/extensions/redux-store","docId":"extensions/redux-store"},{"type":"link","label":"Push Notifications","href":"/guides/0.4/extensions/push-notifications","docId":"extensions/push-notifications"}],"collapsed":true,"collapsible":true,"href":"/guides/0.4/extensions/"}]},"docs":{"concepts/agents":{"id":"concepts/agents","title":"Agents","description":"When working with any Aries implementation, you will interact with an Aries","sidebar":"tutorialSidebar"},"concepts/did-and-didcomm":{"id":"concepts/did-and-didcomm","title":"DIDs and DIDComm","description":"DIDs","sidebar":"tutorialSidebar"},"concepts/index":{"id":"concepts/index","title":"Concepts","description":"In this section we will discuss the general concepts that are used inside the","sidebar":"tutorialSidebar"},"concepts/platform-and-environment":{"id":"concepts/platform-and-environment","title":"Platform and Environment","description":"Aries framework JavaScript is developed to support a Node.JS and React Native environment. With this it is entirely possible to build an entire SSI ecosystem with Aries Framework JavaScript. This would use Node.JS as an issuer as a verifier, and uses React Native as a holder.","sidebar":"tutorialSidebar"},"ecosystem/index":{"id":"ecosystem/index","title":"The Aries JavaScript Ecosystem","description":"The Aries JavaScript ecosystem includes various components that are spread across multiple repositories. In this section we\'ll go over what these components are and how the relate to one another.","sidebar":"tutorialSidebar"},"extensions/index":{"id":"extensions/index","title":"Extensions","description":"Aries Framework JavaScript Extensions is an extensions repository to Aries Framework JavaScript (AFJ). It hosts libraries built on top of Aries Framework JavaScript that don\'t necessarily belong to the core of the project.","sidebar":"tutorialSidebar"},"extensions/push-notifications":{"id":"extensions/push-notifications","title":"Push Notifications","description":"The Push Notifications plugin package provides a way for you to register your APNs and Firebase push notification token at an agent, allowing you to use push notifications directly from AFJ.","sidebar":"tutorialSidebar"},"extensions/react-hooks":{"id":"extensions/react-hooks","title":"React Hooks","description":"The React Hooks package exposes useful React hooks that allow you to easily interact with AFJ from a React client application.","sidebar":"tutorialSidebar"},"extensions/redux-store":{"id":"extensions/redux-store","title":"Redux Store","description":"The Redux Store is an implementation of state management that can be used to build React & React Native SSI clients using AFJ.","sidebar":"tutorialSidebar"},"extensions/rest":{"id":"extensions/rest","title":"REST API","description":"The Aries Framework JavaScript (AFJ) REST API provides simple RESTful endpoints for AFJ methods, to allow you stand up an agent for communication over the internet instantly. You simply provide your agent configuration. The REST endpoints allow you to interact with your agent over HTTP and WebSockets.","sidebar":"tutorialSidebar"},"getting-started/index":{"id":"getting-started/index","title":"Getting started","description":"In this section we will go over everything you need to get started on a technical level. First there are some general prerequisites for Node.JS and React Native. Aries Framework JavaScript works for creating both server-side applications (commonly but not always for creating issuer and verifier agents) and mobile applications (commonly holder agents).","sidebar":"tutorialSidebar"},"getting-started/prerequisites":{"id":"getting-started/prerequisites","title":"Prerequisites","description":"To work with Aries Framework JavaScript we need to install some dependencies and set-up our Node.JS environment. Even when creating a mobile app in React Native, we need Node.JS installed. We will go over the specific installation process for each platform. Go ahead and pick your system of choice to get started!","sidebar":"tutorialSidebar"},"getting-started/set-up/anoncreds-rs":{"id":"getting-started/set-up/anoncreds-rs","title":"AnonCreds RS","description":"AnonCreds RS is a direct implementation of the AnonCreds V1.0 specification that provides functionality like; creating a schema object, creating a credential definition object, creating a credential, verifying a proof presentation and much more.","sidebar":"tutorialSidebar"},"getting-started/set-up/aries-askar":{"id":"getting-started/set-up/aries-askar","title":"Aries Askar","description":"Aries Askar provides secure, encrypted storage and cryptographic support for encrypting, decrypting, signing and verifying data. It also provides both the Wallet and StorageService implementations for the agent.","sidebar":"tutorialSidebar"},"getting-started/set-up/cheqd/index":{"id":"getting-started/set-up/cheqd/index","title":"cheqd","description":"cheqd is a blockchain network, built in the Cosmos ecosystem for Self-Sovereign Identity (SSI). The cheqd Network leverages the cheqd DID method and enables DID-Linked Resources to be written to the network, associated with a DID and controlled using the verification methods in the DID Document.","sidebar":"tutorialSidebar"},"getting-started/set-up/index":{"id":"getting-started/set-up/index","title":"Agent Setup","description":"This guide assumes you have followed the Prerequisites, and you have a valid","sidebar":"tutorialSidebar"},"getting-started/set-up/indy-sdk/index":{"id":"getting-started/set-up/indy-sdk/index","title":"Indy SDK","description":"Indy SDK provides a distributed ledger based foundation for self-sovereign identity. It can provide the Wallet and StorageService implementations for the agent, as well as a way to interact with Indy ledgers and an implementation of the legacy (v0.1) AnonCreds Specification","sidebar":"tutorialSidebar"},"getting-started/set-up/indy-sdk/linux":{"id":"getting-started/set-up/indy-sdk/linux","title":"Linux","description":"To install Indy SDK on Linux, a couple of dependencies are required. This guide covers the installation for the more popular Linux distributions.","sidebar":"tutorialSidebar"},"getting-started/set-up/indy-sdk/macos-arm":{"id":"getting-started/set-up/indy-sdk/macos-arm","title":"macOS (ARM)","description":"To install Indy SDK on macOS, a couple of dependencies are required. This guide covers the installation of the Indy SDK for macs with an ARM processor. For installing the Indy SDK on Intel based macs, please refer to the Indy SDK macOS (Intel) guide.","sidebar":"tutorialSidebar"},"getting-started/set-up/indy-sdk/macos-intel":{"id":"getting-started/set-up/indy-sdk/macos-intel","title":"macOS (Intel)","description":"To install Indy SDK on macOS a couple of dependencies are required. This guide covers the installation of the Indy SDK for macs with an Intel processor. For installing the Indy SDK on ARM based macs, please refer to the Indy SDK macOS (ARM) guide.","sidebar":"tutorialSidebar"},"getting-started/set-up/indy-sdk/react-native":{"id":"getting-started/set-up/indy-sdk/react-native","title":"React Native","description":"The setup of Indy SDK for React Native is rather different than Node.JS. We do not have to install dependencies on the host-platform, but for the build target. For React Native this would be the Indy SDK for Android & iOS. This guide covers both the Android and iOS setup, as in most React Native projects you will need both.","sidebar":"tutorialSidebar"},"getting-started/set-up/indy-sdk/windows":{"id":"getting-started/set-up/indy-sdk/windows","title":"Windows","description":"To install Indy SDK on Windows, you can download the pre-built binary from the Sovrin repository.","sidebar":"tutorialSidebar"},"getting-started/set-up/indy-vdr":{"id":"getting-started/set-up/indy-vdr","title":"Indy VDR","description":"Hyperledger Indy VDR, Verifiable Data Registry, can be used to connect to one or more Indy Node ledger pools given sets of genesis transactions. Methods are provided to construct ledger requests and send them to the validators, collecting the results and ensuring that there is a consensus between the nodes. In the context of Aries Framework JavaScript, we mainly leverage it to register, and resolve, schemas, credential definitions and DIDs.","sidebar":"tutorialSidebar"},"index":{"id":"index","title":"Intro","description":"Welcome, to the Aries JavaScript community!","sidebar":"tutorialSidebar"},"tutorials/agent-config/index":{"id":"tutorials/agent-config/index","title":"Agent Config","description":"The Aries agent provided by [Aries Framework","sidebar":"tutorialSidebar"},"tutorials/agent-config/logging":{"id":"tutorials/agent-config/logging","title":"Logging","description":"Using the Default ConsoleLogger","sidebar":"tutorialSidebar"},"tutorials/cheqd/index":{"id":"tutorials/cheqd/index","title":"Cheqd Did Module","description":"In this tutorial we will see how to use the cheqd modules in detail","sidebar":"tutorialSidebar"},"tutorials/create-a-connection":{"id":"tutorials/create-a-connection","title":"Create a connection","description":"In this tutorial we will create a connection as Acme Corp with Bob. We will","sidebar":"tutorialSidebar"},"tutorials/index":{"id":"tutorials/index","title":"Tutorials","description":"In this section we will explain some features that everyone will use. This","sidebar":"tutorialSidebar"},"tutorials/indy-sdk-postgres-database-nodejs/index":{"id":"tutorials/indy-sdk-postgres-database-nodejs/index","title":"Using PostgreSQL as Database for Indy SDK in Node.js","description":"By default the Indy SDK will use an SQLite database for storage. In mobile environments this is sufficient and allows us to keep storage local to the device, but in server environments we oftentimes want a more scalable storage solution. By leveraging the PostgreSQL plugin for Indy SDK we can use PostgreSQL as a storage solution instead of SQLite.","sidebar":"tutorialSidebar"},"tutorials/indy-sdk-postgres-database-nodejs/linux":{"id":"tutorials/indy-sdk-postgres-database-nodejs/linux","title":"Postgres Setup for Linux","description":"Prerequisites","sidebar":"tutorialSidebar"},"tutorials/indy-sdk-postgres-database-nodejs/macos":{"id":"tutorials/indy-sdk-postgres-database-nodejs/macos","title":"Postgres Setup for macOS","description":"Prerequisites","sidebar":"tutorialSidebar"},"tutorials/indy-sdk-postgres-database-nodejs/windows":{"id":"tutorials/indy-sdk-postgres-database-nodejs/windows","title":"Postgres Setup for windows","description":"Build Environment Prerequisites","sidebar":"tutorialSidebar"},"tutorials/issue-a-credential":{"id":"tutorials/issue-a-credential","title":"Issue a credential","description":"In this tutorial we will issue a credential from the Issuer to a Holder. We will start with setting up both their agents with the minimal configuration required to follow this tutorial. It is assumed that there is a connection between the Issuer and the Holder and the Issuer also has a registered schema and credential definition. After initializing the Issuer will send a credential to the holder, and will then accept this credential and automatically store it in their wallet.","sidebar":"tutorialSidebar"},"tutorials/mediation":{"id":"tutorials/mediation","title":"Mediation","description":"This section assumes that you have:","sidebar":"tutorialSidebar"},"tutorials/registering-schema-and-credential-definition":{"id":"tutorials/registering-schema-and-credential-definition","title":"Registering a schema and credential definition on an AnonCreds Registry","description":"In this tutorial we will register a schema and credential definition on an AnonCredsRegistry e.g. Hyperledger Indy ledger indy-vdr, cheqd.","sidebar":"tutorialSidebar"},"updating/index":{"id":"updating/index","title":"Updating AFJ","description":"This section will cover everything you need to know about updating Aries Framework JavaScript to a newer version.","sidebar":"tutorialSidebar"},"updating/update-assistant":{"id":"updating/update-assistant","title":"Update Assistant","description":"The Update Assistant helps you update the storage objects from AFJ to newer versions. This documents describes the different ways you can leverage the Update Assistant from fully managed to more manual approaches.","sidebar":"tutorialSidebar"},"updating/update-indy-sdk-to-askar":{"id":"updating/update-indy-sdk-to-askar","title":"Migrating from an Indy SDK Wallet to Aries Askar","description":"This documentation explains the process of migrating your Indy SDK wallet to Aries Askar.","sidebar":"tutorialSidebar"},"updating/versions/0.1-to-0.2":{"id":"updating/versions/0.1-to-0.2","title":"Migrating from AFJ 0.1.0 to 0.2.x","description":"This document describes everything you need to know for updating AFJ 0.1.0 to 0.2.x. If you\'re not aware of how updating in AFJ works make sure to first read the guide on Updating AFJ.","sidebar":"tutorialSidebar"},"updating/versions/0.2-to-0.3":{"id":"updating/versions/0.2-to-0.3","title":"Migrating from AFJ 0.2.x to 0.3.x","description":"This document describes everything you need to know for updating AFJ 0.2.x to 0.3.x. If you\'re not aware of how updating in AFJ works make sure to first read the guide on Updating AFJ.","sidebar":"tutorialSidebar"},"updating/versions/0.3-to-0.4":{"id":"updating/versions/0.3-to-0.4","title":"Migrating from AFJ 0.3.x to 0.4.x","description":"This document describes everything you need to know for updating AFJ 0.3.x to 0.4.x. If you\'re not aware of how updating in AFJ works make sure to first read the guide on Updating AFJ.","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/assets/js/17b50570.e8f44455.js b/assets/js/17b50570.e8f44455.js deleted file mode 100644 index 0cea8206..00000000 --- a/assets/js/17b50570.e8f44455.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[9593],{6514:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"0.4","label":"v0.4.x","banner":null,"badge":true,"noIndex":false,"className":"docs-version-0.4","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Intro","href":"/guides/","docId":"index"},{"type":"category","label":"Getting started","items":[{"type":"link","label":"Prerequisites","href":"/guides/getting-started/prerequisites","docId":"getting-started/prerequisites"},{"type":"category","label":"Agent Setup","items":[{"type":"link","label":"Aries Askar","href":"/guides/getting-started/set-up/aries-askar","docId":"getting-started/set-up/aries-askar"},{"type":"category","label":"Indy SDK","items":[{"type":"link","label":"Linux","href":"/guides/getting-started/set-up/indy-sdk/linux","docId":"getting-started/set-up/indy-sdk/linux"},{"type":"link","label":"Windows","href":"/guides/getting-started/set-up/indy-sdk/windows","docId":"getting-started/set-up/indy-sdk/windows"},{"type":"link","label":"macOS (Intel)","href":"/guides/getting-started/set-up/indy-sdk/macos-intel","docId":"getting-started/set-up/indy-sdk/macos-intel"},{"type":"link","label":"macOS (ARM)","href":"/guides/getting-started/set-up/indy-sdk/macos-arm","docId":"getting-started/set-up/indy-sdk/macos-arm"},{"type":"link","label":"React Native","href":"/guides/getting-started/set-up/indy-sdk/react-native","docId":"getting-started/set-up/indy-sdk/react-native"}],"collapsed":true,"collapsible":true,"href":"/guides/getting-started/set-up/indy-sdk/"},{"type":"link","label":"AnonCreds RS","href":"/guides/getting-started/set-up/anoncreds-rs","docId":"getting-started/set-up/anoncreds-rs"},{"type":"link","label":"Indy VDR","href":"/guides/getting-started/set-up/indy-vdr","docId":"getting-started/set-up/indy-vdr"},{"type":"link","label":"cheqd","href":"/guides/getting-started/set-up/cheqd/","docId":"getting-started/set-up/cheqd/index"}],"collapsed":true,"collapsible":true,"href":"/guides/getting-started/set-up/"}],"collapsed":true,"collapsible":true,"href":"/guides/getting-started/"},{"type":"category","label":"Concepts","items":[{"type":"link","label":"Agents","href":"/guides/concepts/agents","docId":"concepts/agents"},{"type":"link","label":"DIDs and DIDComm","href":"/guides/concepts/did-and-didcomm","docId":"concepts/did-and-didcomm"},{"type":"link","label":"Platform and Environment","href":"/guides/concepts/platform-and-environment","docId":"concepts/platform-and-environment"}],"collapsed":true,"collapsible":true,"href":"/guides/concepts/"},{"type":"category","label":"Tutorials","items":[{"type":"category","label":"Agent Config","items":[{"type":"link","label":"Logging","href":"/guides/tutorials/agent-config/logging","docId":"tutorials/agent-config/logging"}],"collapsed":true,"collapsible":true,"href":"/guides/tutorials/agent-config/"},{"type":"link","label":"Create a connection","href":"/guides/tutorials/create-a-connection","docId":"tutorials/create-a-connection"},{"type":"link","label":"Cheqd Did Module","href":"/guides/tutorials/cheqd/","docId":"tutorials/cheqd/index"},{"type":"link","label":"Registering a schema and credential definition on an AnonCreds Registry","href":"/guides/tutorials/registering-schema-and-credential-definition","docId":"tutorials/registering-schema-and-credential-definition"},{"type":"link","label":"Issue a credential","href":"/guides/tutorials/issue-a-credential","docId":"tutorials/issue-a-credential"},{"type":"link","label":"Mediation","href":"/guides/tutorials/mediation","docId":"tutorials/mediation"},{"type":"category","label":"Using PostgreSQL with the Indy SDK","items":[{"type":"link","label":"Postgres Setup for Linux","href":"/guides/tutorials/indy-sdk-postgres-database-nodejs/linux","docId":"tutorials/indy-sdk-postgres-database-nodejs/linux"},{"type":"link","label":"Postgres Setup for macOS","href":"/guides/tutorials/indy-sdk-postgres-database-nodejs/macos","docId":"tutorials/indy-sdk-postgres-database-nodejs/macos"},{"type":"link","label":"Postgres Setup for windows","href":"/guides/tutorials/indy-sdk-postgres-database-nodejs/windows","docId":"tutorials/indy-sdk-postgres-database-nodejs/windows"}],"collapsed":true,"collapsible":true,"href":"/guides/tutorials/indy-sdk-postgres-database-nodejs/"}],"collapsed":true,"collapsible":true,"href":"/guides/tutorials/"},{"type":"category","label":"Updating","items":[{"type":"link","label":"Update Assistant","href":"/guides/updating/update-assistant","docId":"updating/update-assistant"},{"type":"link","label":"Migrating from an Indy SDK Wallet to Aries Askar","href":"/guides/updating/update-indy-sdk-to-askar","docId":"updating/update-indy-sdk-to-askar"},{"type":"link","label":"Migrating from AFJ 0.1.0 to 0.2.x","href":"/guides/updating/versions/0.1-to-0.2","docId":"updating/versions/0.1-to-0.2"},{"type":"link","label":"Migrating from AFJ 0.2.x to 0.3.x","href":"/guides/updating/versions/0.2-to-0.3","docId":"updating/versions/0.2-to-0.3"},{"type":"link","label":"Migrating from AFJ 0.3.x to 0.4.x","href":"/guides/updating/versions/0.3-to-0.4","docId":"updating/versions/0.3-to-0.4"}],"collapsed":true,"collapsible":true,"href":"/guides/updating/"},{"type":"link","label":"The Aries JavaScript Ecosystem","href":"/guides/ecosystem/","docId":"ecosystem/index"},{"type":"category","label":"Extensions","items":[{"type":"link","label":"REST API","href":"/guides/extensions/rest","docId":"extensions/rest"},{"type":"link","label":"React Hooks","href":"/guides/extensions/react-hooks","docId":"extensions/react-hooks"},{"type":"link","label":"Redux Store","href":"/guides/extensions/redux-store","docId":"extensions/redux-store"},{"type":"link","label":"Push Notifications","href":"/guides/extensions/push-notifications","docId":"extensions/push-notifications"}],"collapsed":true,"collapsible":true,"href":"/guides/extensions/"}]},"docs":{"concepts/agents":{"id":"concepts/agents","title":"Agents","description":"When working with any Aries implementation, you will interact with an Aries","sidebar":"tutorialSidebar"},"concepts/did-and-didcomm":{"id":"concepts/did-and-didcomm","title":"DIDs and DIDComm","description":"DIDs","sidebar":"tutorialSidebar"},"concepts/index":{"id":"concepts/index","title":"Concepts","description":"In this section we will discuss the general concepts that are used inside the","sidebar":"tutorialSidebar"},"concepts/platform-and-environment":{"id":"concepts/platform-and-environment","title":"Platform and Environment","description":"Aries framework JavaScript is developed to support a Node.JS and React Native environment. With this it is entirely possible to build an entire SSI ecosystem with Aries Framework JavaScript. This would use Node.JS as an issuer as a verifier, and uses React Native as a holder.","sidebar":"tutorialSidebar"},"ecosystem/index":{"id":"ecosystem/index","title":"The Aries JavaScript Ecosystem","description":"The Aries JavaScript ecosystem includes various components that are spread across multiple repositories. In this section we\'ll go over what these components are and how the relate to one another.","sidebar":"tutorialSidebar"},"extensions/index":{"id":"extensions/index","title":"Extensions","description":"Aries Framework JavaScript Extensions is an extensions repository to Aries Framework JavaScript (AFJ). It hosts libraries built on top of Aries Framework JavaScript that don\'t necessarily belong to the core of the project.","sidebar":"tutorialSidebar"},"extensions/push-notifications":{"id":"extensions/push-notifications","title":"Push Notifications","description":"The Push Notifications plugin package provides a way for you to register your APNs and Firebase push notification token at an agent, allowing you to use push notifications directly from AFJ.","sidebar":"tutorialSidebar"},"extensions/react-hooks":{"id":"extensions/react-hooks","title":"React Hooks","description":"The React Hooks package exposes useful React hooks that allow you to easily interact with AFJ from a React client application.","sidebar":"tutorialSidebar"},"extensions/redux-store":{"id":"extensions/redux-store","title":"Redux Store","description":"The Redux Store is an implementation of state management that can be used to build React & React Native SSI clients using AFJ.","sidebar":"tutorialSidebar"},"extensions/rest":{"id":"extensions/rest","title":"REST API","description":"The Aries Framework JavaScript (AFJ) REST API provides simple RESTful endpoints for AFJ methods, to allow you stand up an agent for communication over the internet instantly. You simply provide your agent configuration. The REST endpoints allow you to interact with your agent over HTTP and WebSockets.","sidebar":"tutorialSidebar"},"getting-started/index":{"id":"getting-started/index","title":"Getting started","description":"In this section we will go over everything you need to get started on a technical level. First there are some general prerequisites for Node.JS and React Native. Aries Framework JavaScript works for creating both server-side applications (commonly but not always for creating issuer and verifier agents) and mobile applications (commonly holder agents).","sidebar":"tutorialSidebar"},"getting-started/prerequisites":{"id":"getting-started/prerequisites","title":"Prerequisites","description":"To work with Aries Framework JavaScript we need to install some dependencies and set-up our Node.JS environment. Even when creating a mobile app in React Native, we need Node.JS installed. We will go over the specific installation process for each platform. Go ahead and pick your system of choice to get started!","sidebar":"tutorialSidebar"},"getting-started/set-up/anoncreds-rs":{"id":"getting-started/set-up/anoncreds-rs","title":"AnonCreds RS","description":"AnonCreds RS is a direct implementation of the AnonCreds V1.0 specification that provides functionality like; creating a schema object, creating a credential definition object, creating a credential, verifying a proof presentation and much more.","sidebar":"tutorialSidebar"},"getting-started/set-up/aries-askar":{"id":"getting-started/set-up/aries-askar","title":"Aries Askar","description":"Aries Askar provides secure, encrypted storage and cryptographic support for encrypting, decrypting, signing and verifying data. It also provides both the Wallet and StorageService implementations for the agent.","sidebar":"tutorialSidebar"},"getting-started/set-up/cheqd/index":{"id":"getting-started/set-up/cheqd/index","title":"cheqd","description":"cheqd is a blockchain network, built in the Cosmos ecosystem for Self-Sovereign Identity (SSI). The cheqd Network leverages the cheqd DID method and enables DID-Linked Resources to be written to the network, associated with a DID and controlled using the verification methods in the DID Document.","sidebar":"tutorialSidebar"},"getting-started/set-up/index":{"id":"getting-started/set-up/index","title":"Agent Setup","description":"This guide assumes you have followed the Prerequisites, and you have a valid","sidebar":"tutorialSidebar"},"getting-started/set-up/indy-sdk/index":{"id":"getting-started/set-up/indy-sdk/index","title":"Indy SDK","description":"Indy SDK provides a distributed ledger based foundation for self-sovereign identity. It can provide the Wallet and StorageService implementations for the agent, as well as a way to interact with Indy ledgers and an implementation of the legacy (v0.1) AnonCreds Specification","sidebar":"tutorialSidebar"},"getting-started/set-up/indy-sdk/linux":{"id":"getting-started/set-up/indy-sdk/linux","title":"Linux","description":"To install Indy SDK on Linux, a couple of dependencies are required. This guide covers the installation for the more popular Linux distributions.","sidebar":"tutorialSidebar"},"getting-started/set-up/indy-sdk/macos-arm":{"id":"getting-started/set-up/indy-sdk/macos-arm","title":"macOS (ARM)","description":"To install Indy SDK on macOS, a couple of dependencies are required. This guide covers the installation of the Indy SDK for macs with an ARM processor. For installing the Indy SDK on Intel based macs, please refer to the Indy SDK macOS (Intel) guide.","sidebar":"tutorialSidebar"},"getting-started/set-up/indy-sdk/macos-intel":{"id":"getting-started/set-up/indy-sdk/macos-intel","title":"macOS (Intel)","description":"To install Indy SDK on macOS a couple of dependencies are required. This guide covers the installation of the Indy SDK for macs with an Intel processor. For installing the Indy SDK on ARM based macs, please refer to the Indy SDK macOS (ARM) guide.","sidebar":"tutorialSidebar"},"getting-started/set-up/indy-sdk/react-native":{"id":"getting-started/set-up/indy-sdk/react-native","title":"React Native","description":"The setup of Indy SDK for React Native is rather different than Node.JS. We do not have to install dependencies on the host-platform, but for the build target. For React Native this would be the Indy SDK for Android & iOS. This guide covers both the Android and iOS setup, as in most React Native projects you will need both.","sidebar":"tutorialSidebar"},"getting-started/set-up/indy-sdk/windows":{"id":"getting-started/set-up/indy-sdk/windows","title":"Windows","description":"To install Indy SDK on Windows, you can download the pre-built binary from the Sovrin repository.","sidebar":"tutorialSidebar"},"getting-started/set-up/indy-vdr":{"id":"getting-started/set-up/indy-vdr","title":"Indy VDR","description":"Hyperledger Indy VDR, Verifiable Data Registry, can be used to connect to one or more Indy Node ledger pools given sets of genesis transactions. Methods are provided to construct ledger requests and send them to the validators, collecting the results and ensuring that there is a consensus between the nodes. In the context of Aries Framework JavaScript, we mainly leverage it to register, and resolve, schemas, credential definitions and DIDs.","sidebar":"tutorialSidebar"},"index":{"id":"index","title":"Intro","description":"Welcome, to the Aries JavaScript community!","sidebar":"tutorialSidebar"},"tutorials/agent-config/index":{"id":"tutorials/agent-config/index","title":"Agent Config","description":"The Aries agent provided by [Aries Framework","sidebar":"tutorialSidebar"},"tutorials/agent-config/logging":{"id":"tutorials/agent-config/logging","title":"Logging","description":"Using the Default ConsoleLogger","sidebar":"tutorialSidebar"},"tutorials/cheqd/index":{"id":"tutorials/cheqd/index","title":"Cheqd Did Module","description":"In this tutorial we will see how to use the cheqd modules in detail","sidebar":"tutorialSidebar"},"tutorials/create-a-connection":{"id":"tutorials/create-a-connection","title":"Create a connection","description":"In this tutorial we will create a connection as Acme Corp with Bob. We will","sidebar":"tutorialSidebar"},"tutorials/index":{"id":"tutorials/index","title":"Tutorials","description":"In this section we will explain some features that everyone will use. This","sidebar":"tutorialSidebar"},"tutorials/indy-sdk-postgres-database-nodejs/index":{"id":"tutorials/indy-sdk-postgres-database-nodejs/index","title":"Using PostgreSQL as Database for Indy SDK in Node.js","description":"By default the Indy SDK will use an SQLite database for storage. In mobile environments this is sufficient and allows us to keep storage local to the device, but in server environments we oftentimes want a more scalable storage solution. By leveraging the PostgreSQL plugin for Indy SDK we can use PostgreSQL as a storage solution instead of SQLite.","sidebar":"tutorialSidebar"},"tutorials/indy-sdk-postgres-database-nodejs/linux":{"id":"tutorials/indy-sdk-postgres-database-nodejs/linux","title":"Postgres Setup for Linux","description":"Prerequisites","sidebar":"tutorialSidebar"},"tutorials/indy-sdk-postgres-database-nodejs/macos":{"id":"tutorials/indy-sdk-postgres-database-nodejs/macos","title":"Postgres Setup for macOS","description":"Prerequisites","sidebar":"tutorialSidebar"},"tutorials/indy-sdk-postgres-database-nodejs/windows":{"id":"tutorials/indy-sdk-postgres-database-nodejs/windows","title":"Postgres Setup for windows","description":"Build Environment Prerequisites","sidebar":"tutorialSidebar"},"tutorials/issue-a-credential":{"id":"tutorials/issue-a-credential","title":"Issue a credential","description":"In this tutorial we will issue a credential from the Issuer to a Holder. We will start with setting up both their agents with the minimal configuration required to follow this tutorial. It is assumed that there is a connection between the Issuer and the Holder and the Issuer also has a registered schema and credential definition. After initializing the Issuer will send a credential to the holder, and will then accept this credential and automatically store it in their wallet.","sidebar":"tutorialSidebar"},"tutorials/mediation":{"id":"tutorials/mediation","title":"Mediation","description":"This section assumes that you have:","sidebar":"tutorialSidebar"},"tutorials/registering-schema-and-credential-definition":{"id":"tutorials/registering-schema-and-credential-definition","title":"Registering a schema and credential definition on an AnonCreds Registry","description":"In this tutorial we will register a schema and credential definition on an AnonCredsRegistry e.g. Hyperledger Indy ledger indy-vdr, cheqd.","sidebar":"tutorialSidebar"},"updating/index":{"id":"updating/index","title":"Updating AFJ","description":"This section will cover everything you need to know about updating Aries Framework JavaScript to a newer version.","sidebar":"tutorialSidebar"},"updating/update-assistant":{"id":"updating/update-assistant","title":"Update Assistant","description":"The Update Assistant helps you update the storage objects from AFJ to newer versions. This documents describes the different ways you can leverage the Update Assistant from fully managed to more manual approaches.","sidebar":"tutorialSidebar"},"updating/update-indy-sdk-to-askar":{"id":"updating/update-indy-sdk-to-askar","title":"Migrating from an Indy SDK Wallet to Aries Askar","description":"This documentation explains the process of migrating your Indy SDK wallet to Aries Askar.","sidebar":"tutorialSidebar"},"updating/versions/0.1-to-0.2":{"id":"updating/versions/0.1-to-0.2","title":"Migrating from AFJ 0.1.0 to 0.2.x","description":"This document describes everything you need to know for updating AFJ 0.1.0 to 0.2.x. If you\'re not aware of how updating in AFJ works make sure to first read the guide on Updating AFJ.","sidebar":"tutorialSidebar"},"updating/versions/0.2-to-0.3":{"id":"updating/versions/0.2-to-0.3","title":"Migrating from AFJ 0.2.x to 0.3.x","description":"This document describes everything you need to know for updating AFJ 0.2.x to 0.3.x. If you\'re not aware of how updating in AFJ works make sure to first read the guide on Updating AFJ.","sidebar":"tutorialSidebar"},"updating/versions/0.3-to-0.4":{"id":"updating/versions/0.3-to-0.4","title":"Migrating from AFJ 0.3.x to 0.4.x","description":"This document describes everything you need to know for updating AFJ 0.3.x to 0.4.x. If you\'re not aware of how updating in AFJ works make sure to first read the guide on Updating AFJ.","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/assets/js/1c0f7eb0.0c8de7f9.js b/assets/js/1c0f7eb0.0c8de7f9.js new file mode 100644 index 00000000..a1e255d7 --- /dev/null +++ b/assets/js/1c0f7eb0.0c8de7f9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[6614],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>g});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),u=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=u(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),c=u(n),m=r,g=c["".concat(l,".").concat(m)]||c[m]||d[m]||i;return n?a.createElement(g,o(o({ref:t},p),{},{components:n})):a.createElement(g,o({ref:t},p))}));function g(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[c]="string"==typeof e?e:r,o[1]=s;for(var u=2;u{n.d(t,{Z:()=>f});var a=n(7294),r=n(6010),i=n(3438),o=n(9960),s=n(3919),l=n(5999);const u={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function p(e){let{href:t,children:n}=e;return a.createElement(o.Z,{href:t,className:(0,r.Z)("card padding--lg",u.cardContainer)},n)}function c(e){let{href:t,icon:n,title:i,description:o}=e;return a.createElement(p,{href:t},a.createElement("h2",{className:(0,r.Z)("text--truncate",u.cardTitle),title:i},n," ",i),o&&a.createElement("p",{className:(0,r.Z)("text--truncate",u.cardDescription),title:o},o))}function d(e){let{item:t}=e;const n=(0,i.Wl)(t);return n?a.createElement(c,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,l.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function m(e){let{item:t}=e;const n=(0,s.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,i.xz)(t.docId??void 0);return a.createElement(c,{href:t.href,icon:n,title:t.label,description:r?.description})}function g(e){let{item:t}=e;switch(t.type){case"link":return a.createElement(m,{item:t});case"category":return a.createElement(d,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function h(e){let{className:t}=e;const n=(0,i.jA)();return a.createElement(f,{items:n.items,className:t})}function f(e){const{items:t,className:n}=e;if(!t)return a.createElement(h,e);const o=(0,i.MN)(t);return a.createElement("section",{className:(0,r.Z)("row",n)},o.map(((e,t)=>a.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},a.createElement(g,{item:e})))))}},5162:(e,t,n)=>{n.d(t,{Z:()=>o});var a=n(7294),r=n(6010);const i={tabItem:"tabItem_Ymn6"};function o(e){let{children:t,hidden:n,className:o}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(i.tabItem,o),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>N});var a=n(7462),r=n(7294),i=n(6010),o=n(2466),s=n(6550),l=n(1980),u=n(7392),p=n(12);function c(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function d(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??c(n);return function(e){const t=(0,u.l)(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 m(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 a=(0,s.k6)(),i=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,l._X)(i),(0,r.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(a.location.search);t.set(i,e),a.replace({...a.location,search:t.toString()})}),[i,a])]}function h(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,i=d(e),[o,s]=(0,r.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(!m({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:i}))),[l,u]=g({queryString:n,groupId:a}),[c,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,i]=(0,p.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:a}),f=(()=>{const e=l??c;return m({value:e,tabValues:i})?e:null})();(0,r.useLayoutEffect)((()=>{f&&s(f)}),[f]);return{selectedValue:o,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);s(e),u(e),h(e)}),[u,h,i]),tabValues:i}}var f=n(2389);const k={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function b(e){let{className:t,block:n,selectedValue:s,selectValue:l,tabValues:u}=e;const p=[],{blockElementScrollPositionUntilNextRender:c}=(0,o.o5)(),d=e=>{const t=e.currentTarget,n=p.indexOf(t),a=u[n].value;a!==s&&(c(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=p.indexOf(e.currentTarget)+1;t=p[n]??p[0];break}case"ArrowLeft":{const n=p.indexOf(e.currentTarget)-1;t=p[n]??p[p.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},u.map((e=>{let{value:t,label:n,attributes:o}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>p.push(e),onKeyDown:m,onClick:d},o,{className:(0,i.Z)("tabs__item",k.tabItem,o?.className,{"tabs__item--active":s===t})}),n??t)})))}function y(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function v(e){const t=h(e);return r.createElement("div",{className:(0,i.Z)("tabs-container",k.tabList)},r.createElement(b,(0,a.Z)({},e,t)),r.createElement(y,(0,a.Z)({},e,t)))}function N(e){const t=(0,f.Z)();return r.createElement(v,(0,a.Z)({key:String(t)},e))}},3018:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>u,default:()=>h,frontMatter:()=>l,metadata:()=>p,toc:()=>d});var a=n(7462),r=(n(7294),n(3905)),i=n(4866),o=n(5162),s=n(2991);const l={},u="Agent Setup",p={unversionedId:"getting-started/set-up/index",id:"version-0.4/getting-started/set-up/index",title:"Agent Setup",description:"This guide assumes you have followed the Prerequisites, and you have a valid",source:"@site/versioned_docs/version-0.4/getting-started/set-up/index.md",sourceDirName:"getting-started/set-up",slug:"/getting-started/set-up/",permalink:"/guides/0.4/getting-started/set-up/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Prerequisites",permalink:"/guides/0.4/getting-started/prerequisites"},next:{title:"Aries Askar",permalink:"/guides/0.4/getting-started/set-up/aries-askar"}},c={},d=[{value:"Installing the required dependencies",id:"installing-the-required-dependencies",level:3},{value:"Additional setup",id:"additional-setup",level:3},{value:"Setting up the agent",id:"setting-up-the-agent",level:3},{value:"Adding a wallet and storage implementation",id:"adding-a-wallet-and-storage-implementation",level:3},{value:"Setting up the transports",id:"setting-up-the-transports",level:3},{value:"Initializing the agent",id:"initializing-the-agent",level:3},{value:"Next Steps",id:"next-steps",level:3},{value:"Useful resources",id:"useful-resources",level:3}],m={toc:d},g="wrapper";function h(e){let{components:t,...n}=e;return(0,r.kt)(g,(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"agent-setup"},"Agent Setup"),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This guide assumes you have followed the ",(0,r.kt)("a",{parentName:"p",href:"./prerequisites"},"Prerequisites"),", and you have a valid\n",(0,r.kt)("a",{parentName:"p",href:"https://nodejs.org"},"Node.JS")," or ",(0,r.kt)("a",{parentName:"p",href:"https://reactnative.dev"},"React Native")," project setup.")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Aries Framework JavaScript is still in ",(0,r.kt)("strong",{parentName:"p"},"active development"),", and as such some APIs are still experimental. ",(0,r.kt)("strong",{parentName:"p"},"When using any experimental features, make sure to use an exact version of AFJ")," (",(0,r.kt)("inlineCode",{parentName:"p"},"0.4.0"),") instead of a range (",(0,r.kt)("inlineCode",{parentName:"p"},"^0.4.0"),"), to prevent accidental breaking changes. If you're not leveraging any experimental features, you can use a range (",(0,r.kt)("inlineCode",{parentName:"p"},"^0.4.0"),") to get the latest bugfixes and features."),(0,r.kt)("p",{parentName:"admonition"},"For AFJ ",(0,r.kt)("inlineCode",{parentName:"p"},"0.4.x"),", ",(0,r.kt)("strong",{parentName:"p"},"the following features are experimental"),":"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},"Implementing your own ",(0,r.kt)("inlineCode",{parentName:"li"},"AnonCredsRegistry")," and AnonCreds service implementation."),(0,r.kt)("li",{parentName:"ul"},"Using the shared component libraries from ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/aries-askar"),", ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/indy-vdr")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/anoncreds-rs")),(0,r.kt)("li",{parentName:"ul"},"Using OpenID4VC from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/openid4vc-client")," module"),(0,r.kt)("li",{parentName:"ul"},"W3C JWT Verifiable Credentials"),(0,r.kt)("li",{parentName:"ul"},"Using multi-tenancy from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/tenants")," module"),(0,r.kt)("li",{parentName:"ul"},"Using BBS+ Signatures from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/bbs-signatures")," module"),(0,r.kt)("li",{parentName:"ul"},"Using the cheqd module from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/cheqd")," module"))),(0,r.kt)("h3",{id:"installing-the-required-dependencies"},"Installing the required dependencies"),(0,r.kt)("p",null,"First we have to install the minimal amount of dependencies that are required\nfor configuring an Aries Framework JavaScript (AFJ) agent."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @aries-framework/core@^0.4.0 @aries-framework/node@^0.4.0\n"))),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @aries-framework/core@^0.4.0 @aries-framework/react-native@^0.4.0 react-native-fs react-native-get-random-values\n")))),(0,r.kt)("h3",{id:"additional-setup"},"Additional setup"),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.js",value:"tab1",mdxType:"TabItem"},(0,r.kt)("p",null,"No additional setup is required for Node.JS")),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("p",null,"Since ",(0,r.kt)("a",{parentName:"p",href:"https://reactnative.dev"},"React Native")," does not have an implementation\nfor\n",(0,r.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues"},(0,r.kt)("inlineCode",{parentName:"a"},"crypto.getRandomValues()")),"\nwe have to setup a polyfill for this. We have to do this at the entrypoint of\nthe application. This could is most likely ",(0,r.kt)("inlineCode",{parentName:"p"},"index.(js|ts|jsx|tsx)")," at the root\nof your application."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-diff",metastring:'title="index.tsx" showLineNumbers',title:'"index.tsx"',showLineNumbers:!0},"+ import 'react-native-get-random-values'\n")),(0,r.kt)("p",null,"In addition you need add support for resolving modules with the ",(0,r.kt)("inlineCode",{parentName:"p"},".cjs")," extension, as this is used by some of AFJ's dependencies and not automatically supported by React Native."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="metro.config.js" showLineNumbers',title:'"metro.config.js"',showLineNumbers:!0},"module.exports = {\n // ... other Metro config options ...\n resolver: {\n // make sure this includes `cjs` (and other extensions you need)\n sourceExts: ['js', 'json', 'ts', 'tsx', 'cjs'],\n },\n}\n")),(0,r.kt)("p",null,"Finally, if you're using ",(0,r.kt)("a",{parentName:"p",href:"https://expo.dev"},"Expo")," you need to add a custom resolution 'hack' that removes support for the legacy unimodules."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Yarn")),(0,r.kt)("p",null,"For yarn we can replace the ",(0,r.kt)("inlineCode",{parentName:"p"},"@unimodules/react-native-adapter")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"@unimodules/core")," dependencies with an empty directory. Make sure to create the ",(0,r.kt)("inlineCode",{parentName:"p"},"noop")," directory in the root of your project and create a ",(0,r.kt)("inlineCode",{parentName:"p"},".gitkeep")," file in the directory so that the directory is committed to your repository."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="package.json" showLineNumbers',title:'"package.json"',showLineNumbers:!0},'{\n // ... other package.json options ...\n "resolutions": {\n "@unimodules/react-native-adapter": "./noop",\n "@unimodules/core": "./noop"\n }\n}\n')),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"NPM")),(0,r.kt)("p",null,"Not supported at the moment. NPM overrides work different than Yarn resolutions, and thus we can't use the same trick. If you're using NPM, feel free to open a PR with a working solution."))),(0,r.kt)("h3",{id:"setting-up-the-agent"},"Setting up the agent"),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"this section does not assume any knowledge of the agent configuration.\nIn the ",(0,r.kt)("a",{parentName:"p",href:"../tutorials/agent-config"},"Agent Config")," tutorial we will discuss in-depth what every\nfield in the configuration does and when to set it.")),(0,r.kt)("p",null,"In order to use the agent in the application we have to configure and\ninitialize it. This following configuration is quite generic and possibly not\nenough for your specific use cases. Please refer to the\n",(0,r.kt)("a",{parentName:"p",href:"../tutorials/index"},"tutorials")," for a more use-case-specific agent setup."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up.ts section-1",showLineNumbers:!0,"set-up.ts":!0,"section-1":!0},""))),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-rn.ts section-1",showLineNumbers:!0,"set-up-rn.ts":!0,"section-1":!0},"")))),(0,r.kt)("h3",{id:"adding-a-wallet-and-storage-implementation"},"Adding a wallet and storage implementation"),(0,r.kt)("p",null,"After creating the ",(0,r.kt)("inlineCode",{parentName:"p"},"Agent")," instance, we need to provide the agent with a wallet and storage implementation. AFJ provides a few implementations out of the box, but you can also implement your own. Currently the following Wallet and Storage implementations are supported out of the box. Follow the specific guides to set up the wallet and storage implementation of your choice."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"./set-up/aries-askar"},"Aries Askar")," - Recommended."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"./set-up/indy-sdk"},"Indy SDK")," - Legacy. Will be deprecated in the future.")),(0,r.kt)(s.Z,{items:[{type:"link",label:"Aries Askar",href:"./set-up/aries-askar",docId:"getting-started/set-up/aries-askar"},{type:"link",label:"Indy SDK",href:"./set-up/indy-sdk",docId:"getting-started/set-up/indy-sdk/index"}],mdxType:"DocCardList"}),(0,r.kt)("h3",{id:"setting-up-the-transports"},"Setting up the transports"),(0,r.kt)("p",null,"Finally, we have to set an outbound transport that\nwill handle traffic from the agent. It is also possible to set an inbound\ntransport in the same way as the outbound transport."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.js",value:"tab1",mdxType:"TabItem"},(0,r.kt)("p",null,"Sets up an WS outbound and HTTP inbound and outbound transport."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up.ts section-2",showLineNumbers:!0,"set-up.ts":!0,"section-2":!0},""))),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("p",null,"For mobile agents the WebSocket transport is often required. We will go into\nmore depth about the reasons for this in the ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.4/tutorials/mediation"},"mediation")," section."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-rn.ts section-2",showLineNumbers:!0,"set-up-rn.ts":!0,"section-2":!0},"")))),(0,r.kt)("h3",{id:"initializing-the-agent"},"Initializing the agent"),(0,r.kt)("p",null,"Finally, we can initialize the agent and it's ready for use."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.js",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up.ts section-3",showLineNumbers:!0,"set-up.ts":!0,"section-3":!0},""))),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-rn.ts section-3",showLineNumbers:!0,"set-up-rn.ts":!0,"section-3":!0},"")))),(0,r.kt)("h3",{id:"next-steps"},"Next Steps"),(0,r.kt)("p",null,"Now that you have your agent setup, it's time to start building your application. Head over to the tutorials page to get started."),(0,r.kt)(s.Z,{items:[{type:"link",label:"Tutorials",href:"../tutorials/index",docId:"tutorials/index"},{type:"link",label:"Create a Connection",href:"../tutorials/create-a-connection",docId:"tutorials/create-a-connection"}],mdxType:"DocCardList"}),(0,r.kt)("h3",{id:"useful-resources"},"Useful resources"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0004-agents/README.md"},"Hyperledger Aries RFC - 004:\nAgents"))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1c0f7eb0.ae59bc78.js b/assets/js/1c0f7eb0.ae59bc78.js deleted file mode 100644 index 1fde66a6..00000000 --- a/assets/js/1c0f7eb0.ae59bc78.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[6614],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>g});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),u=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=u(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),c=u(n),m=r,g=c["".concat(l,".").concat(m)]||c[m]||d[m]||i;return n?a.createElement(g,o(o({ref:t},p),{},{components:n})):a.createElement(g,o({ref:t},p))}));function g(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[c]="string"==typeof e?e:r,o[1]=s;for(var u=2;u{n.d(t,{Z:()=>f});var a=n(7294),r=n(6010),i=n(3438),o=n(9960),s=n(3919),l=n(5999);const u={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function p(e){let{href:t,children:n}=e;return a.createElement(o.Z,{href:t,className:(0,r.Z)("card padding--lg",u.cardContainer)},n)}function c(e){let{href:t,icon:n,title:i,description:o}=e;return a.createElement(p,{href:t},a.createElement("h2",{className:(0,r.Z)("text--truncate",u.cardTitle),title:i},n," ",i),o&&a.createElement("p",{className:(0,r.Z)("text--truncate",u.cardDescription),title:o},o))}function d(e){let{item:t}=e;const n=(0,i.Wl)(t);return n?a.createElement(c,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,l.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function m(e){let{item:t}=e;const n=(0,s.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,i.xz)(t.docId??void 0);return a.createElement(c,{href:t.href,icon:n,title:t.label,description:r?.description})}function g(e){let{item:t}=e;switch(t.type){case"link":return a.createElement(m,{item:t});case"category":return a.createElement(d,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function h(e){let{className:t}=e;const n=(0,i.jA)();return a.createElement(f,{items:n.items,className:t})}function f(e){const{items:t,className:n}=e;if(!t)return a.createElement(h,e);const o=(0,i.MN)(t);return a.createElement("section",{className:(0,r.Z)("row",n)},o.map(((e,t)=>a.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},a.createElement(g,{item:e})))))}},5162:(e,t,n)=>{n.d(t,{Z:()=>o});var a=n(7294),r=n(6010);const i={tabItem:"tabItem_Ymn6"};function o(e){let{children:t,hidden:n,className:o}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(i.tabItem,o),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>N});var a=n(7462),r=n(7294),i=n(6010),o=n(2466),s=n(6550),l=n(1980),u=n(7392),p=n(12);function c(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function d(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??c(n);return function(e){const t=(0,u.l)(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 m(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 a=(0,s.k6)(),i=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,l._X)(i),(0,r.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(a.location.search);t.set(i,e),a.replace({...a.location,search:t.toString()})}),[i,a])]}function h(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,i=d(e),[o,s]=(0,r.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(!m({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:i}))),[l,u]=g({queryString:n,groupId:a}),[c,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,i]=(0,p.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:a}),f=(()=>{const e=l??c;return m({value:e,tabValues:i})?e:null})();(0,r.useLayoutEffect)((()=>{f&&s(f)}),[f]);return{selectedValue:o,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);s(e),u(e),h(e)}),[u,h,i]),tabValues:i}}var f=n(2389);const k={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function b(e){let{className:t,block:n,selectedValue:s,selectValue:l,tabValues:u}=e;const p=[],{blockElementScrollPositionUntilNextRender:c}=(0,o.o5)(),d=e=>{const t=e.currentTarget,n=p.indexOf(t),a=u[n].value;a!==s&&(c(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=p.indexOf(e.currentTarget)+1;t=p[n]??p[0];break}case"ArrowLeft":{const n=p.indexOf(e.currentTarget)-1;t=p[n]??p[p.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},u.map((e=>{let{value:t,label:n,attributes:o}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>p.push(e),onKeyDown:m,onClick:d},o,{className:(0,i.Z)("tabs__item",k.tabItem,o?.className,{"tabs__item--active":s===t})}),n??t)})))}function y(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function v(e){const t=h(e);return r.createElement("div",{className:(0,i.Z)("tabs-container",k.tabList)},r.createElement(b,(0,a.Z)({},e,t)),r.createElement(y,(0,a.Z)({},e,t)))}function N(e){const t=(0,f.Z)();return r.createElement(v,(0,a.Z)({key:String(t)},e))}},3018:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>u,default:()=>h,frontMatter:()=>l,metadata:()=>p,toc:()=>d});var a=n(7462),r=(n(7294),n(3905)),i=n(4866),o=n(5162),s=n(2991);const l={},u="Agent Setup",p={unversionedId:"getting-started/set-up/index",id:"version-0.4/getting-started/set-up/index",title:"Agent Setup",description:"This guide assumes you have followed the Prerequisites, and you have a valid",source:"@site/versioned_docs/version-0.4/getting-started/set-up/index.md",sourceDirName:"getting-started/set-up",slug:"/getting-started/set-up/",permalink:"/guides/getting-started/set-up/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Prerequisites",permalink:"/guides/getting-started/prerequisites"},next:{title:"Aries Askar",permalink:"/guides/getting-started/set-up/aries-askar"}},c={},d=[{value:"Installing the required dependencies",id:"installing-the-required-dependencies",level:3},{value:"Additional setup",id:"additional-setup",level:3},{value:"Setting up the agent",id:"setting-up-the-agent",level:3},{value:"Adding a wallet and storage implementation",id:"adding-a-wallet-and-storage-implementation",level:3},{value:"Setting up the transports",id:"setting-up-the-transports",level:3},{value:"Initializing the agent",id:"initializing-the-agent",level:3},{value:"Next Steps",id:"next-steps",level:3},{value:"Useful resources",id:"useful-resources",level:3}],m={toc:d},g="wrapper";function h(e){let{components:t,...n}=e;return(0,r.kt)(g,(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"agent-setup"},"Agent Setup"),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This guide assumes you have followed the ",(0,r.kt)("a",{parentName:"p",href:"./prerequisites"},"Prerequisites"),", and you have a valid\n",(0,r.kt)("a",{parentName:"p",href:"https://nodejs.org"},"Node.JS")," or ",(0,r.kt)("a",{parentName:"p",href:"https://reactnative.dev"},"React Native")," project setup.")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Aries Framework JavaScript is still in ",(0,r.kt)("strong",{parentName:"p"},"active development"),", and as such some APIs are still experimental. ",(0,r.kt)("strong",{parentName:"p"},"When using any experimental features, make sure to use an exact version of AFJ")," (",(0,r.kt)("inlineCode",{parentName:"p"},"0.4.0"),") instead of a range (",(0,r.kt)("inlineCode",{parentName:"p"},"^0.4.0"),"), to prevent accidental breaking changes. If you're not leveraging any experimental features, you can use a range (",(0,r.kt)("inlineCode",{parentName:"p"},"^0.4.0"),") to get the latest bugfixes and features."),(0,r.kt)("p",{parentName:"admonition"},"For AFJ ",(0,r.kt)("inlineCode",{parentName:"p"},"0.4.x"),", ",(0,r.kt)("strong",{parentName:"p"},"the following features are experimental"),":"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},"Implementing your own ",(0,r.kt)("inlineCode",{parentName:"li"},"AnonCredsRegistry")," and AnonCreds service implementation."),(0,r.kt)("li",{parentName:"ul"},"Using the shared component libraries from ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/aries-askar"),", ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/indy-vdr")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/anoncreds-rs")),(0,r.kt)("li",{parentName:"ul"},"Using OpenID4VC from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/openid4vc-client")," module"),(0,r.kt)("li",{parentName:"ul"},"W3C JWT Verifiable Credentials"),(0,r.kt)("li",{parentName:"ul"},"Using multi-tenancy from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/tenants")," module"),(0,r.kt)("li",{parentName:"ul"},"Using BBS+ Signatures from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/bbs-signatures")," module"),(0,r.kt)("li",{parentName:"ul"},"Using the cheqd module from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/cheqd")," module"))),(0,r.kt)("h3",{id:"installing-the-required-dependencies"},"Installing the required dependencies"),(0,r.kt)("p",null,"First we have to install the minimal amount of dependencies that are required\nfor configuring an Aries Framework JavaScript (AFJ) agent."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @aries-framework/core@^0.4.0 @aries-framework/node@^0.4.0\n"))),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @aries-framework/core@^0.4.0 @aries-framework/react-native@^0.4.0 react-native-fs react-native-get-random-values\n")))),(0,r.kt)("h3",{id:"additional-setup"},"Additional setup"),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.js",value:"tab1",mdxType:"TabItem"},(0,r.kt)("p",null,"No additional setup is required for Node.JS")),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("p",null,"Since ",(0,r.kt)("a",{parentName:"p",href:"https://reactnative.dev"},"React Native")," does not have an implementation\nfor\n",(0,r.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues"},(0,r.kt)("inlineCode",{parentName:"a"},"crypto.getRandomValues()")),"\nwe have to setup a polyfill for this. We have to do this at the entrypoint of\nthe application. This could is most likely ",(0,r.kt)("inlineCode",{parentName:"p"},"index.(js|ts|jsx|tsx)")," at the root\nof your application."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-diff",metastring:'title="index.tsx" showLineNumbers',title:'"index.tsx"',showLineNumbers:!0},"+ import 'react-native-get-random-values'\n")),(0,r.kt)("p",null,"In addition you need add support for resolving modules with the ",(0,r.kt)("inlineCode",{parentName:"p"},".cjs")," extension, as this is used by some of AFJ's dependencies and not automatically supported by React Native."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="metro.config.js" showLineNumbers',title:'"metro.config.js"',showLineNumbers:!0},"module.exports = {\n // ... other Metro config options ...\n resolver: {\n // make sure this includes `cjs` (and other extensions you need)\n sourceExts: ['js', 'json', 'ts', 'tsx', 'cjs'],\n },\n}\n")),(0,r.kt)("p",null,"Finally, if you're using ",(0,r.kt)("a",{parentName:"p",href:"https://expo.dev"},"Expo")," you need to add a custom resolution 'hack' that removes support for the legacy unimodules."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Yarn")),(0,r.kt)("p",null,"For yarn we can replace the ",(0,r.kt)("inlineCode",{parentName:"p"},"@unimodules/react-native-adapter")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"@unimodules/core")," dependencies with an empty directory. Make sure to create the ",(0,r.kt)("inlineCode",{parentName:"p"},"noop")," directory in the root of your project and create a ",(0,r.kt)("inlineCode",{parentName:"p"},".gitkeep")," file in the directory so that the directory is committed to your repository."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="package.json" showLineNumbers',title:'"package.json"',showLineNumbers:!0},'{\n // ... other package.json options ...\n "resolutions": {\n "@unimodules/react-native-adapter": "./noop",\n "@unimodules/core": "./noop"\n }\n}\n')),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"NPM")),(0,r.kt)("p",null,"Not supported at the moment. NPM overrides work different than Yarn resolutions, and thus we can't use the same trick. If you're using NPM, feel free to open a PR with a working solution."))),(0,r.kt)("h3",{id:"setting-up-the-agent"},"Setting up the agent"),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"this section does not assume any knowledge of the agent configuration.\nIn the ",(0,r.kt)("a",{parentName:"p",href:"../tutorials/agent-config"},"Agent Config")," tutorial we will discuss in-depth what every\nfield in the configuration does and when to set it.")),(0,r.kt)("p",null,"In order to use the agent in the application we have to configure and\ninitialize it. This following configuration is quite generic and possibly not\nenough for your specific use cases. Please refer to the\n",(0,r.kt)("a",{parentName:"p",href:"../tutorials/index"},"tutorials")," for a more use-case-specific agent setup."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up.ts section-1",showLineNumbers:!0,"set-up.ts":!0,"section-1":!0},""))),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-rn.ts section-1",showLineNumbers:!0,"set-up-rn.ts":!0,"section-1":!0},"")))),(0,r.kt)("h3",{id:"adding-a-wallet-and-storage-implementation"},"Adding a wallet and storage implementation"),(0,r.kt)("p",null,"After creating the ",(0,r.kt)("inlineCode",{parentName:"p"},"Agent")," instance, we need to provide the agent with a wallet and storage implementation. AFJ provides a few implementations out of the box, but you can also implement your own. Currently the following Wallet and Storage implementations are supported out of the box. Follow the specific guides to set up the wallet and storage implementation of your choice."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"./set-up/aries-askar"},"Aries Askar")," - Recommended."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"./set-up/indy-sdk"},"Indy SDK")," - Legacy. Will be deprecated in the future.")),(0,r.kt)(s.Z,{items:[{type:"link",label:"Aries Askar",href:"./set-up/aries-askar",docId:"getting-started/set-up/aries-askar"},{type:"link",label:"Indy SDK",href:"./set-up/indy-sdk",docId:"getting-started/set-up/indy-sdk/index"}],mdxType:"DocCardList"}),(0,r.kt)("h3",{id:"setting-up-the-transports"},"Setting up the transports"),(0,r.kt)("p",null,"Finally, we have to set an outbound transport that\nwill handle traffic from the agent. It is also possible to set an inbound\ntransport in the same way as the outbound transport."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.js",value:"tab1",mdxType:"TabItem"},(0,r.kt)("p",null,"Sets up an WS outbound and HTTP inbound and outbound transport."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up.ts section-2",showLineNumbers:!0,"set-up.ts":!0,"section-2":!0},""))),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("p",null,"For mobile agents the WebSocket transport is often required. We will go into\nmore depth about the reasons for this in the ",(0,r.kt)("a",{parentName:"p",href:"/guides/tutorials/mediation"},"mediation")," section."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-rn.ts section-2",showLineNumbers:!0,"set-up-rn.ts":!0,"section-2":!0},"")))),(0,r.kt)("h3",{id:"initializing-the-agent"},"Initializing the agent"),(0,r.kt)("p",null,"Finally, we can initialize the agent and it's ready for use."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.js",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up.ts section-3",showLineNumbers:!0,"set-up.ts":!0,"section-3":!0},""))),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-rn.ts section-3",showLineNumbers:!0,"set-up-rn.ts":!0,"section-3":!0},"")))),(0,r.kt)("h3",{id:"next-steps"},"Next Steps"),(0,r.kt)("p",null,"Now that you have your agent setup, it's time to start building your application. Head over to the tutorials page to get started."),(0,r.kt)(s.Z,{items:[{type:"link",label:"Tutorials",href:"../tutorials/index",docId:"tutorials/index"},{type:"link",label:"Create a Connection",href:"../tutorials/create-a-connection",docId:"tutorials/create-a-connection"}],mdxType:"DocCardList"}),(0,r.kt)("h3",{id:"useful-resources"},"Useful resources"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0004-agents/README.md"},"Hyperledger Aries RFC - 004:\nAgents"))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1cc62cef.10e0beb9.js b/assets/js/1cc62cef.10e0beb9.js new file mode 100644 index 00000000..7d518791 --- /dev/null +++ b/assets/js/1cc62cef.10e0beb9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[9626],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>h});var i=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function n(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,i)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=i.createContext({}),p=function(e){var t=i.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},c=function(e){var t=p(e.components);return i.createElement(l.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var r=e.components,a=e.mdxType,n=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),m=p(r),d=a,h=m["".concat(l,".").concat(d)]||m[d]||u[d]||n;return r?i.createElement(h,o(o({ref:t},c),{},{components:r})):i.createElement(h,o({ref:t},c))}));function h(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var n=r.length,o=new Array(n);o[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[m]="string"==typeof e?e:a,o[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>n,metadata:()=>s,toc:()=>p});var i=r(7462),a=(r(7294),r(3905));const n={},o="The Aries JavaScript Ecosystem",s={unversionedId:"ecosystem/index",id:"version-0.4/ecosystem/index",title:"The Aries JavaScript Ecosystem",description:"The Aries JavaScript ecosystem includes various components that are spread across multiple repositories. In this section we'll go over what these components are and how the relate to one another.",source:"@site/versioned_docs/version-0.4/ecosystem/index.md",sourceDirName:"ecosystem",slug:"/ecosystem/",permalink:"/guides/0.4/ecosystem/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Migrating from AFJ 0.3.x to 0.4.x",permalink:"/guides/0.4/updating/versions/0.3-to-0.4"},next:{title:"Extensions",permalink:"/guides/0.4/extensions/"}},l={},p=[{value:"Repositories",id:"repositories",level:2},{value:"Documentation",id:"documentation",level:2},{value:"Aries Framework JavaScript",id:"aries-framework-javascript",level:3},{value:"Contributing in the Aries JS Ecosystem",id:"contributing-in-the-aries-js-ecosystem",level:2},{value:"Developer Contributions",id:"developer-contributions",level:3}],c={toc:p},m="wrapper";function u(e){let{components:t,...r}=e;return(0,a.kt)(m,(0,i.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"the-aries-javascript-ecosystem"},"The Aries JavaScript Ecosystem"),(0,a.kt)("p",null,"The Aries JavaScript ecosystem includes various components that are spread across multiple repositories. In this section we'll go over what these components are and how the relate to one another."),(0,a.kt)("h2",{id:"repositories"},"Repositories"),(0,a.kt)("p",null,"Currently, Aries JavaScript is composed out of three separate repositories:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-framework-javascript"},"Aries Framework JavaScript")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-framework-javascript-ext"},"Aries Framework JavaScript Extensions")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-mobile-agent-react-native"},"Aries Mobile Agent React Native (Bifold)"))),(0,a.kt)("h2",{id:"documentation"},"Documentation"),(0,a.kt)("p",null,"You can find their documentation here:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"https://credo.js.org/guides"},"Aries Framework JavaScript")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"https://credo.js.org/guides/extensions"},"Aries Framework JavaScript Extensions")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-mobile-agent-react-native/blob/main/README.md"},"Aries Mobile Agent React Native (Bifold)"))),(0,a.kt)("h3",{id:"aries-framework-javascript"},"Aries Framework JavaScript"),(0,a.kt)("p",null,"Aries Framework JavaScript (AFJ) is at the core of the Aries JavaScript ecosystem. AFJ provides all the functionality related to cryptography, storage, messaging and more that is required"),(0,a.kt)("h2",{id:"contributing-in-the-aries-js-ecosystem"},"Contributing in the Aries JS Ecosystem"),(0,a.kt)("p",null,"Consider attending our weekly meetings to become aware of the current development cadence."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://wiki.hyperledger.org/display/ARIES/Framework+JS+Meetings"},"Aries Framework JS Meeting")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://wiki.hyperledger.org/display/ARIES/Aries+Bifold+User+Group"},"Aries Bifold Meeting")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://wiki.hyperledger.org/display/ARIES/Aries+Working+Group"},"Aries Working Group Meeting"))),(0,a.kt)("h3",{id:"developer-contributions"},"Developer Contributions"),(0,a.kt)("p",null,"Each project maintains its own CONTRIBUTING guidance:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-framework-javascript/blob/main/CONTRIBUTING.md"},"AFJ CONTRIBUTING.md")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-framework-javascript-ext/blob/main/CONTRIBUTING.md"},"AFJ-Ext CONTRIBUTING.md")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-mobile-agent-react-native/blob/main/CONTRIBUTING"},"Aries Bifold CONTRIBUTING"))),(0,a.kt)("p",null,"Each project has a significant set of developer conventions, checklists, templates, and actions to provide guidance and boundaries for a contribution.\nConsider looking at previous issues and their corresponding PRs to get a sense of the latest."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1cc62cef.74aa4746.js b/assets/js/1cc62cef.74aa4746.js deleted file mode 100644 index a270cd62..00000000 --- a/assets/js/1cc62cef.74aa4746.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[9626],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>h});var i=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function n(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,i)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=i.createContext({}),p=function(e){var t=i.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},c=function(e){var t=p(e.components);return i.createElement(l.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var r=e.components,a=e.mdxType,n=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),m=p(r),d=a,h=m["".concat(l,".").concat(d)]||m[d]||u[d]||n;return r?i.createElement(h,o(o({ref:t},c),{},{components:r})):i.createElement(h,o({ref:t},c))}));function h(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var n=r.length,o=new Array(n);o[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[m]="string"==typeof e?e:a,o[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>n,metadata:()=>s,toc:()=>p});var i=r(7462),a=(r(7294),r(3905));const n={},o="The Aries JavaScript Ecosystem",s={unversionedId:"ecosystem/index",id:"version-0.4/ecosystem/index",title:"The Aries JavaScript Ecosystem",description:"The Aries JavaScript ecosystem includes various components that are spread across multiple repositories. In this section we'll go over what these components are and how the relate to one another.",source:"@site/versioned_docs/version-0.4/ecosystem/index.md",sourceDirName:"ecosystem",slug:"/ecosystem/",permalink:"/guides/ecosystem/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Migrating from AFJ 0.3.x to 0.4.x",permalink:"/guides/updating/versions/0.3-to-0.4"},next:{title:"Extensions",permalink:"/guides/extensions/"}},l={},p=[{value:"Repositories",id:"repositories",level:2},{value:"Documentation",id:"documentation",level:2},{value:"Aries Framework JavaScript",id:"aries-framework-javascript",level:3},{value:"Contributing in the Aries JS Ecosystem",id:"contributing-in-the-aries-js-ecosystem",level:2},{value:"Developer Contributions",id:"developer-contributions",level:3}],c={toc:p},m="wrapper";function u(e){let{components:t,...r}=e;return(0,a.kt)(m,(0,i.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"the-aries-javascript-ecosystem"},"The Aries JavaScript Ecosystem"),(0,a.kt)("p",null,"The Aries JavaScript ecosystem includes various components that are spread across multiple repositories. In this section we'll go over what these components are and how the relate to one another."),(0,a.kt)("h2",{id:"repositories"},"Repositories"),(0,a.kt)("p",null,"Currently, Aries JavaScript is composed out of three separate repositories:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-framework-javascript"},"Aries Framework JavaScript")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-framework-javascript-ext"},"Aries Framework JavaScript Extensions")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-mobile-agent-react-native"},"Aries Mobile Agent React Native (Bifold)"))),(0,a.kt)("h2",{id:"documentation"},"Documentation"),(0,a.kt)("p",null,"You can find their documentation here:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"https://credo.js.org/guides"},"Aries Framework JavaScript")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"https://credo.js.org/guides/extensions"},"Aries Framework JavaScript Extensions")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-mobile-agent-react-native/blob/main/README.md"},"Aries Mobile Agent React Native (Bifold)"))),(0,a.kt)("h3",{id:"aries-framework-javascript"},"Aries Framework JavaScript"),(0,a.kt)("p",null,"Aries Framework JavaScript (AFJ) is at the core of the Aries JavaScript ecosystem. AFJ provides all the functionality related to cryptography, storage, messaging and more that is required"),(0,a.kt)("h2",{id:"contributing-in-the-aries-js-ecosystem"},"Contributing in the Aries JS Ecosystem"),(0,a.kt)("p",null,"Consider attending our weekly meetings to become aware of the current development cadence."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://wiki.hyperledger.org/display/ARIES/Framework+JS+Meetings"},"Aries Framework JS Meeting")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://wiki.hyperledger.org/display/ARIES/Aries+Bifold+User+Group"},"Aries Bifold Meeting")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://wiki.hyperledger.org/display/ARIES/Aries+Working+Group"},"Aries Working Group Meeting"))),(0,a.kt)("h3",{id:"developer-contributions"},"Developer Contributions"),(0,a.kt)("p",null,"Each project maintains its own CONTRIBUTING guidance:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-framework-javascript/blob/main/CONTRIBUTING.md"},"AFJ CONTRIBUTING.md")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-framework-javascript-ext/blob/main/CONTRIBUTING.md"},"AFJ-Ext CONTRIBUTING.md")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-mobile-agent-react-native/blob/main/CONTRIBUTING"},"Aries Bifold CONTRIBUTING"))),(0,a.kt)("p",null,"Each project has a significant set of developer conventions, checklists, templates, and actions to provide guidance and boundaries for a contribution.\nConsider looking at previous issues and their corresponding PRs to get a sense of the latest."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2003ac23.5a088efe.js b/assets/js/2003ac23.def5b47e.js similarity index 86% rename from assets/js/2003ac23.5a088efe.js rename to assets/js/2003ac23.def5b47e.js index 3472b35a..07bdafc1 100644 --- a/assets/js/2003ac23.5a088efe.js +++ b/assets/js/2003ac23.def5b47e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7529],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);function c(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(c[n]=e[n]);return c}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(c[n]=e[n])}return c}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,c=e.mdxType,i=e.originalType,s=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),u=l(n),m=c,f=u["".concat(s,".").concat(m)]||u[m]||d[m]||i;return n?r.createElement(f,o(o({ref:t},p),{},{components:n})):r.createElement(f,o({ref:t},p))}));function f(e,t){var n=arguments,c=t&&t.mdxType;if("string"==typeof e||c){var i=n.length,o=new Array(i);o[0]=m;var a={};for(var s in t)hasOwnProperty.call(t,s)&&(a[s]=t[s]);a.originalType=e,a[u]="string"==typeof e?e:c,o[1]=a;for(var l=2;l{n.d(t,{Z:()=>h});var r=n(7294),c=n(6010),i=n(3438),o=n(9960),a=n(3919),s=n(5999);const l={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function p(e){let{href:t,children:n}=e;return r.createElement(o.Z,{href:t,className:(0,c.Z)("card padding--lg",l.cardContainer)},n)}function u(e){let{href:t,icon:n,title:i,description:o}=e;return r.createElement(p,{href:t},r.createElement("h2",{className:(0,c.Z)("text--truncate",l.cardTitle),title:i},n," ",i),o&&r.createElement("p",{className:(0,c.Z)("text--truncate",l.cardDescription),title:o},o))}function d(e){let{item:t}=e;const n=(0,i.Wl)(t);return n?r.createElement(u,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,s.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function m(e){let{item:t}=e;const n=(0,a.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",c=(0,i.xz)(t.docId??void 0);return r.createElement(u,{href:t.href,icon:n,title:t.label,description:c?.description})}function f(e){let{item:t}=e;switch(t.type){case"link":return r.createElement(m,{item:t});case"category":return r.createElement(d,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function y(e){let{className:t}=e;const n=(0,i.jA)();return r.createElement(h,{items:n.items,className:t})}function h(e){const{items:t,className:n}=e;if(!t)return r.createElement(y,e);const o=(0,i.MN)(t);return r.createElement("section",{className:(0,c.Z)("row",n)},o.map(((e,t)=>r.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},r.createElement(f,{item:e})))))}},6314:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=n(7462),c=(n(7294),n(3905)),i=n(2991);const o={},a="Concepts",s={unversionedId:"concepts/index",id:"concepts/index",title:"Concepts",description:"In this section we will discuss the general concepts that are used inside the",source:"@site/guides/concepts/index.md",sourceDirName:"concepts",slug:"/concepts/",permalink:"/guides/0.5/concepts/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"cheqd",permalink:"/guides/0.5/getting-started/set-up/cheqd/"},next:{title:"Agents",permalink:"/guides/0.5/concepts/agents"}},l={},p=[],u={toc:p},d="wrapper";function m(e){let{components:t,...n}=e;return(0,c.kt)(d,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,c.kt)("h1",{id:"concepts"},"Concepts"),(0,c.kt)("p",null,"In this section we will discuss the general concepts that are used inside the\naries-javascript ecosystem. These concepts will help you understand the basics\non a high level."),(0,c.kt)(i.Z,{mdxType:"DocCardList"}))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7529],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);function c(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(c[n]=e[n]);return c}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(c[n]=e[n])}return c}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,c=e.mdxType,i=e.originalType,s=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),u=l(n),m=c,f=u["".concat(s,".").concat(m)]||u[m]||d[m]||i;return n?r.createElement(f,o(o({ref:t},p),{},{components:n})):r.createElement(f,o({ref:t},p))}));function f(e,t){var n=arguments,c=t&&t.mdxType;if("string"==typeof e||c){var i=n.length,o=new Array(i);o[0]=m;var a={};for(var s in t)hasOwnProperty.call(t,s)&&(a[s]=t[s]);a.originalType=e,a[u]="string"==typeof e?e:c,o[1]=a;for(var l=2;l{n.d(t,{Z:()=>h});var r=n(7294),c=n(6010),i=n(3438),o=n(9960),a=n(3919),s=n(5999);const l={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function p(e){let{href:t,children:n}=e;return r.createElement(o.Z,{href:t,className:(0,c.Z)("card padding--lg",l.cardContainer)},n)}function u(e){let{href:t,icon:n,title:i,description:o}=e;return r.createElement(p,{href:t},r.createElement("h2",{className:(0,c.Z)("text--truncate",l.cardTitle),title:i},n," ",i),o&&r.createElement("p",{className:(0,c.Z)("text--truncate",l.cardDescription),title:o},o))}function d(e){let{item:t}=e;const n=(0,i.Wl)(t);return n?r.createElement(u,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,s.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function m(e){let{item:t}=e;const n=(0,a.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",c=(0,i.xz)(t.docId??void 0);return r.createElement(u,{href:t.href,icon:n,title:t.label,description:c?.description})}function f(e){let{item:t}=e;switch(t.type){case"link":return r.createElement(m,{item:t});case"category":return r.createElement(d,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function y(e){let{className:t}=e;const n=(0,i.jA)();return r.createElement(h,{items:n.items,className:t})}function h(e){const{items:t,className:n}=e;if(!t)return r.createElement(y,e);const o=(0,i.MN)(t);return r.createElement("section",{className:(0,c.Z)("row",n)},o.map(((e,t)=>r.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},r.createElement(f,{item:e})))))}},6314:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=n(7462),c=(n(7294),n(3905)),i=n(2991);const o={},a="Concepts",s={unversionedId:"concepts/index",id:"concepts/index",title:"Concepts",description:"In this section we will discuss the general concepts that are used inside the",source:"@site/guides/concepts/index.md",sourceDirName:"concepts",slug:"/concepts/",permalink:"/guides/concepts/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"cheqd",permalink:"/guides/getting-started/set-up/cheqd/"},next:{title:"Agents",permalink:"/guides/concepts/agents"}},l={},p=[],u={toc:p},d="wrapper";function m(e){let{components:t,...n}=e;return(0,c.kt)(d,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,c.kt)("h1",{id:"concepts"},"Concepts"),(0,c.kt)("p",null,"In this section we will discuss the general concepts that are used inside the\naries-javascript ecosystem. These concepts will help you understand the basics\non a high level."),(0,c.kt)(i.Z,{mdxType:"DocCardList"}))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/207a1e16.d117fc44.js b/assets/js/207a1e16.d117fc44.js new file mode 100644 index 00000000..6ee0074d --- /dev/null +++ b/assets/js/207a1e16.d117fc44.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[6407],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(n),m=o,f=u["".concat(l,".").concat(m)]||u[m]||d[m]||a;return n?r.createElement(f,i(i({ref:t},c),{},{components:n})):r.createElement(f,i({ref:t},c))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const a={},i="REST API",s={unversionedId:"extensions/rest",id:"version-0.4/extensions/rest",title:"REST API",description:"The Aries Framework JavaScript (AFJ) REST API provides simple RESTful endpoints for AFJ methods, to allow you stand up an agent for communication over the internet instantly. You simply provide your agent configuration. The REST endpoints allow you to interact with your agent over HTTP and WebSockets.",source:"@site/versioned_docs/version-0.4/extensions/rest.md",sourceDirName:"extensions",slug:"/extensions/rest",permalink:"/guides/0.4/extensions/rest",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Extensions",permalink:"/guides/0.4/extensions/"},next:{title:"React Hooks",permalink:"/guides/0.4/extensions/react-hooks"}},l={},p=[{value:"Quick Setup",id:"quick-setup",level:2},{value:"Directly on computer",id:"directly-on-computer",level:3},{value:"Configuration",id:"configuration",level:3}],c={toc:p},u="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"rest-api"},"REST API"),(0,o.kt)("p",null,"The Aries Framework JavaScript (AFJ) REST API provides simple RESTful endpoints for AFJ methods, to allow you stand up an agent for communication over the internet instantly. You simply provide your agent configuration. The REST endpoints allow you to interact with your agent over HTTP and WebSockets."),(0,o.kt)("p",null,"The AFJ REST API is the most convenient way for self-sovereign identity (SSI) developers to interact with SSI agents."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"\u2b50 ",(0,o.kt)("strong",{parentName:"li"},"Endpoints")," to create connections, issue credentials, and request proofs."),(0,o.kt)("li",{parentName:"ul"},"\ud83d\udcbb ",(0,o.kt)("strong",{parentName:"li"},"CLI")," that makes it super easy to start an instance of the REST API."),(0,o.kt)("li",{parentName:"ul"},"\ud83c\udf10 ",(0,o.kt)("strong",{parentName:"li"},"Interoperable")," with all major Aries implementations.")),(0,o.kt)("admonition",{type:"danger"},(0,o.kt)("p",{parentName:"admonition"},"The ",(0,o.kt)("inlineCode",{parentName:"p"},"@aries-framework/rest")," package has not been updated to work with the latest version (",(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"0.4.x")),") of ",(0,o.kt)("inlineCode",{parentName:"p"},"@aries-framework/core"),". The documentation in this section is for version ",(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"0.9.x"))," of the ",(0,o.kt)("inlineCode",{parentName:"p"},"@aries-framework/rest")," package, that works with ",(0,o.kt)("inlineCode",{parentName:"p"},"@aries-framework/core")," version ",(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"0.2.x")),". Extension packages (such as REST API) are versioned separately from the core packages.")),(0,o.kt)("h2",{id:"quick-setup"},"Quick Setup"),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"This guide assumes you have followed the install guides for the framework (See ",(0,o.kt)("a",{parentName:"p",href:"../../getting-started/index.md"},"Getting Started")," section) for your platform and a valid ",(0,o.kt)("a",{parentName:"p",href:"https://nodejs.org"},"Node.js")," project setup.")),(0,o.kt)("p",null,"Using the CLI is the easiest way to get started with REST API."),(0,o.kt)("p",null,"You can do this directly on your machine."),(0,o.kt)("h3",{id:"directly-on-computer"},"Directly on computer"),(0,o.kt)("p",null,"After installing and confirming that Libindy is installed, simply run:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},'npx -p @aries-framework/rest afj-rest start \\\n --label "AFJ Rest" \\\n --wallet-id "walletId" \\\n --wallet-key "walletKey" \\\n --endpoint http://localhost:5000 \\\n --admin-port 3000 \\\n --outbound-transport http \\\n --inbound-transport http 5000\n')),(0,o.kt)("p",null,"The REST API provides an OpenAPI schema that can easily be viewed using the SwaggerUI that is provided with the server. The endpoint documentation can be viewed at the ",(0,o.kt)("inlineCode",{parentName:"p"},"/docs")," endpoint (e.g. ",(0,o.kt)("a",{parentName:"p",href:"http://localhost:3000/docs"},"http://localhost:3000/docs"),")."),(0,o.kt)("h3",{id:"configuration"},"Configuration"),(0,o.kt)("p",null,"To find out all available configuration options from the CLI, you can run the CLI command with ",(0,o.kt)("inlineCode",{parentName:"p"},"--help"),". This will print a full list of all available options."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"npx -p @aries-framework/rest afj-rest start --help\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/207a1e16.f970394b.js b/assets/js/207a1e16.f970394b.js deleted file mode 100644 index ec90ca58..00000000 --- a/assets/js/207a1e16.f970394b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[6407],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(n),m=o,f=u["".concat(l,".").concat(m)]||u[m]||d[m]||a;return n?r.createElement(f,i(i({ref:t},c),{},{components:n})):r.createElement(f,i({ref:t},c))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const a={},i="REST API",s={unversionedId:"extensions/rest",id:"version-0.4/extensions/rest",title:"REST API",description:"The Aries Framework JavaScript (AFJ) REST API provides simple RESTful endpoints for AFJ methods, to allow you stand up an agent for communication over the internet instantly. You simply provide your agent configuration. The REST endpoints allow you to interact with your agent over HTTP and WebSockets.",source:"@site/versioned_docs/version-0.4/extensions/rest.md",sourceDirName:"extensions",slug:"/extensions/rest",permalink:"/guides/extensions/rest",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Extensions",permalink:"/guides/extensions/"},next:{title:"React Hooks",permalink:"/guides/extensions/react-hooks"}},l={},p=[{value:"Quick Setup",id:"quick-setup",level:2},{value:"Directly on computer",id:"directly-on-computer",level:3},{value:"Configuration",id:"configuration",level:3}],c={toc:p},u="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"rest-api"},"REST API"),(0,o.kt)("p",null,"The Aries Framework JavaScript (AFJ) REST API provides simple RESTful endpoints for AFJ methods, to allow you stand up an agent for communication over the internet instantly. You simply provide your agent configuration. The REST endpoints allow you to interact with your agent over HTTP and WebSockets."),(0,o.kt)("p",null,"The AFJ REST API is the most convenient way for self-sovereign identity (SSI) developers to interact with SSI agents."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"\u2b50 ",(0,o.kt)("strong",{parentName:"li"},"Endpoints")," to create connections, issue credentials, and request proofs."),(0,o.kt)("li",{parentName:"ul"},"\ud83d\udcbb ",(0,o.kt)("strong",{parentName:"li"},"CLI")," that makes it super easy to start an instance of the REST API."),(0,o.kt)("li",{parentName:"ul"},"\ud83c\udf10 ",(0,o.kt)("strong",{parentName:"li"},"Interoperable")," with all major Aries implementations.")),(0,o.kt)("admonition",{type:"danger"},(0,o.kt)("p",{parentName:"admonition"},"The ",(0,o.kt)("inlineCode",{parentName:"p"},"@aries-framework/rest")," package has not been updated to work with the latest version (",(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"0.4.x")),") of ",(0,o.kt)("inlineCode",{parentName:"p"},"@aries-framework/core"),". The documentation in this section is for version ",(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"0.9.x"))," of the ",(0,o.kt)("inlineCode",{parentName:"p"},"@aries-framework/rest")," package, that works with ",(0,o.kt)("inlineCode",{parentName:"p"},"@aries-framework/core")," version ",(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"0.2.x")),". Extension packages (such as REST API) are versioned separately from the core packages.")),(0,o.kt)("h2",{id:"quick-setup"},"Quick Setup"),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"This guide assumes you have followed the install guides for the framework (See ",(0,o.kt)("a",{parentName:"p",href:"../../getting-started/index.md"},"Getting Started")," section) for your platform and a valid ",(0,o.kt)("a",{parentName:"p",href:"https://nodejs.org"},"Node.js")," project setup.")),(0,o.kt)("p",null,"Using the CLI is the easiest way to get started with REST API."),(0,o.kt)("p",null,"You can do this directly on your machine."),(0,o.kt)("h3",{id:"directly-on-computer"},"Directly on computer"),(0,o.kt)("p",null,"After installing and confirming that Libindy is installed, simply run:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},'npx -p @aries-framework/rest afj-rest start \\\n --label "AFJ Rest" \\\n --wallet-id "walletId" \\\n --wallet-key "walletKey" \\\n --endpoint http://localhost:5000 \\\n --admin-port 3000 \\\n --outbound-transport http \\\n --inbound-transport http 5000\n')),(0,o.kt)("p",null,"The REST API provides an OpenAPI schema that can easily be viewed using the SwaggerUI that is provided with the server. The endpoint documentation can be viewed at the ",(0,o.kt)("inlineCode",{parentName:"p"},"/docs")," endpoint (e.g. ",(0,o.kt)("a",{parentName:"p",href:"http://localhost:3000/docs"},"http://localhost:3000/docs"),")."),(0,o.kt)("h3",{id:"configuration"},"Configuration"),(0,o.kt)("p",null,"To find out all available configuration options from the CLI, you can run the CLI command with ",(0,o.kt)("inlineCode",{parentName:"p"},"--help"),". This will print a full list of all available options."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"npx -p @aries-framework/rest afj-rest start --help\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/224ce49c.4dd8e634.js b/assets/js/224ce49c.4233b0c4.js similarity index 57% rename from assets/js/224ce49c.4dd8e634.js rename to assets/js/224ce49c.4233b0c4.js index e02f81f3..2373aaf6 100644 --- a/assets/js/224ce49c.4dd8e634.js +++ b/assets/js/224ce49c.4233b0c4.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8135],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),d=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=d(e.components);return r.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=d(n),m=a,f=p["".concat(l,".").concat(m)]||p[m]||u[m]||i;return n?r.createElement(f,o(o({ref:t},c),{},{components:n})):r.createElement(f,o({ref:t},c))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:a,o[1]=s;for(var d=2;d{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>d});var r=n(7462),a=(n(7294),n(3905));const i={},o="macOS (Intel)",s={unversionedId:"getting-started/set-up/indy-sdk/macos-intel",id:"version-0.4/getting-started/set-up/indy-sdk/macos-intel",title:"macOS (Intel)",description:"To install Indy SDK on macOS a couple of dependencies are required. This guide covers the installation of the Indy SDK for macs with an Intel processor. For installing the Indy SDK on ARM based macs, please refer to the Indy SDK macOS (ARM) guide.",source:"@site/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/macos-intel.md",sourceDirName:"getting-started/set-up/indy-sdk",slug:"/getting-started/set-up/indy-sdk/macos-intel",permalink:"/guides/getting-started/set-up/indy-sdk/macos-intel",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Windows",permalink:"/guides/getting-started/set-up/indy-sdk/windows"},next:{title:"macOS (ARM)",permalink:"/guides/getting-started/set-up/indy-sdk/macos-arm"}},l={},d=[{value:"Indy SDK",id:"indy-sdk",level:3},{value:"Confirm installation",id:"confirm-installation",level:3}],c={toc:d},p="wrapper";function u(e){let{components:t,...n}=e;return(0,a.kt)(p,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"macos-intel"},"macOS (Intel)"),(0,a.kt)("p",null,"To install ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk"},"Indy SDK")," on macOS a couple of dependencies are required. This guide covers the installation of the Indy SDK for macs with an Intel processor. For installing the Indy SDK on ARM based macs, please refer to the ",(0,a.kt)("a",{parentName:"p",href:"./macos-arm"},"Indy SDK macOS (ARM)")," guide."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"This installation assumes that you have ",(0,a.kt)("a",{parentName:"p",href:"https://brew.sh"},"brew")," installed. If not, please install it via this command:"),(0,a.kt)("pre",{parentName:"admonition"},(0,a.kt)("code",{parentName:"pre"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n'))),(0,a.kt)("h3",{id:"indy-sdk"},"Indy SDK"),(0,a.kt)("p",null,"The Indy SDK has not been distributed properly for macOS. We have made a ",(0,a.kt)("a",{parentName:"p",href:"https://docs.brew.sh/Taps"},"brew tap")," for ",(0,a.kt)("inlineCode",{parentName:"p"},"libindy")," and it will also install all of the required dependencies."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"brew install blu3beri/libindy/libindy\n")),(0,a.kt)("h3",{id:"confirm-installation"},"Confirm installation"),(0,a.kt)("p",null,"To see whether the Indy SDK is correctly installed on your system, run the following command and it should not error."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"npx -p @aries-framework/node@^0.3 is-indy-installed\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8135],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),d=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=d(e.components);return r.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=d(n),m=a,f=p["".concat(l,".").concat(m)]||p[m]||u[m]||i;return n?r.createElement(f,o(o({ref:t},c),{},{components:n})):r.createElement(f,o({ref:t},c))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:a,o[1]=s;for(var d=2;d{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>d});var r=n(7462),a=(n(7294),n(3905));const i={},o="macOS (Intel)",s={unversionedId:"getting-started/set-up/indy-sdk/macos-intel",id:"version-0.4/getting-started/set-up/indy-sdk/macos-intel",title:"macOS (Intel)",description:"To install Indy SDK on macOS a couple of dependencies are required. This guide covers the installation of the Indy SDK for macs with an Intel processor. For installing the Indy SDK on ARM based macs, please refer to the Indy SDK macOS (ARM) guide.",source:"@site/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/macos-intel.md",sourceDirName:"getting-started/set-up/indy-sdk",slug:"/getting-started/set-up/indy-sdk/macos-intel",permalink:"/guides/0.4/getting-started/set-up/indy-sdk/macos-intel",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Windows",permalink:"/guides/0.4/getting-started/set-up/indy-sdk/windows"},next:{title:"macOS (ARM)",permalink:"/guides/0.4/getting-started/set-up/indy-sdk/macos-arm"}},l={},d=[{value:"Indy SDK",id:"indy-sdk",level:3},{value:"Confirm installation",id:"confirm-installation",level:3}],c={toc:d},p="wrapper";function u(e){let{components:t,...n}=e;return(0,a.kt)(p,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"macos-intel"},"macOS (Intel)"),(0,a.kt)("p",null,"To install ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk"},"Indy SDK")," on macOS a couple of dependencies are required. This guide covers the installation of the Indy SDK for macs with an Intel processor. For installing the Indy SDK on ARM based macs, please refer to the ",(0,a.kt)("a",{parentName:"p",href:"./macos-arm"},"Indy SDK macOS (ARM)")," guide."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"This installation assumes that you have ",(0,a.kt)("a",{parentName:"p",href:"https://brew.sh"},"brew")," installed. If not, please install it via this command:"),(0,a.kt)("pre",{parentName:"admonition"},(0,a.kt)("code",{parentName:"pre"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n'))),(0,a.kt)("h3",{id:"indy-sdk"},"Indy SDK"),(0,a.kt)("p",null,"The Indy SDK has not been distributed properly for macOS. We have made a ",(0,a.kt)("a",{parentName:"p",href:"https://docs.brew.sh/Taps"},"brew tap")," for ",(0,a.kt)("inlineCode",{parentName:"p"},"libindy")," and it will also install all of the required dependencies."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"brew install blu3beri/libindy/libindy\n")),(0,a.kt)("h3",{id:"confirm-installation"},"Confirm installation"),(0,a.kt)("p",null,"To see whether the Indy SDK is correctly installed on your system, run the following command and it should not error."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"npx -p @aries-framework/node@^0.3 is-indy-installed\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/232d48ef.845fb5c1.js b/assets/js/232d48ef.845fb5c1.js new file mode 100644 index 00000000..1d1d2f7f --- /dev/null +++ b/assets/js/232d48ef.845fb5c1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[2959],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),l=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},d=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},g=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=l(n),g=r,m=p["".concat(c,".").concat(g)]||p[g]||u[g]||i;return n?a.createElement(m,o(o({ref:t},d),{},{components:n})):a.createElement(m,o({ref:t},d))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=g;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:r,o[1]=s;for(var l=2;l{n.d(t,{Z:()=>f});var a=n(7294),r=n(6010),i=n(3438),o=n(9960),s=n(3919),c=n(5999);const l={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function d(e){let{href:t,children:n}=e;return a.createElement(o.Z,{href:t,className:(0,r.Z)("card padding--lg",l.cardContainer)},n)}function p(e){let{href:t,icon:n,title:i,description:o}=e;return a.createElement(d,{href:t},a.createElement("h2",{className:(0,r.Z)("text--truncate",l.cardTitle),title:i},n," ",i),o&&a.createElement("p",{className:(0,r.Z)("text--truncate",l.cardDescription),title:o},o))}function u(e){let{item:t}=e;const n=(0,i.Wl)(t);return n?a.createElement(p,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,c.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function g(e){let{item:t}=e;const n=(0,s.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,i.xz)(t.docId??void 0);return a.createElement(p,{href:t.href,icon:n,title:t.label,description:r?.description})}function m(e){let{item:t}=e;switch(t.type){case"link":return a.createElement(g,{item:t});case"category":return a.createElement(u,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function h(e){let{className:t}=e;const n=(0,i.jA)();return a.createElement(f,{items:n.items,className:t})}function f(e){const{items:t,className:n}=e;if(!t)return a.createElement(h,e);const o=(0,i.MN)(t);return a.createElement("section",{className:(0,r.Z)("row",n)},o.map(((e,t)=>a.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},a.createElement(m,{item:e})))))}},189:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>g,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var a=n(7462),r=(n(7294),n(3905)),i=n(2991);const o={},s="Updating AFJ",c={unversionedId:"updating/index",id:"version-0.4/updating/index",title:"Updating AFJ",description:"This section will cover everything you need to know about updating Aries Framework JavaScript to a newer version.",source:"@site/versioned_docs/version-0.4/updating/index.md",sourceDirName:"updating",slug:"/updating/",permalink:"/guides/0.4/updating/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Postgres Setup for windows",permalink:"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/windows"},next:{title:"Update Assistant",permalink:"/guides/0.4/updating/update-assistant"}},l={},d=[{value:"Versioning",id:"versioning",level:2},{value:"Types of breaking changes",id:"types-of-breaking-changes",level:2},{value:"Breaking Code Changes",id:"breaking-code-changes",level:3},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:3},{value:"Migration Guides",id:"migration-guides",level:2}],p={toc:d},u="wrapper";function g(e){let{components:t,...n}=e;return(0,r.kt)(u,(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"updating-afj"},"Updating AFJ"),(0,r.kt)("p",null,"This section will cover everything you need to know about updating Aries Framework JavaScript to a newer version."),(0,r.kt)(i.Z,{mdxType:"DocCardList"}),(0,r.kt)("h2",{id:"versioning"},"Versioning"),(0,r.kt)("p",null,"Aries Framework JavaScript follows ",(0,r.kt)("a",{parentName:"p",href:"https://semver.org/"},"semantic versioning"),". This means that major version changes (",(0,r.kt)("strong",{parentName:"p"},"1"),".0.0) are considered breaking changes. When features are added this is a minor version change (0.",(0,r.kt)("strong",{parentName:"p"},"1"),".0). For bug fixes the patch version change is used (0.0.",(0,r.kt)("strong",{parentName:"p"},"1"),")."),(0,r.kt)("p",null,"While AFJ is still in pre-1.0.0 version, the version change types are shifted to the right. This means a major version change is now a minor change (0.",(0,r.kt)("strong",{parentName:"p"},"1"),".0) and a minor change is now a patch change (0.0.",(0,r.kt)("strong",{parentName:"p"},"1"),"). This is done to keep the version below 1.0.0, indicating the framework is still in early development and users can expect more breaking changes that when the version has already reached 1.0.0."),(0,r.kt)("p",null,"This means if the second number in the version (0.",(0,r.kt)("strong",{parentName:"p"},"1"),".0) changes, you need to be careful with updating and always consult this page for update instructions. If only the third number changes (0.0.",(0,r.kt)("strong",{parentName:"p"},"1"),"), you can update without any issues."),(0,r.kt)("h2",{id:"types-of-breaking-changes"},"Types of breaking changes"),(0,r.kt)("p",null,"Updates to AFJ bring new features and improvements to the framework. To better adapt the framework to new features we sometimes make breaking changes that will improve how AFJ works. There's two parts to updates with breaking changes:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Breaking code changes"),(0,r.kt)("li",{parentName:"ol"},"Breaking storage changes")),(0,r.kt)("h3",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,r.kt)("p",null,"Breaking changes to code means changes to how you interact with AFJ. This includes methods being renamed, moved to another module or extended to better integrate with new features. We'll try to cover all breaking changes in migration guides, so you know exactly what is needed to update to a new version and keep the same functionality."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"If you encounter any breaking changes that aren't mentioned in the migration docs, please open an issue in the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-javascript-docs/issues"},"Aries JavaScript Docs")," repository, or directly create a PR describing the change.")),(0,r.kt)("h3",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,r.kt)("p",null,"Breaking changes to storage are a bit more complex to deal with. While breaking changes to code only require you to update your code once, breaking changes to storage needs to be updated for every agent instance. Luckily, we've made the migration as easy as possible for you using the ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.4/updating/update-assistant"},"Update Assistant"),". The Update Assistant will update all storage objects to the storage model that is expected by the newest version. If a version made changes to the storage, this will be explicitly mentioned in the migration guide. See the ",(0,r.kt)("a",{parentName:"p",href:"/guides/updating/update-assistant"},"Update Assistant")," documentation for detailed instructions on how to use the update assistant."),(0,r.kt)("h2",{id:"migration-guides"},"Migration Guides"),(0,r.kt)("p",null,"Currently the following migration guides are available:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/guides/0.4/updating/versions/0.1-to-0.2"},"Migrating from AFJ 0.1.0 to 0.2.x")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/guides/0.4/updating/versions/0.2-to-0.3"},"Migrating from AFJ 0.2.x to 0.3.x")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/guides/0.4/updating/versions/0.3-to-0.4"},"Migrating from AFJ 0.3.x to 0.4.x")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/guides/0.4/updating/update-indy-sdk-to-askar"},"Migrating from an Indy SDK Wallet to Aries Askar"))))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/232d48ef.ca668017.js b/assets/js/232d48ef.ca668017.js deleted file mode 100644 index bbc8ac09..00000000 --- a/assets/js/232d48ef.ca668017.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[2959],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),l=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},d=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},g=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=l(n),g=r,m=p["".concat(c,".").concat(g)]||p[g]||u[g]||i;return n?a.createElement(m,o(o({ref:t},d),{},{components:n})):a.createElement(m,o({ref:t},d))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=g;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:r,o[1]=s;for(var l=2;l{n.d(t,{Z:()=>f});var a=n(7294),r=n(6010),i=n(3438),o=n(9960),s=n(3919),c=n(5999);const l={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function d(e){let{href:t,children:n}=e;return a.createElement(o.Z,{href:t,className:(0,r.Z)("card padding--lg",l.cardContainer)},n)}function p(e){let{href:t,icon:n,title:i,description:o}=e;return a.createElement(d,{href:t},a.createElement("h2",{className:(0,r.Z)("text--truncate",l.cardTitle),title:i},n," ",i),o&&a.createElement("p",{className:(0,r.Z)("text--truncate",l.cardDescription),title:o},o))}function u(e){let{item:t}=e;const n=(0,i.Wl)(t);return n?a.createElement(p,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,c.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function g(e){let{item:t}=e;const n=(0,s.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,i.xz)(t.docId??void 0);return a.createElement(p,{href:t.href,icon:n,title:t.label,description:r?.description})}function m(e){let{item:t}=e;switch(t.type){case"link":return a.createElement(g,{item:t});case"category":return a.createElement(u,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function h(e){let{className:t}=e;const n=(0,i.jA)();return a.createElement(f,{items:n.items,className:t})}function f(e){const{items:t,className:n}=e;if(!t)return a.createElement(h,e);const o=(0,i.MN)(t);return a.createElement("section",{className:(0,r.Z)("row",n)},o.map(((e,t)=>a.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},a.createElement(m,{item:e})))))}},189:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>g,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var a=n(7462),r=(n(7294),n(3905)),i=n(2991);const o={},s="Updating AFJ",c={unversionedId:"updating/index",id:"version-0.4/updating/index",title:"Updating AFJ",description:"This section will cover everything you need to know about updating Aries Framework JavaScript to a newer version.",source:"@site/versioned_docs/version-0.4/updating/index.md",sourceDirName:"updating",slug:"/updating/",permalink:"/guides/updating/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Postgres Setup for windows",permalink:"/guides/tutorials/indy-sdk-postgres-database-nodejs/windows"},next:{title:"Update Assistant",permalink:"/guides/updating/update-assistant"}},l={},d=[{value:"Versioning",id:"versioning",level:2},{value:"Types of breaking changes",id:"types-of-breaking-changes",level:2},{value:"Breaking Code Changes",id:"breaking-code-changes",level:3},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:3},{value:"Migration Guides",id:"migration-guides",level:2}],p={toc:d},u="wrapper";function g(e){let{components:t,...n}=e;return(0,r.kt)(u,(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"updating-afj"},"Updating AFJ"),(0,r.kt)("p",null,"This section will cover everything you need to know about updating Aries Framework JavaScript to a newer version."),(0,r.kt)(i.Z,{mdxType:"DocCardList"}),(0,r.kt)("h2",{id:"versioning"},"Versioning"),(0,r.kt)("p",null,"Aries Framework JavaScript follows ",(0,r.kt)("a",{parentName:"p",href:"https://semver.org/"},"semantic versioning"),". This means that major version changes (",(0,r.kt)("strong",{parentName:"p"},"1"),".0.0) are considered breaking changes. When features are added this is a minor version change (0.",(0,r.kt)("strong",{parentName:"p"},"1"),".0). For bug fixes the patch version change is used (0.0.",(0,r.kt)("strong",{parentName:"p"},"1"),")."),(0,r.kt)("p",null,"While AFJ is still in pre-1.0.0 version, the version change types are shifted to the right. This means a major version change is now a minor change (0.",(0,r.kt)("strong",{parentName:"p"},"1"),".0) and a minor change is now a patch change (0.0.",(0,r.kt)("strong",{parentName:"p"},"1"),"). This is done to keep the version below 1.0.0, indicating the framework is still in early development and users can expect more breaking changes that when the version has already reached 1.0.0."),(0,r.kt)("p",null,"This means if the second number in the version (0.",(0,r.kt)("strong",{parentName:"p"},"1"),".0) changes, you need to be careful with updating and always consult this page for update instructions. If only the third number changes (0.0.",(0,r.kt)("strong",{parentName:"p"},"1"),"), you can update without any issues."),(0,r.kt)("h2",{id:"types-of-breaking-changes"},"Types of breaking changes"),(0,r.kt)("p",null,"Updates to AFJ bring new features and improvements to the framework. To better adapt the framework to new features we sometimes make breaking changes that will improve how AFJ works. There's two parts to updates with breaking changes:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Breaking code changes"),(0,r.kt)("li",{parentName:"ol"},"Breaking storage changes")),(0,r.kt)("h3",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,r.kt)("p",null,"Breaking changes to code means changes to how you interact with AFJ. This includes methods being renamed, moved to another module or extended to better integrate with new features. We'll try to cover all breaking changes in migration guides, so you know exactly what is needed to update to a new version and keep the same functionality."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"If you encounter any breaking changes that aren't mentioned in the migration docs, please open an issue in the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-javascript-docs/issues"},"Aries JavaScript Docs")," repository, or directly create a PR describing the change.")),(0,r.kt)("h3",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,r.kt)("p",null,"Breaking changes to storage are a bit more complex to deal with. While breaking changes to code only require you to update your code once, breaking changes to storage needs to be updated for every agent instance. Luckily, we've made the migration as easy as possible for you using the ",(0,r.kt)("a",{parentName:"p",href:"/guides/updating/update-assistant"},"Update Assistant"),". The Update Assistant will update all storage objects to the storage model that is expected by the newest version. If a version made changes to the storage, this will be explicitly mentioned in the migration guide. See the ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.5/updating/update-assistant"},"Update Assistant")," documentation for detailed instructions on how to use the update assistant."),(0,r.kt)("h2",{id:"migration-guides"},"Migration Guides"),(0,r.kt)("p",null,"Currently the following migration guides are available:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/guides/updating/versions/0.1-to-0.2"},"Migrating from AFJ 0.1.0 to 0.2.x")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/guides/updating/versions/0.2-to-0.3"},"Migrating from AFJ 0.2.x to 0.3.x")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/guides/updating/versions/0.3-to-0.4"},"Migrating from AFJ 0.3.x to 0.4.x")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/guides/updating/update-indy-sdk-to-askar"},"Migrating from an Indy SDK Wallet to Aries Askar"))))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2332f431.54f6ecb1.js b/assets/js/2332f431.54f6ecb1.js deleted file mode 100644 index 919e5075..00000000 --- a/assets/js/2332f431.54f6ecb1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[82],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>g});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),u=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=u(e.components);return a.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=u(n),m=r,g=p["".concat(l,".").concat(m)]||p[m]||d[m]||i;return n?a.createElement(g,o(o({ref:t},c),{},{components:n})):a.createElement(g,o({ref:t},c))}));function g(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:r,o[1]=s;for(var u=2;u{n.d(t,{Z:()=>f});var a=n(7294),r=n(6010),i=n(3438),o=n(9960),s=n(3919),l=n(5999);const u={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function c(e){let{href:t,children:n}=e;return a.createElement(o.Z,{href:t,className:(0,r.Z)("card padding--lg",u.cardContainer)},n)}function p(e){let{href:t,icon:n,title:i,description:o}=e;return a.createElement(c,{href:t},a.createElement("h2",{className:(0,r.Z)("text--truncate",u.cardTitle),title:i},n," ",i),o&&a.createElement("p",{className:(0,r.Z)("text--truncate",u.cardDescription),title:o},o))}function d(e){let{item:t}=e;const n=(0,i.Wl)(t);return n?a.createElement(p,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,l.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function m(e){let{item:t}=e;const n=(0,s.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,i.xz)(t.docId??void 0);return a.createElement(p,{href:t.href,icon:n,title:t.label,description:r?.description})}function g(e){let{item:t}=e;switch(t.type){case"link":return a.createElement(m,{item:t});case"category":return a.createElement(d,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function h(e){let{className:t}=e;const n=(0,i.jA)();return a.createElement(f,{items:n.items,className:t})}function f(e){const{items:t,className:n}=e;if(!t)return a.createElement(h,e);const o=(0,i.MN)(t);return a.createElement("section",{className:(0,r.Z)("row",n)},o.map(((e,t)=>a.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},a.createElement(g,{item:e})))))}},5162:(e,t,n)=>{n.d(t,{Z:()=>o});var a=n(7294),r=n(6010);const i={tabItem:"tabItem_Ymn6"};function o(e){let{children:t,hidden:n,className:o}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(i.tabItem,o),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>N});var a=n(7462),r=n(7294),i=n(6010),o=n(2466),s=n(6550),l=n(1980),u=n(7392),c=n(12);function p(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function d(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,u.l)(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 m(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 a=(0,s.k6)(),i=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,l._X)(i),(0,r.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(a.location.search);t.set(i,e),a.replace({...a.location,search:t.toString()})}),[i,a])]}function h(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,i=d(e),[o,s]=(0,r.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(!m({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:i}))),[l,u]=g({queryString:n,groupId:a}),[p,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,i]=(0,c.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:a}),f=(()=>{const e=l??p;return m({value:e,tabValues:i})?e:null})();(0,r.useLayoutEffect)((()=>{f&&s(f)}),[f]);return{selectedValue:o,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);s(e),u(e),h(e)}),[u,h,i]),tabValues:i}}var f=n(2389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:n,selectedValue:s,selectValue:l,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,o.o5)(),d=e=>{const t=e.currentTarget,n=c.indexOf(t),a=u[n].value;a!==s&&(p(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},u.map((e=>{let{value:t,label:n,attributes:o}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},o,{className:(0,i.Z)("tabs__item",b.tabItem,o?.className,{"tabs__item--active":s===t})}),n??t)})))}function y(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function v(e){const t=h(e);return r.createElement("div",{className:(0,i.Z)("tabs-container",b.tabList)},r.createElement(k,(0,a.Z)({},e,t)),r.createElement(y,(0,a.Z)({},e,t)))}function N(e){const t=(0,f.Z)();return r.createElement(v,(0,a.Z)({key:String(t)},e))}},8278:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>u,default:()=>h,frontMatter:()=>l,metadata:()=>c,toc:()=>d});var a=n(7462),r=(n(7294),n(3905)),i=n(4866),o=n(5162),s=n(2991);const l={},u="Agent Setup",c={unversionedId:"getting-started/set-up/index",id:"getting-started/set-up/index",title:"Agent Setup",description:"This guide assumes you have followed the Prerequisites, and you have a valid",source:"@site/guides/getting-started/set-up/index.md",sourceDirName:"getting-started/set-up",slug:"/getting-started/set-up/",permalink:"/guides/0.5/getting-started/set-up/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Prerequisites",permalink:"/guides/0.5/getting-started/prerequisites"},next:{title:"Aries Askar",permalink:"/guides/0.5/getting-started/set-up/aries-askar"}},p={},d=[{value:"Installing the required dependencies",id:"installing-the-required-dependencies",level:3},{value:"Additional setup",id:"additional-setup",level:3},{value:"Setting up the agent",id:"setting-up-the-agent",level:3},{value:"Adding a wallet and storage implementation",id:"adding-a-wallet-and-storage-implementation",level:3},{value:"Setting up the transports",id:"setting-up-the-transports",level:3},{value:"Initializing the agent",id:"initializing-the-agent",level:3},{value:"Next Steps",id:"next-steps",level:3},{value:"Useful resources",id:"useful-resources",level:3}],m={toc:d},g="wrapper";function h(e){let{components:t,...n}=e;return(0,r.kt)(g,(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"agent-setup"},"Agent Setup"),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This guide assumes you have followed the ",(0,r.kt)("a",{parentName:"p",href:"./prerequisites"},"Prerequisites"),", and you have a valid\n",(0,r.kt)("a",{parentName:"p",href:"https://nodejs.org"},"Node.JS")," or ",(0,r.kt)("a",{parentName:"p",href:"https://reactnative.dev"},"React Native")," project setup.")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Credo is still in ",(0,r.kt)("strong",{parentName:"p"},"active development"),", and as such some APIs are still experimental. ",(0,r.kt)("strong",{parentName:"p"},"When using any experimental features, make sure to use an exact version of Credo")," (",(0,r.kt)("inlineCode",{parentName:"p"},"0.5.0"),") instead of a range (",(0,r.kt)("inlineCode",{parentName:"p"},"^0.5.0"),"), to prevent accidental breaking changes. If you're not leveraging any experimental features, you can use a range (",(0,r.kt)("inlineCode",{parentName:"p"},"^0.5.0"),") to get the latest bugfixes and features."),(0,r.kt)("p",{parentName:"admonition"},"For Credo ",(0,r.kt)("inlineCode",{parentName:"p"},"0.5.x"),", ",(0,r.kt)("strong",{parentName:"p"},"the following features are experimental"),":"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},"Using OpenID4VC from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@credo-ts/openid4vc")," module"),(0,r.kt)("li",{parentName:"ul"},"SD-JWT Verifiable Credentials"),(0,r.kt)("li",{parentName:"ul"},"Using multi-tenancy from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@credo-ts/tenants")," module"),(0,r.kt)("li",{parentName:"ul"},"Using BBS+ Signatures from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@credo-ts/bbs-signatures")," module"),(0,r.kt)("li",{parentName:"ul"},"Using the cheqd module from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@credo-ts/cheqd")," module"))),(0,r.kt)("h3",{id:"installing-the-required-dependencies"},"Installing the required dependencies"),(0,r.kt)("p",null,"First we have to install the minimal amount of dependencies that are required for configuring an Credo agent."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @credo-ts/core@^0.5.0 @credo-ts/node@^0.5.0\n"))),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @credo-ts/core@^0.5.0 @credo-ts/react-native@^0.5.0 react-native-fs react-native-get-random-values\n")))),(0,r.kt)("h3",{id:"additional-setup"},"Additional setup"),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.js",value:"tab1",mdxType:"TabItem"},(0,r.kt)("p",null,"No additional setup is required for Node.JS")),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("p",null,"Since ",(0,r.kt)("a",{parentName:"p",href:"https://reactnative.dev"},"React Native")," does not have an implementation\nfor\n",(0,r.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues"},(0,r.kt)("inlineCode",{parentName:"a"},"crypto.getRandomValues()")),"\nwe have to setup a polyfill for this. We have to do this at the entrypoint of\nthe application. This could is most likely ",(0,r.kt)("inlineCode",{parentName:"p"},"index.(js|ts|jsx|tsx)")," at the root\nof your application."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-diff",metastring:'title="index.tsx" showLineNumbers',title:'"index.tsx"',showLineNumbers:!0},"+ import 'react-native-get-random-values'\n")),(0,r.kt)("p",null,"In addition you need add support for resolving modules with the ",(0,r.kt)("inlineCode",{parentName:"p"},".cjs")," extension, as this is used by some of Credo's dependencies and not automatically supported by React Native."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="metro.config.js" showLineNumbers',title:'"metro.config.js"',showLineNumbers:!0},"module.exports = {\n // ... other Metro config options ...\n resolver: {\n // make sure this includes `cjs` (and other extensions you need)\n sourceExts: ['js', 'json', 'ts', 'tsx', 'cjs'],\n },\n}\n")),(0,r.kt)("p",null,"Finally, if you're using ",(0,r.kt)("a",{parentName:"p",href:"https://expo.dev"},"Expo")," you need to add a custom resolution 'hack' that removes support for the legacy unimodules."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Yarn")),(0,r.kt)("p",null,"For yarn we can replace the ",(0,r.kt)("inlineCode",{parentName:"p"},"@unimodules/react-native-adapter")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"@unimodules/core")," dependencies with an empty directory. Make sure to create the ",(0,r.kt)("inlineCode",{parentName:"p"},"noop")," directory in the root of your project and create a ",(0,r.kt)("inlineCode",{parentName:"p"},".gitkeep")," file in the directory so that the directory is committed to your repository."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="package.json" showLineNumbers',title:'"package.json"',showLineNumbers:!0},'{\n // ... other package.json options ...\n "resolutions": {\n "@unimodules/react-native-adapter": "./noop",\n "@unimodules/core": "./noop"\n }\n}\n')),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"NPM")),(0,r.kt)("p",null,"Not supported at the moment. NPM overrides work different than Yarn resolutions, and thus we can't use the same trick. If you're using NPM, feel free to open a PR with a working solution."))),(0,r.kt)("h3",{id:"setting-up-the-agent"},"Setting up the agent"),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"this section does not assume any knowledge of the agent configuration.\nIn the ",(0,r.kt)("a",{parentName:"p",href:"../tutorials/agent-config"},"Agent Config")," tutorial we will discuss in-depth what every\nfield in the configuration does and when to set it.")),(0,r.kt)("p",null,"In order to use the agent in the application we have to configure and\ninitialize it. This following configuration is quite generic and possibly not\nenough for your specific use cases. Please refer to the\n",(0,r.kt)("a",{parentName:"p",href:"../tutorials"},"tutorials")," for a more use-case-specific agent setup."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up.ts section-1",showLineNumbers:!0,"set-up.ts":!0,"section-1":!0},""))),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-rn.ts section-1",showLineNumbers:!0,"set-up-rn.ts":!0,"section-1":!0},"")))),(0,r.kt)("h3",{id:"adding-a-wallet-and-storage-implementation"},"Adding a wallet and storage implementation"),(0,r.kt)("p",null,"After creating the ",(0,r.kt)("inlineCode",{parentName:"p"},"Agent")," instance, we need to provide the agent with a wallet and storage implementation. Credo provides one implementations out of the box, but you can also implement your own. Currently a Wallet and Storage implementation using Aries Askar is supported out of the box."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"./set-up/aries-askar"},"Aries Askar"))),(0,r.kt)(s.Z,{items:[{type:"link",label:"Aries Askar",href:"./set-up/aries-askar",docId:"getting-started/set-up/aries-askar"}],mdxType:"DocCardList"}),(0,r.kt)("h3",{id:"setting-up-the-transports"},"Setting up the transports"),(0,r.kt)("p",null,"Finally, we have to set an outbound transport that\nwill handle traffic from the agent. It is also possible to set an inbound\ntransport in the same way as the outbound transport."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.js",value:"tab1",mdxType:"TabItem"},(0,r.kt)("p",null,"Sets up an WS outbound and HTTP inbound and outbound transport."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up.ts section-2",showLineNumbers:!0,"set-up.ts":!0,"section-2":!0},""))),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("p",null,"For mobile agents the WebSocket transport is often required. We will go into\nmore depth about the reasons for this in the ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.5/tutorials/mediation"},"mediation")," section."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-rn.ts section-2",showLineNumbers:!0,"set-up-rn.ts":!0,"section-2":!0},"")))),(0,r.kt)("h3",{id:"initializing-the-agent"},"Initializing the agent"),(0,r.kt)("p",null,"Finally, we can initialize the agent and it's ready for use."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.js",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up.ts section-3",showLineNumbers:!0,"set-up.ts":!0,"section-3":!0},""))),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-rn.ts section-3",showLineNumbers:!0,"set-up-rn.ts":!0,"section-3":!0},"")))),(0,r.kt)("h3",{id:"next-steps"},"Next Steps"),(0,r.kt)("p",null,"Now that you have your agent setup, it's time to start building your application. Head over to the tutorials page to get started."),(0,r.kt)(s.Z,{items:[{type:"link",label:"Tutorials",href:"../tutorials/index",docId:"tutorials/index"},{type:"link",label:"Create a Connection",href:"../tutorials/create-a-connection",docId:"tutorials/create-a-connection"}],mdxType:"DocCardList"}),(0,r.kt)("h3",{id:"useful-resources"},"Useful resources"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0004-agents/README.md"},"Hyperledger Aries RFC - 004:\nAgents"))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2332f431.fd538c03.js b/assets/js/2332f431.fd538c03.js new file mode 100644 index 00000000..aaeb7a32 --- /dev/null +++ b/assets/js/2332f431.fd538c03.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[82],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>g});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),u=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=u(e.components);return a.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=u(n),m=r,g=p["".concat(l,".").concat(m)]||p[m]||d[m]||i;return n?a.createElement(g,o(o({ref:t},c),{},{components:n})):a.createElement(g,o({ref:t},c))}));function g(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:r,o[1]=s;for(var u=2;u{n.d(t,{Z:()=>f});var a=n(7294),r=n(6010),i=n(3438),o=n(9960),s=n(3919),l=n(5999);const u={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function c(e){let{href:t,children:n}=e;return a.createElement(o.Z,{href:t,className:(0,r.Z)("card padding--lg",u.cardContainer)},n)}function p(e){let{href:t,icon:n,title:i,description:o}=e;return a.createElement(c,{href:t},a.createElement("h2",{className:(0,r.Z)("text--truncate",u.cardTitle),title:i},n," ",i),o&&a.createElement("p",{className:(0,r.Z)("text--truncate",u.cardDescription),title:o},o))}function d(e){let{item:t}=e;const n=(0,i.Wl)(t);return n?a.createElement(p,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,l.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function m(e){let{item:t}=e;const n=(0,s.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,i.xz)(t.docId??void 0);return a.createElement(p,{href:t.href,icon:n,title:t.label,description:r?.description})}function g(e){let{item:t}=e;switch(t.type){case"link":return a.createElement(m,{item:t});case"category":return a.createElement(d,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function h(e){let{className:t}=e;const n=(0,i.jA)();return a.createElement(f,{items:n.items,className:t})}function f(e){const{items:t,className:n}=e;if(!t)return a.createElement(h,e);const o=(0,i.MN)(t);return a.createElement("section",{className:(0,r.Z)("row",n)},o.map(((e,t)=>a.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},a.createElement(g,{item:e})))))}},5162:(e,t,n)=>{n.d(t,{Z:()=>o});var a=n(7294),r=n(6010);const i={tabItem:"tabItem_Ymn6"};function o(e){let{children:t,hidden:n,className:o}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(i.tabItem,o),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>N});var a=n(7462),r=n(7294),i=n(6010),o=n(2466),s=n(6550),l=n(1980),u=n(7392),c=n(12);function p(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function d(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,u.l)(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 m(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 a=(0,s.k6)(),i=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,l._X)(i),(0,r.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(a.location.search);t.set(i,e),a.replace({...a.location,search:t.toString()})}),[i,a])]}function h(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,i=d(e),[o,s]=(0,r.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(!m({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:i}))),[l,u]=g({queryString:n,groupId:a}),[p,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,i]=(0,c.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:a}),f=(()=>{const e=l??p;return m({value:e,tabValues:i})?e:null})();(0,r.useLayoutEffect)((()=>{f&&s(f)}),[f]);return{selectedValue:o,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);s(e),u(e),h(e)}),[u,h,i]),tabValues:i}}var f=n(2389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:n,selectedValue:s,selectValue:l,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,o.o5)(),d=e=>{const t=e.currentTarget,n=c.indexOf(t),a=u[n].value;a!==s&&(p(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},u.map((e=>{let{value:t,label:n,attributes:o}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},o,{className:(0,i.Z)("tabs__item",b.tabItem,o?.className,{"tabs__item--active":s===t})}),n??t)})))}function y(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function v(e){const t=h(e);return r.createElement("div",{className:(0,i.Z)("tabs-container",b.tabList)},r.createElement(k,(0,a.Z)({},e,t)),r.createElement(y,(0,a.Z)({},e,t)))}function N(e){const t=(0,f.Z)();return r.createElement(v,(0,a.Z)({key:String(t)},e))}},8278:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>u,default:()=>h,frontMatter:()=>l,metadata:()=>c,toc:()=>d});var a=n(7462),r=(n(7294),n(3905)),i=n(4866),o=n(5162),s=n(2991);const l={},u="Agent Setup",c={unversionedId:"getting-started/set-up/index",id:"getting-started/set-up/index",title:"Agent Setup",description:"This guide assumes you have followed the Prerequisites, and you have a valid",source:"@site/guides/getting-started/set-up/index.md",sourceDirName:"getting-started/set-up",slug:"/getting-started/set-up/",permalink:"/guides/getting-started/set-up/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Prerequisites",permalink:"/guides/getting-started/prerequisites"},next:{title:"Aries Askar",permalink:"/guides/getting-started/set-up/aries-askar"}},p={},d=[{value:"Installing the required dependencies",id:"installing-the-required-dependencies",level:3},{value:"Additional setup",id:"additional-setup",level:3},{value:"Setting up the agent",id:"setting-up-the-agent",level:3},{value:"Adding a wallet and storage implementation",id:"adding-a-wallet-and-storage-implementation",level:3},{value:"Setting up the transports",id:"setting-up-the-transports",level:3},{value:"Initializing the agent",id:"initializing-the-agent",level:3},{value:"Next Steps",id:"next-steps",level:3},{value:"Useful resources",id:"useful-resources",level:3}],m={toc:d},g="wrapper";function h(e){let{components:t,...n}=e;return(0,r.kt)(g,(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"agent-setup"},"Agent Setup"),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This guide assumes you have followed the ",(0,r.kt)("a",{parentName:"p",href:"./prerequisites"},"Prerequisites"),", and you have a valid\n",(0,r.kt)("a",{parentName:"p",href:"https://nodejs.org"},"Node.JS")," or ",(0,r.kt)("a",{parentName:"p",href:"https://reactnative.dev"},"React Native")," project setup.")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Credo is still in ",(0,r.kt)("strong",{parentName:"p"},"active development"),", and as such some APIs are still experimental. ",(0,r.kt)("strong",{parentName:"p"},"When using any experimental features, make sure to use an exact version of Credo")," (",(0,r.kt)("inlineCode",{parentName:"p"},"0.5.0"),") instead of a range (",(0,r.kt)("inlineCode",{parentName:"p"},"^0.5.0"),"), to prevent accidental breaking changes. If you're not leveraging any experimental features, you can use a range (",(0,r.kt)("inlineCode",{parentName:"p"},"^0.5.0"),") to get the latest bugfixes and features."),(0,r.kt)("p",{parentName:"admonition"},"For Credo ",(0,r.kt)("inlineCode",{parentName:"p"},"0.5.x"),", ",(0,r.kt)("strong",{parentName:"p"},"the following features are experimental"),":"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},"Using OpenID4VC from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@credo-ts/openid4vc")," module"),(0,r.kt)("li",{parentName:"ul"},"SD-JWT Verifiable Credentials"),(0,r.kt)("li",{parentName:"ul"},"Using multi-tenancy from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@credo-ts/tenants")," module"),(0,r.kt)("li",{parentName:"ul"},"Using BBS+ Signatures from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@credo-ts/bbs-signatures")," module"),(0,r.kt)("li",{parentName:"ul"},"Using the cheqd module from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@credo-ts/cheqd")," module"))),(0,r.kt)("h3",{id:"installing-the-required-dependencies"},"Installing the required dependencies"),(0,r.kt)("p",null,"First we have to install the minimal amount of dependencies that are required for configuring an Credo agent."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @credo-ts/core@^0.5.0 @credo-ts/node@^0.5.0\n"))),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @credo-ts/core@^0.5.0 @credo-ts/react-native@^0.5.0 react-native-fs react-native-get-random-values\n")))),(0,r.kt)("h3",{id:"additional-setup"},"Additional setup"),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.js",value:"tab1",mdxType:"TabItem"},(0,r.kt)("p",null,"No additional setup is required for Node.JS")),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("p",null,"Since ",(0,r.kt)("a",{parentName:"p",href:"https://reactnative.dev"},"React Native")," does not have an implementation\nfor\n",(0,r.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues"},(0,r.kt)("inlineCode",{parentName:"a"},"crypto.getRandomValues()")),"\nwe have to setup a polyfill for this. We have to do this at the entrypoint of\nthe application. This could is most likely ",(0,r.kt)("inlineCode",{parentName:"p"},"index.(js|ts|jsx|tsx)")," at the root\nof your application."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-diff",metastring:'title="index.tsx" showLineNumbers',title:'"index.tsx"',showLineNumbers:!0},"+ import 'react-native-get-random-values'\n")),(0,r.kt)("p",null,"In addition you need add support for resolving modules with the ",(0,r.kt)("inlineCode",{parentName:"p"},".cjs")," extension, as this is used by some of Credo's dependencies and not automatically supported by React Native."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="metro.config.js" showLineNumbers',title:'"metro.config.js"',showLineNumbers:!0},"module.exports = {\n // ... other Metro config options ...\n resolver: {\n // make sure this includes `cjs` (and other extensions you need)\n sourceExts: ['js', 'json', 'ts', 'tsx', 'cjs'],\n },\n}\n")),(0,r.kt)("p",null,"Finally, if you're using ",(0,r.kt)("a",{parentName:"p",href:"https://expo.dev"},"Expo")," you need to add a custom resolution 'hack' that removes support for the legacy unimodules."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Yarn")),(0,r.kt)("p",null,"For yarn we can replace the ",(0,r.kt)("inlineCode",{parentName:"p"},"@unimodules/react-native-adapter")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"@unimodules/core")," dependencies with an empty directory. Make sure to create the ",(0,r.kt)("inlineCode",{parentName:"p"},"noop")," directory in the root of your project and create a ",(0,r.kt)("inlineCode",{parentName:"p"},".gitkeep")," file in the directory so that the directory is committed to your repository."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="package.json" showLineNumbers',title:'"package.json"',showLineNumbers:!0},'{\n // ... other package.json options ...\n "resolutions": {\n "@unimodules/react-native-adapter": "./noop",\n "@unimodules/core": "./noop"\n }\n}\n')),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"NPM")),(0,r.kt)("p",null,"Not supported at the moment. NPM overrides work different than Yarn resolutions, and thus we can't use the same trick. If you're using NPM, feel free to open a PR with a working solution."))),(0,r.kt)("h3",{id:"setting-up-the-agent"},"Setting up the agent"),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"this section does not assume any knowledge of the agent configuration.\nIn the ",(0,r.kt)("a",{parentName:"p",href:"../tutorials/agent-config"},"Agent Config")," tutorial we will discuss in-depth what every\nfield in the configuration does and when to set it.")),(0,r.kt)("p",null,"In order to use the agent in the application we have to configure and\ninitialize it. This following configuration is quite generic and possibly not\nenough for your specific use cases. Please refer to the\n",(0,r.kt)("a",{parentName:"p",href:"../tutorials"},"tutorials")," for a more use-case-specific agent setup."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up.ts section-1",showLineNumbers:!0,"set-up.ts":!0,"section-1":!0},""))),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-rn.ts section-1",showLineNumbers:!0,"set-up-rn.ts":!0,"section-1":!0},"")))),(0,r.kt)("h3",{id:"adding-a-wallet-and-storage-implementation"},"Adding a wallet and storage implementation"),(0,r.kt)("p",null,"After creating the ",(0,r.kt)("inlineCode",{parentName:"p"},"Agent")," instance, we need to provide the agent with a wallet and storage implementation. Credo provides one implementations out of the box, but you can also implement your own. Currently a Wallet and Storage implementation using Aries Askar is supported out of the box."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"./set-up/aries-askar"},"Aries Askar"))),(0,r.kt)(s.Z,{items:[{type:"link",label:"Aries Askar",href:"./set-up/aries-askar",docId:"getting-started/set-up/aries-askar"}],mdxType:"DocCardList"}),(0,r.kt)("h3",{id:"setting-up-the-transports"},"Setting up the transports"),(0,r.kt)("p",null,"Finally, we have to set an outbound transport that\nwill handle traffic from the agent. It is also possible to set an inbound\ntransport in the same way as the outbound transport."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.js",value:"tab1",mdxType:"TabItem"},(0,r.kt)("p",null,"Sets up an WS outbound and HTTP inbound and outbound transport."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up.ts section-2",showLineNumbers:!0,"set-up.ts":!0,"section-2":!0},""))),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("p",null,"For mobile agents the WebSocket transport is often required. We will go into\nmore depth about the reasons for this in the ",(0,r.kt)("a",{parentName:"p",href:"/guides/tutorials/mediation"},"mediation")," section."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-rn.ts section-2",showLineNumbers:!0,"set-up-rn.ts":!0,"section-2":!0},"")))),(0,r.kt)("h3",{id:"initializing-the-agent"},"Initializing the agent"),(0,r.kt)("p",null,"Finally, we can initialize the agent and it's ready for use."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.js",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up.ts section-3",showLineNumbers:!0,"set-up.ts":!0,"section-3":!0},""))),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-rn.ts section-3",showLineNumbers:!0,"set-up-rn.ts":!0,"section-3":!0},"")))),(0,r.kt)("h3",{id:"next-steps"},"Next Steps"),(0,r.kt)("p",null,"Now that you have your agent setup, it's time to start building your application. Head over to the tutorials page to get started."),(0,r.kt)(s.Z,{items:[{type:"link",label:"Tutorials",href:"../tutorials/index",docId:"tutorials/index"},{type:"link",label:"Create a Connection",href:"../tutorials/create-a-connection",docId:"tutorials/create-a-connection"}],mdxType:"DocCardList"}),(0,r.kt)("h3",{id:"useful-resources"},"Useful resources"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0004-agents/README.md"},"Hyperledger Aries RFC - 004:\nAgents"))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/29b62a39.8a0485b3.js b/assets/js/29b62a39.8a0485b3.js new file mode 100644 index 00000000..c27acc73 --- /dev/null +++ b/assets/js/29b62a39.8a0485b3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[1498],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(r),f=o,m=d["".concat(l,".").concat(f)]||d[f]||p[f]||a;return r?n.createElement(m,i(i({ref:t},u),{},{components:r})):n.createElement(m,i({ref:t},u))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=f;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:o,i[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const a={},i="Intro",s={unversionedId:"index",id:"index",title:"Intro",description:"Welcome, to the Credo community!",source:"@site/guides/index.md",sourceDirName:".",slug:"/",permalink:"/guides/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",next:{title:"Getting started",permalink:"/guides/getting-started/"}},l={},c=[],u={toc:c},d="wrapper";function p(e){let{components:t,...r}=e;return(0,o.kt)(d,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"intro"},"Intro"),(0,o.kt)("p",null,"Welcome, to the Credo community!"),(0,o.kt)("p",null,"There's no way around it. Working with self-sovereign identity can be difficult. Luckily this documentation's main goal is to make it easy for you, whether you have SSI experience or not. This documentation will either help you create a JavaScript based SSI solution yourself, or help you find the right resources in the community to assist you!"),(0,o.kt)("p",null,"So what is ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts"},"Credo"),"?"),(0,o.kt)("p",null,'Credo originated as a project named "Aries Framework JavaScript" under the Hyperledger Aries umbrella. It has since been migrated from the Hyperledger Foundation to the OpenWallet Foundation and rebranded as Credo. As a result of its origin and strong ties to the Hyperledger community, a significant portion of its codebase adheres to Hyperledger Aries standards (RFCs), and the code and documentation make references to other Hyperledger-related projects.'),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"Hyperledger Aries provides a shared, reusable, interoperable tool kit designed for initiatives and solutions focused on creating, transmitting and storing verifiable digital credentials."),(0,o.kt)("p",{parentName:"blockquote"},"\u2014 Hyperledger Foundation")),(0,o.kt)("p",null,"There are ",(0,o.kt)("a",{parentName:"p",href:"https://wiki.hyperledger.org/display/ARIES"},"several")," other Aries-based frameworks that help you build solutions using verifiable credentials. This one is written in TypeScript and is specifically well suited for Multi-Platform development as it supports Node.js and React Native. We, the community, like to view it as the most accessible framework mostly because it is written in TypeScript, and our maintainers and contributors work to keep developer user experience a top priority."),(0,o.kt)("p",null,"These docs are not just for the core framework, but also all that surround it. So you'll find ",(0,o.kt)("a",{parentName:"p",href:"/guides/concepts/"},"general explanations about the concepts used"),", ",(0,o.kt)("a",{parentName:"p",href:"/guides/tutorials/"},"specific tutorials for common use cases")," and ",(0,o.kt)("a",{parentName:"p",href:"/guides/ecosystem/"},"relevant projects and related repositories"),". Most of all you'll find solid documentation with lots of code examples and an enthusiastic community that wants to build great stuff together."),(0,o.kt)("p",null,"Are you ready to get started?"))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/29b62a39.f8bd6331.js b/assets/js/29b62a39.f8bd6331.js deleted file mode 100644 index 3a460685..00000000 --- a/assets/js/29b62a39.f8bd6331.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[1498],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(r),f=o,m=d["".concat(l,".").concat(f)]||d[f]||p[f]||a;return r?n.createElement(m,i(i({ref:t},u),{},{components:r})):n.createElement(m,i({ref:t},u))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=f;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:o,i[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const a={},i="Intro",s={unversionedId:"index",id:"index",title:"Intro",description:"Welcome, to the Credo community!",source:"@site/guides/index.md",sourceDirName:".",slug:"/",permalink:"/guides/0.5/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",next:{title:"Getting started",permalink:"/guides/0.5/getting-started/"}},l={},c=[],u={toc:c},d="wrapper";function p(e){let{components:t,...r}=e;return(0,o.kt)(d,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"intro"},"Intro"),(0,o.kt)("p",null,"Welcome, to the Credo community!"),(0,o.kt)("p",null,"There's no way around it. Working with self-sovereign identity can be difficult. Luckily this documentation's main goal is to make it easy for you, whether you have SSI experience or not. This documentation will either help you create a JavaScript based SSI solution yourself, or help you find the right resources in the community to assist you!"),(0,o.kt)("p",null,"So what is ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts"},"Credo"),"?"),(0,o.kt)("p",null,'Credo originated as a project named "Aries Framework JavaScript" under the Hyperledger Aries umbrella. It has since been migrated from the Hyperledger Foundation to the OpenWallet Foundation and rebranded as Credo. As a result of its origin and strong ties to the Hyperledger community, a significant portion of its codebase adheres to Hyperledger Aries standards (RFCs), and the code and documentation make references to other Hyperledger-related projects.'),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"Hyperledger Aries provides a shared, reusable, interoperable tool kit designed for initiatives and solutions focused on creating, transmitting and storing verifiable digital credentials."),(0,o.kt)("p",{parentName:"blockquote"},"\u2014 Hyperledger Foundation")),(0,o.kt)("p",null,"There are ",(0,o.kt)("a",{parentName:"p",href:"https://wiki.hyperledger.org/display/ARIES"},"several")," other Aries-based frameworks that help you build solutions using verifiable credentials. This one is written in TypeScript and is specifically well suited for Multi-Platform development as it supports Node.js and React Native. We, the community, like to view it as the most accessible framework mostly because it is written in TypeScript, and our maintainers and contributors work to keep developer user experience a top priority."),(0,o.kt)("p",null,"These docs are not just for the core framework, but also all that surround it. So you'll find ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.5/concepts/"},"general explanations about the concepts used"),", ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.5/tutorials/"},"specific tutorials for common use cases")," and ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.5/ecosystem/"},"relevant projects and related repositories"),". Most of all you'll find solid documentation with lots of code examples and an enthusiastic community that wants to build great stuff together."),(0,o.kt)("p",null,"Are you ready to get started?"))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2bf743db.f063a5e7.js b/assets/js/2bf743db.f9fffbe3.js similarity index 61% rename from assets/js/2bf743db.f063a5e7.js rename to assets/js/2bf743db.f9fffbe3.js index 71782400..69217f8a 100644 --- a/assets/js/2bf743db.f063a5e7.js +++ b/assets/js/2bf743db.f9fffbe3.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[5880],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>y});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),d=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=d(e.components);return r.createElement(l.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),c=d(n),m=o,y=c["".concat(l,".").concat(m)]||c[m]||u[m]||i;return n?r.createElement(y,a(a({ref:t},p),{},{components:n})):r.createElement(y,a({ref:t},p))}));function y(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[c]="string"==typeof e?e:o,a[1]=s;for(var d=2;d{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>d});var r=n(7462),o=(n(7294),n(3905));const i={},a="Windows",s={unversionedId:"getting-started/set-up/indy-sdk/windows",id:"version-0.4/getting-started/set-up/indy-sdk/windows",title:"Windows",description:"To install Indy SDK on Windows, you can download the pre-built binary from the Sovrin repository.",source:"@site/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/windows.md",sourceDirName:"getting-started/set-up/indy-sdk",slug:"/getting-started/set-up/indy-sdk/windows",permalink:"/guides/getting-started/set-up/indy-sdk/windows",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Linux",permalink:"/guides/getting-started/set-up/indy-sdk/linux"},next:{title:"macOS (Intel)",permalink:"/guides/getting-started/set-up/indy-sdk/macos-intel"}},l={},d=[{value:"Confirm installation",id:"confirm-installation",level:3}],p={toc:d},c="wrapper";function u(e){let{components:t,...n}=e;return(0,o.kt)(c,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"windows"},"Windows"),(0,o.kt)("p",null,"To install ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk"},"Indy SDK")," on Windows, you can download the pre-built binary from the ",(0,o.kt)("a",{parentName:"p",href:"https://repo.sovrin.org/windows/libindy/master/1.16.0-1636/libindy_1.16.0.zip"},"Sovrin repository"),"."),(0,o.kt)("p",null,"Once downloaded, extract the zip into a ",(0,o.kt)("strong",{parentName:"p"},"permanent location"),"."),(0,o.kt)("p",null,"Next, go to ",(0,o.kt)("inlineCode",{parentName:"p"},"environment variables")," on your system and click on ",(0,o.kt)("inlineCode",{parentName:"p"},"new")," at\n",(0,o.kt)("inlineCode",{parentName:"p"},"System Variables"),". The name MUST be ",(0,o.kt)("inlineCode",{parentName:"p"},"LD_LIBRARY_PATH")," and the value MUST be\nthe path to the extracted libraries."),(0,o.kt)("h3",{id:"confirm-installation"},"Confirm installation"),(0,o.kt)("p",null,"To see whether the Indy SDK is correctly installed on your system, run the following command and it should not error."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-console"},"npx -p @aries-framework/node@^0.3 is-indy-installed\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[5880],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>y});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),d=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=d(e.components);return r.createElement(l.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),c=d(n),m=o,y=c["".concat(l,".").concat(m)]||c[m]||u[m]||i;return n?r.createElement(y,a(a({ref:t},p),{},{components:n})):r.createElement(y,a({ref:t},p))}));function y(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[c]="string"==typeof e?e:o,a[1]=s;for(var d=2;d{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>d});var r=n(7462),o=(n(7294),n(3905));const i={},a="Windows",s={unversionedId:"getting-started/set-up/indy-sdk/windows",id:"version-0.4/getting-started/set-up/indy-sdk/windows",title:"Windows",description:"To install Indy SDK on Windows, you can download the pre-built binary from the Sovrin repository.",source:"@site/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/windows.md",sourceDirName:"getting-started/set-up/indy-sdk",slug:"/getting-started/set-up/indy-sdk/windows",permalink:"/guides/0.4/getting-started/set-up/indy-sdk/windows",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Linux",permalink:"/guides/0.4/getting-started/set-up/indy-sdk/linux"},next:{title:"macOS (Intel)",permalink:"/guides/0.4/getting-started/set-up/indy-sdk/macos-intel"}},l={},d=[{value:"Confirm installation",id:"confirm-installation",level:3}],p={toc:d},c="wrapper";function u(e){let{components:t,...n}=e;return(0,o.kt)(c,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"windows"},"Windows"),(0,o.kt)("p",null,"To install ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk"},"Indy SDK")," on Windows, you can download the pre-built binary from the ",(0,o.kt)("a",{parentName:"p",href:"https://repo.sovrin.org/windows/libindy/master/1.16.0-1636/libindy_1.16.0.zip"},"Sovrin repository"),"."),(0,o.kt)("p",null,"Once downloaded, extract the zip into a ",(0,o.kt)("strong",{parentName:"p"},"permanent location"),"."),(0,o.kt)("p",null,"Next, go to ",(0,o.kt)("inlineCode",{parentName:"p"},"environment variables")," on your system and click on ",(0,o.kt)("inlineCode",{parentName:"p"},"new")," at\n",(0,o.kt)("inlineCode",{parentName:"p"},"System Variables"),". The name MUST be ",(0,o.kt)("inlineCode",{parentName:"p"},"LD_LIBRARY_PATH")," and the value MUST be\nthe path to the extracted libraries."),(0,o.kt)("h3",{id:"confirm-installation"},"Confirm installation"),(0,o.kt)("p",null,"To see whether the Indy SDK is correctly installed on your system, run the following command and it should not error."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-console"},"npx -p @aries-framework/node@^0.3 is-indy-installed\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2e77271a.17296e73.js b/assets/js/2e77271a.17296e73.js new file mode 100644 index 00000000..e1dfcf8f --- /dev/null +++ b/assets/js/2e77271a.17296e73.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7024],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>g});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),d=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=d(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),c=d(n),m=o,g=c["".concat(l,".").concat(m)]||c[m]||p[m]||r;return n?a.createElement(g,s(s({ref:t},u),{},{components:n})):a.createElement(g,s({ref:t},u))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,s=new Array(r);s[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[c]="string"==typeof e?e:o,s[1]=i;for(var d=2;d{n.d(t,{Z:()=>s});var a=n(7294),o=n(6010);const r={tabItem:"tabItem_Ymn6"};function s(e){let{children:t,hidden:n,className:s}=e;return a.createElement("div",{role:"tabpanel",className:(0,o.Z)(r.tabItem,s),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),o=n(7294),r=n(6010),s=n(2466),i=n(6550),l=n(1980),d=n(7392),u=n(12);function c(e){return function(e){return o.Children.map(e,(e=>{if((0,o.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:o}}=e;return{value:t,label:n,attributes:a,default:o}}))}function p(e){const{values:t,children:n}=e;return(0,o.useMemo)((()=>{const e=t??c(n);return function(e){const t=(0,d.l)(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 m(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 a=(0,i.k6)(),r=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,l._X)(r),(0,o.useCallback)((e=>{if(!r)return;const t=new URLSearchParams(a.location.search);t.set(r,e),a.replace({...a.location,search:t.toString()})}),[r,a])]}function h(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,r=p(e),[s,i]=(0,o.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(!m({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:r}))),[l,d]=g({queryString:n,groupId:a}),[c,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,r]=(0,u.Nk)(n);return[a,(0,o.useCallback)((e=>{n&&r.set(e)}),[n,r])]}({groupId:a}),f=(()=>{const e=l??c;return m({value:e,tabValues:r})?e:null})();(0,o.useLayoutEffect)((()=>{f&&i(f)}),[f]);return{selectedValue:s,selectValue:(0,o.useCallback)((e=>{if(!m({value:e,tabValues:r}))throw new Error(`Can't select invalid tab value=${e}`);i(e),d(e),h(e)}),[d,h,r]),tabValues:r}}var f=n(2389);const k={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){let{className:t,block:n,selectedValue:i,selectValue:l,tabValues:d}=e;const u=[],{blockElementScrollPositionUntilNextRender:c}=(0,s.o5)(),p=e=>{const t=e.currentTarget,n=u.indexOf(t),a=d[n].value;a!==i&&(c(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=u.indexOf(e.currentTarget)+1;t=u[n]??u[0];break}case"ArrowLeft":{const n=u.indexOf(e.currentTarget)-1;t=u[n]??u[u.length-1];break}}t?.focus()};return o.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.Z)("tabs",{"tabs--block":n},t)},d.map((e=>{let{value:t,label:n,attributes:s}=e;return o.createElement("li",(0,a.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>u.push(e),onKeyDown:m,onClick:p},s,{className:(0,r.Z)("tabs__item",k.tabItem,s?.className,{"tabs__item--active":i===t})}),n??t)})))}function b(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,o.cloneElement)(e,{className:"margin-top--md"}):null}return o.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,o.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function v(e){const t=h(e);return o.createElement("div",{className:(0,r.Z)("tabs-container",k.tabList)},o.createElement(y,(0,a.Z)({},e,t)),o.createElement(b,(0,a.Z)({},e,t)))}function w(e){const t=(0,f.Z)();return o.createElement(v,(0,a.Z)({key:String(t)},e))}},7079:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>g,frontMatter:()=>i,metadata:()=>d,toc:()=>c});var a=n(7462),o=(n(7294),n(3905)),r=n(4866),s=n(5162);const i={},l="Migrating from AFJ 0.2.x to 0.3.x",d={unversionedId:"updating/versions/0.2-to-0.3",id:"version-0.4/updating/versions/0.2-to-0.3",title:"Migrating from AFJ 0.2.x to 0.3.x",description:"This document describes everything you need to know for updating AFJ 0.2.x to 0.3.x. If you're not aware of how updating in AFJ works make sure to first read the guide on Updating AFJ.",source:"@site/versioned_docs/version-0.4/updating/versions/0.2-to-0.3.md",sourceDirName:"updating/versions",slug:"/updating/versions/0.2-to-0.3",permalink:"/guides/0.4/updating/versions/0.2-to-0.3",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Migrating from AFJ 0.1.0 to 0.2.x",permalink:"/guides/0.4/updating/versions/0.1-to-0.2"},next:{title:"Migrating from AFJ 0.3.x to 0.4.x",permalink:"/guides/0.4/updating/versions/0.3-to-0.4"}},u={},c=[{value:"React Native",id:"react-native",level:4},{value:"Node",id:"node",level:4},{value:"Breaking Code Changes",id:"breaking-code-changes",level:2},{value:"Agent creation",id:"agent-creation",level:3},{value:"0.2.x",id:"02x",level:5},{value:"0.3.x",id:"03x",level:5},{value:"did:key usage in protocols",id:"didkey-usage-in-protocols",level:3},{value:"Modules extracted from the core",id:"modules-extracted-from-the-core",level:3},{value:"0.2.x",id:"02x-1",level:5},{value:"0.3.x",id:"03x-1",level:5},{value:"Discover Features Module",id:"discover-features-module",level:3},{value:"0.2.x",id:"02x-2",level:5},{value:"0.3.x",id:"03x-2",level:5},{value:"0.2.x",id:"02x-3",level:5},{value:"0.3.x",id:"03x-3",level:5},{value:"Ledger Module",id:"ledger-module",level:3},{value:"Proofs Module",id:"proofs-module",level:3},{value:"Module API Updates",id:"module-api-updates",level:4},{value:"0.2.x",id:"02x-4",level:5},{value:"0.3.x",id:"03x-4",level:5},{value:"Messages Extracted from Proof Exchange Record",id:"messages-extracted-from-proof-exchange-record",level:4},{value:"0.2.x",id:"02x-5",level:5},{value:"0.3.x",id:"03x-5",level:5},{value:"Out Of Band Proofs and Credentials",id:"out-of-band-proofs-and-credentials",level:3},{value:"0.2.x",id:"02x-6",level:4},{value:"0.3.x",id:"03x-6",level:4},{value:"Updating Custom Modules to the new Plugin API",id:"updating-custom-modules-to-the-new-plugin-api",level:3},{value:"Renaming handler classes",id:"renaming-handler-classes",level:4},{value:"0.2.x",id:"02x-7",level:5},{value:"0.3.x",id:"03x-7",level:5},{value:"Using AgentContext",id:"using-agentcontext",level:4},{value:"0.2.x",id:"02x-8",level:4},{value:"0.3.x",id:"03x-8",level:4},{value:"Using OutboundMessageContext",id:"using-outboundmessagecontext",level:4},{value:"0.2.x",id:"02x-9",level:4},{value:"0.3.x",id:"03x-9",level:4},{value:"Updating module structure to register in new Plugin API",id:"updating-module-structure-to-register-in-new-plugin-api",level:4},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:2},{value:"Migrate Proof Record Properties",id:"migrate-proof-record-properties",level:3},{value:"0.2.x",id:"02x-10",level:4},{value:"0.3.x",id:"03x-10",level:4},{value:"Migrate Connection Record properties",id:"migrate-connection-record-properties",level:3},{value:"Migrate Did Record properties",id:"migrate-did-record-properties",level:3},{value:"0.2.x",id:"02x-11",level:4},{value:"0.3.x",id:"03x-11",level:4}],p={toc:c},m="wrapper";function g(e){let{components:t,...n}=e;return(0,o.kt)(m,(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"migrating-from-afj-02x-to-03x"},"Migrating from AFJ 0.2.x to 0.3.x"),(0,o.kt)("p",null,"This document describes everything you need to know for updating AFJ 0.2.x to 0.3.x. If you're not aware of how updating in AFJ works make sure to first read the guide on ",(0,o.kt)("a",{parentName:"p",href:"/guides/updating/"},"Updating AFJ"),"."),(0,o.kt)("p",null,"First of all, update you dependencies to the 0.3.x versions. This will also update the needed peer depedencnies. ",(0,o.kt)("strong",{parentName:"p"},"Extension packages are not updated with this command"),". You need to update these manually, and make sure they're up to date with the latest version of AFJ."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"React Native",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/react-native@^0.3.0 @aries-framework/core@^0.3.0 indy-sdk-react-native@^0.3.0\n\n# or NPM\nnpn install @aries-framework/react-native@^0.3.0 @aries-framework/core@^0.3.0 indy-sdk-react-native@^0.3.0\n"))),(0,o.kt)(s.Z,{label:"Node",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/node@^0.3.0 @aries-framework/core@^0.3.0\n\n# or NPM\nnpm install @aries-framework/node@^0.3.0 @aries-framework/core@^0.3.0\n")))),(0,o.kt)("h2",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,o.kt)("p",null,"This section will list all breaking changes made to the public API of AFJ between version 0.2.x and 0.3.0."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here (e.g. see ",(0,o.kt)("a",{parentName:"p",href:"#Updating-Custom-Modules-to-the-new-Plugin-API"},"Updating Custom Modules to the Plugin API"),"), but it is possible some breaking changes are not documented here (feel free to open PRs).")),(0,o.kt)("h3",{id:"agent-creation"},"Agent creation"),(0,o.kt)("p",null,"The agent constructor has been updated to a single ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentOptions")," object that contains the config and dependencies properties."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const agent = new Agent(agentConfig, agentDependencies)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const agent = new Agent({ config: agentConfig, dependencies: agentDependencies })\n")))),(0,o.kt)("p",null,"This object contains:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"config: Agent's initial configuration"),(0,o.kt)("li",{parentName:"ul"},"dependencies: platform-specific Agent dependencies"),(0,o.kt)("li",{parentName:"ul"},"modules: optional field for internal module configuration and custom module registration")),(0,o.kt)("p",null,"For easy migration, you can simply construct ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentOptions")," by putting current InitConfig into ",(0,o.kt)("inlineCode",{parentName:"p"},"config")," key and agentDependencies into ",(0,o.kt)("inlineCode",{parentName:"p"},"dependencies")," key."),(0,o.kt)("p",null,"Note that, if you are defining ",(0,o.kt)("inlineCode",{parentName:"p"},"indyLedgers")," configuration, you should set the indyNamespace for every ledger, as explained in ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.4/tutorials/agent-config/#indyledgers"},"Agent Config tutorial"),"."),(0,o.kt)("h3",{id:"didkey-usage-in-protocols"},"did:key usage in protocols"),(0,o.kt)("p",null,"In accordance with ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/tree/b3a3942ef052039e73cd23d847f42947f8287da2/features/0360-use-did-key"},"Aries RFC 0360"),", since 0.2.5 there is a configuration parameter called ",(0,o.kt)("inlineCode",{parentName:"p"},"useDidKeyInProtocols")," which, when enabled, will encode keys in did:key instead of previous base58 format, unless the other party has started a protocol and is using base58."),(0,o.kt)("p",null,"This parameter was previously disabled by default and now it is enabled. If your agent only interacts with modern agents (e.g. AFJ 0.2.5 and newer) this will not represent any issue. Otherwise it is safer to explicitly set it to ",(0,o.kt)("inlineCode",{parentName:"p"},"false"),". However, keep in mind that we expect this setting to be deprecated in the future, so we encourage you to update all your agents to use did:key."),(0,o.kt)("h3",{id:"modules-extracted-from-the-core"},"Modules extracted from the core"),(0,o.kt)("p",null,"In this release two modules were extracted from the core and published as separate, optional packages:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"actionMenu has been moved to @aries-framework/action-menu"),(0,o.kt)("li",{parentName:"ul"},"questionAnswer has been moved to @aries-framework/question-answer")),(0,o.kt)("p",null,"If you want to use them, you can integrate in an Agent instance by injecting them in constructor, as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { ActionMenuModule } from '@aries-framework/action-menu'\nimport { QuestionAnswerModule } from '@aries-framework/question-answer'\n\nconst agent = new Agent({\n config: {\n /* config */\n },\n dependencies: agentDependencies,\n modules: {\n actionMenu: new ActionMenuModule(),\n questionAnswer: new QuestionAnswerModule(),\n /* other custom modules */\n },\n})\n")),(0,o.kt)("p",null,"As they are now considered custom modules, their API can be accessed in ",(0,o.kt)("inlineCode",{parentName:"p"},"modules")," namespace, so you should add it to every call to them."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.questionAnswer.sendQuestion(connectionId, {\n question: 'Do you want to play?',\n validResponses: [{ text: 'Yes' }, { text: 'No' }],\n})\n\nawait agent.questionAnswer.sendAnswer(questionAnswerRecordId, 'Yes')\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.modules.questionAnswer.sendQuestion(connectionId, {\n question: 'Do you want to play?',\n validResponses: [{ text: 'Yes' }, { text: 'No' }],\n})\n\nawait agent.modules.questionAnswer.sendAnswer(questionAnswerRecordId, 'Yes')\n")))),(0,o.kt)("h3",{id:"discover-features-module"},"Discover Features Module"),(0,o.kt)("p",null,"This module now supports both Discover Features V1 and V2, and as it happened to other modules, ",(0,o.kt)("inlineCode",{parentName:"p"},"queryFeatures")," method parameters have been unified to a single object and requires to specify the version of Discover Features protocol to be used. Note that ",(0,o.kt)("inlineCode",{parentName:"p"},"query")," property has been replaced by the more general ",(0,o.kt)("inlineCode",{parentName:"p"},"queries")," which accepts multiple features to be search for. To convert a query to this new format you simply need to create a single-object array whose unique object whose ",(0,o.kt)("inlineCode",{parentName:"p"},"featureType")," field is 'protocol' and ",(0,o.kt)("inlineCode",{parentName:"p"},"match")," field is the query itself."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.discovery.queryFeatures(connectionId, {\n query: 'https://didcomm.org/messagepickup/2.0',\n comment: 'Detect if protocol is supported',\n})\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.discovery.queryFeatures({\n connectionId,\n protocolVersion: 'v1',\n queries: [{ featureType: 'protocol', match: 'https://didcomm.org/messagepickup/2.0' }],\n comment: 'Detect if protocol is supported',\n})\n")))),(0,o.kt)("p",null,"The convenience method ",(0,o.kt)("strong",{parentName:"p"},"isProtocolSupported")," has been replaced by the more general synchronous mode of queryFeatures, which works when awaitDisclosures in options is set. Instead of returning a boolean, it returns an object with matching features:"),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const isPickUpV2Supported = await agent.discovery.isProtocolSupported(connectionId, StatusRequestMessage)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const discloseForPickupV2 = await agent.discovery.queryFeatures({\n connectionId: connectionId,\n protocolVersion: 'v1',\n queries: [{ featureType: 'protocol', match: StatusMessage.type.protocolUri }],\n awaitDisclosures: true,\n awaitDisclosuresTimeoutMs: 7000,\n})\n\nconst isPickUpV2Supported = discloseForPickupV2.features?.length === 1\n")))),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"Discover Features module does not rely anymore on Agent ",(0,o.kt)("inlineCode",{parentName:"p"},"Dispatcher")," to determine protocol support. Instead, it uses the new Feature Registry, where any custom modules implementing protocols must register them."),(0,o.kt)("p",{parentName:"admonition"},"This procedure can be done in module's ",(0,o.kt)("inlineCode",{parentName:"p"},"register(dependencyManager, featureRegistry)"),".")),(0,o.kt)("h3",{id:"ledger-module"},"Ledger Module"),(0,o.kt)("p",null,"Apart from the aforementioned indyLedgers configuration, you should also ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.4/tutorials/issue-a-credential#side-notes"},"note a slight change")," in behaviour when attempting to register credential definitions that already exists on the ledger but not in the wallet."),(0,o.kt)("h3",{id:"proofs-module"},"Proofs Module"),(0,o.kt)("h4",{id:"module-api-updates"},"Module API Updates"),(0,o.kt)("p",null,"Much in the same way as in 0.2.0 release when ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.4/updating/versions/0.1-to-0.2#module-api-updates"},"Issue Credential V2 protocol")," has been added, now that Present Proof V2 is supported, we introduced changes to proofs module."),(0,o.kt)("p",null,"Basically, for all methods in the proofs module you should take the following steps to update your code:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Move all function parameters into a single object. All module methods now take a single object that contain all properties."),(0,o.kt)("li",{parentName:"ol"},"For methods that initiate proposals, requests or presentations (",(0,o.kt)("inlineCode",{parentName:"li"},"proposeProof"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"acceptProposal"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"requestProof"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"acceptPresentation"),", etc.), you should pass ",(0,o.kt)("inlineCode",{parentName:"li"},"protocolVersion: 'v1'")," to indicate we should use the v1 protocol"),(0,o.kt)("li",{parentName:"ol"},"All indy specific attributes (e.g. Presentation Preview) should be passed in the ",(0,o.kt)("inlineCode",{parentName:"li"},"proofFormats.indy")," object."),(0,o.kt)("li",{parentName:"ol"},"Some indy objects, as the preview should now be passed only as their attributes (i.e. no need of creating the object instance) and provided in the ",(0,o.kt)("inlineCode",{parentName:"li"},"proofFormats.indy")," object.")),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.proofs.proposeProof(\n 'connectionId',\n new PresentationPreview({\n attributes: [new PresentationPreviewAttribute({ name: 'key', value: 'value' })],\n predicates: [\n new PresentationPreviewPredicate({\n name: 'age',\n credentialDefinitionId,\n predicate: PredicateType.GreaterThanOrEqualTo,\n threshold: 50,\n }),\n ],\n })\n)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.proofs.proposeProof({\n connectionId: connection.id,\n protocolVersion: 'v1',\n proofFormats: {\n indy: {\n attributes: [{ name: 'key', value: 'value' }],\n predicates: [{name: 'age', credentialDefinitionId, predicate: PredicateType.GreaterThanOrEqualTo, threshold: 50, ]\n },\n },\n comment: 'Propose proof comment',\n})\n")))),(0,o.kt)("h4",{id:"messages-extracted-from-proof-exchange-record"},"Messages Extracted from Proof Exchange Record"),(0,o.kt)("p",null,"The DIDComm messages that were previously stored on the proof record, have been extracted to separate DIDComm message records. This makes it easier to work with multiple versions of the protocol internally, and keeps the proof exchange record agnostic of the protocol version. Instead of accessing the messages through the ",(0,o.kt)("inlineCode",{parentName:"p"},"proposalMessage"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"requestMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"presentationMessage")," parameters, we now expose dedicated methods on the proofs module to retrieve the message."),(0,o.kt)("p",null,"With the addition of the v2 messages, all v1 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," while v2 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V2")," (",(0,o.kt)("inlineCode",{parentName:"p"},"V1RequestPresentationMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"V2RequestPresentationMessage"),"). If you were using these messages classes throughout your codebase, update them to use the ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," prefix."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const proofRecord = await agent.proofs.getById('proofRecordId')\n\nconst proposalMessage = proofRecord.proposalMessage\nconst requestMessage = proofRecord.requestMessage\nconst presentationMessage = proofRecord.presentationMessage\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const proofRecord = await agent.proofs.getById('proofRecordId')\n\nconst proposalMessage = await agent.proofs.findProposalMessage('proofRecordId')\nconst requestMessage = await agent.proofs.findRequestMessage('proofRecordId')\nconst presentationMessage = await agent.proofs.findPresentationMessage('proofRecordId')\n")),(0,o.kt)("p",null,"Because AFJ now also supports the present proof v2 protocol, the return type of this protocol has been changed to ",(0,o.kt)("inlineCode",{parentName:"p"},"V1XXXMessage | V2XXXMessage | null"),". Take this into account when working with the messages."),(0,o.kt)("p",null,"You can check if a message is a specific version by using the ",(0,o.kt)("inlineCode",{parentName:"p"},"instanceof")," operator:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"if (proposalMessage instanceof V1RequestPresentationMessage) {\n // do something\n}\n")))),(0,o.kt)("h3",{id:"out-of-band-proofs-and-credentials"},"Out Of Band Proofs and Credentials"),(0,o.kt)("p",null,"With the addition of the out of band module, the creation of connection-less messages has been split into two steps, allowing for better control and flexibility. The previous ",(0,o.kt)("inlineCode",{parentName:"p"},"agent.proofs.createOutOfBandRequest")," has been replaced by the ",(0,o.kt)("inlineCode",{parentName:"p"},"agent.proofs.createRequest")," method. This new method creates a proof request that is not tied to any connection."),(0,o.kt)("p",null,"What you can now do is call ",(0,o.kt)("inlineCode",{parentName:"p"},"agent.oob.createLegacyConnectionlessInvitation")," to attach the service decorator to the message and get a legacy connectionless message."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { requestMessage, proofRecord } = await agent.proofs.createOutOfBandRequest({\n requestedAttributes: {\n group1: {\n name: 'dateOfBirth',\n restrictions: [{ schemaId: 'F72i3Y3Q4i466efjYJYCHM:2:aha_cert:4.1.1' }],\n },\n },\n})\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { message, proofRecord } = await agent.proofs.createRequest({\n protocolVersion: 'v1',\n proofFormats: {\n indy: {\n requestedAttributes: {\n group1: {\n name: 'dateOfBirth',\n restrictions: [\n {\n schemaId: 'F72i3Y3Q4i466efjYJYCHM:2:aha_cert:4.1.1',\n },\n ],\n },\n },\n },\n },\n})\n\nconst { invitationUrl, message: messageWithServiceDecorator } = await agent.oob.createLegacyConnectionlessInvitation({\n recordId: proofRecord.id,\n domain: 'https://google.com',\n message,\n})\n")))),(0,o.kt)("p",null,"Out of band invitations are the new way to send messages out of band. You can use it for connection-less exchanges, but also for exchanges that you want to establish a connection for first. Here's an example on how to use the out of band module to create a connection-less invitation for a proof request:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const outOfBandRecord = await agent.oob.createInvitation({\n handshake: false, // set to true if you want to create a connection\n messages: [message],\n})\n\nconst invitationUrl = outOfBandRecord.outOfBandInvitation.toUrl({\n domain: 'https://afj.com',\n})\n")),(0,o.kt)("p",null,"As you can see, there's now a lot more ways to use a message not tied to a connection. By splitting the creation of the message from the creation of the invitation, we can now create a message not bound to a connection (at time of creation) for multiple use cases."),(0,o.kt)("h3",{id:"updating-custom-modules-to-the-new-plugin-api"},"Updating Custom Modules to the new Plugin API"),(0,o.kt)("p",null,"Although this isn't a breaking change to the public API of the framework, it is something that you will need to take into account if you have custom modules and want to upgrade them to make compatible with AFJ 0.3.0."),(0,o.kt)("h4",{id:"renaming-handler-classes"},"Renaming handler classes"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"Handler")," has been have been renamed to ",(0,o.kt)("inlineCode",{parentName:"p"},"MessageHandler")," to be be more descriptive, along with related types and methods. This means:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Handler")," is now ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandler")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"HandlerInboundMessage")," is now ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandlerInboundMessage")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Dispatcher.registerHandler")," is now ",(0,o.kt)("inlineCode",{parentName:"li"},"Dispatcher.registerMessageHandler")," and is marked as deprecated. The recommended way of registering handlers is by using the new ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandlerRegistry")," object by calling ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandlerRegistry.registerMessageHandler"),".")),(0,o.kt)("p",null,"If your custom module include message handlers, you must update them accordingly."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"export class MyHandler implements Handler {\n public supportedMessages = [MyMessage]\n\n public async handle(inboundMessage: HandlerInboundMessage) {\n ...\n }\n}\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"export class MyHandler implements MessageHandler {\n public supportedMessages = [MyMessage]\n\n public async handle(inboundMessage: MessageHandlerInboundMessage) {\n ...\n }\n}\n")))),(0,o.kt)("h4",{id:"using-agentcontext"},"Using AgentContext"),(0,o.kt)("p",null,"First of all, it's worth noting that now all services and repositories have been made stateless. A new ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentContext")," is introduced that holds the current context, which is passed to each method call. Therefore, you'll need to update every call to services, repositories and also eventEmitter methods to pass ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentContext")," object as first argument."),(0,o.kt)("p",null,"AgentContext can be obtained from either:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"MessageContext used by message handlers (accesed as messageContext.agentContext)"),(0,o.kt)("li",{parentName:"ul"},"Injected in your API constructor: you can store the instance and pass it to all your service and repository calls")),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"}," public async createRequest(options: CreateRequestOptions) {\n const message = new RequestMessage({\n parentThreadId: options.parentThreadId,\n })\n\n const record = new MyRecord({\n connectionId: options.connectionRecord.id,\n threadId: message.id,\n parentThreadId: options.parentThreadId,\n })\n\n await this.myRecordRepository.save(record)\n\n this.eventEmitter.emit({\n type: MyRecordEventTypes.StateChanged,\n payload: {\n myRecord: record,\n previousState: null,\n },\n })\n\n return { record, message }\n }\n\n public async processRequest(messageContext: HandlerInboundMessage) {\n const { message } = messageContext\n\n const record = new MyRecord({\n connectionId: connection.id,\n threadId: messageContext.message.id,\n parentThreadId: messageContext.message.thread?.parentThreadId,\n })\n\n await this.myRepository.save(record)\n\n return record\n }\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"}," public async createRequest(agentContext: AgentContext, options: CreateRequestOptions) {\n const message = new RequestMessage({\n parentThreadId: options.parentThreadId,\n })\n\n const record = new MyRecord({\n connectionId: options.connectionRecord.id,\n threadId: message.id,\n parentThreadId: options.parentThreadId,\n })\n\n await this.myRecordRepository.save(agentContext, record)\n\n this.eventEmitter.emit(agentContext, {\n type: MyRecordEventTypes.StateChanged,\n payload: {\n myRecord: record,\n previousState: null,\n },\n })\n\n return { record, message }\n }\n\n public async processRequest(messageContext: MessageHandlerInboundMessage) {\n const { message } = messageContext\n\n const record = new MyRecord({\n connectionId: connection.id,\n threadId: messageContext.message.id,\n parentThreadId: messageContext.message.thread?.parentThreadId,\n })\n\n await this.myRepository.save(messageContext.agentContext, record)\n\n return record\n }\n")))),(0,o.kt)("h4",{id:"using-outboundmessagecontext"},"Using OutboundMessageContext"),(0,o.kt)("p",null,"If your module implements a protocol that sends messages to other agents, you will notice that Agent's ",(0,o.kt)("inlineCode",{parentName:"p"},"MessageSender")," now receives the more generic ",(0,o.kt)("inlineCode",{parentName:"p"},"OutboundMessageContext")," class, which replaces previous helper method ",(0,o.kt)("inlineCode",{parentName:"p"},"createOutboundMessage"),"."),(0,o.kt)("p",null,"You can take advantage of this new mechanism to associate a record to the context, in order to do specific actions to it when outbound message state changes (e.g. a ",(0,o.kt)("inlineCode",{parentName:"p"},"MessageSendingError")," is thrown or ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentMessageSentEvent")," is emitted)."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { createOutboundMessage } from '@aries-framework/core'\n\nconst outboundMessage = createOutboundMessage(connection, message)\nawait this.messageSender.sendMessage(outboundMessage)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { OutboundMessageContext } from '@aries-framework/core'\n\nconst outboundMessageContext = new OutboundMessageContext(message, {\n agentContext: this.agentContext,\n connection,\n // optional, if you want to link the message to a related record\n associatedRecord: record,\n})\n\nawait this.messageSender.sendMessage(outboundMessageContext)\n")))),(0,o.kt)("h4",{id:"updating-module-structure-to-register-in-new-plugin-api"},"Updating module structure to register in new Plugin API"),(0,o.kt)("p",null,"Existing modules can benefit from the new Plugin API mechanism by doing the following modifications:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Rename Module class (e.g. MyModule) to API class (MyApi) and add @injectable decorator. Inject AgentContext in order to pass it to any services or repositories it might call. For instance:")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { injectable } from '@aries-framework/core'\n\n@injectable() // <-- Add this\nexport class MyApi {\n private messageSender: MessageSender\n private myService: MyService\n private connectionService: ConnectionService\n private agentContext: AgentContext // <-- Add this\n\n public constructor(\n messageHandlerRegistry: MessageHandlerRegistry, // <-- use this instead of Dispatcher\n messageSender: MessageSender,\n myService: MyService,\n connectionService: ConnectionService,\n agentContext: AgentContext // <-- Add this\n ) {\n this.messageSender = messageSender\n this.myService = myService\n this.connectionService = connectionService\n this.agentContext = agentContext // <-- Add this\n this.registerHandlers(messageHandlerRegistry) // <-- use messageHandlerRegistry instead of dispatcher\n }\n")),(0,o.kt)("ol",{start:2},(0,o.kt)("li",{parentName:"ol"},"Create a new Module class that implements Module interface and registers the dependencies and features. For instance:")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import type { DependencyManager, FeatureRegistry, Module } from '@aries-framework/core'\n\nimport { Protocol } from '@aries-framework/core'\n\nexport class MyModule implements Module {\n public readonly api = MyApi // the one we've just renamed from MyModule\n\n public register(dependencyManager: DependencyManager, featureRegistry: FeatureRegistry) {\n // Api\n dependencyManager.registerContextScoped(MyApi)\n\n // Services\n dependencyManager.registerSingleton(MyService)\n\n // Repositories\n dependencyManager.registerSingleton(MyRepository)\n\n // Feature Registry: don't forget to register your protocols and other features your module may add\n featureRegistry.register(\n new Protocol({\n id: 'https://didcomm.org/my-protocol/1.0',\n roles: [MyRole.Sender, MyRole.Receiver],\n })\n )\n }\n")),(0,o.kt)("p",null,"After doing this, you can add your module to agent constructor like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const agent = new Agent({\n config: {\n /* config */\n },\n dependencies: agentDependencies,\n modules: {\n myModule: new MyModule(),\n /* other custom modules */\n },\n})\n\n// MyModule API can be accessed in agent.modules namespace\nawait agent.modules.myModule.doSomething()\n\nawait agent.modules.myModule.doAnotherThing()\n")),(0,o.kt)("h2",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,o.kt)("p",null,"The 0.3.0 release introduces some breaking changes to the storage format, mainly related to Proof Exchanges."),(0,o.kt)("p",null,"Below all breaking storage changes are explained in as much detail as possible. The update assistant provides all tools to migrate without a hassle, but it is important to know what has changed. All examples only show the keys that have changed, unrelated keys in records have been omitted."),(0,o.kt)("p",null,"See the ",(0,o.kt)("a",{parentName:"p",href:"/guides/updating/update-assistant"},"Update Assistant")," documentation for a guide on how to use the update assistant."),(0,o.kt)("p",null,"There are no config parameters to be provided to the update assistant to migrate from 0.2.x to 0.3.x."),(0,o.kt)("h3",{id:"migrate-proof-record-properties"},"Migrate Proof Record Properties"),(0,o.kt)("p",null,"In 0.3.0 the v1 DIDComm messages have been moved out of the proof record into separate records using the DidCommMessageRepository. The migration scripts extracts all messages (proposalMessage, requestMessage, presentationMessage) and moves them into the DidCommMessageRepository. With the addition of support for different protocol versions the proof record now stores the protocol version."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "proposalMessage": { ... },\n "requestMessage": { ... },\n "presentationMessage": { ... },\n}\n'))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "protocolVersion": "v1"\n}\n')))),(0,o.kt)("h3",{id:"migrate-connection-record-properties"},"Migrate Connection Record properties"),(0,o.kt)("p",null,"The recently introduced ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionType")," tag has been pluralized to reflect the fact that more than a single connection type can be defined for a given connection. Also, it is now available as a direct record property (e.g. can be queried and set by using ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionRecord.connectionTypes"),") apart from the tag for efficient search."),(0,o.kt)("p",null,"The migration script renames ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionType")," to ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionTypes")," in all connections, and also searches for any mediation connection and adds ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionType.Mediator")," as one of its types."),(0,o.kt)("h3",{id:"migrate-did-record-properties"},"Migrate Did Record properties"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"didRecord.id")," was previously the did itself. However to allow for connecting with self, where multiple did records are created for the same did, the id property is now an uuid and a separate did property is added."),(0,o.kt)("p",null,"The migration script generates a new ID for each did record and stores its did into didRecord.did property."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": "did"\n}\n'))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": "uuid",\n "did": "did"\n}\n')))))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2e77271a.27bf11c9.js b/assets/js/2e77271a.27bf11c9.js deleted file mode 100644 index c5cd00bc..00000000 --- a/assets/js/2e77271a.27bf11c9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7024],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>g});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),d=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=d(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),c=d(n),m=o,g=c["".concat(l,".").concat(m)]||c[m]||p[m]||r;return n?a.createElement(g,s(s({ref:t},u),{},{components:n})):a.createElement(g,s({ref:t},u))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,s=new Array(r);s[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[c]="string"==typeof e?e:o,s[1]=i;for(var d=2;d{n.d(t,{Z:()=>s});var a=n(7294),o=n(6010);const r={tabItem:"tabItem_Ymn6"};function s(e){let{children:t,hidden:n,className:s}=e;return a.createElement("div",{role:"tabpanel",className:(0,o.Z)(r.tabItem,s),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),o=n(7294),r=n(6010),s=n(2466),i=n(6550),l=n(1980),d=n(7392),u=n(12);function c(e){return function(e){return o.Children.map(e,(e=>{if((0,o.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:o}}=e;return{value:t,label:n,attributes:a,default:o}}))}function p(e){const{values:t,children:n}=e;return(0,o.useMemo)((()=>{const e=t??c(n);return function(e){const t=(0,d.l)(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 m(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 a=(0,i.k6)(),r=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,l._X)(r),(0,o.useCallback)((e=>{if(!r)return;const t=new URLSearchParams(a.location.search);t.set(r,e),a.replace({...a.location,search:t.toString()})}),[r,a])]}function h(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,r=p(e),[s,i]=(0,o.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(!m({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:r}))),[l,d]=g({queryString:n,groupId:a}),[c,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,r]=(0,u.Nk)(n);return[a,(0,o.useCallback)((e=>{n&&r.set(e)}),[n,r])]}({groupId:a}),f=(()=>{const e=l??c;return m({value:e,tabValues:r})?e:null})();(0,o.useLayoutEffect)((()=>{f&&i(f)}),[f]);return{selectedValue:s,selectValue:(0,o.useCallback)((e=>{if(!m({value:e,tabValues:r}))throw new Error(`Can't select invalid tab value=${e}`);i(e),d(e),h(e)}),[d,h,r]),tabValues:r}}var f=n(2389);const k={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){let{className:t,block:n,selectedValue:i,selectValue:l,tabValues:d}=e;const u=[],{blockElementScrollPositionUntilNextRender:c}=(0,s.o5)(),p=e=>{const t=e.currentTarget,n=u.indexOf(t),a=d[n].value;a!==i&&(c(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=u.indexOf(e.currentTarget)+1;t=u[n]??u[0];break}case"ArrowLeft":{const n=u.indexOf(e.currentTarget)-1;t=u[n]??u[u.length-1];break}}t?.focus()};return o.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.Z)("tabs",{"tabs--block":n},t)},d.map((e=>{let{value:t,label:n,attributes:s}=e;return o.createElement("li",(0,a.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>u.push(e),onKeyDown:m,onClick:p},s,{className:(0,r.Z)("tabs__item",k.tabItem,s?.className,{"tabs__item--active":i===t})}),n??t)})))}function b(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,o.cloneElement)(e,{className:"margin-top--md"}):null}return o.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,o.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function v(e){const t=h(e);return o.createElement("div",{className:(0,r.Z)("tabs-container",k.tabList)},o.createElement(y,(0,a.Z)({},e,t)),o.createElement(b,(0,a.Z)({},e,t)))}function w(e){const t=(0,f.Z)();return o.createElement(v,(0,a.Z)({key:String(t)},e))}},7079:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>g,frontMatter:()=>i,metadata:()=>d,toc:()=>c});var a=n(7462),o=(n(7294),n(3905)),r=n(4866),s=n(5162);const i={},l="Migrating from AFJ 0.2.x to 0.3.x",d={unversionedId:"updating/versions/0.2-to-0.3",id:"version-0.4/updating/versions/0.2-to-0.3",title:"Migrating from AFJ 0.2.x to 0.3.x",description:"This document describes everything you need to know for updating AFJ 0.2.x to 0.3.x. If you're not aware of how updating in AFJ works make sure to first read the guide on Updating AFJ.",source:"@site/versioned_docs/version-0.4/updating/versions/0.2-to-0.3.md",sourceDirName:"updating/versions",slug:"/updating/versions/0.2-to-0.3",permalink:"/guides/updating/versions/0.2-to-0.3",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Migrating from AFJ 0.1.0 to 0.2.x",permalink:"/guides/updating/versions/0.1-to-0.2"},next:{title:"Migrating from AFJ 0.3.x to 0.4.x",permalink:"/guides/updating/versions/0.3-to-0.4"}},u={},c=[{value:"React Native",id:"react-native",level:4},{value:"Node",id:"node",level:4},{value:"Breaking Code Changes",id:"breaking-code-changes",level:2},{value:"Agent creation",id:"agent-creation",level:3},{value:"0.2.x",id:"02x",level:5},{value:"0.3.x",id:"03x",level:5},{value:"did:key usage in protocols",id:"didkey-usage-in-protocols",level:3},{value:"Modules extracted from the core",id:"modules-extracted-from-the-core",level:3},{value:"0.2.x",id:"02x-1",level:5},{value:"0.3.x",id:"03x-1",level:5},{value:"Discover Features Module",id:"discover-features-module",level:3},{value:"0.2.x",id:"02x-2",level:5},{value:"0.3.x",id:"03x-2",level:5},{value:"0.2.x",id:"02x-3",level:5},{value:"0.3.x",id:"03x-3",level:5},{value:"Ledger Module",id:"ledger-module",level:3},{value:"Proofs Module",id:"proofs-module",level:3},{value:"Module API Updates",id:"module-api-updates",level:4},{value:"0.2.x",id:"02x-4",level:5},{value:"0.3.x",id:"03x-4",level:5},{value:"Messages Extracted from Proof Exchange Record",id:"messages-extracted-from-proof-exchange-record",level:4},{value:"0.2.x",id:"02x-5",level:5},{value:"0.3.x",id:"03x-5",level:5},{value:"Out Of Band Proofs and Credentials",id:"out-of-band-proofs-and-credentials",level:3},{value:"0.2.x",id:"02x-6",level:4},{value:"0.3.x",id:"03x-6",level:4},{value:"Updating Custom Modules to the new Plugin API",id:"updating-custom-modules-to-the-new-plugin-api",level:3},{value:"Renaming handler classes",id:"renaming-handler-classes",level:4},{value:"0.2.x",id:"02x-7",level:5},{value:"0.3.x",id:"03x-7",level:5},{value:"Using AgentContext",id:"using-agentcontext",level:4},{value:"0.2.x",id:"02x-8",level:4},{value:"0.3.x",id:"03x-8",level:4},{value:"Using OutboundMessageContext",id:"using-outboundmessagecontext",level:4},{value:"0.2.x",id:"02x-9",level:4},{value:"0.3.x",id:"03x-9",level:4},{value:"Updating module structure to register in new Plugin API",id:"updating-module-structure-to-register-in-new-plugin-api",level:4},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:2},{value:"Migrate Proof Record Properties",id:"migrate-proof-record-properties",level:3},{value:"0.2.x",id:"02x-10",level:4},{value:"0.3.x",id:"03x-10",level:4},{value:"Migrate Connection Record properties",id:"migrate-connection-record-properties",level:3},{value:"Migrate Did Record properties",id:"migrate-did-record-properties",level:3},{value:"0.2.x",id:"02x-11",level:4},{value:"0.3.x",id:"03x-11",level:4}],p={toc:c},m="wrapper";function g(e){let{components:t,...n}=e;return(0,o.kt)(m,(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"migrating-from-afj-02x-to-03x"},"Migrating from AFJ 0.2.x to 0.3.x"),(0,o.kt)("p",null,"This document describes everything you need to know for updating AFJ 0.2.x to 0.3.x. If you're not aware of how updating in AFJ works make sure to first read the guide on ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.5/updating/"},"Updating AFJ"),"."),(0,o.kt)("p",null,"First of all, update you dependencies to the 0.3.x versions. This will also update the needed peer depedencnies. ",(0,o.kt)("strong",{parentName:"p"},"Extension packages are not updated with this command"),". You need to update these manually, and make sure they're up to date with the latest version of AFJ."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"React Native",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/react-native@^0.3.0 @aries-framework/core@^0.3.0 indy-sdk-react-native@^0.3.0\n\n# or NPM\nnpn install @aries-framework/react-native@^0.3.0 @aries-framework/core@^0.3.0 indy-sdk-react-native@^0.3.0\n"))),(0,o.kt)(s.Z,{label:"Node",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/node@^0.3.0 @aries-framework/core@^0.3.0\n\n# or NPM\nnpm install @aries-framework/node@^0.3.0 @aries-framework/core@^0.3.0\n")))),(0,o.kt)("h2",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,o.kt)("p",null,"This section will list all breaking changes made to the public API of AFJ between version 0.2.x and 0.3.0."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here (e.g. see ",(0,o.kt)("a",{parentName:"p",href:"#Updating-Custom-Modules-to-the-new-Plugin-API"},"Updating Custom Modules to the Plugin API"),"), but it is possible some breaking changes are not documented here (feel free to open PRs).")),(0,o.kt)("h3",{id:"agent-creation"},"Agent creation"),(0,o.kt)("p",null,"The agent constructor has been updated to a single ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentOptions")," object that contains the config and dependencies properties."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const agent = new Agent(agentConfig, agentDependencies)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const agent = new Agent({ config: agentConfig, dependencies: agentDependencies })\n")))),(0,o.kt)("p",null,"This object contains:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"config: Agent's initial configuration"),(0,o.kt)("li",{parentName:"ul"},"dependencies: platform-specific Agent dependencies"),(0,o.kt)("li",{parentName:"ul"},"modules: optional field for internal module configuration and custom module registration")),(0,o.kt)("p",null,"For easy migration, you can simply construct ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentOptions")," by putting current InitConfig into ",(0,o.kt)("inlineCode",{parentName:"p"},"config")," key and agentDependencies into ",(0,o.kt)("inlineCode",{parentName:"p"},"dependencies")," key."),(0,o.kt)("p",null,"Note that, if you are defining ",(0,o.kt)("inlineCode",{parentName:"p"},"indyLedgers")," configuration, you should set the indyNamespace for every ledger, as explained in ",(0,o.kt)("a",{parentName:"p",href:"/guides/tutorials/agent-config/#indyledgers"},"Agent Config tutorial"),"."),(0,o.kt)("h3",{id:"didkey-usage-in-protocols"},"did:key usage in protocols"),(0,o.kt)("p",null,"In accordance with ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/tree/b3a3942ef052039e73cd23d847f42947f8287da2/features/0360-use-did-key"},"Aries RFC 0360"),", since 0.2.5 there is a configuration parameter called ",(0,o.kt)("inlineCode",{parentName:"p"},"useDidKeyInProtocols")," which, when enabled, will encode keys in did:key instead of previous base58 format, unless the other party has started a protocol and is using base58."),(0,o.kt)("p",null,"This parameter was previously disabled by default and now it is enabled. If your agent only interacts with modern agents (e.g. AFJ 0.2.5 and newer) this will not represent any issue. Otherwise it is safer to explicitly set it to ",(0,o.kt)("inlineCode",{parentName:"p"},"false"),". However, keep in mind that we expect this setting to be deprecated in the future, so we encourage you to update all your agents to use did:key."),(0,o.kt)("h3",{id:"modules-extracted-from-the-core"},"Modules extracted from the core"),(0,o.kt)("p",null,"In this release two modules were extracted from the core and published as separate, optional packages:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"actionMenu has been moved to @aries-framework/action-menu"),(0,o.kt)("li",{parentName:"ul"},"questionAnswer has been moved to @aries-framework/question-answer")),(0,o.kt)("p",null,"If you want to use them, you can integrate in an Agent instance by injecting them in constructor, as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { ActionMenuModule } from '@aries-framework/action-menu'\nimport { QuestionAnswerModule } from '@aries-framework/question-answer'\n\nconst agent = new Agent({\n config: {\n /* config */\n },\n dependencies: agentDependencies,\n modules: {\n actionMenu: new ActionMenuModule(),\n questionAnswer: new QuestionAnswerModule(),\n /* other custom modules */\n },\n})\n")),(0,o.kt)("p",null,"As they are now considered custom modules, their API can be accessed in ",(0,o.kt)("inlineCode",{parentName:"p"},"modules")," namespace, so you should add it to every call to them."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.questionAnswer.sendQuestion(connectionId, {\n question: 'Do you want to play?',\n validResponses: [{ text: 'Yes' }, { text: 'No' }],\n})\n\nawait agent.questionAnswer.sendAnswer(questionAnswerRecordId, 'Yes')\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.modules.questionAnswer.sendQuestion(connectionId, {\n question: 'Do you want to play?',\n validResponses: [{ text: 'Yes' }, { text: 'No' }],\n})\n\nawait agent.modules.questionAnswer.sendAnswer(questionAnswerRecordId, 'Yes')\n")))),(0,o.kt)("h3",{id:"discover-features-module"},"Discover Features Module"),(0,o.kt)("p",null,"This module now supports both Discover Features V1 and V2, and as it happened to other modules, ",(0,o.kt)("inlineCode",{parentName:"p"},"queryFeatures")," method parameters have been unified to a single object and requires to specify the version of Discover Features protocol to be used. Note that ",(0,o.kt)("inlineCode",{parentName:"p"},"query")," property has been replaced by the more general ",(0,o.kt)("inlineCode",{parentName:"p"},"queries")," which accepts multiple features to be search for. To convert a query to this new format you simply need to create a single-object array whose unique object whose ",(0,o.kt)("inlineCode",{parentName:"p"},"featureType")," field is 'protocol' and ",(0,o.kt)("inlineCode",{parentName:"p"},"match")," field is the query itself."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.discovery.queryFeatures(connectionId, {\n query: 'https://didcomm.org/messagepickup/2.0',\n comment: 'Detect if protocol is supported',\n})\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.discovery.queryFeatures({\n connectionId,\n protocolVersion: 'v1',\n queries: [{ featureType: 'protocol', match: 'https://didcomm.org/messagepickup/2.0' }],\n comment: 'Detect if protocol is supported',\n})\n")))),(0,o.kt)("p",null,"The convenience method ",(0,o.kt)("strong",{parentName:"p"},"isProtocolSupported")," has been replaced by the more general synchronous mode of queryFeatures, which works when awaitDisclosures in options is set. Instead of returning a boolean, it returns an object with matching features:"),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const isPickUpV2Supported = await agent.discovery.isProtocolSupported(connectionId, StatusRequestMessage)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const discloseForPickupV2 = await agent.discovery.queryFeatures({\n connectionId: connectionId,\n protocolVersion: 'v1',\n queries: [{ featureType: 'protocol', match: StatusMessage.type.protocolUri }],\n awaitDisclosures: true,\n awaitDisclosuresTimeoutMs: 7000,\n})\n\nconst isPickUpV2Supported = discloseForPickupV2.features?.length === 1\n")))),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"Discover Features module does not rely anymore on Agent ",(0,o.kt)("inlineCode",{parentName:"p"},"Dispatcher")," to determine protocol support. Instead, it uses the new Feature Registry, where any custom modules implementing protocols must register them."),(0,o.kt)("p",{parentName:"admonition"},"This procedure can be done in module's ",(0,o.kt)("inlineCode",{parentName:"p"},"register(dependencyManager, featureRegistry)"),".")),(0,o.kt)("h3",{id:"ledger-module"},"Ledger Module"),(0,o.kt)("p",null,"Apart from the aforementioned indyLedgers configuration, you should also ",(0,o.kt)("a",{parentName:"p",href:"/guides/tutorials/issue-a-credential#side-notes"},"note a slight change")," in behaviour when attempting to register credential definitions that already exists on the ledger but not in the wallet."),(0,o.kt)("h3",{id:"proofs-module"},"Proofs Module"),(0,o.kt)("h4",{id:"module-api-updates"},"Module API Updates"),(0,o.kt)("p",null,"Much in the same way as in 0.2.0 release when ",(0,o.kt)("a",{parentName:"p",href:"/guides/updating/versions/0.1-to-0.2#module-api-updates"},"Issue Credential V2 protocol")," has been added, now that Present Proof V2 is supported, we introduced changes to proofs module."),(0,o.kt)("p",null,"Basically, for all methods in the proofs module you should take the following steps to update your code:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Move all function parameters into a single object. All module methods now take a single object that contain all properties."),(0,o.kt)("li",{parentName:"ol"},"For methods that initiate proposals, requests or presentations (",(0,o.kt)("inlineCode",{parentName:"li"},"proposeProof"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"acceptProposal"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"requestProof"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"acceptPresentation"),", etc.), you should pass ",(0,o.kt)("inlineCode",{parentName:"li"},"protocolVersion: 'v1'")," to indicate we should use the v1 protocol"),(0,o.kt)("li",{parentName:"ol"},"All indy specific attributes (e.g. Presentation Preview) should be passed in the ",(0,o.kt)("inlineCode",{parentName:"li"},"proofFormats.indy")," object."),(0,o.kt)("li",{parentName:"ol"},"Some indy objects, as the preview should now be passed only as their attributes (i.e. no need of creating the object instance) and provided in the ",(0,o.kt)("inlineCode",{parentName:"li"},"proofFormats.indy")," object.")),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.proofs.proposeProof(\n 'connectionId',\n new PresentationPreview({\n attributes: [new PresentationPreviewAttribute({ name: 'key', value: 'value' })],\n predicates: [\n new PresentationPreviewPredicate({\n name: 'age',\n credentialDefinitionId,\n predicate: PredicateType.GreaterThanOrEqualTo,\n threshold: 50,\n }),\n ],\n })\n)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.proofs.proposeProof({\n connectionId: connection.id,\n protocolVersion: 'v1',\n proofFormats: {\n indy: {\n attributes: [{ name: 'key', value: 'value' }],\n predicates: [{name: 'age', credentialDefinitionId, predicate: PredicateType.GreaterThanOrEqualTo, threshold: 50, ]\n },\n },\n comment: 'Propose proof comment',\n})\n")))),(0,o.kt)("h4",{id:"messages-extracted-from-proof-exchange-record"},"Messages Extracted from Proof Exchange Record"),(0,o.kt)("p",null,"The DIDComm messages that were previously stored on the proof record, have been extracted to separate DIDComm message records. This makes it easier to work with multiple versions of the protocol internally, and keeps the proof exchange record agnostic of the protocol version. Instead of accessing the messages through the ",(0,o.kt)("inlineCode",{parentName:"p"},"proposalMessage"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"requestMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"presentationMessage")," parameters, we now expose dedicated methods on the proofs module to retrieve the message."),(0,o.kt)("p",null,"With the addition of the v2 messages, all v1 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," while v2 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V2")," (",(0,o.kt)("inlineCode",{parentName:"p"},"V1RequestPresentationMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"V2RequestPresentationMessage"),"). If you were using these messages classes throughout your codebase, update them to use the ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," prefix."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const proofRecord = await agent.proofs.getById('proofRecordId')\n\nconst proposalMessage = proofRecord.proposalMessage\nconst requestMessage = proofRecord.requestMessage\nconst presentationMessage = proofRecord.presentationMessage\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const proofRecord = await agent.proofs.getById('proofRecordId')\n\nconst proposalMessage = await agent.proofs.findProposalMessage('proofRecordId')\nconst requestMessage = await agent.proofs.findRequestMessage('proofRecordId')\nconst presentationMessage = await agent.proofs.findPresentationMessage('proofRecordId')\n")),(0,o.kt)("p",null,"Because AFJ now also supports the present proof v2 protocol, the return type of this protocol has been changed to ",(0,o.kt)("inlineCode",{parentName:"p"},"V1XXXMessage | V2XXXMessage | null"),". Take this into account when working with the messages."),(0,o.kt)("p",null,"You can check if a message is a specific version by using the ",(0,o.kt)("inlineCode",{parentName:"p"},"instanceof")," operator:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"if (proposalMessage instanceof V1RequestPresentationMessage) {\n // do something\n}\n")))),(0,o.kt)("h3",{id:"out-of-band-proofs-and-credentials"},"Out Of Band Proofs and Credentials"),(0,o.kt)("p",null,"With the addition of the out of band module, the creation of connection-less messages has been split into two steps, allowing for better control and flexibility. The previous ",(0,o.kt)("inlineCode",{parentName:"p"},"agent.proofs.createOutOfBandRequest")," has been replaced by the ",(0,o.kt)("inlineCode",{parentName:"p"},"agent.proofs.createRequest")," method. This new method creates a proof request that is not tied to any connection."),(0,o.kt)("p",null,"What you can now do is call ",(0,o.kt)("inlineCode",{parentName:"p"},"agent.oob.createLegacyConnectionlessInvitation")," to attach the service decorator to the message and get a legacy connectionless message."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { requestMessage, proofRecord } = await agent.proofs.createOutOfBandRequest({\n requestedAttributes: {\n group1: {\n name: 'dateOfBirth',\n restrictions: [{ schemaId: 'F72i3Y3Q4i466efjYJYCHM:2:aha_cert:4.1.1' }],\n },\n },\n})\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { message, proofRecord } = await agent.proofs.createRequest({\n protocolVersion: 'v1',\n proofFormats: {\n indy: {\n requestedAttributes: {\n group1: {\n name: 'dateOfBirth',\n restrictions: [\n {\n schemaId: 'F72i3Y3Q4i466efjYJYCHM:2:aha_cert:4.1.1',\n },\n ],\n },\n },\n },\n },\n})\n\nconst { invitationUrl, message: messageWithServiceDecorator } = await agent.oob.createLegacyConnectionlessInvitation({\n recordId: proofRecord.id,\n domain: 'https://google.com',\n message,\n})\n")))),(0,o.kt)("p",null,"Out of band invitations are the new way to send messages out of band. You can use it for connection-less exchanges, but also for exchanges that you want to establish a connection for first. Here's an example on how to use the out of band module to create a connection-less invitation for a proof request:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const outOfBandRecord = await agent.oob.createInvitation({\n handshake: false, // set to true if you want to create a connection\n messages: [message],\n})\n\nconst invitationUrl = outOfBandRecord.outOfBandInvitation.toUrl({\n domain: 'https://afj.com',\n})\n")),(0,o.kt)("p",null,"As you can see, there's now a lot more ways to use a message not tied to a connection. By splitting the creation of the message from the creation of the invitation, we can now create a message not bound to a connection (at time of creation) for multiple use cases."),(0,o.kt)("h3",{id:"updating-custom-modules-to-the-new-plugin-api"},"Updating Custom Modules to the new Plugin API"),(0,o.kt)("p",null,"Although this isn't a breaking change to the public API of the framework, it is something that you will need to take into account if you have custom modules and want to upgrade them to make compatible with AFJ 0.3.0."),(0,o.kt)("h4",{id:"renaming-handler-classes"},"Renaming handler classes"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"Handler")," has been have been renamed to ",(0,o.kt)("inlineCode",{parentName:"p"},"MessageHandler")," to be be more descriptive, along with related types and methods. This means:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Handler")," is now ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandler")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"HandlerInboundMessage")," is now ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandlerInboundMessage")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Dispatcher.registerHandler")," is now ",(0,o.kt)("inlineCode",{parentName:"li"},"Dispatcher.registerMessageHandler")," and is marked as deprecated. The recommended way of registering handlers is by using the new ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandlerRegistry")," object by calling ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandlerRegistry.registerMessageHandler"),".")),(0,o.kt)("p",null,"If your custom module include message handlers, you must update them accordingly."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"export class MyHandler implements Handler {\n public supportedMessages = [MyMessage]\n\n public async handle(inboundMessage: HandlerInboundMessage) {\n ...\n }\n}\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"export class MyHandler implements MessageHandler {\n public supportedMessages = [MyMessage]\n\n public async handle(inboundMessage: MessageHandlerInboundMessage) {\n ...\n }\n}\n")))),(0,o.kt)("h4",{id:"using-agentcontext"},"Using AgentContext"),(0,o.kt)("p",null,"First of all, it's worth noting that now all services and repositories have been made stateless. A new ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentContext")," is introduced that holds the current context, which is passed to each method call. Therefore, you'll need to update every call to services, repositories and also eventEmitter methods to pass ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentContext")," object as first argument."),(0,o.kt)("p",null,"AgentContext can be obtained from either:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"MessageContext used by message handlers (accesed as messageContext.agentContext)"),(0,o.kt)("li",{parentName:"ul"},"Injected in your API constructor: you can store the instance and pass it to all your service and repository calls")),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"}," public async createRequest(options: CreateRequestOptions) {\n const message = new RequestMessage({\n parentThreadId: options.parentThreadId,\n })\n\n const record = new MyRecord({\n connectionId: options.connectionRecord.id,\n threadId: message.id,\n parentThreadId: options.parentThreadId,\n })\n\n await this.myRecordRepository.save(record)\n\n this.eventEmitter.emit({\n type: MyRecordEventTypes.StateChanged,\n payload: {\n myRecord: record,\n previousState: null,\n },\n })\n\n return { record, message }\n }\n\n public async processRequest(messageContext: HandlerInboundMessage) {\n const { message } = messageContext\n\n const record = new MyRecord({\n connectionId: connection.id,\n threadId: messageContext.message.id,\n parentThreadId: messageContext.message.thread?.parentThreadId,\n })\n\n await this.myRepository.save(record)\n\n return record\n }\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"}," public async createRequest(agentContext: AgentContext, options: CreateRequestOptions) {\n const message = new RequestMessage({\n parentThreadId: options.parentThreadId,\n })\n\n const record = new MyRecord({\n connectionId: options.connectionRecord.id,\n threadId: message.id,\n parentThreadId: options.parentThreadId,\n })\n\n await this.myRecordRepository.save(agentContext, record)\n\n this.eventEmitter.emit(agentContext, {\n type: MyRecordEventTypes.StateChanged,\n payload: {\n myRecord: record,\n previousState: null,\n },\n })\n\n return { record, message }\n }\n\n public async processRequest(messageContext: MessageHandlerInboundMessage) {\n const { message } = messageContext\n\n const record = new MyRecord({\n connectionId: connection.id,\n threadId: messageContext.message.id,\n parentThreadId: messageContext.message.thread?.parentThreadId,\n })\n\n await this.myRepository.save(messageContext.agentContext, record)\n\n return record\n }\n")))),(0,o.kt)("h4",{id:"using-outboundmessagecontext"},"Using OutboundMessageContext"),(0,o.kt)("p",null,"If your module implements a protocol that sends messages to other agents, you will notice that Agent's ",(0,o.kt)("inlineCode",{parentName:"p"},"MessageSender")," now receives the more generic ",(0,o.kt)("inlineCode",{parentName:"p"},"OutboundMessageContext")," class, which replaces previous helper method ",(0,o.kt)("inlineCode",{parentName:"p"},"createOutboundMessage"),"."),(0,o.kt)("p",null,"You can take advantage of this new mechanism to associate a record to the context, in order to do specific actions to it when outbound message state changes (e.g. a ",(0,o.kt)("inlineCode",{parentName:"p"},"MessageSendingError")," is thrown or ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentMessageSentEvent")," is emitted)."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { createOutboundMessage } from '@aries-framework/core'\n\nconst outboundMessage = createOutboundMessage(connection, message)\nawait this.messageSender.sendMessage(outboundMessage)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { OutboundMessageContext } from '@aries-framework/core'\n\nconst outboundMessageContext = new OutboundMessageContext(message, {\n agentContext: this.agentContext,\n connection,\n // optional, if you want to link the message to a related record\n associatedRecord: record,\n})\n\nawait this.messageSender.sendMessage(outboundMessageContext)\n")))),(0,o.kt)("h4",{id:"updating-module-structure-to-register-in-new-plugin-api"},"Updating module structure to register in new Plugin API"),(0,o.kt)("p",null,"Existing modules can benefit from the new Plugin API mechanism by doing the following modifications:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Rename Module class (e.g. MyModule) to API class (MyApi) and add @injectable decorator. Inject AgentContext in order to pass it to any services or repositories it might call. For instance:")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { injectable } from '@aries-framework/core'\n\n@injectable() // <-- Add this\nexport class MyApi {\n private messageSender: MessageSender\n private myService: MyService\n private connectionService: ConnectionService\n private agentContext: AgentContext // <-- Add this\n\n public constructor(\n messageHandlerRegistry: MessageHandlerRegistry, // <-- use this instead of Dispatcher\n messageSender: MessageSender,\n myService: MyService,\n connectionService: ConnectionService,\n agentContext: AgentContext // <-- Add this\n ) {\n this.messageSender = messageSender\n this.myService = myService\n this.connectionService = connectionService\n this.agentContext = agentContext // <-- Add this\n this.registerHandlers(messageHandlerRegistry) // <-- use messageHandlerRegistry instead of dispatcher\n }\n")),(0,o.kt)("ol",{start:2},(0,o.kt)("li",{parentName:"ol"},"Create a new Module class that implements Module interface and registers the dependencies and features. For instance:")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import type { DependencyManager, FeatureRegistry, Module } from '@aries-framework/core'\n\nimport { Protocol } from '@aries-framework/core'\n\nexport class MyModule implements Module {\n public readonly api = MyApi // the one we've just renamed from MyModule\n\n public register(dependencyManager: DependencyManager, featureRegistry: FeatureRegistry) {\n // Api\n dependencyManager.registerContextScoped(MyApi)\n\n // Services\n dependencyManager.registerSingleton(MyService)\n\n // Repositories\n dependencyManager.registerSingleton(MyRepository)\n\n // Feature Registry: don't forget to register your protocols and other features your module may add\n featureRegistry.register(\n new Protocol({\n id: 'https://didcomm.org/my-protocol/1.0',\n roles: [MyRole.Sender, MyRole.Receiver],\n })\n )\n }\n")),(0,o.kt)("p",null,"After doing this, you can add your module to agent constructor like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const agent = new Agent({\n config: {\n /* config */\n },\n dependencies: agentDependencies,\n modules: {\n myModule: new MyModule(),\n /* other custom modules */\n },\n})\n\n// MyModule API can be accessed in agent.modules namespace\nawait agent.modules.myModule.doSomething()\n\nawait agent.modules.myModule.doAnotherThing()\n")),(0,o.kt)("h2",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,o.kt)("p",null,"The 0.3.0 release introduces some breaking changes to the storage format, mainly related to Proof Exchanges."),(0,o.kt)("p",null,"Below all breaking storage changes are explained in as much detail as possible. The update assistant provides all tools to migrate without a hassle, but it is important to know what has changed. All examples only show the keys that have changed, unrelated keys in records have been omitted."),(0,o.kt)("p",null,"See the ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.5/updating/update-assistant"},"Update Assistant")," documentation for a guide on how to use the update assistant."),(0,o.kt)("p",null,"There are no config parameters to be provided to the update assistant to migrate from 0.2.x to 0.3.x."),(0,o.kt)("h3",{id:"migrate-proof-record-properties"},"Migrate Proof Record Properties"),(0,o.kt)("p",null,"In 0.3.0 the v1 DIDComm messages have been moved out of the proof record into separate records using the DidCommMessageRepository. The migration scripts extracts all messages (proposalMessage, requestMessage, presentationMessage) and moves them into the DidCommMessageRepository. With the addition of support for different protocol versions the proof record now stores the protocol version."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "proposalMessage": { ... },\n "requestMessage": { ... },\n "presentationMessage": { ... },\n}\n'))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "protocolVersion": "v1"\n}\n')))),(0,o.kt)("h3",{id:"migrate-connection-record-properties"},"Migrate Connection Record properties"),(0,o.kt)("p",null,"The recently introduced ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionType")," tag has been pluralized to reflect the fact that more than a single connection type can be defined for a given connection. Also, it is now available as a direct record property (e.g. can be queried and set by using ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionRecord.connectionTypes"),") apart from the tag for efficient search."),(0,o.kt)("p",null,"The migration script renames ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionType")," to ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionTypes")," in all connections, and also searches for any mediation connection and adds ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionType.Mediator")," as one of its types."),(0,o.kt)("h3",{id:"migrate-did-record-properties"},"Migrate Did Record properties"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"didRecord.id")," was previously the did itself. However to allow for connecting with self, where multiple did records are created for the same did, the id property is now an uuid and a separate did property is added."),(0,o.kt)("p",null,"The migration script generates a new ID for each did record and stores its did into didRecord.did property."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": "did"\n}\n'))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": "uuid",\n "did": "did"\n}\n')))))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/30ebf81b.cc59b5ec.js b/assets/js/30ebf81b.e9ce7f8e.js similarity index 62% rename from assets/js/30ebf81b.cc59b5ec.js rename to assets/js/30ebf81b.e9ce7f8e.js index 9142e493..3378b59b 100644 --- a/assets/js/30ebf81b.cc59b5ec.js +++ b/assets/js/30ebf81b.e9ce7f8e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[1912],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),p=u(r),m=a,f=p["".concat(s,".").concat(m)]||p[m]||d[m]||o;return r?n.createElement(f,l(l({ref:t},c),{},{components:r})):n.createElement(f,l({ref:t},c))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=m;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[p]="string"==typeof e?e:a,l[1]=i;for(var u=2;u{r.d(t,{Z:()=>l});var n=r(7294),a=r(6010);const o={tabItem:"tabItem_Ymn6"};function l(e){let{children:t,hidden:r,className:l}=e;return n.createElement("div",{role:"tabpanel",className:(0,a.Z)(o.tabItem,l),hidden:r},t)}},4866:(e,t,r)=>{r.d(t,{Z:()=>w});var n=r(7462),a=r(7294),o=r(6010),l=r(2466),i=r(6550),s=r(1980),u=r(7392),c=r(12);function p(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:r,attributes:n,default:a}}=e;return{value:t,label:r,attributes:n,default:a}}))}function d(e){const{values:t,children:r}=e;return(0,a.useMemo)((()=>{const e=t??p(r);return function(e){const t=(0,u.l)(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,r])}function m(e){let{value:t,tabValues:r}=e;return r.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:r}=e;const n=(0,i.k6)(),o=function(e){let{queryString:t=!1,groupId:r}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!r)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 r??null}({queryString:t,groupId:r});return[(0,s._X)(o),(0,a.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(n.location.search);t.set(o,e),n.replace({...n.location,search:t.toString()})}),[o,n])]}function h(e){const{defaultValue:t,queryString:r=!1,groupId:n}=e,o=d(e),[l,i]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:r}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=r.find((e=>e.default))??r[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:o}))),[s,u]=f({queryString:r,groupId:n}),[p,h]=function(e){let{groupId:t}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,o]=(0,c.Nk)(r);return[n,(0,a.useCallback)((e=>{r&&o.set(e)}),[r,o])]}({groupId:n}),b=(()=>{const e=s??p;return m({value:e,tabValues:o})?e:null})();(0,a.useLayoutEffect)((()=>{b&&i(b)}),[b]);return{selectedValue:l,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);i(e),u(e),h(e)}),[u,h,o]),tabValues:o}}var b=r(2389);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function g(e){let{className:t,block:r,selectedValue:i,selectValue:s,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,l.o5)(),d=e=>{const t=e.currentTarget,r=c.indexOf(t),n=u[r].value;n!==i&&(p(t),s(n))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const r=c.indexOf(e.currentTarget)+1;t=c[r]??c[0];break}case"ArrowLeft":{const r=c.indexOf(e.currentTarget)-1;t=c[r]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":r},t)},u.map((e=>{let{value:t,label:r,attributes:l}=e;return a.createElement("li",(0,n.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},l,{className:(0,o.Z)("tabs__item",v.tabItem,l?.className,{"tabs__item--active":i===t})}),r??t)})))}function k(e){let{lazy:t,children:r,selectedValue:n}=e;if(r=Array.isArray(r)?r:[r],t){const e=r.find((e=>e.props.value===n));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},r.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==n}))))}function y(e){const t=h(e);return a.createElement("div",{className:(0,o.Z)("tabs-container",v.tabList)},a.createElement(g,(0,n.Z)({},e,t)),a.createElement(k,(0,n.Z)({},e,t)))}function w(e){const t=(0,b.Z)();return a.createElement(y,(0,n.Z)({key:String(t)},e))}},2286:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>f,frontMatter:()=>i,metadata:()=>u,toc:()=>p});var n=r(7462),a=(r(7294),r(3905)),o=r(4866),l=r(5162);const i={},s="Prerequisites",u={unversionedId:"getting-started/prerequisites",id:"version-0.4/getting-started/prerequisites",title:"Prerequisites",description:"To work with Aries Framework JavaScript we need to install some dependencies and set-up our Node.JS environment. Even when creating a mobile app in React Native, we need Node.JS installed. We will go over the specific installation process for each platform. Go ahead and pick your system of choice to get started!",source:"@site/versioned_docs/version-0.4/getting-started/prerequisites.md",sourceDirName:"getting-started",slug:"/getting-started/prerequisites",permalink:"/guides/getting-started/prerequisites",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Getting started",permalink:"/guides/getting-started/"},next:{title:"Agent Setup",permalink:"/guides/getting-started/set-up/"}},c={},p=[{value:"Node.JS",id:"nodejs",level:3},{value:"Windows",id:"windows",level:4},{value:"macOS",id:"macos",level:4},{value:"Linux",id:"linux",level:4},{value:"Arch Linux",id:"arch-linux",level:5},{value:"Debian",id:"debian",level:5},{value:"Red Hat",id:"red-hat",level:5},{value:"NPM",id:"npm",level:3},{value:"Yarn",id:"yarn",level:3},{value:"Project Setup",id:"project-setup",level:3}],d={toc:p},m="wrapper";function f(e){let{components:t,...r}=e;return(0,a.kt)(m,(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"prerequisites"},"Prerequisites"),(0,a.kt)("p",null,"To work with ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript"},"Aries Framework JavaScript")," we need to install some dependencies and set-up our Node.JS environment. Even when creating a mobile app in React Native, we need Node.JS installed. We will go over the specific installation process for each platform. Go ahead and pick your system of choice to get started!"),(0,a.kt)("p",null,"The specific items that we set-up:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://nodejs.org"},"Node.JS")," - v16 or v18"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://classic.yarnpkg.com/lang/en/docs/install"},"yarn")," or ",(0,a.kt)("a",{parentName:"li",href:"https://www.npmjs.com/"},"npm")),(0,a.kt)("li",{parentName:"ul"},"Node.JS or React Native project.")),(0,a.kt)("h3",{id:"nodejs"},"Node.JS"),(0,a.kt)("p",null,"NodeJS is the most popular JavaScript runtime environment excluding browsers. It can run on your desktop or even a server."),(0,a.kt)(o.Z,{mdxType:"Tabs"},(0,a.kt)(l.Z,{label:"Windows",value:"tab1",mdxType:"TabItem"},(0,a.kt)("p",null,"You can download it from the ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.org/en/download/"},"Node.JS Website"))),(0,a.kt)(l.Z,{label:"macOS",value:"tab2",mdxType:"TabItem"},(0,a.kt)("p",null,"Make sure you have ",(0,a.kt)("a",{parentName:"p",href:"https://brew.sh/"},"Homebrew")," installed. If not you can install it with the following command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n')),(0,a.kt)("p",null,"Then install Node.JS with the following command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"brew install nodejs\n")),(0,a.kt)("p",null,"Alternatively, you can download it from the ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.org/en/download/"},"Node.JS Website"))),(0,a.kt)(l.Z,{label:"Linux",value:"tab3",mdxType:"TabItem"},(0,a.kt)("p",null,"Either follow one of the specific steps for installing Node.JS on linux below, or you can download it directly from the ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.org/en/download/"},"Node.JS Website")),(0,a.kt)("h5",{id:"arch-linux"},"Arch Linux"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"pacman -S nodejs npm\n")),(0,a.kt)("h5",{id:"debian"},"Debian"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"curl -fsSL https://deb.nodesource.com/setup_18.x | bash -\napt-get install -y nodejs\n")),(0,a.kt)("h5",{id:"red-hat"},"Red Hat"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"curl -sL https://rpm.nodesource.com/setup_18.x | bash -\nyum install nodejs\n")))),(0,a.kt)("h3",{id:"npm"},"NPM"),(0,a.kt)("p",null,"The Node Package Manager comes pre-bundled with the NodeJS installation from above."),(0,a.kt)("h3",{id:"yarn"},"Yarn"),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"Only required when not using npm")),(0,a.kt)("p",null,"For every platform, the installation of yarn is the same."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"npm install --global yarn\n")),(0,a.kt)("h3",{id:"project-setup"},"Project Setup"),(0,a.kt)("p",null,"Finally, you need to make sure you have a project set-up using Node.JS or React Native. If you're not familiar with setting up a project, we suggest following the ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.dev/en/learn/"},"Introduction to Node.JS")," or ",(0,a.kt)("a",{parentName:"p",href:"https://reactnative.dev/docs/environment-setup"},"React Native Quickstart")," guides."))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[1912],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),p=u(r),m=a,f=p["".concat(s,".").concat(m)]||p[m]||d[m]||o;return r?n.createElement(f,l(l({ref:t},c),{},{components:r})):n.createElement(f,l({ref:t},c))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=m;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[p]="string"==typeof e?e:a,l[1]=i;for(var u=2;u{r.d(t,{Z:()=>l});var n=r(7294),a=r(6010);const o={tabItem:"tabItem_Ymn6"};function l(e){let{children:t,hidden:r,className:l}=e;return n.createElement("div",{role:"tabpanel",className:(0,a.Z)(o.tabItem,l),hidden:r},t)}},4866:(e,t,r)=>{r.d(t,{Z:()=>w});var n=r(7462),a=r(7294),o=r(6010),l=r(2466),i=r(6550),s=r(1980),u=r(7392),c=r(12);function p(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:r,attributes:n,default:a}}=e;return{value:t,label:r,attributes:n,default:a}}))}function d(e){const{values:t,children:r}=e;return(0,a.useMemo)((()=>{const e=t??p(r);return function(e){const t=(0,u.l)(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,r])}function m(e){let{value:t,tabValues:r}=e;return r.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:r}=e;const n=(0,i.k6)(),o=function(e){let{queryString:t=!1,groupId:r}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!r)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 r??null}({queryString:t,groupId:r});return[(0,s._X)(o),(0,a.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(n.location.search);t.set(o,e),n.replace({...n.location,search:t.toString()})}),[o,n])]}function h(e){const{defaultValue:t,queryString:r=!1,groupId:n}=e,o=d(e),[l,i]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:r}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=r.find((e=>e.default))??r[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:o}))),[s,u]=f({queryString:r,groupId:n}),[p,h]=function(e){let{groupId:t}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,o]=(0,c.Nk)(r);return[n,(0,a.useCallback)((e=>{r&&o.set(e)}),[r,o])]}({groupId:n}),b=(()=>{const e=s??p;return m({value:e,tabValues:o})?e:null})();(0,a.useLayoutEffect)((()=>{b&&i(b)}),[b]);return{selectedValue:l,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);i(e),u(e),h(e)}),[u,h,o]),tabValues:o}}var b=r(2389);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function g(e){let{className:t,block:r,selectedValue:i,selectValue:s,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,l.o5)(),d=e=>{const t=e.currentTarget,r=c.indexOf(t),n=u[r].value;n!==i&&(p(t),s(n))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const r=c.indexOf(e.currentTarget)+1;t=c[r]??c[0];break}case"ArrowLeft":{const r=c.indexOf(e.currentTarget)-1;t=c[r]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":r},t)},u.map((e=>{let{value:t,label:r,attributes:l}=e;return a.createElement("li",(0,n.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},l,{className:(0,o.Z)("tabs__item",v.tabItem,l?.className,{"tabs__item--active":i===t})}),r??t)})))}function k(e){let{lazy:t,children:r,selectedValue:n}=e;if(r=Array.isArray(r)?r:[r],t){const e=r.find((e=>e.props.value===n));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},r.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==n}))))}function y(e){const t=h(e);return a.createElement("div",{className:(0,o.Z)("tabs-container",v.tabList)},a.createElement(g,(0,n.Z)({},e,t)),a.createElement(k,(0,n.Z)({},e,t)))}function w(e){const t=(0,b.Z)();return a.createElement(y,(0,n.Z)({key:String(t)},e))}},2286:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>f,frontMatter:()=>i,metadata:()=>u,toc:()=>p});var n=r(7462),a=(r(7294),r(3905)),o=r(4866),l=r(5162);const i={},s="Prerequisites",u={unversionedId:"getting-started/prerequisites",id:"version-0.4/getting-started/prerequisites",title:"Prerequisites",description:"To work with Aries Framework JavaScript we need to install some dependencies and set-up our Node.JS environment. Even when creating a mobile app in React Native, we need Node.JS installed. We will go over the specific installation process for each platform. Go ahead and pick your system of choice to get started!",source:"@site/versioned_docs/version-0.4/getting-started/prerequisites.md",sourceDirName:"getting-started",slug:"/getting-started/prerequisites",permalink:"/guides/0.4/getting-started/prerequisites",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Getting started",permalink:"/guides/0.4/getting-started/"},next:{title:"Agent Setup",permalink:"/guides/0.4/getting-started/set-up/"}},c={},p=[{value:"Node.JS",id:"nodejs",level:3},{value:"Windows",id:"windows",level:4},{value:"macOS",id:"macos",level:4},{value:"Linux",id:"linux",level:4},{value:"Arch Linux",id:"arch-linux",level:5},{value:"Debian",id:"debian",level:5},{value:"Red Hat",id:"red-hat",level:5},{value:"NPM",id:"npm",level:3},{value:"Yarn",id:"yarn",level:3},{value:"Project Setup",id:"project-setup",level:3}],d={toc:p},m="wrapper";function f(e){let{components:t,...r}=e;return(0,a.kt)(m,(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"prerequisites"},"Prerequisites"),(0,a.kt)("p",null,"To work with ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript"},"Aries Framework JavaScript")," we need to install some dependencies and set-up our Node.JS environment. Even when creating a mobile app in React Native, we need Node.JS installed. We will go over the specific installation process for each platform. Go ahead and pick your system of choice to get started!"),(0,a.kt)("p",null,"The specific items that we set-up:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://nodejs.org"},"Node.JS")," - v16 or v18"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://classic.yarnpkg.com/lang/en/docs/install"},"yarn")," or ",(0,a.kt)("a",{parentName:"li",href:"https://www.npmjs.com/"},"npm")),(0,a.kt)("li",{parentName:"ul"},"Node.JS or React Native project.")),(0,a.kt)("h3",{id:"nodejs"},"Node.JS"),(0,a.kt)("p",null,"NodeJS is the most popular JavaScript runtime environment excluding browsers. It can run on your desktop or even a server."),(0,a.kt)(o.Z,{mdxType:"Tabs"},(0,a.kt)(l.Z,{label:"Windows",value:"tab1",mdxType:"TabItem"},(0,a.kt)("p",null,"You can download it from the ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.org/en/download/"},"Node.JS Website"))),(0,a.kt)(l.Z,{label:"macOS",value:"tab2",mdxType:"TabItem"},(0,a.kt)("p",null,"Make sure you have ",(0,a.kt)("a",{parentName:"p",href:"https://brew.sh/"},"Homebrew")," installed. If not you can install it with the following command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n')),(0,a.kt)("p",null,"Then install Node.JS with the following command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"brew install nodejs\n")),(0,a.kt)("p",null,"Alternatively, you can download it from the ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.org/en/download/"},"Node.JS Website"))),(0,a.kt)(l.Z,{label:"Linux",value:"tab3",mdxType:"TabItem"},(0,a.kt)("p",null,"Either follow one of the specific steps for installing Node.JS on linux below, or you can download it directly from the ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.org/en/download/"},"Node.JS Website")),(0,a.kt)("h5",{id:"arch-linux"},"Arch Linux"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"pacman -S nodejs npm\n")),(0,a.kt)("h5",{id:"debian"},"Debian"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"curl -fsSL https://deb.nodesource.com/setup_18.x | bash -\napt-get install -y nodejs\n")),(0,a.kt)("h5",{id:"red-hat"},"Red Hat"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"curl -sL https://rpm.nodesource.com/setup_18.x | bash -\nyum install nodejs\n")))),(0,a.kt)("h3",{id:"npm"},"NPM"),(0,a.kt)("p",null,"The Node Package Manager comes pre-bundled with the NodeJS installation from above."),(0,a.kt)("h3",{id:"yarn"},"Yarn"),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"Only required when not using npm")),(0,a.kt)("p",null,"For every platform, the installation of yarn is the same."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"npm install --global yarn\n")),(0,a.kt)("h3",{id:"project-setup"},"Project Setup"),(0,a.kt)("p",null,"Finally, you need to make sure you have a project set-up using Node.JS or React Native. If you're not familiar with setting up a project, we suggest following the ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.dev/en/learn/"},"Introduction to Node.JS")," or ",(0,a.kt)("a",{parentName:"p",href:"https://reactnative.dev/docs/environment-setup"},"React Native Quickstart")," guides."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/32456564.74f902ca.js b/assets/js/32456564.74f902ca.js deleted file mode 100644 index 6eb6a67b..00000000 --- a/assets/js/32456564.74f902ca.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8937],{3905:(t,e,a)=>{a.d(e,{Zo:()=>p,kt:()=>h});var n=a(7294);function i(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function s(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function r(t){for(var e=1;e=0||(i[a]=t[a]);return i}(t,e);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(i[a]=t[a])}return i}var l=n.createContext({}),u=function(t){var e=n.useContext(l),a=e;return t&&(a="function"==typeof t?t(e):r(r({},e),t)),a},p=function(t){var e=u(t.components);return n.createElement(l.Provider,{value:e},t.children)},d="mdxType",g={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},c=n.forwardRef((function(t,e){var a=t.components,i=t.mdxType,s=t.originalType,l=t.parentName,p=o(t,["components","mdxType","originalType","parentName"]),d=u(a),c=i,h=d["".concat(l,".").concat(c)]||d[c]||g[c]||s;return a?n.createElement(h,r(r({ref:e},p),{},{components:a})):n.createElement(h,r({ref:e},p))}));function h(t,e){var a=arguments,i=e&&e.mdxType;if("string"==typeof t||i){var s=a.length,r=new Array(s);r[0]=c;var o={};for(var l in e)hasOwnProperty.call(e,l)&&(o[l]=e[l]);o.originalType=t,o[d]="string"==typeof t?t:i,r[1]=o;for(var u=2;u{a.r(e),a.d(e,{assets:()=>l,contentTitle:()=>r,default:()=>g,frontMatter:()=>s,metadata:()=>o,toc:()=>u});var n=a(7462),i=(a(7294),a(3905));const s={},r="Update Assistant",o={unversionedId:"updating/update-assistant",id:"updating/update-assistant",title:"Update Assistant",description:"The Update Assistant helps you update the storage objects from Credo to newer versions. This documents describes the different ways you can leverage the Update Assistant from fully managed to more manual approaches.",source:"@site/guides/updating/update-assistant.md",sourceDirName:"updating",slug:"/updating/update-assistant",permalink:"/guides/0.5/updating/update-assistant",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Updating Credo",permalink:"/guides/0.5/updating/"},next:{title:"Migrating from an Indy SDK Wallet to Aries Askar",permalink:"/guides/0.5/updating/update-indy-sdk-to-askar"}},l={},u=[{value:"Update Strategies",id:"update-strategies",level:2},{value:"Manually instantiating the update assistant on agent startup",id:"manually-instantiating-the-update-assistant-on-agent-startup",level:3},{value:"Storing the agent storage version outside of the agent storage",id:"storing-the-agent-storage-version-outside-of-the-agent-storage",level:3},{value:"Automatically update on agent startup",id:"automatically-update-on-agent-startup",level:3},{value:"Backups",id:"backups",level:2}],p={toc:u},d="wrapper";function g(t){let{components:e,...a}=t;return(0,i.kt)(d,(0,n.Z)({},p,a,{components:e,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"update-assistant"},"Update Assistant"),(0,i.kt)("p",null,"The Update Assistant helps you update the storage objects from Credo to newer versions. This documents describes the different ways you can leverage the Update Assistant from fully managed to more manual approaches."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#update-strategies"},"Update Strategies"),(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#manually-instantiating-the-update-assistant-on-agent-startup"},"Manually instantiating the update assistant on agent startup")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#storing-the-agent-storage-version-outside-of-the-agent-storage"},"Storing the agent storage version outside of the agent storage")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#automatically-update-on-agent-startup"},"Automatically update on agent startup")))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#backups"},"Backups"))),(0,i.kt)("h2",{id:"update-strategies"},"Update Strategies"),(0,i.kt)("p",null,"There are three options on how to leverage the update assistant on agent startup:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Manually instantiating the update assistant on agent startup"),(0,i.kt)("li",{parentName:"ol"},"Storing the agent storage version outside of the agent storage"),(0,i.kt)("li",{parentName:"ol"},"Automatically update on agent startup")),(0,i.kt)("h3",{id:"manually-instantiating-the-update-assistant-on-agent-startup"},"Manually instantiating the update assistant on agent startup"),(0,i.kt)("p",null,"When the version of the storage is stored inside the agent storage, it means we need to check if the agent needs to be updated on every agent startup. We'll initialize the update assistant and check whether the storage is up to date. The advantage of this approach is that you don't have to store anything yourself, and have full control over the workflow."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts"},"import { UpdateAssistant, Agent } from '@credo-ts/core'\n\n// or @credo-ts/node\nimport { agentDependencies } from '@credo-ts/react-native'\n\n// First create the agent\nconst agent = new Agent({\n config,\n dependencies: agentDependencies,\n})\n\n// Then initialize the update assistant with the update config\nconst updateAssistant = new UpdateAssistant(agent, {\n v0_1ToV0_2: {\n mediationRoleUpdateStrategy: 'allMediator',\n },\n})\n\n// Initialize the update assistant so we can read the current storage version\n// from the wallet. If you manually initialize the wallet you should do this _before_\n// calling initialize on the update assistant\n// await agent.wallet.initialize(walletConfig)\nawait updateAssistant.initialize()\n\n// Check if the agent is up to date, if not call update\nif (!(await updateAssistant.isUpToDate())) {\n await updateAssistant.update()\n}\n\n// Once finished initialize the agent. You should do this on every launch of the agent\nawait agent.initialize()\n")),(0,i.kt)("h3",{id:"storing-the-agent-storage-version-outside-of-the-agent-storage"},"Storing the agent storage version outside of the agent storage"),(0,i.kt)("p",null,"When the version of the storage is stored outside of the agent storage, you don't have to initialize the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," on every agent agent startup. You can just check if the storage version is up to date and instantiate the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," if not. The advantage of this approach is that you don't have to instantiate the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," on every agent startup, but this does mean that you have to store the storage version yourself."),(0,i.kt)("p",null,"When a wallet has been exported and later imported you don't always have the latest version available. If this is the case you can always rely on Method 1 or 2 for updating the wallet, and storing the version yourself afterwards. You can also get the current version by calling ",(0,i.kt)("inlineCode",{parentName:"p"},"await updateAssistant.getCurrentAgentStorageVersion()"),". Do note the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," needs to be initialized before calling this method."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts"},"import { UpdateAssistant, Agent } from '@credo-ts/core'\n\n// or @credo-ts/node\nimport { agentDependencies } from '@credo-ts/react-native'\n\n// The storage version will normally be stored in e.g. persistent storage on a mobile device\nlet currentStorageVersion: VersionString = '0.1'\n\n// First create the agent\nconst agent = new Agent({\n config,\n dependencies: agentDependencies,\n})\n\n// We only initialize the update assistant if our stored version is not equal\n// to the frameworkStorageVersion of the UpdateAssistant. The advantage of this\n// is that we don't have to initialize the UpdateAssistant to retrieve the current\n// storage version.\nif (currentStorageVersion !== UpdateAssistant.frameworkStorageVersion) {\n const updateAssistant = new UpdateAssistant(agent, {\n v0_1ToV0_2: {\n mediationRoleUpdateStrategy: 'recipientIfEndpoint',\n },\n })\n\n // Same as with the previous strategy, if you normally call agent.wallet.initialize() manually\n // you need to call this before calling updateAssistant.initialize()\n await updateAssistant.initialize()\n\n await updateAssistant.update()\n\n // Store the version so we can leverage it during the next agent startup and don't have\n // to initialize the update assistant again until a new version is released\n currentStorageVersion = UpdateAssistant.frameworkStorageVersion\n}\n\n// Once finished initialize the agent. You should do this on every launch of the agent\nawait agent.initialize()\n")),(0,i.kt)("h3",{id:"automatically-update-on-agent-startup"},"Automatically update on agent startup"),(0,i.kt)("p",null,"This is by far the easiest way to update the agent, but has the least amount of flexibility and is not configurable. This means you will have to use the default update options to update the agent storage. You can find the default update config in the respective version migration guides (e.g. in ",(0,i.kt)("a",{parentName:"p",href:"/guides/0.5/updating/versions/0.1-to-0.2"},"0.1-to-0.2"),")."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts"},"import { UpdateAssistant, Agent } from '@credo-ts/core'\n\n// or @credo-ts/node\nimport { agentDependencies } from '@credo-ts/react-native'\n\n// First create the agent, setting the autoUpdateStorageOnStartup option to true\nconst agent = new Agent({\n config: {\n ...config,\n autoUpdateStorageOnStartup: true,\n },\n dependencies: agentDependencies,\n})\n\n// Then we call initialize, which under the hood will call the update assistant if the storage is not update to date.\nawait agent.initialize()\n")),(0,i.kt)("h2",{id:"backups"},"Backups"),(0,i.kt)("p",null,"Before starting the update, the update assistant will automatically create a backup of the wallet. If the migration succeeds the backup won't be used. If the backup fails, another backup will be made of the migrated wallet, after which the backup will be restored."),(0,i.kt)("p",null,"The backups can be found at the following locations. The ",(0,i.kt)("inlineCode",{parentName:"p"},"backupIdentifier")," is generated at the start of the update process and generated based on the current timestamp."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Backup path: ",(0,i.kt)("inlineCode",{parentName:"li"},"${agent.config.fileSystem.basePath}/afj/migration/backup/${backupIdentifier}")),(0,i.kt)("li",{parentName:"ul"},"Migration backup: ",(0,i.kt)("inlineCode",{parentName:"li"},"${agent.config.fileSystem.basePath}/afj/migration/backup/${backupIdentifier}-error"))),(0,i.kt)("blockquote",null,(0,i.kt)("p",{parentName:"blockquote"},"In the future the backup assistant will make a number of improvements to the recovery process. Namely:"),(0,i.kt)("ul",{parentName:"blockquote"},(0,i.kt)("li",{parentName:"ul"},"Do not throw an error if the update fails, but rather return an object that contains the status, and include the backup paths and backup identifiers."))))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/32456564.eadba1f4.js b/assets/js/32456564.eadba1f4.js new file mode 100644 index 00000000..d4b8682e --- /dev/null +++ b/assets/js/32456564.eadba1f4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8937],{3905:(t,e,a)=>{a.d(e,{Zo:()=>p,kt:()=>h});var n=a(7294);function i(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function s(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function r(t){for(var e=1;e=0||(i[a]=t[a]);return i}(t,e);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(i[a]=t[a])}return i}var l=n.createContext({}),u=function(t){var e=n.useContext(l),a=e;return t&&(a="function"==typeof t?t(e):r(r({},e),t)),a},p=function(t){var e=u(t.components);return n.createElement(l.Provider,{value:e},t.children)},d="mdxType",g={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},c=n.forwardRef((function(t,e){var a=t.components,i=t.mdxType,s=t.originalType,l=t.parentName,p=o(t,["components","mdxType","originalType","parentName"]),d=u(a),c=i,h=d["".concat(l,".").concat(c)]||d[c]||g[c]||s;return a?n.createElement(h,r(r({ref:e},p),{},{components:a})):n.createElement(h,r({ref:e},p))}));function h(t,e){var a=arguments,i=e&&e.mdxType;if("string"==typeof t||i){var s=a.length,r=new Array(s);r[0]=c;var o={};for(var l in e)hasOwnProperty.call(e,l)&&(o[l]=e[l]);o.originalType=t,o[d]="string"==typeof t?t:i,r[1]=o;for(var u=2;u{a.r(e),a.d(e,{assets:()=>l,contentTitle:()=>r,default:()=>g,frontMatter:()=>s,metadata:()=>o,toc:()=>u});var n=a(7462),i=(a(7294),a(3905));const s={},r="Update Assistant",o={unversionedId:"updating/update-assistant",id:"updating/update-assistant",title:"Update Assistant",description:"The Update Assistant helps you update the storage objects from Credo to newer versions. This documents describes the different ways you can leverage the Update Assistant from fully managed to more manual approaches.",source:"@site/guides/updating/update-assistant.md",sourceDirName:"updating",slug:"/updating/update-assistant",permalink:"/guides/updating/update-assistant",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Updating Credo",permalink:"/guides/updating/"},next:{title:"Migrating from an Indy SDK Wallet to Aries Askar",permalink:"/guides/updating/update-indy-sdk-to-askar"}},l={},u=[{value:"Update Strategies",id:"update-strategies",level:2},{value:"Manually instantiating the update assistant on agent startup",id:"manually-instantiating-the-update-assistant-on-agent-startup",level:3},{value:"Storing the agent storage version outside of the agent storage",id:"storing-the-agent-storage-version-outside-of-the-agent-storage",level:3},{value:"Automatically update on agent startup",id:"automatically-update-on-agent-startup",level:3},{value:"Backups",id:"backups",level:2}],p={toc:u},d="wrapper";function g(t){let{components:e,...a}=t;return(0,i.kt)(d,(0,n.Z)({},p,a,{components:e,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"update-assistant"},"Update Assistant"),(0,i.kt)("p",null,"The Update Assistant helps you update the storage objects from Credo to newer versions. This documents describes the different ways you can leverage the Update Assistant from fully managed to more manual approaches."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#update-strategies"},"Update Strategies"),(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#manually-instantiating-the-update-assistant-on-agent-startup"},"Manually instantiating the update assistant on agent startup")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#storing-the-agent-storage-version-outside-of-the-agent-storage"},"Storing the agent storage version outside of the agent storage")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#automatically-update-on-agent-startup"},"Automatically update on agent startup")))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#backups"},"Backups"))),(0,i.kt)("h2",{id:"update-strategies"},"Update Strategies"),(0,i.kt)("p",null,"There are three options on how to leverage the update assistant on agent startup:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Manually instantiating the update assistant on agent startup"),(0,i.kt)("li",{parentName:"ol"},"Storing the agent storage version outside of the agent storage"),(0,i.kt)("li",{parentName:"ol"},"Automatically update on agent startup")),(0,i.kt)("h3",{id:"manually-instantiating-the-update-assistant-on-agent-startup"},"Manually instantiating the update assistant on agent startup"),(0,i.kt)("p",null,"When the version of the storage is stored inside the agent storage, it means we need to check if the agent needs to be updated on every agent startup. We'll initialize the update assistant and check whether the storage is up to date. The advantage of this approach is that you don't have to store anything yourself, and have full control over the workflow."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts"},"import { UpdateAssistant, Agent } from '@credo-ts/core'\n\n// or @credo-ts/node\nimport { agentDependencies } from '@credo-ts/react-native'\n\n// First create the agent\nconst agent = new Agent({\n config,\n dependencies: agentDependencies,\n})\n\n// Then initialize the update assistant with the update config\nconst updateAssistant = new UpdateAssistant(agent, {\n v0_1ToV0_2: {\n mediationRoleUpdateStrategy: 'allMediator',\n },\n})\n\n// Initialize the update assistant so we can read the current storage version\n// from the wallet. If you manually initialize the wallet you should do this _before_\n// calling initialize on the update assistant\n// await agent.wallet.initialize(walletConfig)\nawait updateAssistant.initialize()\n\n// Check if the agent is up to date, if not call update\nif (!(await updateAssistant.isUpToDate())) {\n await updateAssistant.update()\n}\n\n// Once finished initialize the agent. You should do this on every launch of the agent\nawait agent.initialize()\n")),(0,i.kt)("h3",{id:"storing-the-agent-storage-version-outside-of-the-agent-storage"},"Storing the agent storage version outside of the agent storage"),(0,i.kt)("p",null,"When the version of the storage is stored outside of the agent storage, you don't have to initialize the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," on every agent agent startup. You can just check if the storage version is up to date and instantiate the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," if not. The advantage of this approach is that you don't have to instantiate the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," on every agent startup, but this does mean that you have to store the storage version yourself."),(0,i.kt)("p",null,"When a wallet has been exported and later imported you don't always have the latest version available. If this is the case you can always rely on Method 1 or 2 for updating the wallet, and storing the version yourself afterwards. You can also get the current version by calling ",(0,i.kt)("inlineCode",{parentName:"p"},"await updateAssistant.getCurrentAgentStorageVersion()"),". Do note the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," needs to be initialized before calling this method."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts"},"import { UpdateAssistant, Agent } from '@credo-ts/core'\n\n// or @credo-ts/node\nimport { agentDependencies } from '@credo-ts/react-native'\n\n// The storage version will normally be stored in e.g. persistent storage on a mobile device\nlet currentStorageVersion: VersionString = '0.1'\n\n// First create the agent\nconst agent = new Agent({\n config,\n dependencies: agentDependencies,\n})\n\n// We only initialize the update assistant if our stored version is not equal\n// to the frameworkStorageVersion of the UpdateAssistant. The advantage of this\n// is that we don't have to initialize the UpdateAssistant to retrieve the current\n// storage version.\nif (currentStorageVersion !== UpdateAssistant.frameworkStorageVersion) {\n const updateAssistant = new UpdateAssistant(agent, {\n v0_1ToV0_2: {\n mediationRoleUpdateStrategy: 'recipientIfEndpoint',\n },\n })\n\n // Same as with the previous strategy, if you normally call agent.wallet.initialize() manually\n // you need to call this before calling updateAssistant.initialize()\n await updateAssistant.initialize()\n\n await updateAssistant.update()\n\n // Store the version so we can leverage it during the next agent startup and don't have\n // to initialize the update assistant again until a new version is released\n currentStorageVersion = UpdateAssistant.frameworkStorageVersion\n}\n\n// Once finished initialize the agent. You should do this on every launch of the agent\nawait agent.initialize()\n")),(0,i.kt)("h3",{id:"automatically-update-on-agent-startup"},"Automatically update on agent startup"),(0,i.kt)("p",null,"This is by far the easiest way to update the agent, but has the least amount of flexibility and is not configurable. This means you will have to use the default update options to update the agent storage. You can find the default update config in the respective version migration guides (e.g. in ",(0,i.kt)("a",{parentName:"p",href:"/guides/updating/versions/0.1-to-0.2"},"0.1-to-0.2"),")."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts"},"import { UpdateAssistant, Agent } from '@credo-ts/core'\n\n// or @credo-ts/node\nimport { agentDependencies } from '@credo-ts/react-native'\n\n// First create the agent, setting the autoUpdateStorageOnStartup option to true\nconst agent = new Agent({\n config: {\n ...config,\n autoUpdateStorageOnStartup: true,\n },\n dependencies: agentDependencies,\n})\n\n// Then we call initialize, which under the hood will call the update assistant if the storage is not update to date.\nawait agent.initialize()\n")),(0,i.kt)("h2",{id:"backups"},"Backups"),(0,i.kt)("p",null,"Before starting the update, the update assistant will automatically create a backup of the wallet. If the migration succeeds the backup won't be used. If the backup fails, another backup will be made of the migrated wallet, after which the backup will be restored."),(0,i.kt)("p",null,"The backups can be found at the following locations. The ",(0,i.kt)("inlineCode",{parentName:"p"},"backupIdentifier")," is generated at the start of the update process and generated based on the current timestamp."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Backup path: ",(0,i.kt)("inlineCode",{parentName:"li"},"${agent.config.fileSystem.basePath}/afj/migration/backup/${backupIdentifier}")),(0,i.kt)("li",{parentName:"ul"},"Migration backup: ",(0,i.kt)("inlineCode",{parentName:"li"},"${agent.config.fileSystem.basePath}/afj/migration/backup/${backupIdentifier}-error"))),(0,i.kt)("blockquote",null,(0,i.kt)("p",{parentName:"blockquote"},"In the future the backup assistant will make a number of improvements to the recovery process. Namely:"),(0,i.kt)("ul",{parentName:"blockquote"},(0,i.kt)("li",{parentName:"ul"},"Do not throw an error if the update fails, but rather return an object that contains the status, and include the backup paths and backup identifiers."))))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/331e6edf.375ff227.js b/assets/js/331e6edf.375ff227.js deleted file mode 100644 index 583cdad0..00000000 --- a/assets/js/331e6edf.375ff227.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[9196],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>h});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},d=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,c=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),u=l(n),p=a,h=u["".concat(c,".").concat(p)]||u[p]||g[p]||i;return n?r.createElement(h,o(o({ref:t},d),{},{components:n})):r.createElement(h,o({ref:t},d))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=p;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:a,o[1]=s;for(var l=2;l{n.d(t,{Z:()=>f});var r=n(7294),a=n(6010),i=n(3438),o=n(9960),s=n(3919),c=n(5999);const l={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function d(e){let{href:t,children:n}=e;return r.createElement(o.Z,{href:t,className:(0,a.Z)("card padding--lg",l.cardContainer)},n)}function u(e){let{href:t,icon:n,title:i,description:o}=e;return r.createElement(d,{href:t},r.createElement("h2",{className:(0,a.Z)("text--truncate",l.cardTitle),title:i},n," ",i),o&&r.createElement("p",{className:(0,a.Z)("text--truncate",l.cardDescription),title:o},o))}function g(e){let{item:t}=e;const n=(0,i.Wl)(t);return n?r.createElement(u,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,c.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function p(e){let{item:t}=e;const n=(0,s.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",a=(0,i.xz)(t.docId??void 0);return r.createElement(u,{href:t.href,icon:n,title:t.label,description:a?.description})}function h(e){let{item:t}=e;switch(t.type){case"link":return r.createElement(p,{item:t});case"category":return r.createElement(g,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function m(e){let{className:t}=e;const n=(0,i.jA)();return r.createElement(f,{items:n.items,className:t})}function f(e){const{items:t,className:n}=e;if(!t)return r.createElement(m,e);const o=(0,i.MN)(t);return r.createElement("section",{className:(0,a.Z)("row",n)},o.map(((e,t)=>r.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},r.createElement(h,{item:e})))))}},8856:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var r=n(7462),a=(n(7294),n(3905)),i=n(2991);const o={},s="Updating Credo",c={unversionedId:"updating/index",id:"updating/index",title:"Updating Credo",description:"This section will cover everything you need to know about updating Credo to a newer version.",source:"@site/guides/updating/index.md",sourceDirName:"updating",slug:"/updating/",permalink:"/guides/0.5/updating/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Mediation",permalink:"/guides/0.5/tutorials/mediation"},next:{title:"Update Assistant",permalink:"/guides/0.5/updating/update-assistant"}},l={},d=[{value:"Versioning",id:"versioning",level:2},{value:"Types of breaking changes",id:"types-of-breaking-changes",level:2},{value:"Breaking Code Changes",id:"breaking-code-changes",level:3},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:3},{value:"Migration Guides",id:"migration-guides",level:2}],u={toc:d},g="wrapper";function p(e){let{components:t,...n}=e;return(0,a.kt)(g,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"updating-credo"},"Updating Credo"),(0,a.kt)("p",null,"This section will cover everything you need to know about updating Credo to a newer version."),(0,a.kt)(i.Z,{mdxType:"DocCardList"}),(0,a.kt)("h2",{id:"versioning"},"Versioning"),(0,a.kt)("p",null,"Credo follows ",(0,a.kt)("a",{parentName:"p",href:"https://semver.org/"},"semantic versioning"),". This means that major version changes (",(0,a.kt)("strong",{parentName:"p"},"1"),".0.0) are considered breaking changes. When features are added this is a minor version change (0.",(0,a.kt)("strong",{parentName:"p"},"1"),".0). For bug fixes the patch version change is used (0.0.",(0,a.kt)("strong",{parentName:"p"},"1"),")."),(0,a.kt)("p",null,"While Credo is still in pre-1.0.0 version, the version change types are shifted to the right. This means a major version change is now a minor change (0.",(0,a.kt)("strong",{parentName:"p"},"1"),".0) and a minor change is now a patch change (0.0.",(0,a.kt)("strong",{parentName:"p"},"1"),"). This is done to keep the version below 1.0.0, indicating the framework is still in early development and users can expect more breaking changes that when the version has already reached 1.0.0."),(0,a.kt)("p",null,"This means if the second number in the version (0.",(0,a.kt)("strong",{parentName:"p"},"1"),".0) changes, you need to be careful with updating and always consult this page for update instructions. If only the third number changes (0.0.",(0,a.kt)("strong",{parentName:"p"},"1"),"), you can update without any issues."),(0,a.kt)("h2",{id:"types-of-breaking-changes"},"Types of breaking changes"),(0,a.kt)("p",null,"Updates to Credo bring new features and improvements to the framework. To better adapt the framework to new features we sometimes make breaking changes that will improve how Credo works. There's two parts to updates with breaking changes:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Breaking code changes"),(0,a.kt)("li",{parentName:"ol"},"Breaking storage changes")),(0,a.kt)("h3",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,a.kt)("p",null,"Breaking changes to code means changes to how you interact with Credo. This includes methods being renamed, moved to another module or extended to better integrate with new features. We'll try to cover all breaking changes in migration guides, so you know exactly what is needed to update to a new version and keep the same functionality."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"If you encounter any breaking changes that aren't mentioned in the migration docs, please open an issue in the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts-docs/issues"},"Credo Docs")," repository, or directly create a PR describing the change.")),(0,a.kt)("h3",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,a.kt)("p",null,"Breaking changes to storage are a bit more complex to deal with. While breaking changes to code only require you to update your code once, breaking changes to storage needs to be updated for every agent instance. Luckily, we've made the migration as easy as possible for you using the ",(0,a.kt)("a",{parentName:"p",href:"/guides/0.5/updating/update-assistant"},"Update Assistant"),". The Update Assistant will update all storage objects to the storage model that is expected by the newest version. If a version made changes to the storage, this will be explicitly mentioned in the migration guide. See the ",(0,a.kt)("a",{parentName:"p",href:"/guides/0.5/updating/update-assistant"},"Update Assistant")," documentation for detailed instructions on how to use the update assistant."),(0,a.kt)("h2",{id:"migration-guides"},"Migration Guides"),(0,a.kt)("p",null,"Currently the following migration guides are available:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/0.5/updating/versions/0.1-to-0.2"},"Migrating from Credo 0.1.0 to 0.2.x")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/0.5/updating/versions/0.2-to-0.3"},"Migrating from Credo 0.2.x to 0.3.x")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/0.5/updating/versions/0.3-to-0.4"},"Migrating from Credo 0.3.x to 0.4.x")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/0.5/updating/update-indy-sdk-to-askar"},"Migrating from an Indy SDK Wallet to Aries Askar"))))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/331e6edf.6d94b848.js b/assets/js/331e6edf.6d94b848.js new file mode 100644 index 00000000..ed23c661 --- /dev/null +++ b/assets/js/331e6edf.6d94b848.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[9196],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>h});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},d=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,c=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),u=l(n),p=a,h=u["".concat(c,".").concat(p)]||u[p]||g[p]||i;return n?r.createElement(h,o(o({ref:t},d),{},{components:n})):r.createElement(h,o({ref:t},d))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=p;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:a,o[1]=s;for(var l=2;l{n.d(t,{Z:()=>f});var r=n(7294),a=n(6010),i=n(3438),o=n(9960),s=n(3919),c=n(5999);const l={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function d(e){let{href:t,children:n}=e;return r.createElement(o.Z,{href:t,className:(0,a.Z)("card padding--lg",l.cardContainer)},n)}function u(e){let{href:t,icon:n,title:i,description:o}=e;return r.createElement(d,{href:t},r.createElement("h2",{className:(0,a.Z)("text--truncate",l.cardTitle),title:i},n," ",i),o&&r.createElement("p",{className:(0,a.Z)("text--truncate",l.cardDescription),title:o},o))}function g(e){let{item:t}=e;const n=(0,i.Wl)(t);return n?r.createElement(u,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,c.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function p(e){let{item:t}=e;const n=(0,s.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",a=(0,i.xz)(t.docId??void 0);return r.createElement(u,{href:t.href,icon:n,title:t.label,description:a?.description})}function h(e){let{item:t}=e;switch(t.type){case"link":return r.createElement(p,{item:t});case"category":return r.createElement(g,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function m(e){let{className:t}=e;const n=(0,i.jA)();return r.createElement(f,{items:n.items,className:t})}function f(e){const{items:t,className:n}=e;if(!t)return r.createElement(m,e);const o=(0,i.MN)(t);return r.createElement("section",{className:(0,a.Z)("row",n)},o.map(((e,t)=>r.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},r.createElement(h,{item:e})))))}},8856:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var r=n(7462),a=(n(7294),n(3905)),i=n(2991);const o={},s="Updating Credo",c={unversionedId:"updating/index",id:"updating/index",title:"Updating Credo",description:"This section will cover everything you need to know about updating Credo to a newer version.",source:"@site/guides/updating/index.md",sourceDirName:"updating",slug:"/updating/",permalink:"/guides/updating/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Mediation",permalink:"/guides/tutorials/mediation"},next:{title:"Update Assistant",permalink:"/guides/updating/update-assistant"}},l={},d=[{value:"Versioning",id:"versioning",level:2},{value:"Types of breaking changes",id:"types-of-breaking-changes",level:2},{value:"Breaking Code Changes",id:"breaking-code-changes",level:3},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:3},{value:"Migration Guides",id:"migration-guides",level:2}],u={toc:d},g="wrapper";function p(e){let{components:t,...n}=e;return(0,a.kt)(g,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"updating-credo"},"Updating Credo"),(0,a.kt)("p",null,"This section will cover everything you need to know about updating Credo to a newer version."),(0,a.kt)(i.Z,{mdxType:"DocCardList"}),(0,a.kt)("h2",{id:"versioning"},"Versioning"),(0,a.kt)("p",null,"Credo follows ",(0,a.kt)("a",{parentName:"p",href:"https://semver.org/"},"semantic versioning"),". This means that major version changes (",(0,a.kt)("strong",{parentName:"p"},"1"),".0.0) are considered breaking changes. When features are added this is a minor version change (0.",(0,a.kt)("strong",{parentName:"p"},"1"),".0). For bug fixes the patch version change is used (0.0.",(0,a.kt)("strong",{parentName:"p"},"1"),")."),(0,a.kt)("p",null,"While Credo is still in pre-1.0.0 version, the version change types are shifted to the right. This means a major version change is now a minor change (0.",(0,a.kt)("strong",{parentName:"p"},"1"),".0) and a minor change is now a patch change (0.0.",(0,a.kt)("strong",{parentName:"p"},"1"),"). This is done to keep the version below 1.0.0, indicating the framework is still in early development and users can expect more breaking changes that when the version has already reached 1.0.0."),(0,a.kt)("p",null,"This means if the second number in the version (0.",(0,a.kt)("strong",{parentName:"p"},"1"),".0) changes, you need to be careful with updating and always consult this page for update instructions. If only the third number changes (0.0.",(0,a.kt)("strong",{parentName:"p"},"1"),"), you can update without any issues."),(0,a.kt)("h2",{id:"types-of-breaking-changes"},"Types of breaking changes"),(0,a.kt)("p",null,"Updates to Credo bring new features and improvements to the framework. To better adapt the framework to new features we sometimes make breaking changes that will improve how Credo works. There's two parts to updates with breaking changes:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Breaking code changes"),(0,a.kt)("li",{parentName:"ol"},"Breaking storage changes")),(0,a.kt)("h3",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,a.kt)("p",null,"Breaking changes to code means changes to how you interact with Credo. This includes methods being renamed, moved to another module or extended to better integrate with new features. We'll try to cover all breaking changes in migration guides, so you know exactly what is needed to update to a new version and keep the same functionality."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"If you encounter any breaking changes that aren't mentioned in the migration docs, please open an issue in the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts-docs/issues"},"Credo Docs")," repository, or directly create a PR describing the change.")),(0,a.kt)("h3",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,a.kt)("p",null,"Breaking changes to storage are a bit more complex to deal with. While breaking changes to code only require you to update your code once, breaking changes to storage needs to be updated for every agent instance. Luckily, we've made the migration as easy as possible for you using the ",(0,a.kt)("a",{parentName:"p",href:"/guides/updating/update-assistant"},"Update Assistant"),". The Update Assistant will update all storage objects to the storage model that is expected by the newest version. If a version made changes to the storage, this will be explicitly mentioned in the migration guide. See the ",(0,a.kt)("a",{parentName:"p",href:"/guides/updating/update-assistant"},"Update Assistant")," documentation for detailed instructions on how to use the update assistant."),(0,a.kt)("h2",{id:"migration-guides"},"Migration Guides"),(0,a.kt)("p",null,"Currently the following migration guides are available:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/updating/versions/0.1-to-0.2"},"Migrating from Credo 0.1.0 to 0.2.x")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/updating/versions/0.2-to-0.3"},"Migrating from Credo 0.2.x to 0.3.x")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/updating/versions/0.3-to-0.4"},"Migrating from Credo 0.3.x to 0.4.x")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/updating/update-indy-sdk-to-askar"},"Migrating from an Indy SDK Wallet to Aries Askar"))))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/34eb4307.064bb15e.js b/assets/js/34eb4307.064bb15e.js deleted file mode 100644 index 80034a86..00000000 --- a/assets/js/34eb4307.064bb15e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7314],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(r),f=o,m=u["".concat(l,".").concat(f)]||u[f]||d[f]||i;return r?n.createElement(m,a(a({ref:t},p),{},{components:r})):n.createElement(m,a({ref:t},p))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=f;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const i={},a="Intro",s={unversionedId:"index",id:"version-0.4/index",title:"Intro",description:"Welcome, to the Aries JavaScript community!",source:"@site/versioned_docs/version-0.4/index.md",sourceDirName:".",slug:"/",permalink:"/guides/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",next:{title:"Getting started",permalink:"/guides/getting-started/"}},l={},c=[],p={toc:c},u="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"intro"},"Intro"),(0,o.kt)("p",null,"Welcome, to the Aries JavaScript community!"),(0,o.kt)("p",null,"There's no way around it. Working with self-sovereign identity can be difficult. Luckily this documentation's main goal is to make it easy for you. Whether you have a lot of experience building with Aries or non-Aries SSI frameworks, or have never heard of terms like Verifiable Credential, ",(0,o.kt)("a",{parentName:"p",href:"/guides/concepts/did-and-didcomm"},"DID"),", or ",(0,o.kt)("a",{parentName:"p",href:"/guides/concepts/agents"},"Agent"),". This documentation will either help you create a JavaScript based SSI solution yourself, or help you find the right resources in the community to assist you!"),(0,o.kt)("p",null,"So what is ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript"},"Hyperledger Aries Framework JavaScript"),"?"),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"Hyperledger Aries provides a shared, reusable, interoperable tool kit designed for initiatives and solutions focused on creating, transmitting and storing verifiable digital credentials."),(0,o.kt)("p",{parentName:"blockquote"},"\u2014 Hyperledger Foundation")),(0,o.kt)("p",null,"There are ",(0,o.kt)("a",{parentName:"p",href:"https://wiki.hyperledger.org/display/ARIES"},"several")," Aries frameworks that help you build solutions using verifiable credentials. This one is written in TypeScript and is specifically well suited for Multi-Platform development as it supports Node.js and React Native. We, the community, like to view it as the most accessible framework mostly because it is written in TypeScript, and our maintainers and contributors work to keep developer user experience a top priority."),(0,o.kt)("p",null,"These docs are not just for the main framework, but also all that surround it. So you'll find ",(0,o.kt)("a",{parentName:"p",href:"/guides/concepts/"},"general explanations about the concepts used"),", ",(0,o.kt)("a",{parentName:"p",href:"/guides/tutorials/"},"specific tutorials for common use cases")," and ",(0,o.kt)("a",{parentName:"p",href:"/guides/ecosystem/"},"relevant projects and related repositories"),". Most of all you'll find solid documentation with lots of code examples and an enthousiastic community that wants to build great stuff together."),(0,o.kt)("p",null,"Are you ready to get started?"))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/34eb4307.46988233.js b/assets/js/34eb4307.46988233.js new file mode 100644 index 00000000..bddd3246 --- /dev/null +++ b/assets/js/34eb4307.46988233.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7314],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(r),f=o,m=u["".concat(l,".").concat(f)]||u[f]||d[f]||i;return r?n.createElement(m,a(a({ref:t},p),{},{components:r})):n.createElement(m,a({ref:t},p))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=f;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const i={},a="Intro",s={unversionedId:"index",id:"version-0.4/index",title:"Intro",description:"Welcome, to the Aries JavaScript community!",source:"@site/versioned_docs/version-0.4/index.md",sourceDirName:".",slug:"/",permalink:"/guides/0.4/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",next:{title:"Getting started",permalink:"/guides/0.4/getting-started/"}},l={},c=[],p={toc:c},u="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"intro"},"Intro"),(0,o.kt)("p",null,"Welcome, to the Aries JavaScript community!"),(0,o.kt)("p",null,"There's no way around it. Working with self-sovereign identity can be difficult. Luckily this documentation's main goal is to make it easy for you. Whether you have a lot of experience building with Aries or non-Aries SSI frameworks, or have never heard of terms like Verifiable Credential, ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.4/concepts/did-and-didcomm"},"DID"),", or ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.4/concepts/agents"},"Agent"),". This documentation will either help you create a JavaScript based SSI solution yourself, or help you find the right resources in the community to assist you!"),(0,o.kt)("p",null,"So what is ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript"},"Hyperledger Aries Framework JavaScript"),"?"),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"Hyperledger Aries provides a shared, reusable, interoperable tool kit designed for initiatives and solutions focused on creating, transmitting and storing verifiable digital credentials."),(0,o.kt)("p",{parentName:"blockquote"},"\u2014 Hyperledger Foundation")),(0,o.kt)("p",null,"There are ",(0,o.kt)("a",{parentName:"p",href:"https://wiki.hyperledger.org/display/ARIES"},"several")," Aries frameworks that help you build solutions using verifiable credentials. This one is written in TypeScript and is specifically well suited for Multi-Platform development as it supports Node.js and React Native. We, the community, like to view it as the most accessible framework mostly because it is written in TypeScript, and our maintainers and contributors work to keep developer user experience a top priority."),(0,o.kt)("p",null,"These docs are not just for the main framework, but also all that surround it. So you'll find ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.4/concepts/"},"general explanations about the concepts used"),", ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.4/tutorials/"},"specific tutorials for common use cases")," and ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.4/ecosystem/"},"relevant projects and related repositories"),". Most of all you'll find solid documentation with lots of code examples and an enthousiastic community that wants to build great stuff together."),(0,o.kt)("p",null,"Are you ready to get started?"))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/365d3941.57d53a45.js b/assets/js/365d3941.57d53a45.js new file mode 100644 index 00000000..04487fe2 --- /dev/null +++ b/assets/js/365d3941.57d53a45.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[6347],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>g});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),d=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=d(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),c=d(n),m=o,g=c["".concat(l,".").concat(m)]||c[m]||p[m]||r;return n?a.createElement(g,s(s({ref:t},u),{},{components:n})):a.createElement(g,s({ref:t},u))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,s=new Array(r);s[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[c]="string"==typeof e?e:o,s[1]=i;for(var d=2;d{n.d(t,{Z:()=>s});var a=n(7294),o=n(6010);const r={tabItem:"tabItem_Ymn6"};function s(e){let{children:t,hidden:n,className:s}=e;return a.createElement("div",{role:"tabpanel",className:(0,o.Z)(r.tabItem,s),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),o=n(7294),r=n(6010),s=n(2466),i=n(6550),l=n(1980),d=n(7392),u=n(12);function c(e){return function(e){return o.Children.map(e,(e=>{if((0,o.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:o}}=e;return{value:t,label:n,attributes:a,default:o}}))}function p(e){const{values:t,children:n}=e;return(0,o.useMemo)((()=>{const e=t??c(n);return function(e){const t=(0,d.l)(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 m(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 a=(0,i.k6)(),r=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,l._X)(r),(0,o.useCallback)((e=>{if(!r)return;const t=new URLSearchParams(a.location.search);t.set(r,e),a.replace({...a.location,search:t.toString()})}),[r,a])]}function h(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,r=p(e),[s,i]=(0,o.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(!m({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:r}))),[l,d]=g({queryString:n,groupId:a}),[c,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,r]=(0,u.Nk)(n);return[a,(0,o.useCallback)((e=>{n&&r.set(e)}),[n,r])]}({groupId:a}),f=(()=>{const e=l??c;return m({value:e,tabValues:r})?e:null})();(0,o.useLayoutEffect)((()=>{f&&i(f)}),[f]);return{selectedValue:s,selectValue:(0,o.useCallback)((e=>{if(!m({value:e,tabValues:r}))throw new Error(`Can't select invalid tab value=${e}`);i(e),d(e),h(e)}),[d,h,r]),tabValues:r}}var f=n(2389);const k={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){let{className:t,block:n,selectedValue:i,selectValue:l,tabValues:d}=e;const u=[],{blockElementScrollPositionUntilNextRender:c}=(0,s.o5)(),p=e=>{const t=e.currentTarget,n=u.indexOf(t),a=d[n].value;a!==i&&(c(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=u.indexOf(e.currentTarget)+1;t=u[n]??u[0];break}case"ArrowLeft":{const n=u.indexOf(e.currentTarget)-1;t=u[n]??u[u.length-1];break}}t?.focus()};return o.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.Z)("tabs",{"tabs--block":n},t)},d.map((e=>{let{value:t,label:n,attributes:s}=e;return o.createElement("li",(0,a.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>u.push(e),onKeyDown:m,onClick:p},s,{className:(0,r.Z)("tabs__item",k.tabItem,s?.className,{"tabs__item--active":i===t})}),n??t)})))}function b(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,o.cloneElement)(e,{className:"margin-top--md"}):null}return o.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,o.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function v(e){const t=h(e);return o.createElement("div",{className:(0,r.Z)("tabs-container",k.tabList)},o.createElement(y,(0,a.Z)({},e,t)),o.createElement(b,(0,a.Z)({},e,t)))}function w(e){const t=(0,f.Z)();return o.createElement(v,(0,a.Z)({key:String(t)},e))}},8412:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>g,frontMatter:()=>i,metadata:()=>d,toc:()=>c});var a=n(7462),o=(n(7294),n(3905)),r=n(4866),s=n(5162);const i={},l="Migrating from Credo 0.2.x to 0.3.x",d={unversionedId:"updating/versions/0.2-to-0.3",id:"updating/versions/0.2-to-0.3",title:"Migrating from Credo 0.2.x to 0.3.x",description:"This document describes everything you need to know for updating Credo 0.2.x to 0.3.x. If you're not aware of how updating in Credo works make sure to first read the guide on Updating Credo.",source:"@site/guides/updating/versions/0.2-to-0.3.md",sourceDirName:"updating/versions",slug:"/updating/versions/0.2-to-0.3",permalink:"/guides/updating/versions/0.2-to-0.3",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Migrating from Credo 0.1.0 to 0.2.x",permalink:"/guides/updating/versions/0.1-to-0.2"},next:{title:"Migrating from Credo 0.3.x to 0.4.x",permalink:"/guides/updating/versions/0.3-to-0.4"}},u={},c=[{value:"React Native",id:"react-native",level:4},{value:"Node",id:"node",level:4},{value:"Breaking Code Changes",id:"breaking-code-changes",level:2},{value:"Agent creation",id:"agent-creation",level:3},{value:"0.2.x",id:"02x",level:5},{value:"0.3.x",id:"03x",level:5},{value:"did:key usage in protocols",id:"didkey-usage-in-protocols",level:3},{value:"Modules extracted from the core",id:"modules-extracted-from-the-core",level:3},{value:"0.2.x",id:"02x-1",level:5},{value:"0.3.x",id:"03x-1",level:5},{value:"Discover Features Module",id:"discover-features-module",level:3},{value:"0.2.x",id:"02x-2",level:5},{value:"0.3.x",id:"03x-2",level:5},{value:"0.2.x",id:"02x-3",level:5},{value:"0.3.x",id:"03x-3",level:5},{value:"Ledger Module",id:"ledger-module",level:3},{value:"Proofs Module",id:"proofs-module",level:3},{value:"Module API Updates",id:"module-api-updates",level:4},{value:"0.2.x",id:"02x-4",level:5},{value:"0.3.x",id:"03x-4",level:5},{value:"Messages Extracted from Proof Exchange Record",id:"messages-extracted-from-proof-exchange-record",level:4},{value:"0.2.x",id:"02x-5",level:5},{value:"0.3.x",id:"03x-5",level:5},{value:"Out Of Band Proofs and Credentials",id:"out-of-band-proofs-and-credentials",level:3},{value:"0.2.x",id:"02x-6",level:4},{value:"0.3.x",id:"03x-6",level:4},{value:"Updating Custom Modules to the new Plugin API",id:"updating-custom-modules-to-the-new-plugin-api",level:3},{value:"Renaming handler classes",id:"renaming-handler-classes",level:4},{value:"0.2.x",id:"02x-7",level:5},{value:"0.3.x",id:"03x-7",level:5},{value:"Using AgentContext",id:"using-agentcontext",level:4},{value:"0.2.x",id:"02x-8",level:4},{value:"0.3.x",id:"03x-8",level:4},{value:"Using OutboundMessageContext",id:"using-outboundmessagecontext",level:4},{value:"0.2.x",id:"02x-9",level:4},{value:"0.3.x",id:"03x-9",level:4},{value:"Updating module structure to register in new Plugin API",id:"updating-module-structure-to-register-in-new-plugin-api",level:4},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:2},{value:"Migrate Proof Record Properties",id:"migrate-proof-record-properties",level:3},{value:"0.2.x",id:"02x-10",level:4},{value:"0.3.x",id:"03x-10",level:4},{value:"Migrate Connection Record properties",id:"migrate-connection-record-properties",level:3},{value:"Migrate Did Record properties",id:"migrate-did-record-properties",level:3},{value:"0.2.x",id:"02x-11",level:4},{value:"0.3.x",id:"03x-11",level:4}],p={toc:c},m="wrapper";function g(e){let{components:t,...n}=e;return(0,o.kt)(m,(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"migrating-from-credo-02x-to-03x"},"Migrating from Credo 0.2.x to 0.3.x"),(0,o.kt)("p",null,"This document describes everything you need to know for updating Credo 0.2.x to 0.3.x. If you're not aware of how updating in Credo works make sure to first read the guide on ",(0,o.kt)("a",{parentName:"p",href:"/guides/updating/"},"Updating Credo"),"."),(0,o.kt)("p",null,"First of all, update you dependencies to the 0.3.x versions. This will also update the needed peer depedencnies. ",(0,o.kt)("strong",{parentName:"p"},"Extension packages are not updated with this command"),". You need to update these manually, and make sure they're up to date with the latest version of Credo."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"React Native",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/react-native@^0.3.0 @aries-framework/core@^0.3.0 indy-sdk-react-native@^0.3.0\n\n# or NPM\nnpn install @aries-framework/react-native@^0.3.0 @aries-framework/core@^0.3.0 indy-sdk-react-native@^0.3.0\n"))),(0,o.kt)(s.Z,{label:"Node",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/node@^0.3.0 @aries-framework/core@^0.3.0\n\n# or NPM\nnpm install @aries-framework/node@^0.3.0 @aries-framework/core@^0.3.0\n")))),(0,o.kt)("h2",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,o.kt)("p",null,"This section will list all breaking changes made to the public API of Credo between version 0.2.x and 0.3.0."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here (e.g. see ",(0,o.kt)("a",{parentName:"p",href:"#updating-custom-modules-to-the-new-plugin-api"},"Updating Custom Modules to the Plugin API"),"), but it is possible some breaking changes are not documented here (feel free to open PRs).")),(0,o.kt)("h3",{id:"agent-creation"},"Agent creation"),(0,o.kt)("p",null,"The agent constructor has been updated to a single ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentOptions")," object that contains the config and dependencies properties."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const agent = new Agent(agentConfig, agentDependencies)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const agent = new Agent({ config: agentConfig, dependencies: agentDependencies })\n")))),(0,o.kt)("p",null,"This object contains:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"config: Agent's initial configuration"),(0,o.kt)("li",{parentName:"ul"},"dependencies: platform-specific Agent dependencies"),(0,o.kt)("li",{parentName:"ul"},"modules: optional field for internal module configuration and custom module registration")),(0,o.kt)("p",null,"For easy migration, you can simply construct ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentOptions")," by putting current InitConfig into ",(0,o.kt)("inlineCode",{parentName:"p"},"config")," key and agentDependencies into ",(0,o.kt)("inlineCode",{parentName:"p"},"dependencies")," key."),(0,o.kt)("p",null,"Note that, if you are defining ",(0,o.kt)("inlineCode",{parentName:"p"},"indyLedgers")," configuration, you should set the indyNamespace for every ledger, as explained in ",(0,o.kt)("a",{parentName:"p",href:"/guides/tutorials/agent-config/#indyledgers"},"Agent Config tutorial"),"."),(0,o.kt)("h3",{id:"didkey-usage-in-protocols"},"did:key usage in protocols"),(0,o.kt)("p",null,"In accordance with ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/tree/b3a3942ef052039e73cd23d847f42947f8287da2/features/0360-use-did-key"},"Aries RFC 0360"),", since 0.2.5 there is a configuration parameter called ",(0,o.kt)("inlineCode",{parentName:"p"},"useDidKeyInProtocols")," which, when enabled, will encode keys in did:key instead of previous base58 format, unless the other party has started a protocol and is using base58."),(0,o.kt)("p",null,"This parameter was previously disabled by default and now it is enabled. If your agent only interacts with modern agents (e.g. Credo 0.2.5 and newer) this will not represent any issue. Otherwise it is safer to explicitly set it to ",(0,o.kt)("inlineCode",{parentName:"p"},"false"),". However, keep in mind that we expect this setting to be deprecated in the future, so we encourage you to update all your agents to use did:key."),(0,o.kt)("h3",{id:"modules-extracted-from-the-core"},"Modules extracted from the core"),(0,o.kt)("p",null,"In this release two modules were extracted from the core and published as separate, optional packages:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"actionMenu has been moved to @aries-framework/action-menu"),(0,o.kt)("li",{parentName:"ul"},"questionAnswer has been moved to @aries-framework/question-answer")),(0,o.kt)("p",null,"If you want to use them, you can integrate in an Agent instance by injecting them in constructor, as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { ActionMenuModule } from '@aries-framework/action-menu'\nimport { QuestionAnswerModule } from '@aries-framework/question-answer'\n\nconst agent = new Agent({\n config: {\n /* config */\n },\n dependencies: agentDependencies,\n modules: {\n actionMenu: new ActionMenuModule(),\n questionAnswer: new QuestionAnswerModule(),\n /* other custom modules */\n },\n})\n")),(0,o.kt)("p",null,"As they are now considered custom modules, their API can be accessed in ",(0,o.kt)("inlineCode",{parentName:"p"},"modules")," namespace, so you should add it to every call to them."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.questionAnswer.sendQuestion(connectionId, {\n question: 'Do you want to play?',\n validResponses: [{ text: 'Yes' }, { text: 'No' }],\n})\n\nawait agent.questionAnswer.sendAnswer(questionAnswerRecordId, 'Yes')\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.modules.questionAnswer.sendQuestion(connectionId, {\n question: 'Do you want to play?',\n validResponses: [{ text: 'Yes' }, { text: 'No' }],\n})\n\nawait agent.modules.questionAnswer.sendAnswer(questionAnswerRecordId, 'Yes')\n")))),(0,o.kt)("h3",{id:"discover-features-module"},"Discover Features Module"),(0,o.kt)("p",null,"This module now supports both Discover Features V1 and V2, and as it happened to other modules, ",(0,o.kt)("inlineCode",{parentName:"p"},"queryFeatures")," method parameters have been unified to a single object and requires to specify the version of Discover Features protocol to be used. Note that ",(0,o.kt)("inlineCode",{parentName:"p"},"query")," property has been replaced by the more general ",(0,o.kt)("inlineCode",{parentName:"p"},"queries")," which accepts multiple features to be search for. To convert a query to this new format you simply need to create a single-object array whose unique object whose ",(0,o.kt)("inlineCode",{parentName:"p"},"featureType")," field is 'protocol' and ",(0,o.kt)("inlineCode",{parentName:"p"},"match")," field is the query itself."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.discovery.queryFeatures(connectionId, {\n query: 'https://didcomm.org/messagepickup/2.0',\n comment: 'Detect if protocol is supported',\n})\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.discovery.queryFeatures({\n connectionId,\n protocolVersion: 'v1',\n queries: [{ featureType: 'protocol', match: 'https://didcomm.org/messagepickup/2.0' }],\n comment: 'Detect if protocol is supported',\n})\n")))),(0,o.kt)("p",null,"The convenience method ",(0,o.kt)("strong",{parentName:"p"},"isProtocolSupported")," has been replaced by the more general synchronous mode of queryFeatures, which works when awaitDisclosures in options is set. Instead of returning a boolean, it returns an object with matching features:"),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const isPickUpV2Supported = await agent.discovery.isProtocolSupported(connectionId, StatusRequestMessage)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const discloseForPickupV2 = await agent.discovery.queryFeatures({\n connectionId: connectionId,\n protocolVersion: 'v1',\n queries: [{ featureType: 'protocol', match: StatusMessage.type.protocolUri }],\n awaitDisclosures: true,\n awaitDisclosuresTimeoutMs: 7000,\n})\n\nconst isPickUpV2Supported = discloseForPickupV2.features?.length === 1\n")))),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"Discover Features module does not rely anymore on Agent ",(0,o.kt)("inlineCode",{parentName:"p"},"Dispatcher")," to determine protocol support. Instead, it uses the new Feature Registry, where any custom modules implementing protocols must register them."),(0,o.kt)("p",{parentName:"admonition"},"This procedure can be done in module's ",(0,o.kt)("inlineCode",{parentName:"p"},"register(dependencyManager, featureRegistry)"),".")),(0,o.kt)("h3",{id:"ledger-module"},"Ledger Module"),(0,o.kt)("p",null,"Apart from the aforementioned indyLedgers configuration, you should also ",(0,o.kt)("a",{parentName:"p",href:"/guides/tutorials/issue-a-credential#side-notes"},"note a slight change")," in behaviour when attempting to register credential definitions that already exists on the ledger but not in the wallet."),(0,o.kt)("h3",{id:"proofs-module"},"Proofs Module"),(0,o.kt)("h4",{id:"module-api-updates"},"Module API Updates"),(0,o.kt)("p",null,"Much in the same way as in 0.2.0 release when ",(0,o.kt)("a",{parentName:"p",href:"/guides/updating/versions/0.1-to-0.2#module-api-updates"},"Issue Credential V2 protocol")," has been added, now that Present Proof V2 is supported, we introduced changes to proofs module."),(0,o.kt)("p",null,"Basically, for all methods in the proofs module you should take the following steps to update your code:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Move all function parameters into a single object. All module methods now take a single object that contain all properties."),(0,o.kt)("li",{parentName:"ol"},"For methods that initiate proposals, requests or presentations (",(0,o.kt)("inlineCode",{parentName:"li"},"proposeProof"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"acceptProposal"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"requestProof"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"acceptPresentation"),", etc.), you should pass ",(0,o.kt)("inlineCode",{parentName:"li"},"protocolVersion: 'v1'")," to indicate we should use the v1 protocol"),(0,o.kt)("li",{parentName:"ol"},"All indy specific attributes (e.g. Presentation Preview) should be passed in the ",(0,o.kt)("inlineCode",{parentName:"li"},"proofFormats.indy")," object."),(0,o.kt)("li",{parentName:"ol"},"Some indy objects, as the preview should now be passed only as their attributes (i.e. no need of creating the object instance) and provided in the ",(0,o.kt)("inlineCode",{parentName:"li"},"proofFormats.indy")," object.")),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.proofs.proposeProof(\n 'connectionId',\n new PresentationPreview({\n attributes: [new PresentationPreviewAttribute({ name: 'key', value: 'value' })],\n predicates: [\n new PresentationPreviewPredicate({\n name: 'age',\n credentialDefinitionId,\n predicate: PredicateType.GreaterThanOrEqualTo,\n threshold: 50,\n }),\n ],\n })\n)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.proofs.proposeProof({\n connectionId: connection.id,\n protocolVersion: 'v1',\n proofFormats: {\n indy: {\n attributes: [{ name: 'key', value: 'value' }],\n predicates: [{name: 'age', credentialDefinitionId, predicate: PredicateType.GreaterThanOrEqualTo, threshold: 50, ]\n },\n },\n comment: 'Propose proof comment',\n})\n")))),(0,o.kt)("h4",{id:"messages-extracted-from-proof-exchange-record"},"Messages Extracted from Proof Exchange Record"),(0,o.kt)("p",null,"The DIDComm messages that were previously stored on the proof record, have been extracted to separate DIDComm message records. This makes it easier to work with multiple versions of the protocol internally, and keeps the proof exchange record agnostic of the protocol version. Instead of accessing the messages through the ",(0,o.kt)("inlineCode",{parentName:"p"},"proposalMessage"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"requestMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"presentationMessage")," parameters, we now expose dedicated methods on the proofs module to retrieve the message."),(0,o.kt)("p",null,"With the addition of the v2 messages, all v1 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," while v2 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V2")," (",(0,o.kt)("inlineCode",{parentName:"p"},"V1RequestPresentationMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"V2RequestPresentationMessage"),"). If you were using these messages classes throughout your codebase, update them to use the ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," prefix."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const proofRecord = await agent.proofs.getById('proofRecordId')\n\nconst proposalMessage = proofRecord.proposalMessage\nconst requestMessage = proofRecord.requestMessage\nconst presentationMessage = proofRecord.presentationMessage\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const proofRecord = await agent.proofs.getById('proofRecordId')\n\nconst proposalMessage = await agent.proofs.findProposalMessage('proofRecordId')\nconst requestMessage = await agent.proofs.findRequestMessage('proofRecordId')\nconst presentationMessage = await agent.proofs.findPresentationMessage('proofRecordId')\n")),(0,o.kt)("p",null,"Because Credo now also supports the present proof v2 protocol, the return type of this protocol has been changed to ",(0,o.kt)("inlineCode",{parentName:"p"},"V1XXXMessage | V2XXXMessage | null"),". Take this into account when working with the messages."),(0,o.kt)("p",null,"You can check if a message is a specific version by using the ",(0,o.kt)("inlineCode",{parentName:"p"},"instanceof")," operator:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"if (proposalMessage instanceof V1RequestPresentationMessage) {\n // do something\n}\n")))),(0,o.kt)("h3",{id:"out-of-band-proofs-and-credentials"},"Out Of Band Proofs and Credentials"),(0,o.kt)("p",null,"With the addition of the out of band module, the creation of connection-less messages has been split into two steps, allowing for better control and flexibility. The previous ",(0,o.kt)("inlineCode",{parentName:"p"},"agent.proofs.createOutOfBandRequest")," has been replaced by the ",(0,o.kt)("inlineCode",{parentName:"p"},"agent.proofs.createRequest")," method. This new method creates a proof request that is not tied to any connection."),(0,o.kt)("p",null,"What you can now do is call ",(0,o.kt)("inlineCode",{parentName:"p"},"agent.oob.createLegacyConnectionlessInvitation")," to attach the service decorator to the message and get a legacy connectionless message."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { requestMessage, proofRecord } = await agent.proofs.createOutOfBandRequest({\n requestedAttributes: {\n group1: {\n name: 'dateOfBirth',\n restrictions: [{ schemaId: 'F72i3Y3Q4i466efjYJYCHM:2:aha_cert:4.1.1' }],\n },\n },\n})\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { message, proofRecord } = await agent.proofs.createRequest({\n protocolVersion: 'v1',\n proofFormats: {\n indy: {\n requestedAttributes: {\n group1: {\n name: 'dateOfBirth',\n restrictions: [\n {\n schemaId: 'F72i3Y3Q4i466efjYJYCHM:2:aha_cert:4.1.1',\n },\n ],\n },\n },\n },\n },\n})\n\nconst { invitationUrl, message: messageWithServiceDecorator } = await agent.oob.createLegacyConnectionlessInvitation({\n recordId: proofRecord.id,\n domain: 'https://google.com',\n message,\n})\n")))),(0,o.kt)("p",null,"Out of band invitations are the new way to send messages out of band. You can use it for connection-less exchanges, but also for exchanges that you want to establish a connection for first. Here's an example on how to use the out of band module to create a connection-less invitation for a proof request:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const outOfBandRecord = await agent.oob.createInvitation({\n handshake: false, // set to true if you want to create a connection\n messages: [message],\n})\n\nconst invitationUrl = outOfBandRecord.outOfBandInvitation.toUrl({\n domain: 'https://Credo.com',\n})\n")),(0,o.kt)("p",null,"As you can see, there's now a lot more ways to use a message not tied to a connection. By splitting the creation of the message from the creation of the invitation, we can now create a message not bound to a connection (at time of creation) for multiple use cases."),(0,o.kt)("h3",{id:"updating-custom-modules-to-the-new-plugin-api"},"Updating Custom Modules to the new Plugin API"),(0,o.kt)("p",null,"Although this isn't a breaking change to the public API of the framework, it is something that you will need to take into account if you have custom modules and want to upgrade them to make compatible with Credo 0.3.0."),(0,o.kt)("h4",{id:"renaming-handler-classes"},"Renaming handler classes"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"Handler")," has been have been renamed to ",(0,o.kt)("inlineCode",{parentName:"p"},"MessageHandler")," to be be more descriptive, along with related types and methods. This means:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Handler")," is now ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandler")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"HandlerInboundMessage")," is now ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandlerInboundMessage")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Dispatcher.registerHandler")," is now ",(0,o.kt)("inlineCode",{parentName:"li"},"Dispatcher.registerMessageHandler")," and is marked as deprecated. The recommended way of registering handlers is by using the new ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandlerRegistry")," object by calling ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandlerRegistry.registerMessageHandler"),".")),(0,o.kt)("p",null,"If your custom module include message handlers, you must update them accordingly."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"export class MyHandler implements Handler {\n public supportedMessages = [MyMessage]\n\n public async handle(inboundMessage: HandlerInboundMessage) {\n ...\n }\n}\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"export class MyHandler implements MessageHandler {\n public supportedMessages = [MyMessage]\n\n public async handle(inboundMessage: MessageHandlerInboundMessage) {\n ...\n }\n}\n")))),(0,o.kt)("h4",{id:"using-agentcontext"},"Using AgentContext"),(0,o.kt)("p",null,"First of all, it's worth noting that now all services and repositories have been made stateless. A new ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentContext")," is introduced that holds the current context, which is passed to each method call. Therefore, you'll need to update every call to services, repositories and also eventEmitter methods to pass ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentContext")," object as first argument."),(0,o.kt)("p",null,"AgentContext can be obtained from either:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"MessageContext used by message handlers (accesed as messageContext.agentContext)"),(0,o.kt)("li",{parentName:"ul"},"Injected in your API constructor: you can store the instance and pass it to all your service and repository calls")),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"}," public async createRequest(options: CreateRequestOptions) {\n const message = new RequestMessage({\n parentThreadId: options.parentThreadId,\n })\n\n const record = new MyRecord({\n connectionId: options.connectionRecord.id,\n threadId: message.id,\n parentThreadId: options.parentThreadId,\n })\n\n await this.myRecordRepository.save(record)\n\n this.eventEmitter.emit({\n type: MyRecordEventTypes.StateChanged,\n payload: {\n myRecord: record,\n previousState: null,\n },\n })\n\n return { record, message }\n }\n\n public async processRequest(messageContext: HandlerInboundMessage) {\n const { message } = messageContext\n\n const record = new MyRecord({\n connectionId: connection.id,\n threadId: messageContext.message.id,\n parentThreadId: messageContext.message.thread?.parentThreadId,\n })\n\n await this.myRepository.save(record)\n\n return record\n }\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"}," public async createRequest(agentContext: AgentContext, options: CreateRequestOptions) {\n const message = new RequestMessage({\n parentThreadId: options.parentThreadId,\n })\n\n const record = new MyRecord({\n connectionId: options.connectionRecord.id,\n threadId: message.id,\n parentThreadId: options.parentThreadId,\n })\n\n await this.myRecordRepository.save(agentContext, record)\n\n this.eventEmitter.emit(agentContext, {\n type: MyRecordEventTypes.StateChanged,\n payload: {\n myRecord: record,\n previousState: null,\n },\n })\n\n return { record, message }\n }\n\n public async processRequest(messageContext: MessageHandlerInboundMessage) {\n const { message } = messageContext\n\n const record = new MyRecord({\n connectionId: connection.id,\n threadId: messageContext.message.id,\n parentThreadId: messageContext.message.thread?.parentThreadId,\n })\n\n await this.myRepository.save(messageContext.agentContext, record)\n\n return record\n }\n")))),(0,o.kt)("h4",{id:"using-outboundmessagecontext"},"Using OutboundMessageContext"),(0,o.kt)("p",null,"If your module implements a protocol that sends messages to other agents, you will notice that Agent's ",(0,o.kt)("inlineCode",{parentName:"p"},"MessageSender")," now receives the more generic ",(0,o.kt)("inlineCode",{parentName:"p"},"OutboundMessageContext")," class, which replaces previous helper method ",(0,o.kt)("inlineCode",{parentName:"p"},"createOutboundMessage"),"."),(0,o.kt)("p",null,"You can take advantage of this new mechanism to associate a record to the context, in order to do specific actions to it when outbound message state changes (e.g. a ",(0,o.kt)("inlineCode",{parentName:"p"},"MessageSendingError")," is thrown or ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentMessageSentEvent")," is emitted)."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { createOutboundMessage } from '@aries-framework/core'\n\nconst outboundMessage = createOutboundMessage(connection, message)\nawait this.messageSender.sendMessage(outboundMessage)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { OutboundMessageContext } from '@aries-framework/core'\n\nconst outboundMessageContext = new OutboundMessageContext(message, {\n agentContext: this.agentContext,\n connection,\n // optional, if you want to link the message to a related record\n associatedRecord: record,\n})\n\nawait this.messageSender.sendMessage(outboundMessageContext)\n")))),(0,o.kt)("h4",{id:"updating-module-structure-to-register-in-new-plugin-api"},"Updating module structure to register in new Plugin API"),(0,o.kt)("p",null,"Existing modules can benefit from the new Plugin API mechanism by doing the following modifications:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Rename Module class (e.g. MyModule) to API class (MyApi) and add @injectable decorator. Inject AgentContext in order to pass it to any services or repositories it might call. For instance:")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { injectable } from '@aries-framework/core'\n\n@injectable() // <-- Add this\nexport class MyApi {\n private messageSender: MessageSender\n private myService: MyService\n private connectionService: ConnectionService\n private agentContext: AgentContext // <-- Add this\n\n public constructor(\n messageHandlerRegistry: MessageHandlerRegistry, // <-- use this instead of Dispatcher\n messageSender: MessageSender,\n myService: MyService,\n connectionService: ConnectionService,\n agentContext: AgentContext // <-- Add this\n ) {\n this.messageSender = messageSender\n this.myService = myService\n this.connectionService = connectionService\n this.agentContext = agentContext // <-- Add this\n this.registerHandlers(messageHandlerRegistry) // <-- use messageHandlerRegistry instead of dispatcher\n }\n")),(0,o.kt)("ol",{start:2},(0,o.kt)("li",{parentName:"ol"},"Create a new Module class that implements Module interface and registers the dependencies and features. For instance:")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import type { DependencyManager, FeatureRegistry, Module } from '@aries-framework/core'\n\nimport { Protocol } from '@aries-framework/core'\n\nexport class MyModule implements Module {\n public readonly api = MyApi // the one we've just renamed from MyModule\n\n public register(dependencyManager: DependencyManager, featureRegistry: FeatureRegistry) {\n // Api\n dependencyManager.registerContextScoped(MyApi)\n\n // Services\n dependencyManager.registerSingleton(MyService)\n\n // Repositories\n dependencyManager.registerSingleton(MyRepository)\n\n // Feature Registry: don't forget to register your protocols and other features your module may add\n featureRegistry.register(\n new Protocol({\n id: 'https://didcomm.org/my-protocol/1.0',\n roles: [MyRole.Sender, MyRole.Receiver],\n })\n )\n }\n")),(0,o.kt)("p",null,"After doing this, you can add your module to agent constructor like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const agent = new Agent({\n config: {\n /* config */\n },\n dependencies: agentDependencies,\n modules: {\n myModule: new MyModule(),\n /* other custom modules */\n },\n})\n\n// MyModule API can be accessed in agent.modules namespace\nawait agent.modules.myModule.doSomething()\n\nawait agent.modules.myModule.doAnotherThing()\n")),(0,o.kt)("h2",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,o.kt)("p",null,"The 0.3.0 release introduces some breaking changes to the storage format, mainly related to Proof Exchanges."),(0,o.kt)("p",null,"Below all breaking storage changes are explained in as much detail as possible. The update assistant provides all tools to migrate without a hassle, but it is important to know what has changed. All examples only show the keys that have changed, unrelated keys in records have been omitted."),(0,o.kt)("p",null,"See the ",(0,o.kt)("a",{parentName:"p",href:"/guides/updating/update-assistant"},"Update Assistant")," documentation for a guide on how to use the update assistant."),(0,o.kt)("p",null,"There are no config parameters to be provided to the update assistant to migrate from 0.2.x to 0.3.x."),(0,o.kt)("h3",{id:"migrate-proof-record-properties"},"Migrate Proof Record Properties"),(0,o.kt)("p",null,"In 0.3.0 the v1 DIDComm messages have been moved out of the proof record into separate records using the DidCommMessageRepository. The migration scripts extracts all messages (proposalMessage, requestMessage, presentationMessage) and moves them into the DidCommMessageRepository. With the addition of support for different protocol versions the proof record now stores the protocol version."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "proposalMessage": { ... },\n "requestMessage": { ... },\n "presentationMessage": { ... },\n}\n'))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "protocolVersion": "v1"\n}\n')))),(0,o.kt)("h3",{id:"migrate-connection-record-properties"},"Migrate Connection Record properties"),(0,o.kt)("p",null,"The recently introduced ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionType")," tag has been pluralized to reflect the fact that more than a single connection type can be defined for a given connection. Also, it is now available as a direct record property (e.g. can be queried and set by using ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionRecord.connectionTypes"),") apart from the tag for efficient search."),(0,o.kt)("p",null,"The migration script renames ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionType")," to ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionTypes")," in all connections, and also searches for any mediation connection and adds ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionType.Mediator")," as one of its types."),(0,o.kt)("h3",{id:"migrate-did-record-properties"},"Migrate Did Record properties"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"didRecord.id")," was previously the did itself. However to allow for connecting with self, where multiple did records are created for the same did, the id property is now an uuid and a separate did property is added."),(0,o.kt)("p",null,"The migration script generates a new ID for each did record and stores its did into didRecord.did property."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": "did"\n}\n'))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": "uuid",\n "did": "did"\n}\n')))))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/365d3941.fd0d0e1b.js b/assets/js/365d3941.fd0d0e1b.js deleted file mode 100644 index a284cee7..00000000 --- a/assets/js/365d3941.fd0d0e1b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[6347],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>g});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),d=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=d(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),c=d(n),m=o,g=c["".concat(l,".").concat(m)]||c[m]||p[m]||r;return n?a.createElement(g,s(s({ref:t},u),{},{components:n})):a.createElement(g,s({ref:t},u))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,s=new Array(r);s[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[c]="string"==typeof e?e:o,s[1]=i;for(var d=2;d{n.d(t,{Z:()=>s});var a=n(7294),o=n(6010);const r={tabItem:"tabItem_Ymn6"};function s(e){let{children:t,hidden:n,className:s}=e;return a.createElement("div",{role:"tabpanel",className:(0,o.Z)(r.tabItem,s),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),o=n(7294),r=n(6010),s=n(2466),i=n(6550),l=n(1980),d=n(7392),u=n(12);function c(e){return function(e){return o.Children.map(e,(e=>{if((0,o.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:o}}=e;return{value:t,label:n,attributes:a,default:o}}))}function p(e){const{values:t,children:n}=e;return(0,o.useMemo)((()=>{const e=t??c(n);return function(e){const t=(0,d.l)(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 m(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 a=(0,i.k6)(),r=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,l._X)(r),(0,o.useCallback)((e=>{if(!r)return;const t=new URLSearchParams(a.location.search);t.set(r,e),a.replace({...a.location,search:t.toString()})}),[r,a])]}function h(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,r=p(e),[s,i]=(0,o.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(!m({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:r}))),[l,d]=g({queryString:n,groupId:a}),[c,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,r]=(0,u.Nk)(n);return[a,(0,o.useCallback)((e=>{n&&r.set(e)}),[n,r])]}({groupId:a}),f=(()=>{const e=l??c;return m({value:e,tabValues:r})?e:null})();(0,o.useLayoutEffect)((()=>{f&&i(f)}),[f]);return{selectedValue:s,selectValue:(0,o.useCallback)((e=>{if(!m({value:e,tabValues:r}))throw new Error(`Can't select invalid tab value=${e}`);i(e),d(e),h(e)}),[d,h,r]),tabValues:r}}var f=n(2389);const k={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){let{className:t,block:n,selectedValue:i,selectValue:l,tabValues:d}=e;const u=[],{blockElementScrollPositionUntilNextRender:c}=(0,s.o5)(),p=e=>{const t=e.currentTarget,n=u.indexOf(t),a=d[n].value;a!==i&&(c(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=u.indexOf(e.currentTarget)+1;t=u[n]??u[0];break}case"ArrowLeft":{const n=u.indexOf(e.currentTarget)-1;t=u[n]??u[u.length-1];break}}t?.focus()};return o.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.Z)("tabs",{"tabs--block":n},t)},d.map((e=>{let{value:t,label:n,attributes:s}=e;return o.createElement("li",(0,a.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>u.push(e),onKeyDown:m,onClick:p},s,{className:(0,r.Z)("tabs__item",k.tabItem,s?.className,{"tabs__item--active":i===t})}),n??t)})))}function b(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,o.cloneElement)(e,{className:"margin-top--md"}):null}return o.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,o.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function v(e){const t=h(e);return o.createElement("div",{className:(0,r.Z)("tabs-container",k.tabList)},o.createElement(y,(0,a.Z)({},e,t)),o.createElement(b,(0,a.Z)({},e,t)))}function w(e){const t=(0,f.Z)();return o.createElement(v,(0,a.Z)({key:String(t)},e))}},8412:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>g,frontMatter:()=>i,metadata:()=>d,toc:()=>c});var a=n(7462),o=(n(7294),n(3905)),r=n(4866),s=n(5162);const i={},l="Migrating from Credo 0.2.x to 0.3.x",d={unversionedId:"updating/versions/0.2-to-0.3",id:"updating/versions/0.2-to-0.3",title:"Migrating from Credo 0.2.x to 0.3.x",description:"This document describes everything you need to know for updating Credo 0.2.x to 0.3.x. If you're not aware of how updating in Credo works make sure to first read the guide on Updating Credo.",source:"@site/guides/updating/versions/0.2-to-0.3.md",sourceDirName:"updating/versions",slug:"/updating/versions/0.2-to-0.3",permalink:"/guides/0.5/updating/versions/0.2-to-0.3",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Migrating from Credo 0.1.0 to 0.2.x",permalink:"/guides/0.5/updating/versions/0.1-to-0.2"},next:{title:"Migrating from Credo 0.3.x to 0.4.x",permalink:"/guides/0.5/updating/versions/0.3-to-0.4"}},u={},c=[{value:"React Native",id:"react-native",level:4},{value:"Node",id:"node",level:4},{value:"Breaking Code Changes",id:"breaking-code-changes",level:2},{value:"Agent creation",id:"agent-creation",level:3},{value:"0.2.x",id:"02x",level:5},{value:"0.3.x",id:"03x",level:5},{value:"did:key usage in protocols",id:"didkey-usage-in-protocols",level:3},{value:"Modules extracted from the core",id:"modules-extracted-from-the-core",level:3},{value:"0.2.x",id:"02x-1",level:5},{value:"0.3.x",id:"03x-1",level:5},{value:"Discover Features Module",id:"discover-features-module",level:3},{value:"0.2.x",id:"02x-2",level:5},{value:"0.3.x",id:"03x-2",level:5},{value:"0.2.x",id:"02x-3",level:5},{value:"0.3.x",id:"03x-3",level:5},{value:"Ledger Module",id:"ledger-module",level:3},{value:"Proofs Module",id:"proofs-module",level:3},{value:"Module API Updates",id:"module-api-updates",level:4},{value:"0.2.x",id:"02x-4",level:5},{value:"0.3.x",id:"03x-4",level:5},{value:"Messages Extracted from Proof Exchange Record",id:"messages-extracted-from-proof-exchange-record",level:4},{value:"0.2.x",id:"02x-5",level:5},{value:"0.3.x",id:"03x-5",level:5},{value:"Out Of Band Proofs and Credentials",id:"out-of-band-proofs-and-credentials",level:3},{value:"0.2.x",id:"02x-6",level:4},{value:"0.3.x",id:"03x-6",level:4},{value:"Updating Custom Modules to the new Plugin API",id:"updating-custom-modules-to-the-new-plugin-api",level:3},{value:"Renaming handler classes",id:"renaming-handler-classes",level:4},{value:"0.2.x",id:"02x-7",level:5},{value:"0.3.x",id:"03x-7",level:5},{value:"Using AgentContext",id:"using-agentcontext",level:4},{value:"0.2.x",id:"02x-8",level:4},{value:"0.3.x",id:"03x-8",level:4},{value:"Using OutboundMessageContext",id:"using-outboundmessagecontext",level:4},{value:"0.2.x",id:"02x-9",level:4},{value:"0.3.x",id:"03x-9",level:4},{value:"Updating module structure to register in new Plugin API",id:"updating-module-structure-to-register-in-new-plugin-api",level:4},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:2},{value:"Migrate Proof Record Properties",id:"migrate-proof-record-properties",level:3},{value:"0.2.x",id:"02x-10",level:4},{value:"0.3.x",id:"03x-10",level:4},{value:"Migrate Connection Record properties",id:"migrate-connection-record-properties",level:3},{value:"Migrate Did Record properties",id:"migrate-did-record-properties",level:3},{value:"0.2.x",id:"02x-11",level:4},{value:"0.3.x",id:"03x-11",level:4}],p={toc:c},m="wrapper";function g(e){let{components:t,...n}=e;return(0,o.kt)(m,(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"migrating-from-credo-02x-to-03x"},"Migrating from Credo 0.2.x to 0.3.x"),(0,o.kt)("p",null,"This document describes everything you need to know for updating Credo 0.2.x to 0.3.x. If you're not aware of how updating in Credo works make sure to first read the guide on ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.5/updating/"},"Updating Credo"),"."),(0,o.kt)("p",null,"First of all, update you dependencies to the 0.3.x versions. This will also update the needed peer depedencnies. ",(0,o.kt)("strong",{parentName:"p"},"Extension packages are not updated with this command"),". You need to update these manually, and make sure they're up to date with the latest version of Credo."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"React Native",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/react-native@^0.3.0 @aries-framework/core@^0.3.0 indy-sdk-react-native@^0.3.0\n\n# or NPM\nnpn install @aries-framework/react-native@^0.3.0 @aries-framework/core@^0.3.0 indy-sdk-react-native@^0.3.0\n"))),(0,o.kt)(s.Z,{label:"Node",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/node@^0.3.0 @aries-framework/core@^0.3.0\n\n# or NPM\nnpm install @aries-framework/node@^0.3.0 @aries-framework/core@^0.3.0\n")))),(0,o.kt)("h2",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,o.kt)("p",null,"This section will list all breaking changes made to the public API of Credo between version 0.2.x and 0.3.0."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here (e.g. see ",(0,o.kt)("a",{parentName:"p",href:"#updating-custom-modules-to-the-new-plugin-api"},"Updating Custom Modules to the Plugin API"),"), but it is possible some breaking changes are not documented here (feel free to open PRs).")),(0,o.kt)("h3",{id:"agent-creation"},"Agent creation"),(0,o.kt)("p",null,"The agent constructor has been updated to a single ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentOptions")," object that contains the config and dependencies properties."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const agent = new Agent(agentConfig, agentDependencies)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const agent = new Agent({ config: agentConfig, dependencies: agentDependencies })\n")))),(0,o.kt)("p",null,"This object contains:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"config: Agent's initial configuration"),(0,o.kt)("li",{parentName:"ul"},"dependencies: platform-specific Agent dependencies"),(0,o.kt)("li",{parentName:"ul"},"modules: optional field for internal module configuration and custom module registration")),(0,o.kt)("p",null,"For easy migration, you can simply construct ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentOptions")," by putting current InitConfig into ",(0,o.kt)("inlineCode",{parentName:"p"},"config")," key and agentDependencies into ",(0,o.kt)("inlineCode",{parentName:"p"},"dependencies")," key."),(0,o.kt)("p",null,"Note that, if you are defining ",(0,o.kt)("inlineCode",{parentName:"p"},"indyLedgers")," configuration, you should set the indyNamespace for every ledger, as explained in ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.5/tutorials/agent-config/#indyledgers"},"Agent Config tutorial"),"."),(0,o.kt)("h3",{id:"didkey-usage-in-protocols"},"did:key usage in protocols"),(0,o.kt)("p",null,"In accordance with ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/tree/b3a3942ef052039e73cd23d847f42947f8287da2/features/0360-use-did-key"},"Aries RFC 0360"),", since 0.2.5 there is a configuration parameter called ",(0,o.kt)("inlineCode",{parentName:"p"},"useDidKeyInProtocols")," which, when enabled, will encode keys in did:key instead of previous base58 format, unless the other party has started a protocol and is using base58."),(0,o.kt)("p",null,"This parameter was previously disabled by default and now it is enabled. If your agent only interacts with modern agents (e.g. Credo 0.2.5 and newer) this will not represent any issue. Otherwise it is safer to explicitly set it to ",(0,o.kt)("inlineCode",{parentName:"p"},"false"),". However, keep in mind that we expect this setting to be deprecated in the future, so we encourage you to update all your agents to use did:key."),(0,o.kt)("h3",{id:"modules-extracted-from-the-core"},"Modules extracted from the core"),(0,o.kt)("p",null,"In this release two modules were extracted from the core and published as separate, optional packages:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"actionMenu has been moved to @aries-framework/action-menu"),(0,o.kt)("li",{parentName:"ul"},"questionAnswer has been moved to @aries-framework/question-answer")),(0,o.kt)("p",null,"If you want to use them, you can integrate in an Agent instance by injecting them in constructor, as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { ActionMenuModule } from '@aries-framework/action-menu'\nimport { QuestionAnswerModule } from '@aries-framework/question-answer'\n\nconst agent = new Agent({\n config: {\n /* config */\n },\n dependencies: agentDependencies,\n modules: {\n actionMenu: new ActionMenuModule(),\n questionAnswer: new QuestionAnswerModule(),\n /* other custom modules */\n },\n})\n")),(0,o.kt)("p",null,"As they are now considered custom modules, their API can be accessed in ",(0,o.kt)("inlineCode",{parentName:"p"},"modules")," namespace, so you should add it to every call to them."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.questionAnswer.sendQuestion(connectionId, {\n question: 'Do you want to play?',\n validResponses: [{ text: 'Yes' }, { text: 'No' }],\n})\n\nawait agent.questionAnswer.sendAnswer(questionAnswerRecordId, 'Yes')\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.modules.questionAnswer.sendQuestion(connectionId, {\n question: 'Do you want to play?',\n validResponses: [{ text: 'Yes' }, { text: 'No' }],\n})\n\nawait agent.modules.questionAnswer.sendAnswer(questionAnswerRecordId, 'Yes')\n")))),(0,o.kt)("h3",{id:"discover-features-module"},"Discover Features Module"),(0,o.kt)("p",null,"This module now supports both Discover Features V1 and V2, and as it happened to other modules, ",(0,o.kt)("inlineCode",{parentName:"p"},"queryFeatures")," method parameters have been unified to a single object and requires to specify the version of Discover Features protocol to be used. Note that ",(0,o.kt)("inlineCode",{parentName:"p"},"query")," property has been replaced by the more general ",(0,o.kt)("inlineCode",{parentName:"p"},"queries")," which accepts multiple features to be search for. To convert a query to this new format you simply need to create a single-object array whose unique object whose ",(0,o.kt)("inlineCode",{parentName:"p"},"featureType")," field is 'protocol' and ",(0,o.kt)("inlineCode",{parentName:"p"},"match")," field is the query itself."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.discovery.queryFeatures(connectionId, {\n query: 'https://didcomm.org/messagepickup/2.0',\n comment: 'Detect if protocol is supported',\n})\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.discovery.queryFeatures({\n connectionId,\n protocolVersion: 'v1',\n queries: [{ featureType: 'protocol', match: 'https://didcomm.org/messagepickup/2.0' }],\n comment: 'Detect if protocol is supported',\n})\n")))),(0,o.kt)("p",null,"The convenience method ",(0,o.kt)("strong",{parentName:"p"},"isProtocolSupported")," has been replaced by the more general synchronous mode of queryFeatures, which works when awaitDisclosures in options is set. Instead of returning a boolean, it returns an object with matching features:"),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const isPickUpV2Supported = await agent.discovery.isProtocolSupported(connectionId, StatusRequestMessage)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const discloseForPickupV2 = await agent.discovery.queryFeatures({\n connectionId: connectionId,\n protocolVersion: 'v1',\n queries: [{ featureType: 'protocol', match: StatusMessage.type.protocolUri }],\n awaitDisclosures: true,\n awaitDisclosuresTimeoutMs: 7000,\n})\n\nconst isPickUpV2Supported = discloseForPickupV2.features?.length === 1\n")))),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"Discover Features module does not rely anymore on Agent ",(0,o.kt)("inlineCode",{parentName:"p"},"Dispatcher")," to determine protocol support. Instead, it uses the new Feature Registry, where any custom modules implementing protocols must register them."),(0,o.kt)("p",{parentName:"admonition"},"This procedure can be done in module's ",(0,o.kt)("inlineCode",{parentName:"p"},"register(dependencyManager, featureRegistry)"),".")),(0,o.kt)("h3",{id:"ledger-module"},"Ledger Module"),(0,o.kt)("p",null,"Apart from the aforementioned indyLedgers configuration, you should also ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.5/tutorials/issue-a-credential#side-notes"},"note a slight change")," in behaviour when attempting to register credential definitions that already exists on the ledger but not in the wallet."),(0,o.kt)("h3",{id:"proofs-module"},"Proofs Module"),(0,o.kt)("h4",{id:"module-api-updates"},"Module API Updates"),(0,o.kt)("p",null,"Much in the same way as in 0.2.0 release when ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.5/updating/versions/0.1-to-0.2#module-api-updates"},"Issue Credential V2 protocol")," has been added, now that Present Proof V2 is supported, we introduced changes to proofs module."),(0,o.kt)("p",null,"Basically, for all methods in the proofs module you should take the following steps to update your code:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Move all function parameters into a single object. All module methods now take a single object that contain all properties."),(0,o.kt)("li",{parentName:"ol"},"For methods that initiate proposals, requests or presentations (",(0,o.kt)("inlineCode",{parentName:"li"},"proposeProof"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"acceptProposal"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"requestProof"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"acceptPresentation"),", etc.), you should pass ",(0,o.kt)("inlineCode",{parentName:"li"},"protocolVersion: 'v1'")," to indicate we should use the v1 protocol"),(0,o.kt)("li",{parentName:"ol"},"All indy specific attributes (e.g. Presentation Preview) should be passed in the ",(0,o.kt)("inlineCode",{parentName:"li"},"proofFormats.indy")," object."),(0,o.kt)("li",{parentName:"ol"},"Some indy objects, as the preview should now be passed only as their attributes (i.e. no need of creating the object instance) and provided in the ",(0,o.kt)("inlineCode",{parentName:"li"},"proofFormats.indy")," object.")),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.proofs.proposeProof(\n 'connectionId',\n new PresentationPreview({\n attributes: [new PresentationPreviewAttribute({ name: 'key', value: 'value' })],\n predicates: [\n new PresentationPreviewPredicate({\n name: 'age',\n credentialDefinitionId,\n predicate: PredicateType.GreaterThanOrEqualTo,\n threshold: 50,\n }),\n ],\n })\n)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.proofs.proposeProof({\n connectionId: connection.id,\n protocolVersion: 'v1',\n proofFormats: {\n indy: {\n attributes: [{ name: 'key', value: 'value' }],\n predicates: [{name: 'age', credentialDefinitionId, predicate: PredicateType.GreaterThanOrEqualTo, threshold: 50, ]\n },\n },\n comment: 'Propose proof comment',\n})\n")))),(0,o.kt)("h4",{id:"messages-extracted-from-proof-exchange-record"},"Messages Extracted from Proof Exchange Record"),(0,o.kt)("p",null,"The DIDComm messages that were previously stored on the proof record, have been extracted to separate DIDComm message records. This makes it easier to work with multiple versions of the protocol internally, and keeps the proof exchange record agnostic of the protocol version. Instead of accessing the messages through the ",(0,o.kt)("inlineCode",{parentName:"p"},"proposalMessage"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"requestMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"presentationMessage")," parameters, we now expose dedicated methods on the proofs module to retrieve the message."),(0,o.kt)("p",null,"With the addition of the v2 messages, all v1 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," while v2 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V2")," (",(0,o.kt)("inlineCode",{parentName:"p"},"V1RequestPresentationMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"V2RequestPresentationMessage"),"). If you were using these messages classes throughout your codebase, update them to use the ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," prefix."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const proofRecord = await agent.proofs.getById('proofRecordId')\n\nconst proposalMessage = proofRecord.proposalMessage\nconst requestMessage = proofRecord.requestMessage\nconst presentationMessage = proofRecord.presentationMessage\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const proofRecord = await agent.proofs.getById('proofRecordId')\n\nconst proposalMessage = await agent.proofs.findProposalMessage('proofRecordId')\nconst requestMessage = await agent.proofs.findRequestMessage('proofRecordId')\nconst presentationMessage = await agent.proofs.findPresentationMessage('proofRecordId')\n")),(0,o.kt)("p",null,"Because Credo now also supports the present proof v2 protocol, the return type of this protocol has been changed to ",(0,o.kt)("inlineCode",{parentName:"p"},"V1XXXMessage | V2XXXMessage | null"),". Take this into account when working with the messages."),(0,o.kt)("p",null,"You can check if a message is a specific version by using the ",(0,o.kt)("inlineCode",{parentName:"p"},"instanceof")," operator:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"if (proposalMessage instanceof V1RequestPresentationMessage) {\n // do something\n}\n")))),(0,o.kt)("h3",{id:"out-of-band-proofs-and-credentials"},"Out Of Band Proofs and Credentials"),(0,o.kt)("p",null,"With the addition of the out of band module, the creation of connection-less messages has been split into two steps, allowing for better control and flexibility. The previous ",(0,o.kt)("inlineCode",{parentName:"p"},"agent.proofs.createOutOfBandRequest")," has been replaced by the ",(0,o.kt)("inlineCode",{parentName:"p"},"agent.proofs.createRequest")," method. This new method creates a proof request that is not tied to any connection."),(0,o.kt)("p",null,"What you can now do is call ",(0,o.kt)("inlineCode",{parentName:"p"},"agent.oob.createLegacyConnectionlessInvitation")," to attach the service decorator to the message and get a legacy connectionless message."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { requestMessage, proofRecord } = await agent.proofs.createOutOfBandRequest({\n requestedAttributes: {\n group1: {\n name: 'dateOfBirth',\n restrictions: [{ schemaId: 'F72i3Y3Q4i466efjYJYCHM:2:aha_cert:4.1.1' }],\n },\n },\n})\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { message, proofRecord } = await agent.proofs.createRequest({\n protocolVersion: 'v1',\n proofFormats: {\n indy: {\n requestedAttributes: {\n group1: {\n name: 'dateOfBirth',\n restrictions: [\n {\n schemaId: 'F72i3Y3Q4i466efjYJYCHM:2:aha_cert:4.1.1',\n },\n ],\n },\n },\n },\n },\n})\n\nconst { invitationUrl, message: messageWithServiceDecorator } = await agent.oob.createLegacyConnectionlessInvitation({\n recordId: proofRecord.id,\n domain: 'https://google.com',\n message,\n})\n")))),(0,o.kt)("p",null,"Out of band invitations are the new way to send messages out of band. You can use it for connection-less exchanges, but also for exchanges that you want to establish a connection for first. Here's an example on how to use the out of band module to create a connection-less invitation for a proof request:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const outOfBandRecord = await agent.oob.createInvitation({\n handshake: false, // set to true if you want to create a connection\n messages: [message],\n})\n\nconst invitationUrl = outOfBandRecord.outOfBandInvitation.toUrl({\n domain: 'https://Credo.com',\n})\n")),(0,o.kt)("p",null,"As you can see, there's now a lot more ways to use a message not tied to a connection. By splitting the creation of the message from the creation of the invitation, we can now create a message not bound to a connection (at time of creation) for multiple use cases."),(0,o.kt)("h3",{id:"updating-custom-modules-to-the-new-plugin-api"},"Updating Custom Modules to the new Plugin API"),(0,o.kt)("p",null,"Although this isn't a breaking change to the public API of the framework, it is something that you will need to take into account if you have custom modules and want to upgrade them to make compatible with Credo 0.3.0."),(0,o.kt)("h4",{id:"renaming-handler-classes"},"Renaming handler classes"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"Handler")," has been have been renamed to ",(0,o.kt)("inlineCode",{parentName:"p"},"MessageHandler")," to be be more descriptive, along with related types and methods. This means:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Handler")," is now ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandler")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"HandlerInboundMessage")," is now ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandlerInboundMessage")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Dispatcher.registerHandler")," is now ",(0,o.kt)("inlineCode",{parentName:"li"},"Dispatcher.registerMessageHandler")," and is marked as deprecated. The recommended way of registering handlers is by using the new ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandlerRegistry")," object by calling ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandlerRegistry.registerMessageHandler"),".")),(0,o.kt)("p",null,"If your custom module include message handlers, you must update them accordingly."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"export class MyHandler implements Handler {\n public supportedMessages = [MyMessage]\n\n public async handle(inboundMessage: HandlerInboundMessage) {\n ...\n }\n}\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"export class MyHandler implements MessageHandler {\n public supportedMessages = [MyMessage]\n\n public async handle(inboundMessage: MessageHandlerInboundMessage) {\n ...\n }\n}\n")))),(0,o.kt)("h4",{id:"using-agentcontext"},"Using AgentContext"),(0,o.kt)("p",null,"First of all, it's worth noting that now all services and repositories have been made stateless. A new ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentContext")," is introduced that holds the current context, which is passed to each method call. Therefore, you'll need to update every call to services, repositories and also eventEmitter methods to pass ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentContext")," object as first argument."),(0,o.kt)("p",null,"AgentContext can be obtained from either:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"MessageContext used by message handlers (accesed as messageContext.agentContext)"),(0,o.kt)("li",{parentName:"ul"},"Injected in your API constructor: you can store the instance and pass it to all your service and repository calls")),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"}," public async createRequest(options: CreateRequestOptions) {\n const message = new RequestMessage({\n parentThreadId: options.parentThreadId,\n })\n\n const record = new MyRecord({\n connectionId: options.connectionRecord.id,\n threadId: message.id,\n parentThreadId: options.parentThreadId,\n })\n\n await this.myRecordRepository.save(record)\n\n this.eventEmitter.emit({\n type: MyRecordEventTypes.StateChanged,\n payload: {\n myRecord: record,\n previousState: null,\n },\n })\n\n return { record, message }\n }\n\n public async processRequest(messageContext: HandlerInboundMessage) {\n const { message } = messageContext\n\n const record = new MyRecord({\n connectionId: connection.id,\n threadId: messageContext.message.id,\n parentThreadId: messageContext.message.thread?.parentThreadId,\n })\n\n await this.myRepository.save(record)\n\n return record\n }\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"}," public async createRequest(agentContext: AgentContext, options: CreateRequestOptions) {\n const message = new RequestMessage({\n parentThreadId: options.parentThreadId,\n })\n\n const record = new MyRecord({\n connectionId: options.connectionRecord.id,\n threadId: message.id,\n parentThreadId: options.parentThreadId,\n })\n\n await this.myRecordRepository.save(agentContext, record)\n\n this.eventEmitter.emit(agentContext, {\n type: MyRecordEventTypes.StateChanged,\n payload: {\n myRecord: record,\n previousState: null,\n },\n })\n\n return { record, message }\n }\n\n public async processRequest(messageContext: MessageHandlerInboundMessage) {\n const { message } = messageContext\n\n const record = new MyRecord({\n connectionId: connection.id,\n threadId: messageContext.message.id,\n parentThreadId: messageContext.message.thread?.parentThreadId,\n })\n\n await this.myRepository.save(messageContext.agentContext, record)\n\n return record\n }\n")))),(0,o.kt)("h4",{id:"using-outboundmessagecontext"},"Using OutboundMessageContext"),(0,o.kt)("p",null,"If your module implements a protocol that sends messages to other agents, you will notice that Agent's ",(0,o.kt)("inlineCode",{parentName:"p"},"MessageSender")," now receives the more generic ",(0,o.kt)("inlineCode",{parentName:"p"},"OutboundMessageContext")," class, which replaces previous helper method ",(0,o.kt)("inlineCode",{parentName:"p"},"createOutboundMessage"),"."),(0,o.kt)("p",null,"You can take advantage of this new mechanism to associate a record to the context, in order to do specific actions to it when outbound message state changes (e.g. a ",(0,o.kt)("inlineCode",{parentName:"p"},"MessageSendingError")," is thrown or ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentMessageSentEvent")," is emitted)."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { createOutboundMessage } from '@aries-framework/core'\n\nconst outboundMessage = createOutboundMessage(connection, message)\nawait this.messageSender.sendMessage(outboundMessage)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { OutboundMessageContext } from '@aries-framework/core'\n\nconst outboundMessageContext = new OutboundMessageContext(message, {\n agentContext: this.agentContext,\n connection,\n // optional, if you want to link the message to a related record\n associatedRecord: record,\n})\n\nawait this.messageSender.sendMessage(outboundMessageContext)\n")))),(0,o.kt)("h4",{id:"updating-module-structure-to-register-in-new-plugin-api"},"Updating module structure to register in new Plugin API"),(0,o.kt)("p",null,"Existing modules can benefit from the new Plugin API mechanism by doing the following modifications:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Rename Module class (e.g. MyModule) to API class (MyApi) and add @injectable decorator. Inject AgentContext in order to pass it to any services or repositories it might call. For instance:")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { injectable } from '@aries-framework/core'\n\n@injectable() // <-- Add this\nexport class MyApi {\n private messageSender: MessageSender\n private myService: MyService\n private connectionService: ConnectionService\n private agentContext: AgentContext // <-- Add this\n\n public constructor(\n messageHandlerRegistry: MessageHandlerRegistry, // <-- use this instead of Dispatcher\n messageSender: MessageSender,\n myService: MyService,\n connectionService: ConnectionService,\n agentContext: AgentContext // <-- Add this\n ) {\n this.messageSender = messageSender\n this.myService = myService\n this.connectionService = connectionService\n this.agentContext = agentContext // <-- Add this\n this.registerHandlers(messageHandlerRegistry) // <-- use messageHandlerRegistry instead of dispatcher\n }\n")),(0,o.kt)("ol",{start:2},(0,o.kt)("li",{parentName:"ol"},"Create a new Module class that implements Module interface and registers the dependencies and features. For instance:")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import type { DependencyManager, FeatureRegistry, Module } from '@aries-framework/core'\n\nimport { Protocol } from '@aries-framework/core'\n\nexport class MyModule implements Module {\n public readonly api = MyApi // the one we've just renamed from MyModule\n\n public register(dependencyManager: DependencyManager, featureRegistry: FeatureRegistry) {\n // Api\n dependencyManager.registerContextScoped(MyApi)\n\n // Services\n dependencyManager.registerSingleton(MyService)\n\n // Repositories\n dependencyManager.registerSingleton(MyRepository)\n\n // Feature Registry: don't forget to register your protocols and other features your module may add\n featureRegistry.register(\n new Protocol({\n id: 'https://didcomm.org/my-protocol/1.0',\n roles: [MyRole.Sender, MyRole.Receiver],\n })\n )\n }\n")),(0,o.kt)("p",null,"After doing this, you can add your module to agent constructor like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const agent = new Agent({\n config: {\n /* config */\n },\n dependencies: agentDependencies,\n modules: {\n myModule: new MyModule(),\n /* other custom modules */\n },\n})\n\n// MyModule API can be accessed in agent.modules namespace\nawait agent.modules.myModule.doSomething()\n\nawait agent.modules.myModule.doAnotherThing()\n")),(0,o.kt)("h2",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,o.kt)("p",null,"The 0.3.0 release introduces some breaking changes to the storage format, mainly related to Proof Exchanges."),(0,o.kt)("p",null,"Below all breaking storage changes are explained in as much detail as possible. The update assistant provides all tools to migrate without a hassle, but it is important to know what has changed. All examples only show the keys that have changed, unrelated keys in records have been omitted."),(0,o.kt)("p",null,"See the ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.5/updating/update-assistant"},"Update Assistant")," documentation for a guide on how to use the update assistant."),(0,o.kt)("p",null,"There are no config parameters to be provided to the update assistant to migrate from 0.2.x to 0.3.x."),(0,o.kt)("h3",{id:"migrate-proof-record-properties"},"Migrate Proof Record Properties"),(0,o.kt)("p",null,"In 0.3.0 the v1 DIDComm messages have been moved out of the proof record into separate records using the DidCommMessageRepository. The migration scripts extracts all messages (proposalMessage, requestMessage, presentationMessage) and moves them into the DidCommMessageRepository. With the addition of support for different protocol versions the proof record now stores the protocol version."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "proposalMessage": { ... },\n "requestMessage": { ... },\n "presentationMessage": { ... },\n}\n'))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "protocolVersion": "v1"\n}\n')))),(0,o.kt)("h3",{id:"migrate-connection-record-properties"},"Migrate Connection Record properties"),(0,o.kt)("p",null,"The recently introduced ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionType")," tag has been pluralized to reflect the fact that more than a single connection type can be defined for a given connection. Also, it is now available as a direct record property (e.g. can be queried and set by using ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionRecord.connectionTypes"),") apart from the tag for efficient search."),(0,o.kt)("p",null,"The migration script renames ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionType")," to ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionTypes")," in all connections, and also searches for any mediation connection and adds ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionType.Mediator")," as one of its types."),(0,o.kt)("h3",{id:"migrate-did-record-properties"},"Migrate Did Record properties"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"didRecord.id")," was previously the did itself. However to allow for connecting with self, where multiple did records are created for the same did, the id property is now an uuid and a separate did property is added."),(0,o.kt)("p",null,"The migration script generates a new ID for each did record and stores its did into didRecord.did property."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": "did"\n}\n'))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": "uuid",\n "did": "did"\n}\n')))))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/369c14e0.a96b6433.js b/assets/js/369c14e0.a96b6433.js new file mode 100644 index 00000000..bfef829f --- /dev/null +++ b/assets/js/369c14e0.a96b6433.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[2913],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>v});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},d=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,a=e.originalType,p=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),f=l(r),c=i,v=f["".concat(p,".").concat(c)]||f[c]||u[c]||a;return r?n.createElement(v,o(o({ref:t},d),{},{components:r})):n.createElement(v,o({ref:t},d))}));function v(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=r.length,o=new Array(a);o[0]=c;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[f]="string"==typeof e?e:i,o[1]=s;for(var l=2;l{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var n=r(7462),i=(r(7294),r(3905));const a={},o="OpenID for Verifiable Credentials",s={unversionedId:"features/openid4vc",id:"features/openid4vc",title:"OpenID for Verifiable Credentials",description:"Since Credo 0.4, support was added to receive credentials using OpenID for Verifiable Credential Issuance, and since 0.5 support was added for all the other OpenID for Verifiable Credential flows.",source:"@site/guides/features/openid4vc.md",sourceDirName:"features",slug:"/features/openid4vc",permalink:"/guides/features/openid4vc",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Hyperledger Aries and Aries Interop Profile",permalink:"/guides/features/aries"},next:{title:"Decentralized Identifiers",permalink:"/guides/features/dids"}},p={},l=[{value:"OpenID for Verifiable Credential Issuance",id:"openid-for-verifiable-credential-issuance",level:2},{value:"OpenID for Verifiable Presentations",id:"openid-for-verifiable-presentations",level:2},{value:"Self-Issued OpenID Provider v2",id:"self-issued-openid-provider-v2",level:2}],d={toc:l},f="wrapper";function u(e){let{components:t,...r}=e;return(0,i.kt)(f,(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"openid-for-verifiable-credentials"},"OpenID for Verifiable Credentials"),(0,i.kt)("p",null,"Since Credo 0.4, support was added to receive credentials using OpenID for Verifiable Credential Issuance, and since 0.5 support was added for all the other OpenID for Verifiable Credential flows."),(0,i.kt)("p",null,"This means Credo has support for ",(0,i.kt)("a",{parentName:"p",href:"https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html"},"OpenID for Verifiable Credential Issuance"),", ",(0,i.kt)("a",{parentName:"p",href:"https://openid.net/specs/openid-4-verifiable-presentations-1_0.html"},"OpenID for Verifiable Presentations"),", and ",(0,i.kt)("a",{parentName:"p",href:"https://openid.net/specs/openid-connect-self-issued-v2-1_0.html"},"Self-Issued OpenID Provider v2"),"."),(0,i.kt)("admonition",{type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Support for OpenID for Verifiable Credentials in Credo is still in an experimental phase, and thus is subject to breaking changes. Also, due to the early stages of these specifications, supported draft versions and flows may change and evolve. As early adopters it\u2019s important to align with the evolving specs, and we are doing out best to keep up-to-date without breaking existing deployments."),(0,i.kt)("p",{parentName:"admonition"},"Currently, work is ongoing to update the supported versions for OpenID4VC to the latest available Draft versions:"),(0,i.kt)("ul",{parentName:"admonition"},(0,i.kt)("li",{parentName:"ul"},"OpenID for Verifiable Credential Issuance - Draft 12"),(0,i.kt)("li",{parentName:"ul"},"OpenID for Verifiable Presentations - Draft 20"),(0,i.kt)("li",{parentName:"ul"},"Self-Issued OpenID Provider - Draft 13"))),(0,i.kt)("h2",{id:"openid-for-verifiable-credential-issuance"},"OpenID for Verifiable Credential Issuance"),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0-11.html"},"OpenID for Verifiable Credential Issuance - Draft 11")," is supported, but only the immediate issuance using the Pre-Authorized Code flow. The deferred endpoint, batch endpoints and Authorized Code Flow are not supported at the moment."),(0,i.kt)("h2",{id:"openid-for-verifiable-presentations"},"OpenID for Verifiable Presentations"),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://openid.net/specs/openid-connect-4-verifiable-presentations-1_0-ID1.html"},"OpenID for Verifiable Presentations - Implementers Draft 1 (Draft 8)")," is supported for requesting and presenting verifiable presentations as part of an authorization request and response. OpenID for Verifiable Presentations is only supported in combination with Self-Issued OpenID Provider V2."),(0,i.kt)("h2",{id:"self-issued-openid-provider-v2"},"Self-Issued OpenID Provider v2"),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://openid.net/specs/openid-connect-self-issued-v2-1_0-ID1.html"},"Self-Issued OpenID Provider V2 - Implementers Draft 1 (Draft 7)")," is supported for allowing holders of credentials to act as their own OpenID Provider, and present credentials to a verifier without the need for a third party. Both SIOPv2 authentication requests and responses with verifiable presentations (using VP Token) or without (using ID Token for e.g. DID authentication) are supported."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/369c14e0.ac5daf50.js b/assets/js/369c14e0.ac5daf50.js deleted file mode 100644 index 7b9254a0..00000000 --- a/assets/js/369c14e0.ac5daf50.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[2913],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>v});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},d=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,a=e.originalType,p=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),f=l(r),c=i,v=f["".concat(p,".").concat(c)]||f[c]||u[c]||a;return r?n.createElement(v,o(o({ref:t},d),{},{components:r})):n.createElement(v,o({ref:t},d))}));function v(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=r.length,o=new Array(a);o[0]=c;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[f]="string"==typeof e?e:i,o[1]=s;for(var l=2;l{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var n=r(7462),i=(r(7294),r(3905));const a={},o="OpenID for Verifiable Credentials",s={unversionedId:"features/openid4vc",id:"features/openid4vc",title:"OpenID for Verifiable Credentials",description:"Since Credo 0.4, support was added to receive credentials using OpenID for Verifiable Credential Issuance, and since 0.5 support was added for all the other OpenID for Verifiable Credential flows.",source:"@site/guides/features/openid4vc.md",sourceDirName:"features",slug:"/features/openid4vc",permalink:"/guides/0.5/features/openid4vc",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Hyperledger Aries and Aries Interop Profile",permalink:"/guides/0.5/features/aries"},next:{title:"Decentralized Identifiers",permalink:"/guides/0.5/features/dids"}},p={},l=[{value:"OpenID for Verifiable Credential Issuance",id:"openid-for-verifiable-credential-issuance",level:2},{value:"OpenID for Verifiable Presentations",id:"openid-for-verifiable-presentations",level:2},{value:"Self-Issued OpenID Provider v2",id:"self-issued-openid-provider-v2",level:2}],d={toc:l},f="wrapper";function u(e){let{components:t,...r}=e;return(0,i.kt)(f,(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"openid-for-verifiable-credentials"},"OpenID for Verifiable Credentials"),(0,i.kt)("p",null,"Since Credo 0.4, support was added to receive credentials using OpenID for Verifiable Credential Issuance, and since 0.5 support was added for all the other OpenID for Verifiable Credential flows."),(0,i.kt)("p",null,"This means Credo has support for ",(0,i.kt)("a",{parentName:"p",href:"https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html"},"OpenID for Verifiable Credential Issuance"),", ",(0,i.kt)("a",{parentName:"p",href:"https://openid.net/specs/openid-4-verifiable-presentations-1_0.html"},"OpenID for Verifiable Presentations"),", and ",(0,i.kt)("a",{parentName:"p",href:"https://openid.net/specs/openid-connect-self-issued-v2-1_0.html"},"Self-Issued OpenID Provider v2"),"."),(0,i.kt)("admonition",{type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Support for OpenID for Verifiable Credentials in Credo is still in an experimental phase, and thus is subject to breaking changes. Also, due to the early stages of these specifications, supported draft versions and flows may change and evolve. As early adopters it\u2019s important to align with the evolving specs, and we are doing out best to keep up-to-date without breaking existing deployments."),(0,i.kt)("p",{parentName:"admonition"},"Currently, work is ongoing to update the supported versions for OpenID4VC to the latest available Draft versions:"),(0,i.kt)("ul",{parentName:"admonition"},(0,i.kt)("li",{parentName:"ul"},"OpenID for Verifiable Credential Issuance - Draft 12"),(0,i.kt)("li",{parentName:"ul"},"OpenID for Verifiable Presentations - Draft 20"),(0,i.kt)("li",{parentName:"ul"},"Self-Issued OpenID Provider - Draft 13"))),(0,i.kt)("h2",{id:"openid-for-verifiable-credential-issuance"},"OpenID for Verifiable Credential Issuance"),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0-11.html"},"OpenID for Verifiable Credential Issuance - Draft 11")," is supported, but only the immediate issuance using the Pre-Authorized Code flow. The deferred endpoint, batch endpoints and Authorized Code Flow are not supported at the moment."),(0,i.kt)("h2",{id:"openid-for-verifiable-presentations"},"OpenID for Verifiable Presentations"),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://openid.net/specs/openid-connect-4-verifiable-presentations-1_0-ID1.html"},"OpenID for Verifiable Presentations - Implementers Draft 1 (Draft 8)")," is supported for requesting and presenting verifiable presentations as part of an authorization request and response. OpenID for Verifiable Presentations is only supported in combination with Self-Issued OpenID Provider V2."),(0,i.kt)("h2",{id:"self-issued-openid-provider-v2"},"Self-Issued OpenID Provider v2"),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://openid.net/specs/openid-connect-self-issued-v2-1_0-ID1.html"},"Self-Issued OpenID Provider V2 - Implementers Draft 1 (Draft 7)")," is supported for allowing holders of credentials to act as their own OpenID Provider, and present credentials to a verifier without the need for a third party. Both SIOPv2 authentication requests and responses with verifiable presentations (using VP Token) or without (using ID Token for e.g. DID authentication) are supported."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/394d7bf2.11f71b02.js b/assets/js/394d7bf2.11f71b02.js new file mode 100644 index 00000000..a4f7d7f2 --- /dev/null +++ b/assets/js/394d7bf2.11f71b02.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8368],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),d=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=d(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=d(n),m=a,h=u["".concat(l,".").concat(m)]||u[m]||p[m]||i;return n?r.createElement(h,o(o({ref:t},c),{},{components:n})):r.createElement(h,o({ref:t},c))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:a,o[1]=s;for(var d=2;d{n.d(t,{Z:()=>o});var r=n(7294),a=n(6010);const i={tabItem:"tabItem_Ymn6"};function o(e){let{children:t,hidden:n,className:o}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(i.tabItem,o),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>N});var r=n(7462),a=n(7294),i=n(6010),o=n(2466),s=n(6550),l=n(1980),d=n(7392),c=n(12);function u(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function p(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??u(n);return function(e){const t=(0,d.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const r=(0,s.k6)(),i=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,l._X)(i),(0,a.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(r.location.search);t.set(i,e),r.replace({...r.location,search:t.toString()})}),[i,r])]}function g(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,i=p(e),[o,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(!m({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 r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:i}))),[l,d]=h({queryString:n,groupId:r}),[u,g]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,i]=(0,c.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:r}),y=(()=>{const e=l??u;return m({value:e,tabValues:i})?e:null})();(0,a.useLayoutEffect)((()=>{y&&s(y)}),[y]);return{selectedValue:o,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);s(e),d(e),g(e)}),[d,g,i]),tabValues:i}}var y=n(2389);const f={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function v(e){let{className:t,block:n,selectedValue:s,selectValue:l,tabValues:d}=e;const c=[],{blockElementScrollPositionUntilNextRender:u}=(0,o.o5)(),p=e=>{const t=e.currentTarget,n=c.indexOf(t),r=d[n].value;r!==s&&(u(t),l(r))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},d.map((e=>{let{value:t,label:n,attributes:o}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:p},o,{className:(0,i.Z)("tabs__item",f.tabItem,o?.className,{"tabs__item--active":s===t})}),n??t)})))}function b(e){let{lazy:t,children:n,selectedValue:r}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function k(e){const t=g(e);return a.createElement("div",{className:(0,i.Z)("tabs-container",f.tabList)},a.createElement(v,(0,r.Z)({},e,t)),a.createElement(b,(0,r.Z)({},e,t)))}function N(e){const t=(0,y.Z)();return a.createElement(k,(0,r.Z)({key:String(t)},e))}},3172:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>d,toc:()=>u});var r=n(7462),a=(n(7294),n(3905)),i=n(4866),o=n(5162);const s={},l="Indy VDR",d={unversionedId:"getting-started/set-up/indy-vdr",id:"getting-started/set-up/indy-vdr",title:"Indy VDR",description:"Hyperledger Indy VDR, Verifiable Data Registry, can be used to connect to one or more Indy Node ledger pools given sets of genesis transactions. Methods are provided to construct ledger requests and send them to the validators, collecting the results and ensuring that there is a consensus between the nodes. In the context of Credo, we mainly leverage it to register, and resolve, schemas, credential definitions and DIDs.",source:"@site/guides/getting-started/set-up/indy-vdr.md",sourceDirName:"getting-started/set-up",slug:"/getting-started/set-up/indy-vdr",permalink:"/guides/getting-started/set-up/indy-vdr",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"AnonCreds",permalink:"/guides/getting-started/set-up/anoncreds"},next:{title:"cheqd",permalink:"/guides/getting-started/set-up/cheqd/"}},c={},u=[{value:"Installing Indy VDR",id:"installing-indy-vdr",level:3},{value:"Adding Indy VDR to the agent",id:"adding-indy-vdr-to-the-agent",level:3},{value:"Configuration",id:"configuration",level:3},{value:"indyVdr",id:"indyvdr",level:4},{value:"networks",id:"networks",level:4},{value:"indyNamespace",id:"indynamespace",level:5},{value:"isProduction",id:"isproduction",level:5},{value:"genesisTransactions",id:"genesistransactions",level:5},{value:"connectOnStartup",id:"connectonstartup",level:5},{value:"transactionAuthorAgreement",id:"transactionauthoragreement",level:5},{value:"transactionAuthorAgreement.version",id:"transactionauthoragreementversion",level:5},{value:"transactionAuthorAgreement.acceptanceMechanism",id:"transactionauthoragreementacceptancemechanism",level:5}],p={toc:u},m="wrapper";function h(e){let{components:t,...n}=e;return(0,a.kt)(m,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"indy-vdr"},"Indy VDR"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-vdr"},"Hyperledger Indy VDR"),", Verifiable Data Registry, can be used to connect to one or more Indy Node ledger pools given sets of genesis transactions. Methods are provided to construct ledger requests and send them to the validators, collecting the results and ensuring that there is a consensus between the nodes. In the context of Credo, we mainly leverage it to register, and resolve, schemas, credential definitions and DIDs."),(0,a.kt)("h3",{id:"installing-indy-vdr"},"Installing Indy VDR"),(0,a.kt)("p",null,"When using Credo with Indy VDR, there are a few extra dependencies that need to be installed. We need to install the ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/indy-vdr"),", which contains all the functionality to register objects on an Hyperledger Indy VDR. Secondly, we need to add native bindings for the specific platform ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/indy-vdr-"),". Currently there are bindings for Node.JS, as ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/indy-vdr-nodejs"),", and React Native as ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperlegder/indy-vdr-react-native"),"."),(0,a.kt)(i.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @credo-ts/indy-vdr@^0.5.0 @hyperledger/indy-vdr-nodejs@^0.2.0\n"))),(0,a.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @credo-ts/indy-vdr@^0.5.0 @hyperledger/indy-vdr-react-native@^0.2.0\n")))),(0,a.kt)("h3",{id:"adding-indy-vdr-to-the-agent"},"Adding Indy VDR to the agent"),(0,a.kt)("p",null,"After installing the dependencies, we can register the Indy VDR module on the agent."),(0,a.kt)(i.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-indy-vdr.ts section-1",showLineNumbers:!0,"set-up-indy-vdr.ts":!0,"section-1":!0},""))),(0,a.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-indy-vdr-rn.ts section-1",showLineNumbers:!0,"set-up-indy-vdr-rn.ts":!0,"section-1":!0},"")))),(0,a.kt)("h3",{id:"configuration"},"Configuration"),(0,a.kt)("p",null,"As you can see below, the Indy VDR module takes the native bindings and a list of networks. This list of networks will be used to resolve and register objects on."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"typescript showLineNumbers set-up-indy-vdr-config.ts section-1",typescript:!0,showLineNumbers:!0,"set-up-indy-vdr-config.ts":!0,"section-1":!0},"")),(0,a.kt)("h4",{id:"indyvdr"},"indyVdr"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"IndyVdr")),(0,a.kt)("p",null,"the ",(0,a.kt)("inlineCode",{parentName:"p"},"indyVdr")," key takes a class that implements all the native bindings for Indy VDR. This can be imoprted from the ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/indy-vdr-nodejs")," package or the ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/indy-vdr-react-native")," package."),(0,a.kt)("h4",{id:"networks"},"networks"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"IndyVdrPoolConfig[]")),(0,a.kt)("p",null,"An array of indy networks to connect to. The list can contain the following object and it must ",(0,a.kt)("a",{parentName:"p",href:"#indyledgersgenesistransactions"},(0,a.kt)("inlineCode",{parentName:"a"},"genesisTransactions")),"."),(0,a.kt)("h5",{id:"indynamespace"},"indyNamespace"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("p",null,"The Indy namespace aka the name identifying the name of the network connecting to. See also ",(0,a.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/indy-did-method/#indy-did-method-identifiers"},"indy did method identifiers")),(0,a.kt)("h5",{id:"isproduction"},(0,a.kt)("inlineCode",{parentName:"h5"},"isProduction")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"boolean")),(0,a.kt)("p",null,"Whether the ledger is a production ledger. This is used for detecting which ledger to use in case of unqualified identifiers as production ledgers have priority."),(0,a.kt)("h5",{id:"genesistransactions"},(0,a.kt)("inlineCode",{parentName:"h5"},"genesisTransactions")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("p",null,"Stringified JSON object of the transaction."),(0,a.kt)("h5",{id:"connectonstartup"},(0,a.kt)("inlineCode",{parentName:"h5"},"connectOnStartup")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"boolean")),(0,a.kt)("p",null,"Whether to connect to the ledger on startup. Defaults to ",(0,a.kt)("inlineCode",{parentName:"p"},"false"),"."),(0,a.kt)("h5",{id:"transactionauthoragreement"},(0,a.kt)("inlineCode",{parentName:"h5"},"transactionAuthorAgreement")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"TransactionAuthorAgreement")),(0,a.kt)("p",null,"JSON representation specifying the version and acceptance mechanism. The version is the unique version of the transaction author agreement acceptance mechanism list (AML). The acceptance mechanism refers to the acceptance mechanism label of the item in the AML. For more details you may consult the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-node/blob/master/docs/source/transactions.md#transaction_author_agreement_aml"},"indy-node docs on AML")),(0,a.kt)("h5",{id:"transactionauthoragreementversion"},(0,a.kt)("inlineCode",{parentName:"h5"},"transactionAuthorAgreement.version")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("p",null,"The version of the AML acceptance mechanism. This is a string representation of a version number e.g. '1' or '1.4'"),(0,a.kt)("h5",{id:"transactionauthoragreementacceptancemechanism"},(0,a.kt)("inlineCode",{parentName:"h5"},"transactionAuthorAgreement.acceptanceMechanism")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("p",null,"The acceptance mechanism to choose. This ",(0,a.kt)("em",{parentName:"p"},"must")," be ",(0,a.kt)("em",{parentName:"p"},"one")," of the available labels of the acceptance mechanisms key-value pairs in the AML e.g. 'EULA'."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/394d7bf2.8e036a29.js b/assets/js/394d7bf2.8e036a29.js deleted file mode 100644 index 4b9f108c..00000000 --- a/assets/js/394d7bf2.8e036a29.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8368],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),d=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=d(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=d(n),m=a,h=u["".concat(l,".").concat(m)]||u[m]||p[m]||i;return n?r.createElement(h,o(o({ref:t},c),{},{components:n})):r.createElement(h,o({ref:t},c))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:a,o[1]=s;for(var d=2;d{n.d(t,{Z:()=>o});var r=n(7294),a=n(6010);const i={tabItem:"tabItem_Ymn6"};function o(e){let{children:t,hidden:n,className:o}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(i.tabItem,o),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>N});var r=n(7462),a=n(7294),i=n(6010),o=n(2466),s=n(6550),l=n(1980),d=n(7392),c=n(12);function u(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function p(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??u(n);return function(e){const t=(0,d.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const r=(0,s.k6)(),i=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,l._X)(i),(0,a.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(r.location.search);t.set(i,e),r.replace({...r.location,search:t.toString()})}),[i,r])]}function g(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,i=p(e),[o,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(!m({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 r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:i}))),[l,d]=h({queryString:n,groupId:r}),[u,g]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,i]=(0,c.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:r}),y=(()=>{const e=l??u;return m({value:e,tabValues:i})?e:null})();(0,a.useLayoutEffect)((()=>{y&&s(y)}),[y]);return{selectedValue:o,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);s(e),d(e),g(e)}),[d,g,i]),tabValues:i}}var y=n(2389);const f={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function v(e){let{className:t,block:n,selectedValue:s,selectValue:l,tabValues:d}=e;const c=[],{blockElementScrollPositionUntilNextRender:u}=(0,o.o5)(),p=e=>{const t=e.currentTarget,n=c.indexOf(t),r=d[n].value;r!==s&&(u(t),l(r))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},d.map((e=>{let{value:t,label:n,attributes:o}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:p},o,{className:(0,i.Z)("tabs__item",f.tabItem,o?.className,{"tabs__item--active":s===t})}),n??t)})))}function b(e){let{lazy:t,children:n,selectedValue:r}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function k(e){const t=g(e);return a.createElement("div",{className:(0,i.Z)("tabs-container",f.tabList)},a.createElement(v,(0,r.Z)({},e,t)),a.createElement(b,(0,r.Z)({},e,t)))}function N(e){const t=(0,y.Z)();return a.createElement(k,(0,r.Z)({key:String(t)},e))}},3172:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>d,toc:()=>u});var r=n(7462),a=(n(7294),n(3905)),i=n(4866),o=n(5162);const s={},l="Indy VDR",d={unversionedId:"getting-started/set-up/indy-vdr",id:"getting-started/set-up/indy-vdr",title:"Indy VDR",description:"Hyperledger Indy VDR, Verifiable Data Registry, can be used to connect to one or more Indy Node ledger pools given sets of genesis transactions. Methods are provided to construct ledger requests and send them to the validators, collecting the results and ensuring that there is a consensus between the nodes. In the context of Credo, we mainly leverage it to register, and resolve, schemas, credential definitions and DIDs.",source:"@site/guides/getting-started/set-up/indy-vdr.md",sourceDirName:"getting-started/set-up",slug:"/getting-started/set-up/indy-vdr",permalink:"/guides/0.5/getting-started/set-up/indy-vdr",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"AnonCreds",permalink:"/guides/0.5/getting-started/set-up/anoncreds"},next:{title:"cheqd",permalink:"/guides/0.5/getting-started/set-up/cheqd/"}},c={},u=[{value:"Installing Indy VDR",id:"installing-indy-vdr",level:3},{value:"Adding Indy VDR to the agent",id:"adding-indy-vdr-to-the-agent",level:3},{value:"Configuration",id:"configuration",level:3},{value:"indyVdr",id:"indyvdr",level:4},{value:"networks",id:"networks",level:4},{value:"indyNamespace",id:"indynamespace",level:5},{value:"isProduction",id:"isproduction",level:5},{value:"genesisTransactions",id:"genesistransactions",level:5},{value:"connectOnStartup",id:"connectonstartup",level:5},{value:"transactionAuthorAgreement",id:"transactionauthoragreement",level:5},{value:"transactionAuthorAgreement.version",id:"transactionauthoragreementversion",level:5},{value:"transactionAuthorAgreement.acceptanceMechanism",id:"transactionauthoragreementacceptancemechanism",level:5}],p={toc:u},m="wrapper";function h(e){let{components:t,...n}=e;return(0,a.kt)(m,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"indy-vdr"},"Indy VDR"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-vdr"},"Hyperledger Indy VDR"),", Verifiable Data Registry, can be used to connect to one or more Indy Node ledger pools given sets of genesis transactions. Methods are provided to construct ledger requests and send them to the validators, collecting the results and ensuring that there is a consensus between the nodes. In the context of Credo, we mainly leverage it to register, and resolve, schemas, credential definitions and DIDs."),(0,a.kt)("h3",{id:"installing-indy-vdr"},"Installing Indy VDR"),(0,a.kt)("p",null,"When using Credo with Indy VDR, there are a few extra dependencies that need to be installed. We need to install the ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/indy-vdr"),", which contains all the functionality to register objects on an Hyperledger Indy VDR. Secondly, we need to add native bindings for the specific platform ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/indy-vdr-"),". Currently there are bindings for Node.JS, as ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/indy-vdr-nodejs"),", and React Native as ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperlegder/indy-vdr-react-native"),"."),(0,a.kt)(i.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @credo-ts/indy-vdr@^0.5.0 @hyperledger/indy-vdr-nodejs@^0.2.0\n"))),(0,a.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @credo-ts/indy-vdr@^0.5.0 @hyperledger/indy-vdr-react-native@^0.2.0\n")))),(0,a.kt)("h3",{id:"adding-indy-vdr-to-the-agent"},"Adding Indy VDR to the agent"),(0,a.kt)("p",null,"After installing the dependencies, we can register the Indy VDR module on the agent."),(0,a.kt)(i.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-indy-vdr.ts section-1",showLineNumbers:!0,"set-up-indy-vdr.ts":!0,"section-1":!0},""))),(0,a.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-indy-vdr-rn.ts section-1",showLineNumbers:!0,"set-up-indy-vdr-rn.ts":!0,"section-1":!0},"")))),(0,a.kt)("h3",{id:"configuration"},"Configuration"),(0,a.kt)("p",null,"As you can see below, the Indy VDR module takes the native bindings and a list of networks. This list of networks will be used to resolve and register objects on."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"typescript showLineNumbers set-up-indy-vdr-config.ts section-1",typescript:!0,showLineNumbers:!0,"set-up-indy-vdr-config.ts":!0,"section-1":!0},"")),(0,a.kt)("h4",{id:"indyvdr"},"indyVdr"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"IndyVdr")),(0,a.kt)("p",null,"the ",(0,a.kt)("inlineCode",{parentName:"p"},"indyVdr")," key takes a class that implements all the native bindings for Indy VDR. This can be imoprted from the ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/indy-vdr-nodejs")," package or the ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/indy-vdr-react-native")," package."),(0,a.kt)("h4",{id:"networks"},"networks"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"IndyVdrPoolConfig[]")),(0,a.kt)("p",null,"An array of indy networks to connect to. The list can contain the following object and it must ",(0,a.kt)("a",{parentName:"p",href:"#indyledgersgenesistransactions"},(0,a.kt)("inlineCode",{parentName:"a"},"genesisTransactions")),"."),(0,a.kt)("h5",{id:"indynamespace"},"indyNamespace"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("p",null,"The Indy namespace aka the name identifying the name of the network connecting to. See also ",(0,a.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/indy-did-method/#indy-did-method-identifiers"},"indy did method identifiers")),(0,a.kt)("h5",{id:"isproduction"},(0,a.kt)("inlineCode",{parentName:"h5"},"isProduction")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"boolean")),(0,a.kt)("p",null,"Whether the ledger is a production ledger. This is used for detecting which ledger to use in case of unqualified identifiers as production ledgers have priority."),(0,a.kt)("h5",{id:"genesistransactions"},(0,a.kt)("inlineCode",{parentName:"h5"},"genesisTransactions")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("p",null,"Stringified JSON object of the transaction."),(0,a.kt)("h5",{id:"connectonstartup"},(0,a.kt)("inlineCode",{parentName:"h5"},"connectOnStartup")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"boolean")),(0,a.kt)("p",null,"Whether to connect to the ledger on startup. Defaults to ",(0,a.kt)("inlineCode",{parentName:"p"},"false"),"."),(0,a.kt)("h5",{id:"transactionauthoragreement"},(0,a.kt)("inlineCode",{parentName:"h5"},"transactionAuthorAgreement")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"TransactionAuthorAgreement")),(0,a.kt)("p",null,"JSON representation specifying the version and acceptance mechanism. The version is the unique version of the transaction author agreement acceptance mechanism list (AML). The acceptance mechanism refers to the acceptance mechanism label of the item in the AML. For more details you may consult the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-node/blob/master/docs/source/transactions.md#transaction_author_agreement_aml"},"indy-node docs on AML")),(0,a.kt)("h5",{id:"transactionauthoragreementversion"},(0,a.kt)("inlineCode",{parentName:"h5"},"transactionAuthorAgreement.version")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("p",null,"The version of the AML acceptance mechanism. This is a string representation of a version number e.g. '1' or '1.4'"),(0,a.kt)("h5",{id:"transactionauthoragreementacceptancemechanism"},(0,a.kt)("inlineCode",{parentName:"h5"},"transactionAuthorAgreement.acceptanceMechanism")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("p",null,"The acceptance mechanism to choose. This ",(0,a.kt)("em",{parentName:"p"},"must")," be ",(0,a.kt)("em",{parentName:"p"},"one")," of the available labels of the acceptance mechanisms key-value pairs in the AML e.g. 'EULA'."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/41c1fec5.ae3a9ded.js b/assets/js/41c1fec5.ae3a9ded.js deleted file mode 100644 index 49cf436f..00000000 --- a/assets/js/41c1fec5.ae3a9ded.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8796],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),p=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},s=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,s=d(e,["components","mdxType","originalType","parentName"]),u=p(r),m=a,f=u["".concat(l,".").concat(m)]||u[m]||c[m]||i;return r?n.createElement(f,o(o({ref:t},s),{},{components:r})):n.createElement(f,o({ref:t},s))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=m;var d={};for(var l in t)hasOwnProperty.call(t,l)&&(d[l]=t[l]);d.originalType=e,d[u]="string"==typeof e?e:a,o[1]=d;for(var p=2;p{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>c,frontMatter:()=>i,metadata:()=>d,toc:()=>p});var n=r(7462),a=(r(7294),r(3905));const i={},o="Decentralized Identifiers",d={unversionedId:"features/dids",id:"features/dids",title:"Decentralized Identifiers",description:"Decentralized identifiers are a core components of Credo, and used everywhere in the framework.",source:"@site/guides/features/dids.md",sourceDirName:"features",slug:"/features/dids",permalink:"/guides/0.5/features/dids",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"OpenID for Verifiable Credentials",permalink:"/guides/0.5/features/openid4vc"},next:{title:"Verifiable Credentials",permalink:"/guides/0.5/features/credentials"}},l={},p=[{value:"Supported DID Methods",id:"supported-did-methods",level:2}],s={toc:p},u="wrapper";function c(e){let{components:t,...r}=e;return(0,a.kt)(u,(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"decentralized-identifiers"},"Decentralized Identifiers"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://www.w3.org/TR/did-core/"},"Decentralized identifiers")," are a core components of Credo, and used everywhere in the framework."),(0,a.kt)("p",null,"The base DID implementation allows all components within the framework (whether it be credential signing, sending messages over DIDComm, or verifying a SIOPv2 ID Token) to leverage DIDs. The pluggable DID Resolver and DID Registrar interfaces allow for easy extension of the supported DID methods."),(0,a.kt)("p",null,"In addition, any DID can be imported into the framework, meaning it can be used for signing of credentials and DIDComm, without needing a DID Registrar to register the DID."),(0,a.kt)("h2",{id:"supported-did-methods"},"Supported DID Methods"),(0,a.kt)("p",null,"Currently the following DID methods are supported by Credo:"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Method"),(0,a.kt)("th",{parentName:"tr",align:null},"Note"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"did:key")),(0,a.kt)("td",{parentName:"tr",align:null})),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"did:jwk")),(0,a.kt)("td",{parentName:"tr",align:null})),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"did:peer")),(0,a.kt)("td",{parentName:"tr",align:null},"Not supported for OpenID4VC")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"did:web")),(0,a.kt)("td",{parentName:"tr",align:null},"No registrar available, but you can use the ",(0,a.kt)("inlineCode",{parentName:"td"},"DidDocumentBuilder")," to build and later import the DID Document.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"did:cheqd")),(0,a.kt)("td",{parentName:"tr",align:null},"Available through the ",(0,a.kt)("inlineCode",{parentName:"td"},"@credo-ts/cheqd")," package.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"did:indy")),(0,a.kt)("td",{parentName:"tr",align:null},"Available through the ",(0,a.kt)("inlineCode",{parentName:"td"},"@credo-ts/indy-vdr")," package.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"did:sov")),(0,a.kt)("td",{parentName:"tr",align:null},"Available through the ",(0,a.kt)("inlineCode",{parentName:"td"},"@credo-ts/indy-vdr")," package.")))))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/41c1fec5.c6cdda00.js b/assets/js/41c1fec5.c6cdda00.js new file mode 100644 index 00000000..b75c9ca4 --- /dev/null +++ b/assets/js/41c1fec5.c6cdda00.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8796],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),p=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},s=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,s=d(e,["components","mdxType","originalType","parentName"]),u=p(r),m=a,f=u["".concat(l,".").concat(m)]||u[m]||c[m]||i;return r?n.createElement(f,o(o({ref:t},s),{},{components:r})):n.createElement(f,o({ref:t},s))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=m;var d={};for(var l in t)hasOwnProperty.call(t,l)&&(d[l]=t[l]);d.originalType=e,d[u]="string"==typeof e?e:a,o[1]=d;for(var p=2;p{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>c,frontMatter:()=>i,metadata:()=>d,toc:()=>p});var n=r(7462),a=(r(7294),r(3905));const i={},o="Decentralized Identifiers",d={unversionedId:"features/dids",id:"features/dids",title:"Decentralized Identifiers",description:"Decentralized identifiers are a core components of Credo, and used everywhere in the framework.",source:"@site/guides/features/dids.md",sourceDirName:"features",slug:"/features/dids",permalink:"/guides/features/dids",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"OpenID for Verifiable Credentials",permalink:"/guides/features/openid4vc"},next:{title:"Verifiable Credentials",permalink:"/guides/features/credentials"}},l={},p=[{value:"Supported DID Methods",id:"supported-did-methods",level:2}],s={toc:p},u="wrapper";function c(e){let{components:t,...r}=e;return(0,a.kt)(u,(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"decentralized-identifiers"},"Decentralized Identifiers"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://www.w3.org/TR/did-core/"},"Decentralized identifiers")," are a core components of Credo, and used everywhere in the framework."),(0,a.kt)("p",null,"The base DID implementation allows all components within the framework (whether it be credential signing, sending messages over DIDComm, or verifying a SIOPv2 ID Token) to leverage DIDs. The pluggable DID Resolver and DID Registrar interfaces allow for easy extension of the supported DID methods."),(0,a.kt)("p",null,"In addition, any DID can be imported into the framework, meaning it can be used for signing of credentials and DIDComm, without needing a DID Registrar to register the DID."),(0,a.kt)("h2",{id:"supported-did-methods"},"Supported DID Methods"),(0,a.kt)("p",null,"Currently the following DID methods are supported by Credo:"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Method"),(0,a.kt)("th",{parentName:"tr",align:null},"Note"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"did:key")),(0,a.kt)("td",{parentName:"tr",align:null})),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"did:jwk")),(0,a.kt)("td",{parentName:"tr",align:null})),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"did:peer")),(0,a.kt)("td",{parentName:"tr",align:null},"Not supported for OpenID4VC")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"did:web")),(0,a.kt)("td",{parentName:"tr",align:null},"No registrar available, but you can use the ",(0,a.kt)("inlineCode",{parentName:"td"},"DidDocumentBuilder")," to build and later import the DID Document.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"did:cheqd")),(0,a.kt)("td",{parentName:"tr",align:null},"Available through the ",(0,a.kt)("inlineCode",{parentName:"td"},"@credo-ts/cheqd")," package.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"did:indy")),(0,a.kt)("td",{parentName:"tr",align:null},"Available through the ",(0,a.kt)("inlineCode",{parentName:"td"},"@credo-ts/indy-vdr")," package.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("inlineCode",{parentName:"td"},"did:sov")),(0,a.kt)("td",{parentName:"tr",align:null},"Available through the ",(0,a.kt)("inlineCode",{parentName:"td"},"@credo-ts/indy-vdr")," package.")))))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/43e7938e.3e109fe7.js b/assets/js/43e7938e.3e109fe7.js deleted file mode 100644 index 499a5e5f..00000000 --- a/assets/js/43e7938e.3e109fe7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[5846],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),u=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=u(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=u(n),m=r,h=d["".concat(l,".").concat(m)]||d[m]||p[m]||i;return n?a.createElement(h,o(o({ref:t},c),{},{components:n})):a.createElement(h,o({ref:t},c))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:r,o[1]=s;for(var u=2;u{n.d(t,{Z:()=>o});var a=n(7294),r=n(6010);const i={tabItem:"tabItem_Ymn6"};function o(e){let{children:t,hidden:n,className:o}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(i.tabItem,o),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>N});var a=n(7462),r=n(7294),i=n(6010),o=n(2466),s=n(6550),l=n(1980),u=n(7392),c=n(12);function d(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function p(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??d(n);return function(e){const t=(0,u.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const a=(0,s.k6)(),i=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,l._X)(i),(0,r.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(a.location.search);t.set(i,e),a.replace({...a.location,search:t.toString()})}),[i,a])]}function f(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,i=p(e),[o,s]=(0,r.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(!m({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:i}))),[l,u]=h({queryString:n,groupId:a}),[d,f]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,i]=(0,c.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:a}),g=(()=>{const e=l??d;return m({value:e,tabValues:i})?e:null})();(0,r.useLayoutEffect)((()=>{g&&s(g)}),[g]);return{selectedValue:o,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);s(e),u(e),f(e)}),[u,f,i]),tabValues:i}}var g=n(2389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:n,selectedValue:s,selectValue:l,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:d}=(0,o.o5)(),p=e=>{const t=e.currentTarget,n=c.indexOf(t),a=u[n].value;a!==s&&(d(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},u.map((e=>{let{value:t,label:n,attributes:o}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:p},o,{className:(0,i.Z)("tabs__item",b.tabItem,o?.className,{"tabs__item--active":s===t})}),n??t)})))}function v(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function y(e){const t=f(e);return r.createElement("div",{className:(0,i.Z)("tabs-container",b.tabList)},r.createElement(k,(0,a.Z)({},e,t)),r.createElement(v,(0,a.Z)({},e,t)))}function N(e){const t=(0,g.Z)();return r.createElement(y,(0,a.Z)({key:String(t)},e))}},6230:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>u,toc:()=>d});var a=n(7462),r=(n(7294),n(3905)),i=n(4866),o=n(5162);const s={},l="Issue a credential",u={unversionedId:"tutorials/issue-a-credential",id:"version-0.4/tutorials/issue-a-credential",title:"Issue a credential",description:"In this tutorial we will issue a credential from the Issuer to a Holder. We will start with setting up both their agents with the minimal configuration required to follow this tutorial. It is assumed that there is a connection between the Issuer and the Holder and the Issuer also has a registered schema and credential definition. After initializing the Issuer will send a credential to the holder, and will then accept this credential and automatically store it in their wallet.",source:"@site/versioned_docs/version-0.4/tutorials/issue-a-credential.md",sourceDirName:"tutorials",slug:"/tutorials/issue-a-credential",permalink:"/guides/tutorials/issue-a-credential",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Registering a schema and credential definition on an AnonCreds Registry",permalink:"/guides/tutorials/registering-schema-and-credential-definition"},next:{title:"Mediation",permalink:"/guides/tutorials/mediation"}},c={},d=[{value:"1. Setting up the agents",id:"1-setting-up-the-agents",level:3},{value:"Issuer",id:"issuer",level:4},{value:"Holder",id:"holder",level:4},{value:"3. Listening for incoming credentials",id:"3-listening-for-incoming-credentials",level:3},{value:"4. Issuing a credential",id:"4-issuing-a-credential",level:3},{value:"Useful resources",id:"useful-resources",level:3}],p={toc:d},m="wrapper";function h(e){let{components:t,...n}=e;return(0,r.kt)(m,(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"issue-a-credential"},"Issue a credential"),(0,r.kt)("p",null,"In this tutorial we will issue a credential from the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," to a ",(0,r.kt)("em",{parentName:"p"},"Holder"),". We will start with setting up both their agents with the minimal configuration required to follow this tutorial. It is assumed that there is a connection between the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," and the ",(0,r.kt)("em",{parentName:"p"},"Holder")," and the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," also has a registered schema and credential definition. After initializing the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," will send a credential to the ",(0,r.kt)("em",{parentName:"p"},"holder"),", and will then accept this credential and automatically store it in their wallet."),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Using ",(0,r.kt)("a",{parentName:"em",href:"https://anoncreds-wg.github.io/anoncreds-spec/"},"AnonCreds")," and the ",(0,r.kt)("a",{parentName:"em",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0453-issue-credential-v2/README.md"},"Issue Credential V2 Protocol")," or the ",(0,r.kt)("a",{parentName:"em",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0036-issue-credential/README.md"},"Issue Credential V1 Protocol"),".")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This section assumes that"),(0,r.kt)("ol",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ol"},"You have ",(0,r.kt)("a",{parentName:"li",href:"../getting-started"},"set-up your develoment environment"),"."),(0,r.kt)("li",{parentName:"ol"},"You have basic knowledge of the required fields in the ",(0,r.kt)("a",{parentName:"li",href:"./agent-config"},"Agent Config")),(0,r.kt)("li",{parentName:"ol"},"You have completed the ",(0,r.kt)("a",{parentName:"li",href:"./create-a-connection"},"Create a Connection tutorial")),(0,r.kt)("li",{parentName:"ol"},"You have a registered schema and credential definition. This can be done by following the ",(0,r.kt)("a",{parentName:"li",href:"./registering-schema-and-credential-definition"},"Registering on a AnonCreds Registry")))),(0,r.kt)("h3",{id:"1-setting-up-the-agents"},"1. Setting up the agents"),(0,r.kt)("p",null,"First for both agents we must setup and initialize an agent to work with. Depending on your target, ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/react-native"},"React Native")," or ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/react-native"},"Node.js"),", it might vary."),(0,r.kt)("p",null,"In this tutorial the ",(0,r.kt)("em",{parentName:"p"},"Holder")," will be in a ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/nodejs"},"Node.js environment")," and the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," also in a ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/nodejs"},"Node.js environment"),"."),(0,r.kt)("h4",{id:"issuer"},"Issuer"),(0,r.kt)("p",null,"For the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," the setup is commonly not the same as the ",(0,r.kt)("em",{parentName:"p"},"Holder"),". In the example they both live in a server environment, meaning they do not need a mediator. More commonly, the ",(0,r.kt)("em",{parentName:"p"},"Holder")," is in a mobile environment where a mediator is required for receiving DIDComm messages."),(0,r.kt)("p",null,"It is also very important for the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," to have a public DID, for the binding with a credential definition, amongst other things. For this demo we will use ",(0,r.kt)("a",{parentName:"p",href:"http://test.bcovrin.vonx.io"},"BCovrin Test"),". If you want to follow this tutorial, you have to register a public DID ",(0,r.kt)("a",{parentName:"p",href:"http://test.bcovrin.vonx.io"},"here")," via the Wallet seed field (this must be the same as the seed inside the config under the key ",(0,r.kt)("a",{parentName:"p",href:"./agent-config#publicdidseed"},(0,r.kt)("inlineCode",{parentName:"a"},"publicDidSeed")),")."),(0,r.kt)("p",null,"In order to reach the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," we have to add a list of ",(0,r.kt)("a",{parentName:"p",href:"./agent-config#endpoints"},(0,r.kt)("inlineCode",{parentName:"a"},"endpoints"))," of the agent that exposes the ",(0,r.kt)("inlineCode",{parentName:"p"},"inboundTransport")," to the public. In the example below we add an ",(0,r.kt)("inlineCode",{parentName:"p"},"inboundTransport")," and use port ",(0,r.kt)("inlineCode",{parentName:"p"},"3002"),". For development purposes it is recommended to use a tunneling service for this, like ",(0,r.kt)("a",{parentName:"p",href:"https://ngrok.com"},"Ngrok"),". Ngrok will allow you to reach your locally exposed endpoint from the public. If a tunneling service is used, make sure to use the ",(0,r.kt)("inlineCode",{parentName:"p"},"HTTPS")," variant as mobile environments, by default, do not accept ",(0,r.kt)("inlineCode",{parentName:"p"},"HTTP")," anymore."),(0,r.kt)("p",null,"To install ",(0,r.kt)("a",{parentName:"p",href:"https://ngrok.com"},"Ngrok")," and expose the port to the public the following commands can be used:"),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"yarn",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"yarn global add ngrok\n\nngrok http \n"))),(0,r.kt)(o.Z,{label:"npm",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"npm install --global ngrok\n\nngrok http \n")))),(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers issue-a-credential.ts section-1",showLineNumbers:!0,"issue-a-credential.ts":!0,"section-1":!0},""))),(0,r.kt)("h4",{id:"holder"},"Holder"),(0,r.kt)("p",null,"For the ",(0,r.kt)("em",{parentName:"p"},"Holder")," we need to setup a basic agent with a wallet, mediator, outbound transport and a ledger."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"If you want to follow this tutorial in a mobile environment:"),(0,r.kt)("ol",{parentName:"blockquote"},(0,r.kt)("li",{parentName:"ol"},"Use the ",(0,r.kt)("inlineCode",{parentName:"li"},"agentDependencies")," from ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/react-native")),(0,r.kt)("li",{parentName:"ol"},"It is very important to note that mobile agents do not support HTTP by default. It is recommended to do everything over HTTPS, but for development HTTP can be enabled for ",(0,r.kt)("a",{parentName:"li",href:"https://stackoverflow.com/questions/30731785/how-do-i-load-an-http-url-with-app-transport-security-enabled-in-ios-9"},"iOS")," and ",(0,r.kt)("a",{parentName:"li",href:"https://stackoverflow.com/questions/51902629/how-to-allow-all-network-connection-types-http-and-https-in-android-9-pie"},"Android"),"."))),(0,r.kt)("admonition",{type:"holder"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers issue-a-credential.ts section-2",showLineNumbers:!0,"issue-a-credential.ts":!0,"section-2":!0},""))),(0,r.kt)("h3",{id:"3-listening-for-incoming-credentials"},"3. Listening for incoming credentials"),(0,r.kt)("p",null,"When we want to accept a credential, we have to listen to incoming credentials and handle accordingly. In this example we do not have any user interaction, but is likely that your application would have a user-interface which would display the credential. When receiving a credential offer you can get the values from ",(0,r.kt)("inlineCode",{parentName:"p"},"credentialExchangeRecord.credentialAttributes"),"."),(0,r.kt)("admonition",{type:"holder"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers issue-a-credential.ts section-3",showLineNumbers:!0,"issue-a-credential.ts":!0,"section-3":!0},""))),(0,r.kt)("h3",{id:"4-issuing-a-credential"},"4. Issuing a credential"),(0,r.kt)("p",null,"Now that everything is setup on both sides, the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," can now offer a credential to the ",(0,r.kt)("em",{parentName:"p"},"Holder"),"."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"In this example we do not instantiate a connection and assume that there is one. Please refer to this guide ",(0,r.kt)("a",{parentName:"p",href:"./create-a-connection"},"Create a connection")," to get a connection and connectionId.")),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Indy",value:"tab1",mdxType:"TabItem"},(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers issue-a-credential.ts section-4",showLineNumbers:!0,"issue-a-credential.ts":!0,"section-4":!0},"")))),(0,r.kt)(o.Z,{label:"AnonCreds",value:"tab2",mdxType:"TabItem"},(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers issue-a-credential.ts section-5",showLineNumbers:!0,"issue-a-credential.ts":!0,"section-5":!0},""))))),(0,r.kt)("h3",{id:"useful-resources"},"Useful resources"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://anoncreds-wg.github.io/anoncreds-spec/"},"AnonCreds")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0036-issue-credential/README.md"},"Issue Credential V1 Protocol")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0453-issue-credential-v2/README.md"},"Issue Credential V2 Protocol"))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/43e7938e.fc896ab9.js b/assets/js/43e7938e.fc896ab9.js new file mode 100644 index 00000000..6be553a9 --- /dev/null +++ b/assets/js/43e7938e.fc896ab9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[5846],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),u=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=u(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=u(n),m=r,h=d["".concat(l,".").concat(m)]||d[m]||p[m]||i;return n?a.createElement(h,o(o({ref:t},c),{},{components:n})):a.createElement(h,o({ref:t},c))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:r,o[1]=s;for(var u=2;u{n.d(t,{Z:()=>o});var a=n(7294),r=n(6010);const i={tabItem:"tabItem_Ymn6"};function o(e){let{children:t,hidden:n,className:o}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(i.tabItem,o),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>N});var a=n(7462),r=n(7294),i=n(6010),o=n(2466),s=n(6550),l=n(1980),u=n(7392),c=n(12);function d(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function p(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??d(n);return function(e){const t=(0,u.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const a=(0,s.k6)(),i=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,l._X)(i),(0,r.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(a.location.search);t.set(i,e),a.replace({...a.location,search:t.toString()})}),[i,a])]}function f(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,i=p(e),[o,s]=(0,r.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(!m({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:i}))),[l,u]=h({queryString:n,groupId:a}),[d,f]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,i]=(0,c.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:a}),g=(()=>{const e=l??d;return m({value:e,tabValues:i})?e:null})();(0,r.useLayoutEffect)((()=>{g&&s(g)}),[g]);return{selectedValue:o,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);s(e),u(e),f(e)}),[u,f,i]),tabValues:i}}var g=n(2389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:n,selectedValue:s,selectValue:l,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:d}=(0,o.o5)(),p=e=>{const t=e.currentTarget,n=c.indexOf(t),a=u[n].value;a!==s&&(d(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},u.map((e=>{let{value:t,label:n,attributes:o}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:p},o,{className:(0,i.Z)("tabs__item",b.tabItem,o?.className,{"tabs__item--active":s===t})}),n??t)})))}function v(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function y(e){const t=f(e);return r.createElement("div",{className:(0,i.Z)("tabs-container",b.tabList)},r.createElement(k,(0,a.Z)({},e,t)),r.createElement(v,(0,a.Z)({},e,t)))}function N(e){const t=(0,g.Z)();return r.createElement(y,(0,a.Z)({key:String(t)},e))}},6230:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>u,toc:()=>d});var a=n(7462),r=(n(7294),n(3905)),i=n(4866),o=n(5162);const s={},l="Issue a credential",u={unversionedId:"tutorials/issue-a-credential",id:"version-0.4/tutorials/issue-a-credential",title:"Issue a credential",description:"In this tutorial we will issue a credential from the Issuer to a Holder. We will start with setting up both their agents with the minimal configuration required to follow this tutorial. It is assumed that there is a connection between the Issuer and the Holder and the Issuer also has a registered schema and credential definition. After initializing the Issuer will send a credential to the holder, and will then accept this credential and automatically store it in their wallet.",source:"@site/versioned_docs/version-0.4/tutorials/issue-a-credential.md",sourceDirName:"tutorials",slug:"/tutorials/issue-a-credential",permalink:"/guides/0.4/tutorials/issue-a-credential",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Registering a schema and credential definition on an AnonCreds Registry",permalink:"/guides/0.4/tutorials/registering-schema-and-credential-definition"},next:{title:"Mediation",permalink:"/guides/0.4/tutorials/mediation"}},c={},d=[{value:"1. Setting up the agents",id:"1-setting-up-the-agents",level:3},{value:"Issuer",id:"issuer",level:4},{value:"Holder",id:"holder",level:4},{value:"3. Listening for incoming credentials",id:"3-listening-for-incoming-credentials",level:3},{value:"4. Issuing a credential",id:"4-issuing-a-credential",level:3},{value:"Useful resources",id:"useful-resources",level:3}],p={toc:d},m="wrapper";function h(e){let{components:t,...n}=e;return(0,r.kt)(m,(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"issue-a-credential"},"Issue a credential"),(0,r.kt)("p",null,"In this tutorial we will issue a credential from the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," to a ",(0,r.kt)("em",{parentName:"p"},"Holder"),". We will start with setting up both their agents with the minimal configuration required to follow this tutorial. It is assumed that there is a connection between the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," and the ",(0,r.kt)("em",{parentName:"p"},"Holder")," and the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," also has a registered schema and credential definition. After initializing the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," will send a credential to the ",(0,r.kt)("em",{parentName:"p"},"holder"),", and will then accept this credential and automatically store it in their wallet."),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Using ",(0,r.kt)("a",{parentName:"em",href:"https://anoncreds-wg.github.io/anoncreds-spec/"},"AnonCreds")," and the ",(0,r.kt)("a",{parentName:"em",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0453-issue-credential-v2/README.md"},"Issue Credential V2 Protocol")," or the ",(0,r.kt)("a",{parentName:"em",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0036-issue-credential/README.md"},"Issue Credential V1 Protocol"),".")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This section assumes that"),(0,r.kt)("ol",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ol"},"You have ",(0,r.kt)("a",{parentName:"li",href:"../getting-started"},"set-up your develoment environment"),"."),(0,r.kt)("li",{parentName:"ol"},"You have basic knowledge of the required fields in the ",(0,r.kt)("a",{parentName:"li",href:"./agent-config"},"Agent Config")),(0,r.kt)("li",{parentName:"ol"},"You have completed the ",(0,r.kt)("a",{parentName:"li",href:"./create-a-connection"},"Create a Connection tutorial")),(0,r.kt)("li",{parentName:"ol"},"You have a registered schema and credential definition. This can be done by following the ",(0,r.kt)("a",{parentName:"li",href:"./registering-schema-and-credential-definition"},"Registering on a AnonCreds Registry")))),(0,r.kt)("h3",{id:"1-setting-up-the-agents"},"1. Setting up the agents"),(0,r.kt)("p",null,"First for both agents we must setup and initialize an agent to work with. Depending on your target, ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/react-native"},"React Native")," or ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/react-native"},"Node.js"),", it might vary."),(0,r.kt)("p",null,"In this tutorial the ",(0,r.kt)("em",{parentName:"p"},"Holder")," will be in a ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/nodejs"},"Node.js environment")," and the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," also in a ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/nodejs"},"Node.js environment"),"."),(0,r.kt)("h4",{id:"issuer"},"Issuer"),(0,r.kt)("p",null,"For the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," the setup is commonly not the same as the ",(0,r.kt)("em",{parentName:"p"},"Holder"),". In the example they both live in a server environment, meaning they do not need a mediator. More commonly, the ",(0,r.kt)("em",{parentName:"p"},"Holder")," is in a mobile environment where a mediator is required for receiving DIDComm messages."),(0,r.kt)("p",null,"It is also very important for the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," to have a public DID, for the binding with a credential definition, amongst other things. For this demo we will use ",(0,r.kt)("a",{parentName:"p",href:"http://test.bcovrin.vonx.io"},"BCovrin Test"),". If you want to follow this tutorial, you have to register a public DID ",(0,r.kt)("a",{parentName:"p",href:"http://test.bcovrin.vonx.io"},"here")," via the Wallet seed field (this must be the same as the seed inside the config under the key ",(0,r.kt)("a",{parentName:"p",href:"./agent-config#publicdidseed"},(0,r.kt)("inlineCode",{parentName:"a"},"publicDidSeed")),")."),(0,r.kt)("p",null,"In order to reach the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," we have to add a list of ",(0,r.kt)("a",{parentName:"p",href:"./agent-config#endpoints"},(0,r.kt)("inlineCode",{parentName:"a"},"endpoints"))," of the agent that exposes the ",(0,r.kt)("inlineCode",{parentName:"p"},"inboundTransport")," to the public. In the example below we add an ",(0,r.kt)("inlineCode",{parentName:"p"},"inboundTransport")," and use port ",(0,r.kt)("inlineCode",{parentName:"p"},"3002"),". For development purposes it is recommended to use a tunneling service for this, like ",(0,r.kt)("a",{parentName:"p",href:"https://ngrok.com"},"Ngrok"),". Ngrok will allow you to reach your locally exposed endpoint from the public. If a tunneling service is used, make sure to use the ",(0,r.kt)("inlineCode",{parentName:"p"},"HTTPS")," variant as mobile environments, by default, do not accept ",(0,r.kt)("inlineCode",{parentName:"p"},"HTTP")," anymore."),(0,r.kt)("p",null,"To install ",(0,r.kt)("a",{parentName:"p",href:"https://ngrok.com"},"Ngrok")," and expose the port to the public the following commands can be used:"),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"yarn",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"yarn global add ngrok\n\nngrok http \n"))),(0,r.kt)(o.Z,{label:"npm",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"npm install --global ngrok\n\nngrok http \n")))),(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers issue-a-credential.ts section-1",showLineNumbers:!0,"issue-a-credential.ts":!0,"section-1":!0},""))),(0,r.kt)("h4",{id:"holder"},"Holder"),(0,r.kt)("p",null,"For the ",(0,r.kt)("em",{parentName:"p"},"Holder")," we need to setup a basic agent with a wallet, mediator, outbound transport and a ledger."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"If you want to follow this tutorial in a mobile environment:"),(0,r.kt)("ol",{parentName:"blockquote"},(0,r.kt)("li",{parentName:"ol"},"Use the ",(0,r.kt)("inlineCode",{parentName:"li"},"agentDependencies")," from ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/react-native")),(0,r.kt)("li",{parentName:"ol"},"It is very important to note that mobile agents do not support HTTP by default. It is recommended to do everything over HTTPS, but for development HTTP can be enabled for ",(0,r.kt)("a",{parentName:"li",href:"https://stackoverflow.com/questions/30731785/how-do-i-load-an-http-url-with-app-transport-security-enabled-in-ios-9"},"iOS")," and ",(0,r.kt)("a",{parentName:"li",href:"https://stackoverflow.com/questions/51902629/how-to-allow-all-network-connection-types-http-and-https-in-android-9-pie"},"Android"),"."))),(0,r.kt)("admonition",{type:"holder"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers issue-a-credential.ts section-2",showLineNumbers:!0,"issue-a-credential.ts":!0,"section-2":!0},""))),(0,r.kt)("h3",{id:"3-listening-for-incoming-credentials"},"3. Listening for incoming credentials"),(0,r.kt)("p",null,"When we want to accept a credential, we have to listen to incoming credentials and handle accordingly. In this example we do not have any user interaction, but is likely that your application would have a user-interface which would display the credential. When receiving a credential offer you can get the values from ",(0,r.kt)("inlineCode",{parentName:"p"},"credentialExchangeRecord.credentialAttributes"),"."),(0,r.kt)("admonition",{type:"holder"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers issue-a-credential.ts section-3",showLineNumbers:!0,"issue-a-credential.ts":!0,"section-3":!0},""))),(0,r.kt)("h3",{id:"4-issuing-a-credential"},"4. Issuing a credential"),(0,r.kt)("p",null,"Now that everything is setup on both sides, the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," can now offer a credential to the ",(0,r.kt)("em",{parentName:"p"},"Holder"),"."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"In this example we do not instantiate a connection and assume that there is one. Please refer to this guide ",(0,r.kt)("a",{parentName:"p",href:"./create-a-connection"},"Create a connection")," to get a connection and connectionId.")),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Indy",value:"tab1",mdxType:"TabItem"},(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers issue-a-credential.ts section-4",showLineNumbers:!0,"issue-a-credential.ts":!0,"section-4":!0},"")))),(0,r.kt)(o.Z,{label:"AnonCreds",value:"tab2",mdxType:"TabItem"},(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers issue-a-credential.ts section-5",showLineNumbers:!0,"issue-a-credential.ts":!0,"section-5":!0},""))))),(0,r.kt)("h3",{id:"useful-resources"},"Useful resources"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://anoncreds-wg.github.io/anoncreds-spec/"},"AnonCreds")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0036-issue-credential/README.md"},"Issue Credential V1 Protocol")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0453-issue-credential-v2/README.md"},"Issue Credential V2 Protocol"))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/466eb4b6.5ddcaedb.js b/assets/js/466eb4b6.5ddcaedb.js new file mode 100644 index 00000000..5c913bb1 --- /dev/null +++ b/assets/js/466eb4b6.5ddcaedb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4354],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>g});var i=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function s(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var d=i.createContext({}),l=function(e){var t=i.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=l(e.components);return i.createElement(d.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},m=i.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,d=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),p=l(n),m=r,g=p["".concat(d,".").concat(m)]||p[m]||u[m]||a;return n?i.createElement(g,s(s({ref:t},c),{},{components:n})):i.createElement(g,s({ref:t},c))}));function g(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,s=new Array(a);s[0]=m;var o={};for(var d in t)hasOwnProperty.call(t,d)&&(o[d]=t[d]);o.originalType=e,o[p]="string"==typeof e?e:r,s[1]=o;for(var l=2;l{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>o,toc:()=>l});var i=n(7462),r=(n(7294),n(3905));const a={},s="Registering a schema and credential definition on an AnonCreds Registry",o={unversionedId:"tutorials/registering-schema-and-credential-definition",id:"tutorials/registering-schema-and-credential-definition",title:"Registering a schema and credential definition on an AnonCreds Registry",description:"In this tutorial we will register a schema and credential definition on an AnonCredsRegistry e.g. Hyperledger Indy ledger indy-vdr, cheqd.",source:"@site/guides/tutorials/registering-schema-and-credential-definition.md",sourceDirName:"tutorials",slug:"/tutorials/registering-schema-and-credential-definition",permalink:"/guides/tutorials/registering-schema-and-credential-definition",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Cheqd Did Module",permalink:"/guides/tutorials/cheqd/"},next:{title:"Issue a credential",permalink:"/guides/tutorials/issue-a-credential"}},d={},l=[{value:"1. Setting up the agent",id:"1-setting-up-the-agent",level:3},{value:"2. Importing a DID (optional)",id:"2-importing-a-did-optional",level:3},{value:"3. Registering a schema",id:"3-registering-a-schema",level:3},{value:"3. Registering a credential definition",id:"3-registering-a-credential-definition",level:3},{value:"Using it",id:"using-it",level:3},{value:"Useful Resources",id:"useful-resources",level:3}],c={toc:l},p="wrapper";function u(e){let{components:t,...n}=e;return(0,r.kt)(p,(0,i.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"registering-a-schema-and-credential-definition-on-an-anoncreds-registry"},"Registering a schema and credential definition on an AnonCreds Registry"),(0,r.kt)("p",null,"In this tutorial we will register a schema and credential definition on an AnonCredsRegistry e.g. Hyperledger Indy ledger ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-vdr"},"indy-vdr"),", ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts/packages/cheqd"},"cheqd"),"."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This section assumes that"),(0,r.kt)("ol",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ol"},"You have ",(0,r.kt)("a",{parentName:"li",href:"../getting-started"},"set-up your development environment"),"."),(0,r.kt)("li",{parentName:"ol"},"You have basic knowledge of the required fields in the ",(0,r.kt)("a",{parentName:"li",href:"./agent-config"},"Agent Config")))),(0,r.kt)("h3",{id:"1-setting-up-the-agent"},"1. Setting up the agent"),(0,r.kt)("p",null,"First, an agent must be setup with a wallet and an indy-vdr or cheqd module. For these code examples, we will use a Node.js environment."),(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers register-schema-and-cred-def.ts section-1",showLineNumbers:!0,"register-schema-and-cred-def.ts":!0,"section-1":!0},""))),(0,r.kt)("h3",{id:"2-importing-a-did-optional"},"2. Importing a DID (optional)"),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"There are many ledgers which can be used to register DIDs on for development."),(0,r.kt)("h4",{parentName:"admonition",id:"indy-vdr"},"Indy VDR"),(0,r.kt)("p",{parentName:"admonition"},"We recommend ",(0,r.kt)("a",{parentName:"p",href:"http://test.bcovrin.vonx.io/"},"BCovrin Testnet"),". This network allows very easily to register a DID from a seed which can then be used as the ",(0,r.kt)("inlineCode",{parentName:"p"},"privateKey")," in the snippet below. The seed is used as the private key for legacy compatibility with the Hyperledger Indy-SDK. The ",(0,r.kt)("a",{parentName:"p",href:"http://test.bcovrin.vonx.io/genesis"},"genesis transactions")," can also be retrieved for easy integration."),(0,r.kt)("h4",{parentName:"admonition",id:"cheqd"},"Cheqd"),(0,r.kt)("p",{parentName:"admonition"},"Follow the ",(0,r.kt)("a",{parentName:"p",href:"/guides/getting-started/set-up/cheqd/"},"cheqd setup")," and ",(0,r.kt)("a",{parentName:"p",href:"/guides/tutorials/cheqd/"},"cheqd DID module")," to setup the network and create a DID. Cheqd supports a mainnet for production and a testnet for development purposes.")),(0,r.kt)("p",null,"In order to register a schema and credential definition, a DID must be added to the agent first. This can be done by calling ",(0,r.kt)("inlineCode",{parentName:"p"},"agent.dids.create()"),", but this does require an endorser DID to be present as the ",(0,r.kt)("inlineCode",{parentName:"p"},"submitterDid"),". For this tutorial a DID will already be registered on the ledger, but it will be imported, with the associated private key, to be used later when registering the schema and credential definition."),(0,r.kt)("p",null,"This section can be omitted if your agent already has a DID in its wallet."),(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers register-schema-and-cred-def.ts section-2",showLineNumbers:!0,"register-schema-and-cred-def.ts":!0,"section-2":!0},""))),(0,r.kt)("h3",{id:"3-registering-a-schema"},"3. Registering a schema"),(0,r.kt)("p",null,"When you have a registered DID on a network and in your wallet, you can register a schema. Registering a schema requires four fields: ",(0,r.kt)("inlineCode",{parentName:"p"},"issuerId"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"name"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"version")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"attrNames"),". It is important to note that the ",(0,r.kt)("inlineCode",{parentName:"p"},"issuerId")," must be the same as a DID in your wallet."),(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers register-schema-and-cred-def.ts section-3",showLineNumbers:!0,"register-schema-and-cred-def.ts":!0,"section-3":!0},""))),(0,r.kt)("h3",{id:"3-registering-a-credential-definition"},"3. Registering a credential definition"),(0,r.kt)("p",null,"After registering a schema, a credential definition can be registered based on the schema. The credential definition, amongst more things, binds the schema to a specific issuer. Schemas can be reused between issuers, but a credential definition is specific to an issuer. In a credential definition revocation can also be specified. This section will not go in-depth about revocation."),(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers register-schema-and-cred-def.ts section-4",showLineNumbers:!0,"register-schema-and-cred-def.ts":!0,"section-4":!0},""))),(0,r.kt)("h3",{id:"using-it"},"Using it"),(0,r.kt)("p",null,"After everything is registered on a AnonCredsRegistry, we can use it to issue credentials. The next tutorial is all about issuing an AnonCreds credential with this setup."),(0,r.kt)("h3",{id:"useful-resources"},"Useful Resources"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://docs.cheqd.io/identity/guides/anoncreds"},"Cheqd AnonCreds Specification"))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/466eb4b6.fa1459da.js b/assets/js/466eb4b6.fa1459da.js deleted file mode 100644 index 9b4dc934..00000000 --- a/assets/js/466eb4b6.fa1459da.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4354],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>g});var i=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function s(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var d=i.createContext({}),l=function(e){var t=i.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=l(e.components);return i.createElement(d.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},m=i.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,d=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),p=l(n),m=r,g=p["".concat(d,".").concat(m)]||p[m]||u[m]||a;return n?i.createElement(g,s(s({ref:t},c),{},{components:n})):i.createElement(g,s({ref:t},c))}));function g(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,s=new Array(a);s[0]=m;var o={};for(var d in t)hasOwnProperty.call(t,d)&&(o[d]=t[d]);o.originalType=e,o[p]="string"==typeof e?e:r,s[1]=o;for(var l=2;l{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>o,toc:()=>l});var i=n(7462),r=(n(7294),n(3905));const a={},s="Registering a schema and credential definition on an AnonCreds Registry",o={unversionedId:"tutorials/registering-schema-and-credential-definition",id:"tutorials/registering-schema-and-credential-definition",title:"Registering a schema and credential definition on an AnonCreds Registry",description:"In this tutorial we will register a schema and credential definition on an AnonCredsRegistry e.g. Hyperledger Indy ledger indy-vdr, cheqd.",source:"@site/guides/tutorials/registering-schema-and-credential-definition.md",sourceDirName:"tutorials",slug:"/tutorials/registering-schema-and-credential-definition",permalink:"/guides/0.5/tutorials/registering-schema-and-credential-definition",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Cheqd Did Module",permalink:"/guides/0.5/tutorials/cheqd/"},next:{title:"Issue a credential",permalink:"/guides/0.5/tutorials/issue-a-credential"}},d={},l=[{value:"1. Setting up the agent",id:"1-setting-up-the-agent",level:3},{value:"2. Importing a DID (optional)",id:"2-importing-a-did-optional",level:3},{value:"3. Registering a schema",id:"3-registering-a-schema",level:3},{value:"3. Registering a credential definition",id:"3-registering-a-credential-definition",level:3},{value:"Using it",id:"using-it",level:3},{value:"Useful Resources",id:"useful-resources",level:3}],c={toc:l},p="wrapper";function u(e){let{components:t,...n}=e;return(0,r.kt)(p,(0,i.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"registering-a-schema-and-credential-definition-on-an-anoncreds-registry"},"Registering a schema and credential definition on an AnonCreds Registry"),(0,r.kt)("p",null,"In this tutorial we will register a schema and credential definition on an AnonCredsRegistry e.g. Hyperledger Indy ledger ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-vdr"},"indy-vdr"),", ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts/packages/cheqd"},"cheqd"),"."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This section assumes that"),(0,r.kt)("ol",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ol"},"You have ",(0,r.kt)("a",{parentName:"li",href:"../getting-started"},"set-up your development environment"),"."),(0,r.kt)("li",{parentName:"ol"},"You have basic knowledge of the required fields in the ",(0,r.kt)("a",{parentName:"li",href:"./agent-config"},"Agent Config")))),(0,r.kt)("h3",{id:"1-setting-up-the-agent"},"1. Setting up the agent"),(0,r.kt)("p",null,"First, an agent must be setup with a wallet and an indy-vdr or cheqd module. For these code examples, we will use a Node.js environment."),(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers register-schema-and-cred-def.ts section-1",showLineNumbers:!0,"register-schema-and-cred-def.ts":!0,"section-1":!0},""))),(0,r.kt)("h3",{id:"2-importing-a-did-optional"},"2. Importing a DID (optional)"),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"There are many ledgers which can be used to register DIDs on for development."),(0,r.kt)("h4",{parentName:"admonition",id:"indy-vdr"},"Indy VDR"),(0,r.kt)("p",{parentName:"admonition"},"We recommend ",(0,r.kt)("a",{parentName:"p",href:"http://test.bcovrin.vonx.io/"},"BCovrin Testnet"),". This network allows very easily to register a DID from a seed which can then be used as the ",(0,r.kt)("inlineCode",{parentName:"p"},"privateKey")," in the snippet below. The seed is used as the private key for legacy compatibility with the Hyperledger Indy-SDK. The ",(0,r.kt)("a",{parentName:"p",href:"http://test.bcovrin.vonx.io/genesis"},"genesis transactions")," can also be retrieved for easy integration."),(0,r.kt)("h4",{parentName:"admonition",id:"cheqd"},"Cheqd"),(0,r.kt)("p",{parentName:"admonition"},"Follow the ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.5/getting-started/set-up/cheqd/"},"cheqd setup")," and ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.5/tutorials/cheqd/"},"cheqd DID module")," to setup the network and create a DID. Cheqd supports a mainnet for production and a testnet for development purposes.")),(0,r.kt)("p",null,"In order to register a schema and credential definition, a DID must be added to the agent first. This can be done by calling ",(0,r.kt)("inlineCode",{parentName:"p"},"agent.dids.create()"),", but this does require an endorser DID to be present as the ",(0,r.kt)("inlineCode",{parentName:"p"},"submitterDid"),". For this tutorial a DID will already be registered on the ledger, but it will be imported, with the associated private key, to be used later when registering the schema and credential definition."),(0,r.kt)("p",null,"This section can be omitted if your agent already has a DID in its wallet."),(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers register-schema-and-cred-def.ts section-2",showLineNumbers:!0,"register-schema-and-cred-def.ts":!0,"section-2":!0},""))),(0,r.kt)("h3",{id:"3-registering-a-schema"},"3. Registering a schema"),(0,r.kt)("p",null,"When you have a registered DID on a network and in your wallet, you can register a schema. Registering a schema requires four fields: ",(0,r.kt)("inlineCode",{parentName:"p"},"issuerId"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"name"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"version")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"attrNames"),". It is important to note that the ",(0,r.kt)("inlineCode",{parentName:"p"},"issuerId")," must be the same as a DID in your wallet."),(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers register-schema-and-cred-def.ts section-3",showLineNumbers:!0,"register-schema-and-cred-def.ts":!0,"section-3":!0},""))),(0,r.kt)("h3",{id:"3-registering-a-credential-definition"},"3. Registering a credential definition"),(0,r.kt)("p",null,"After registering a schema, a credential definition can be registered based on the schema. The credential definition, amongst more things, binds the schema to a specific issuer. Schemas can be reused between issuers, but a credential definition is specific to an issuer. In a credential definition revocation can also be specified. This section will not go in-depth about revocation."),(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers register-schema-and-cred-def.ts section-4",showLineNumbers:!0,"register-schema-and-cred-def.ts":!0,"section-4":!0},""))),(0,r.kt)("h3",{id:"using-it"},"Using it"),(0,r.kt)("p",null,"After everything is registered on a AnonCredsRegistry, we can use it to issue credentials. The next tutorial is all about issuing an AnonCreds credential with this setup."),(0,r.kt)("h3",{id:"useful-resources"},"Useful Resources"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://docs.cheqd.io/identity/guides/anoncreds"},"Cheqd AnonCreds Specification"))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/470c56a2.746ba684.js b/assets/js/470c56a2.746ba684.js deleted file mode 100644 index 8c798494..00000000 --- a/assets/js/470c56a2.746ba684.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[9474],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>g});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),d=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=d(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),c=d(n),m=o,g=c["".concat(l,".").concat(m)]||c[m]||p[m]||r;return n?a.createElement(g,s(s({ref:t},u),{},{components:n})):a.createElement(g,s({ref:t},u))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,s=new Array(r);s[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[c]="string"==typeof e?e:o,s[1]=i;for(var d=2;d{n.d(t,{Z:()=>s});var a=n(7294),o=n(6010);const r={tabItem:"tabItem_Ymn6"};function s(e){let{children:t,hidden:n,className:s}=e;return a.createElement("div",{role:"tabpanel",className:(0,o.Z)(r.tabItem,s),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),o=n(7294),r=n(6010),s=n(2466),i=n(6550),l=n(1980),d=n(7392),u=n(12);function c(e){return function(e){return o.Children.map(e,(e=>{if((0,o.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:o}}=e;return{value:t,label:n,attributes:a,default:o}}))}function p(e){const{values:t,children:n}=e;return(0,o.useMemo)((()=>{const e=t??c(n);return function(e){const t=(0,d.l)(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 m(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 a=(0,i.k6)(),r=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,l._X)(r),(0,o.useCallback)((e=>{if(!r)return;const t=new URLSearchParams(a.location.search);t.set(r,e),a.replace({...a.location,search:t.toString()})}),[r,a])]}function h(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,r=p(e),[s,i]=(0,o.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(!m({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:r}))),[l,d]=g({queryString:n,groupId:a}),[c,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,r]=(0,u.Nk)(n);return[a,(0,o.useCallback)((e=>{n&&r.set(e)}),[n,r])]}({groupId:a}),f=(()=>{const e=l??c;return m({value:e,tabValues:r})?e:null})();(0,o.useLayoutEffect)((()=>{f&&i(f)}),[f]);return{selectedValue:s,selectValue:(0,o.useCallback)((e=>{if(!m({value:e,tabValues:r}))throw new Error(`Can't select invalid tab value=${e}`);i(e),d(e),h(e)}),[d,h,r]),tabValues:r}}var f=n(2389);const k={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){let{className:t,block:n,selectedValue:i,selectValue:l,tabValues:d}=e;const u=[],{blockElementScrollPositionUntilNextRender:c}=(0,s.o5)(),p=e=>{const t=e.currentTarget,n=u.indexOf(t),a=d[n].value;a!==i&&(c(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=u.indexOf(e.currentTarget)+1;t=u[n]??u[0];break}case"ArrowLeft":{const n=u.indexOf(e.currentTarget)-1;t=u[n]??u[u.length-1];break}}t?.focus()};return o.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.Z)("tabs",{"tabs--block":n},t)},d.map((e=>{let{value:t,label:n,attributes:s}=e;return o.createElement("li",(0,a.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>u.push(e),onKeyDown:m,onClick:p},s,{className:(0,r.Z)("tabs__item",k.tabItem,s?.className,{"tabs__item--active":i===t})}),n??t)})))}function b(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,o.cloneElement)(e,{className:"margin-top--md"}):null}return o.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,o.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function v(e){const t=h(e);return o.createElement("div",{className:(0,r.Z)("tabs-container",k.tabList)},o.createElement(y,(0,a.Z)({},e,t)),o.createElement(b,(0,a.Z)({},e,t)))}function w(e){const t=(0,f.Z)();return o.createElement(v,(0,a.Z)({key:String(t)},e))}},8354:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>g,frontMatter:()=>i,metadata:()=>d,toc:()=>c});var a=n(7462),o=(n(7294),n(3905)),r=n(4866),s=n(5162);const i={},l="Migrating from AFJ 0.2.x to 0.3.x",d={unversionedId:"updating/versions/0.2-to-0.3",id:"version-0.3/updating/versions/0.2-to-0.3",title:"Migrating from AFJ 0.2.x to 0.3.x",description:"This document describes everything you need to know for updating AFJ 0.2.x to 0.3.x. If you're not aware of how updating in AFJ works make sure to first read the guide on Updating AFJ.",source:"@site/versioned_docs/version-0.3/updating/versions/0.2-to-0.3.md",sourceDirName:"updating/versions",slug:"/updating/versions/0.2-to-0.3",permalink:"/guides/0.3/updating/versions/0.2-to-0.3",draft:!1,tags:[],version:"0.3",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Migrating from AFJ 0.1.0 to 0.2.x",permalink:"/guides/0.3/updating/versions/0.1-to-0.2"},next:{title:"The Aries JavaScript Ecosystem",permalink:"/guides/0.3/ecosystem/"}},u={},c=[{value:"React Native",id:"react-native",level:4},{value:"Node",id:"node",level:4},{value:"Breaking Code Changes",id:"breaking-code-changes",level:2},{value:"Agent creation",id:"agent-creation",level:3},{value:"0.2.x",id:"02x",level:5},{value:"0.3.x",id:"03x",level:5},{value:"did:key usage in protocols",id:"didkey-usage-in-protocols",level:3},{value:"Modules extracted from the core",id:"modules-extracted-from-the-core",level:3},{value:"0.2.x",id:"02x-1",level:5},{value:"0.3.x",id:"03x-1",level:5},{value:"Discover Features Module",id:"discover-features-module",level:3},{value:"0.2.x",id:"02x-2",level:5},{value:"0.3.x",id:"03x-2",level:5},{value:"0.2.x",id:"02x-3",level:5},{value:"0.3.x",id:"03x-3",level:5},{value:"Ledger Module",id:"ledger-module",level:3},{value:"Proofs Module",id:"proofs-module",level:3},{value:"Module API Updates",id:"module-api-updates",level:4},{value:"0.2.x",id:"02x-4",level:5},{value:"0.3.x",id:"03x-4",level:5},{value:"Messages Extracted from Proof Exchange Record",id:"messages-extracted-from-proof-exchange-record",level:4},{value:"0.2.x",id:"02x-5",level:5},{value:"0.3.x",id:"03x-5",level:5},{value:"Out Of Band Proofs and Credentials",id:"out-of-band-proofs-and-credentials",level:3},{value:"0.2.x",id:"02x-6",level:4},{value:"0.3.x",id:"03x-6",level:4},{value:"Updating Custom Modules to the new Plugin API",id:"updating-custom-modules-to-the-new-plugin-api",level:3},{value:"Renaming handler classes",id:"renaming-handler-classes",level:4},{value:"0.2.x",id:"02x-7",level:5},{value:"0.3.x",id:"03x-7",level:5},{value:"Using AgentContext",id:"using-agentcontext",level:4},{value:"0.2.x",id:"02x-8",level:4},{value:"0.3.x",id:"03x-8",level:4},{value:"Using OutboundMessageContext",id:"using-outboundmessagecontext",level:4},{value:"0.2.x",id:"02x-9",level:4},{value:"0.3.x",id:"03x-9",level:4},{value:"Updating module structure to register in new Plugin API",id:"updating-module-structure-to-register-in-new-plugin-api",level:4},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:2},{value:"Migrate Proof Record Properties",id:"migrate-proof-record-properties",level:3},{value:"0.2.x",id:"02x-10",level:4},{value:"0.3.x",id:"03x-10",level:4},{value:"Migrate Connection Record properties",id:"migrate-connection-record-properties",level:3},{value:"Migrate Did Record properties",id:"migrate-did-record-properties",level:3},{value:"0.2.x",id:"02x-11",level:4},{value:"0.3.x",id:"03x-11",level:4}],p={toc:c},m="wrapper";function g(e){let{components:t,...n}=e;return(0,o.kt)(m,(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"migrating-from-afj-02x-to-03x"},"Migrating from AFJ 0.2.x to 0.3.x"),(0,o.kt)("p",null,"This document describes everything you need to know for updating AFJ 0.2.x to 0.3.x. If you're not aware of how updating in AFJ works make sure to first read the guide on ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.5/updating/"},"Updating AFJ"),"."),(0,o.kt)("p",null,"First of all, update you dependencies to the 0.3.x versions. This will also update the needed peer depedencnies. ",(0,o.kt)("strong",{parentName:"p"},"Extension packages are not updated with this command"),". You need to update these manually, and make sure they're up to date with the latest version of AFJ."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"React Native",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/react-native@^0.3.0 @aries-framework/core@^0.3.0 indy-sdk-react-native@^0.3.0\n\n# or NPM\nnpn install @aries-framework/react-native@^0.3.0 @aries-framework/core@^0.3.0 indy-sdk-react-native@^0.3.0\n"))),(0,o.kt)(s.Z,{label:"Node",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/node@^0.3.0 @aries-framework/core@^0.3.0\n\n# or NPM\nnpm install @aries-framework/node@^0.3.0 @aries-framework/core@^0.3.0\n")))),(0,o.kt)("h2",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,o.kt)("p",null,"This section will list all breaking changes made to the public API of AFJ between version 0.2.x and 0.3.0."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here (e.g. see ",(0,o.kt)("a",{parentName:"p",href:"#Updating-Custom-Modules-to-the-new-Plugin-API"},"Updating Custom Modules to the Plugin API"),"), but it is possible some breaking changes are not documented here (feel free to open PRs).")),(0,o.kt)("h3",{id:"agent-creation"},"Agent creation"),(0,o.kt)("p",null,"The agent constructor has been updated to a single ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentOptions")," object that contains the config and dependencies properties."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const agent = new Agent(agentConfig, agentDependencies)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const agent = new Agent({ config: agentConfig, dependencies: agentDependencies })\n")))),(0,o.kt)("p",null,"This object contains:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"config: Agent's initial configuration"),(0,o.kt)("li",{parentName:"ul"},"dependencies: platform-specific Agent dependencies"),(0,o.kt)("li",{parentName:"ul"},"modules: optional field for internal module configuration and custom module registration")),(0,o.kt)("p",null,"For easy migration, you can simply construct ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentOptions")," by putting current InitConfig into ",(0,o.kt)("inlineCode",{parentName:"p"},"config")," key and agentDependencies into ",(0,o.kt)("inlineCode",{parentName:"p"},"dependencies")," key."),(0,o.kt)("p",null,"Note that, if you are defining ",(0,o.kt)("inlineCode",{parentName:"p"},"indyLedgers")," configuration, you should set the indyNamespace for every ledger, as explained in ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.3/tutorials/agent-config/#indyledgers"},"Agent Config tutorial"),"."),(0,o.kt)("h3",{id:"didkey-usage-in-protocols"},"did:key usage in protocols"),(0,o.kt)("p",null,"In accordance with ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/tree/b3a3942ef052039e73cd23d847f42947f8287da2/features/0360-use-did-key"},"Aries RFC 0360"),", since 0.2.5 there is a configuration parameter called ",(0,o.kt)("inlineCode",{parentName:"p"},"useDidKeyInProtocols")," which, when enabled, will encode keys in did:key instead of previous base58 format, unless the other party has started a protocol and is using base58."),(0,o.kt)("p",null,"This parameter was previously disabled by default and now it is enabled. If your agent only interacts with modern agents (e.g. AFJ 0.2.5 and newer) this will not represent any issue. Otherwise it is safer to explicitly set it to ",(0,o.kt)("inlineCode",{parentName:"p"},"false"),". However, keep in mind that we expect this setting to be deprecated in the future, so we encourage you to update all your agents to use did:key."),(0,o.kt)("h3",{id:"modules-extracted-from-the-core"},"Modules extracted from the core"),(0,o.kt)("p",null,"In this release two modules were extracted from the core and published as separate, optional packages:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"actionMenu has been moved to @aries-framework/action-menu"),(0,o.kt)("li",{parentName:"ul"},"questionAnswer has been moved to @aries-framework/question-answer")),(0,o.kt)("p",null,"If you want to use them, you can integrate in an Agent instance by injecting them in constructor, as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { ActionMenuModule } from '@aries-framework/action-menu'\nimport { QuestionAnswerModule } from '@aries-framework/question-answer'\n\nconst agent = new Agent({\n config: {\n /* config */\n },\n dependencies: agentDependencies,\n modules: {\n actionMenu: new ActionMenuModule(),\n questionAnswer: new QuestionAnswerModule(),\n /* other custom modules */\n },\n})\n")),(0,o.kt)("p",null,"As they are now considered custom modules, their API can be accessed in ",(0,o.kt)("inlineCode",{parentName:"p"},"modules")," namespace, so you should add it to every call to them."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.questionAnswer.sendQuestion(connectionId, {\n question: 'Do you want to play?',\n validResponses: [{ text: 'Yes' }, { text: 'No' }],\n})\n\nawait agent.questionAnswer.sendAnswer(questionAnswerRecordId, 'Yes')\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.modules.questionAnswer.sendQuestion(connectionId, {\n question: 'Do you want to play?',\n validResponses: [{ text: 'Yes' }, { text: 'No' }],\n})\n\nawait agent.modules.questionAnswer.sendAnswer(questionAnswerRecordId, 'Yes')\n")))),(0,o.kt)("h3",{id:"discover-features-module"},"Discover Features Module"),(0,o.kt)("p",null,"This module now supports both Discover Features V1 and V2, and as it happened to other modules, ",(0,o.kt)("inlineCode",{parentName:"p"},"queryFeatures")," method parameters have been unified to a single object and requires to specify the version of Discover Features protocol to be used. Note that ",(0,o.kt)("inlineCode",{parentName:"p"},"query")," property has been replaced by the more general ",(0,o.kt)("inlineCode",{parentName:"p"},"queries")," which accepts multiple features to be search for. To convert a query to this new format you simply need to create a single-object array whose unique object whose ",(0,o.kt)("inlineCode",{parentName:"p"},"featureType")," field is 'protocol' and ",(0,o.kt)("inlineCode",{parentName:"p"},"match")," field is the query itself."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.discovery.queryFeatures(connectionId, {\n query: 'https://didcomm.org/messagepickup/2.0',\n comment: 'Detect if protocol is supported',\n})\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.discovery.queryFeatures({\n connectionId,\n protocolVersion: 'v1',\n queries: [{ featureType: 'protocol', match: 'https://didcomm.org/messagepickup/2.0' }],\n comment: 'Detect if protocol is supported',\n})\n")))),(0,o.kt)("p",null,"The convenience method ",(0,o.kt)("strong",{parentName:"p"},"isProtocolSupported")," has been replaced by the more general synchronous mode of queryFeatures, which works when awaitDisclosures in options is set. Instead of returning a boolean, it returns an object with matching features:"),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const isPickUpV2Supported = await agent.discovery.isProtocolSupported(connectionId, StatusRequestMessage)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const discloseForPickupV2 = await agent.discovery.queryFeatures({\n connectionId: connectionId,\n protocolVersion: 'v1',\n queries: [{ featureType: 'protocol', match: StatusMessage.type.protocolUri }],\n awaitDisclosures: true,\n awaitDisclosuresTimeoutMs: 7000,\n})\n\nconst isPickUpV2Supported = discloseForPickupV2.features?.length === 1\n")))),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"Discover Features module does not rely anymore on Agent ",(0,o.kt)("inlineCode",{parentName:"p"},"Dispatcher")," to determine protocol support. Instead, it uses the new Feature Registry, where any custom modules implementing protocols must register them."),(0,o.kt)("p",{parentName:"admonition"},"This procedure can be done in module's ",(0,o.kt)("inlineCode",{parentName:"p"},"register(dependencyManager, featureRegistry)"),".")),(0,o.kt)("h3",{id:"ledger-module"},"Ledger Module"),(0,o.kt)("p",null,"Apart from the aforementioned indyLedgers configuration, you should also ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.3/tutorials/issue-a-credential#side-notes"},"note a slight change")," in behavior when attempting to register credential definitions that already exists on the ledger but not in the wallet."),(0,o.kt)("h3",{id:"proofs-module"},"Proofs Module"),(0,o.kt)("h4",{id:"module-api-updates"},"Module API Updates"),(0,o.kt)("p",null,"Much in the same way as in 0.2.0 release when ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.3/updating/versions/0.1-to-0.2#module-api-updates"},"Issue Credential V2 protocol")," has been added, now that Present Proof V2 is supported, we introduced changes to proofs module."),(0,o.kt)("p",null,"Basically, for all methods in the proofs module you should take the following steps to update your code:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Move all function parameters into a single object. All module methods now take a single object that contain all properties."),(0,o.kt)("li",{parentName:"ol"},"For methods that initiate proposals, requests or presentations (",(0,o.kt)("inlineCode",{parentName:"li"},"proposeProof"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"acceptProposal"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"requestProof"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"acceptPresentation"),", etc.), you should pass ",(0,o.kt)("inlineCode",{parentName:"li"},"protocolVersion: 'v1'")," to indicate we should use the v1 protocol"),(0,o.kt)("li",{parentName:"ol"},"All indy specific attributes (e.g. Presentation Preview) should be passed in the ",(0,o.kt)("inlineCode",{parentName:"li"},"proofFormats.indy")," object."),(0,o.kt)("li",{parentName:"ol"},"Some indy objects, as the preview should now be passed only as their attributes (i.e. no need of creating the object instance) and provided in the ",(0,o.kt)("inlineCode",{parentName:"li"},"proofFormats.indy")," object.")),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.proofs.proposeProof(\n 'connectionId',\n new PresentationPreview({\n attributes: [new PresentationPreviewAttribute({ name: 'key', value: 'value' })],\n predicates: [\n new PresentationPreviewPredicate({\n name: 'age',\n credentialDefinitionId,\n predicate: PredicateType.GreaterThanOrEqualTo,\n threshold: 50,\n }),\n ],\n })\n)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.proofs.proposeProof({\n connectionId: connection.id,\n protocolVersion: 'v1',\n proofFormats: {\n indy: {\n attributes: [{ name: 'key', value: 'value' }],\n predicates: [{name: 'age', credentialDefinitionId, predicate: PredicateType.GreaterThanOrEqualTo, threshold: 50, ]\n },\n },\n comment: 'Propose proof comment',\n})\n")))),(0,o.kt)("h4",{id:"messages-extracted-from-proof-exchange-record"},"Messages Extracted from Proof Exchange Record"),(0,o.kt)("p",null,"The DIDComm messages that were previously stored on the proof record, have been extracted to separate DIDComm message records. This makes it easier to work with multiple versions of the protocol internally, and keeps the proof exchange record agnostic of the protocol version. Instead of accessing the messages through the ",(0,o.kt)("inlineCode",{parentName:"p"},"proposalMessage"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"requestMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"presentationMessage")," parameters, we now expose dedicated methods on the proofs module to retrieve the message."),(0,o.kt)("p",null,"With the addition of the v2 messages, all v1 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," while v2 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V2")," (",(0,o.kt)("inlineCode",{parentName:"p"},"V1RequestPresentationMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"V2RequestPresentationMessage"),"). If you were using these messages classes throughout your codebase, update them to use the ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," prefix."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const proofRecord = await agent.proofs.getById('proofRecordId')\n\nconst proposalMessage = proofRecord.proposalMessage\nconst requestMessage = proofRecord.requestMessage\nconst presentationMessage = proofRecord.presentationMessage\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const proofRecord = await agent.proofs.getById('proofRecordId')\n\nconst proposalMessage = await agent.proofs.findProposalMessage('proofRecordId')\nconst requestMessage = await agent.proofs.findRequestMessage('proofRecordId')\nconst presentationMessage = await agent.proofs.findPresentationMessage('proofRecordId')\n")),(0,o.kt)("p",null,"Because AFJ now also supports the present proof v2 protocol, the return type of this protocol has been changed to ",(0,o.kt)("inlineCode",{parentName:"p"},"V1XXXMessage | V2XXXMessage | null"),". Take this into account when working with the messages."),(0,o.kt)("p",null,"You can check if a message is a specific version by using the ",(0,o.kt)("inlineCode",{parentName:"p"},"instanceof")," operator:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"if (proposalMessage instanceof V1RequestPresentationMessage) {\n // do something\n}\n")))),(0,o.kt)("h3",{id:"out-of-band-proofs-and-credentials"},"Out Of Band Proofs and Credentials"),(0,o.kt)("p",null,"With the addition of the out of band module, the creation of connection-less messages has been split into two steps, allowing for better control and flexibility. The previous ",(0,o.kt)("inlineCode",{parentName:"p"},"agent.proofs.createOutOfBandRequest")," has been replaced by the ",(0,o.kt)("inlineCode",{parentName:"p"},"agent.proofs.createRequest")," method. This new method creates a proof request that is not tied to any connection."),(0,o.kt)("p",null,"What you can now do is call ",(0,o.kt)("inlineCode",{parentName:"p"},"agent.oob.createLegacyConnectionlessInvitation")," to attach the service decorator to the message and get a legacy connectionless message."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { requestMessage, proofRecord } = await agent.proofs.createOutOfBandRequest({\n requestedAttributes: {\n group1: {\n name: 'dateOfBirth',\n restrictions: [{ schemaId: 'F72i3Y3Q4i466efjYJYCHM:2:aha_cert:4.1.1' }],\n },\n },\n})\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { message, proofRecord } = await agent.proofs.createRequest({\n protocolVersion: 'v1',\n proofFormats: {\n indy: {\n requestedAttributes: {\n group1: {\n name: 'dateOfBirth',\n restrictions: [\n {\n schemaId: 'F72i3Y3Q4i466efjYJYCHM:2:aha_cert:4.1.1',\n },\n ],\n },\n },\n },\n },\n})\n\nconst { invitationUrl, message: messageWithServiceDecorator } = await agent.oob.createLegacyConnectionlessInvitation({\n recordId: proofRecord.id,\n domain: 'https://google.com',\n message,\n})\n")))),(0,o.kt)("p",null,"Out of band invitations are the new way to send messages out of band. You can use it for connection-less exchanges, but also for exchanges that you want to establish a connection for first. Here's an example on how to use the out of band module to create a connection-less invitation for a proof request:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const outOfBandRecord = await agent.oob.createInvitation({\n handshake: false, // set to true if you want to create a connection\n messages: [message],\n})\n\nconst invitationUrl = outOfBandRecord.outOfBandInvitation.toUrl({\n domain: 'https://afj.com',\n})\n")),(0,o.kt)("p",null,"As you can see, there's now a lot more ways to use a message not tied to a connection. By splitting the creation of the message from the creation of the invitation, we can now create a message not bound to a connection (at time of creation) for multiple use cases."),(0,o.kt)("h3",{id:"updating-custom-modules-to-the-new-plugin-api"},"Updating Custom Modules to the new Plugin API"),(0,o.kt)("p",null,"Although this isn't a breaking change to the public API of the framework, it is something that you will need to take into account if you have custom modules and want to upgrade them to make compatible with AFJ 0.3.0."),(0,o.kt)("h4",{id:"renaming-handler-classes"},"Renaming handler classes"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"Handler")," has been have been renamed to ",(0,o.kt)("inlineCode",{parentName:"p"},"MessageHandler")," to be be more descriptive, along with related types and methods. This means:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Handler")," is now ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandler")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"HandlerInboundMessage")," is now ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandlerInboundMessage")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Dispatcher.registerHandler")," is now ",(0,o.kt)("inlineCode",{parentName:"li"},"Dispatcher.registerMessageHandler")," and is marked as deprecated. The recommended way of registering handlers is by using the new ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandlerRegistry")," object by calling ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandlerRegistry.registerMessageHandler"),".")),(0,o.kt)("p",null,"If your custom module include message handlers, you must update them accordingly."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"export class MyHandler implements Handler {\n public supportedMessages = [MyMessage]\n\n public async handle(inboundMessage: HandlerInboundMessage) {\n ...\n }\n}\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"export class MyHandler implements MessageHandler {\n public supportedMessages = [MyMessage]\n\n public async handle(inboundMessage: MessageHandlerInboundMessage) {\n ...\n }\n}\n")))),(0,o.kt)("h4",{id:"using-agentcontext"},"Using AgentContext"),(0,o.kt)("p",null,"First of all, it's worth noting that now all services and repositories have been made stateless. A new ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentContext")," is introduced that holds the current context, which is passed to each method call. Therefore, you'll need to update every call to services, repositories and also eventEmitter methods to pass ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentContext")," object as first argument."),(0,o.kt)("p",null,"AgentContext can be obtained from either:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"MessageContext used by message handlers (accesed as messageContext.agentContext)"),(0,o.kt)("li",{parentName:"ul"},"Injected in your API constructor: you can store the instance and pass it to all your service and repository calls")),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"}," public async createRequest(options: CreateRequestOptions) {\n const message = new RequestMessage({\n parentThreadId: options.parentThreadId,\n })\n\n const record = new MyRecord({\n connectionId: options.connectionRecord.id,\n threadId: message.id,\n parentThreadId: options.parentThreadId,\n })\n\n await this.myRecordRepository.save(record)\n\n this.eventEmitter.emit({\n type: MyRecordEventTypes.StateChanged,\n payload: {\n myRecord: record,\n previousState: null,\n },\n })\n\n return { record, message }\n }\n\n public async processRequest(messageContext: HandlerInboundMessage) {\n const { message } = messageContext\n\n const record = new MyRecord({\n connectionId: connection.id,\n threadId: messageContext.message.id,\n parentThreadId: messageContext.message.thread?.parentThreadId,\n })\n\n await this.myRepository.save(record)\n\n return record\n }\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"}," public async createRequest(agentContext: AgentContext, options: CreateRequestOptions) {\n const message = new RequestMessage({\n parentThreadId: options.parentThreadId,\n })\n\n const record = new MyRecord({\n connectionId: options.connectionRecord.id,\n threadId: message.id,\n parentThreadId: options.parentThreadId,\n })\n\n await this.myRecordRepository.save(agentContext, record)\n\n this.eventEmitter.emit(agentContext, {\n type: MyRecordEventTypes.StateChanged,\n payload: {\n myRecord: record,\n previousState: null,\n },\n })\n\n return { record, message }\n }\n\n public async processRequest(messageContext: MessageHandlerInboundMessage) {\n const { message } = messageContext\n\n const record = new MyRecord({\n connectionId: connection.id,\n threadId: messageContext.message.id,\n parentThreadId: messageContext.message.thread?.parentThreadId,\n })\n\n await this.myRepository.save(messageContext.agentContext, record)\n\n return record\n }\n")))),(0,o.kt)("h4",{id:"using-outboundmessagecontext"},"Using OutboundMessageContext"),(0,o.kt)("p",null,"If your module implements a protocol that sends messages to other agents, you will notice that Agent's ",(0,o.kt)("inlineCode",{parentName:"p"},"MessageSender")," now receives the more generic ",(0,o.kt)("inlineCode",{parentName:"p"},"OutboundMessageContext")," class, which replaces previous helper method ",(0,o.kt)("inlineCode",{parentName:"p"},"createOutboundMessage"),"."),(0,o.kt)("p",null,"You can take advantage of this new mechanism to associate a record to the context, in order to do specific actions to it when outbound message state changes (e.g. a ",(0,o.kt)("inlineCode",{parentName:"p"},"MessageSendingError")," is thrown or ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentMessageSentEvent")," is emitted)."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { createOutboundMessage } from '@aries-framework/core'\n\nconst outboundMessage = createOutboundMessage(connection, message)\nawait this.messageSender.sendMessage(outboundMessage)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { OutboundMessageContext } from '@aries-framework/core'\n\nconst outboundMessageContext = new OutboundMessageContext(message, {\n agentContext: this.agentContext,\n connection,\n // optional, if you want to link the message to a related record\n associatedRecord: record,\n})\n\nawait this.messageSender.sendMessage(outboundMessageContext)\n")))),(0,o.kt)("h4",{id:"updating-module-structure-to-register-in-new-plugin-api"},"Updating module structure to register in new Plugin API"),(0,o.kt)("p",null,"Existing modules can benefit from the new Plugin API mechanism by doing the following modifications:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Rename Module class (e.g. MyModule) to API class (MyApi) and add @injectable decorator. Inject AgentContext in order to pass it to any services or repositories it might call. For instance:")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { injectable } from '@aries-framework/core'\n\n@injectable() // <-- Add this\nexport class MyApi {\n private messageSender: MessageSender\n private myService: MyService\n private connectionService: ConnectionService\n private agentContext: AgentContext // <-- Add this\n\n public constructor(\n messageHandlerRegistry: MessageHandlerRegistry, // <-- use this instead of Dispatcher\n messageSender: MessageSender,\n myService: MyService,\n connectionService: ConnectionService,\n agentContext: AgentContext // <-- Add this\n ) {\n this.messageSender = messageSender\n this.myService = myService\n this.connectionService = connectionService\n this.agentContext = agentContext // <-- Add this\n this.registerHandlers(messageHandlerRegistry) // <-- use messageHandlerRegistry instead of dispatcher\n }\n")),(0,o.kt)("ol",{start:2},(0,o.kt)("li",{parentName:"ol"},"Create a new Module class that implements Module interface and registers the dependencies and features. For instance:")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import type { DependencyManager, FeatureRegistry, Module } from '@aries-framework/core'\n\nimport { Protocol } from '@aries-framework/core'\n\nexport class MyModule implements Module {\n public readonly api = MyApi // the one we've just renamed from MyModule\n\n public register(dependencyManager: DependencyManager, featureRegistry: FeatureRegistry) {\n // Api\n dependencyManager.registerContextScoped(MyApi)\n\n // Services\n dependencyManager.registerSingleton(MyService)\n\n // Repositories\n dependencyManager.registerSingleton(MyRepository)\n\n // Feature Registry: don't forget to register your protocols and other features your module may add\n featureRegistry.register(\n new Protocol({\n id: 'https://didcomm.org/my-protocol/1.0',\n roles: [MyRole.Sender, MyRole.Receiver],\n })\n )\n }\n")),(0,o.kt)("p",null,"After doing this, you can add your module to agent constructor like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const agent = new Agent({\n config: {\n /* config */\n },\n dependencies: agentDependencies,\n modules: {\n myModule: new MyModule(),\n /* other custom modules */\n },\n})\n\n// MyModule API can be accessed in agent.modules namespace\nawait agent.modules.myModule.doSomething()\n\nawait agent.modules.myModule.doAnotherThing()\n")),(0,o.kt)("h2",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,o.kt)("p",null,"The 0.3.0 release introduces some breaking changes to the storage format, mainly related to Proof Exchanges."),(0,o.kt)("p",null,"Below all breaking storage changes are explained in as much detail as possible. The update assistant provides all tools to migrate without a hassle, but it is important to know what has changed. All examples only show the keys that have changed, unrelated keys in records have been omitted."),(0,o.kt)("p",null,"See the ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.5/updating/update-assistant"},"Update Assistant")," documentation for a guide on how to use the update assistant."),(0,o.kt)("p",null,"There are no config parameters to be provided to the update assistant to migrate from 0.2.x to 0.3.x."),(0,o.kt)("h3",{id:"migrate-proof-record-properties"},"Migrate Proof Record Properties"),(0,o.kt)("p",null,"In 0.3.0 the v1 DIDComm messages have been moved out of the proof record into separate records using the DidCommMessageRepository. The migration scripts extracts all messages (proposalMessage, requestMessage, presentationMessage) and moves them into the DidCommMessageRepository. With the addition of support for different protocol versions the proof record now stores the protocol version."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "proposalMessage": { ... },\n "requestMessage": { ... },\n "presentationMessage": { ... },\n}\n'))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "protocolVersion": "v1"\n}\n')))),(0,o.kt)("h3",{id:"migrate-connection-record-properties"},"Migrate Connection Record properties"),(0,o.kt)("p",null,"The recently introduced ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionType")," tag has been pluralized to reflect the fact that more than a single connection type can be defined for a given connection. Also, it is now available as a direct record property (e.g. can be queried and set by using ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionRecord.connectionTypes"),") apart from the tag for efficient search."),(0,o.kt)("p",null,"The migration script renames ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionType")," to ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionTypes")," in all connections, and also searches for any mediation connection and adds ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionType.Mediator")," as one of its types."),(0,o.kt)("h3",{id:"migrate-did-record-properties"},"Migrate Did Record properties"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"didRecord.id")," was previously the did itself. However to allow for connecting with self, where multiple did records are created for the same did, the id property is now an uuid and a separate did property is added."),(0,o.kt)("p",null,"The migration script generates a new ID for each did record and stores its did into didRecord.did property."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": "did"\n}\n'))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": "uuid",\n "did": "did"\n}\n')))))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/470c56a2.de1568d2.js b/assets/js/470c56a2.de1568d2.js new file mode 100644 index 00000000..8de9dfa7 --- /dev/null +++ b/assets/js/470c56a2.de1568d2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[9474],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>g});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),d=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=d(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),c=d(n),m=o,g=c["".concat(l,".").concat(m)]||c[m]||p[m]||r;return n?a.createElement(g,s(s({ref:t},u),{},{components:n})):a.createElement(g,s({ref:t},u))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,s=new Array(r);s[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[c]="string"==typeof e?e:o,s[1]=i;for(var d=2;d{n.d(t,{Z:()=>s});var a=n(7294),o=n(6010);const r={tabItem:"tabItem_Ymn6"};function s(e){let{children:t,hidden:n,className:s}=e;return a.createElement("div",{role:"tabpanel",className:(0,o.Z)(r.tabItem,s),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),o=n(7294),r=n(6010),s=n(2466),i=n(6550),l=n(1980),d=n(7392),u=n(12);function c(e){return function(e){return o.Children.map(e,(e=>{if((0,o.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:o}}=e;return{value:t,label:n,attributes:a,default:o}}))}function p(e){const{values:t,children:n}=e;return(0,o.useMemo)((()=>{const e=t??c(n);return function(e){const t=(0,d.l)(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 m(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 a=(0,i.k6)(),r=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,l._X)(r),(0,o.useCallback)((e=>{if(!r)return;const t=new URLSearchParams(a.location.search);t.set(r,e),a.replace({...a.location,search:t.toString()})}),[r,a])]}function h(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,r=p(e),[s,i]=(0,o.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(!m({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:r}))),[l,d]=g({queryString:n,groupId:a}),[c,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,r]=(0,u.Nk)(n);return[a,(0,o.useCallback)((e=>{n&&r.set(e)}),[n,r])]}({groupId:a}),f=(()=>{const e=l??c;return m({value:e,tabValues:r})?e:null})();(0,o.useLayoutEffect)((()=>{f&&i(f)}),[f]);return{selectedValue:s,selectValue:(0,o.useCallback)((e=>{if(!m({value:e,tabValues:r}))throw new Error(`Can't select invalid tab value=${e}`);i(e),d(e),h(e)}),[d,h,r]),tabValues:r}}var f=n(2389);const k={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){let{className:t,block:n,selectedValue:i,selectValue:l,tabValues:d}=e;const u=[],{blockElementScrollPositionUntilNextRender:c}=(0,s.o5)(),p=e=>{const t=e.currentTarget,n=u.indexOf(t),a=d[n].value;a!==i&&(c(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=u.indexOf(e.currentTarget)+1;t=u[n]??u[0];break}case"ArrowLeft":{const n=u.indexOf(e.currentTarget)-1;t=u[n]??u[u.length-1];break}}t?.focus()};return o.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.Z)("tabs",{"tabs--block":n},t)},d.map((e=>{let{value:t,label:n,attributes:s}=e;return o.createElement("li",(0,a.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>u.push(e),onKeyDown:m,onClick:p},s,{className:(0,r.Z)("tabs__item",k.tabItem,s?.className,{"tabs__item--active":i===t})}),n??t)})))}function b(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,o.cloneElement)(e,{className:"margin-top--md"}):null}return o.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,o.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function v(e){const t=h(e);return o.createElement("div",{className:(0,r.Z)("tabs-container",k.tabList)},o.createElement(y,(0,a.Z)({},e,t)),o.createElement(b,(0,a.Z)({},e,t)))}function w(e){const t=(0,f.Z)();return o.createElement(v,(0,a.Z)({key:String(t)},e))}},8354:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>g,frontMatter:()=>i,metadata:()=>d,toc:()=>c});var a=n(7462),o=(n(7294),n(3905)),r=n(4866),s=n(5162);const i={},l="Migrating from AFJ 0.2.x to 0.3.x",d={unversionedId:"updating/versions/0.2-to-0.3",id:"version-0.3/updating/versions/0.2-to-0.3",title:"Migrating from AFJ 0.2.x to 0.3.x",description:"This document describes everything you need to know for updating AFJ 0.2.x to 0.3.x. If you're not aware of how updating in AFJ works make sure to first read the guide on Updating AFJ.",source:"@site/versioned_docs/version-0.3/updating/versions/0.2-to-0.3.md",sourceDirName:"updating/versions",slug:"/updating/versions/0.2-to-0.3",permalink:"/guides/0.3/updating/versions/0.2-to-0.3",draft:!1,tags:[],version:"0.3",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Migrating from AFJ 0.1.0 to 0.2.x",permalink:"/guides/0.3/updating/versions/0.1-to-0.2"},next:{title:"The Aries JavaScript Ecosystem",permalink:"/guides/0.3/ecosystem/"}},u={},c=[{value:"React Native",id:"react-native",level:4},{value:"Node",id:"node",level:4},{value:"Breaking Code Changes",id:"breaking-code-changes",level:2},{value:"Agent creation",id:"agent-creation",level:3},{value:"0.2.x",id:"02x",level:5},{value:"0.3.x",id:"03x",level:5},{value:"did:key usage in protocols",id:"didkey-usage-in-protocols",level:3},{value:"Modules extracted from the core",id:"modules-extracted-from-the-core",level:3},{value:"0.2.x",id:"02x-1",level:5},{value:"0.3.x",id:"03x-1",level:5},{value:"Discover Features Module",id:"discover-features-module",level:3},{value:"0.2.x",id:"02x-2",level:5},{value:"0.3.x",id:"03x-2",level:5},{value:"0.2.x",id:"02x-3",level:5},{value:"0.3.x",id:"03x-3",level:5},{value:"Ledger Module",id:"ledger-module",level:3},{value:"Proofs Module",id:"proofs-module",level:3},{value:"Module API Updates",id:"module-api-updates",level:4},{value:"0.2.x",id:"02x-4",level:5},{value:"0.3.x",id:"03x-4",level:5},{value:"Messages Extracted from Proof Exchange Record",id:"messages-extracted-from-proof-exchange-record",level:4},{value:"0.2.x",id:"02x-5",level:5},{value:"0.3.x",id:"03x-5",level:5},{value:"Out Of Band Proofs and Credentials",id:"out-of-band-proofs-and-credentials",level:3},{value:"0.2.x",id:"02x-6",level:4},{value:"0.3.x",id:"03x-6",level:4},{value:"Updating Custom Modules to the new Plugin API",id:"updating-custom-modules-to-the-new-plugin-api",level:3},{value:"Renaming handler classes",id:"renaming-handler-classes",level:4},{value:"0.2.x",id:"02x-7",level:5},{value:"0.3.x",id:"03x-7",level:5},{value:"Using AgentContext",id:"using-agentcontext",level:4},{value:"0.2.x",id:"02x-8",level:4},{value:"0.3.x",id:"03x-8",level:4},{value:"Using OutboundMessageContext",id:"using-outboundmessagecontext",level:4},{value:"0.2.x",id:"02x-9",level:4},{value:"0.3.x",id:"03x-9",level:4},{value:"Updating module structure to register in new Plugin API",id:"updating-module-structure-to-register-in-new-plugin-api",level:4},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:2},{value:"Migrate Proof Record Properties",id:"migrate-proof-record-properties",level:3},{value:"0.2.x",id:"02x-10",level:4},{value:"0.3.x",id:"03x-10",level:4},{value:"Migrate Connection Record properties",id:"migrate-connection-record-properties",level:3},{value:"Migrate Did Record properties",id:"migrate-did-record-properties",level:3},{value:"0.2.x",id:"02x-11",level:4},{value:"0.3.x",id:"03x-11",level:4}],p={toc:c},m="wrapper";function g(e){let{components:t,...n}=e;return(0,o.kt)(m,(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"migrating-from-afj-02x-to-03x"},"Migrating from AFJ 0.2.x to 0.3.x"),(0,o.kt)("p",null,"This document describes everything you need to know for updating AFJ 0.2.x to 0.3.x. If you're not aware of how updating in AFJ works make sure to first read the guide on ",(0,o.kt)("a",{parentName:"p",href:"/guides/updating/"},"Updating AFJ"),"."),(0,o.kt)("p",null,"First of all, update you dependencies to the 0.3.x versions. This will also update the needed peer depedencnies. ",(0,o.kt)("strong",{parentName:"p"},"Extension packages are not updated with this command"),". You need to update these manually, and make sure they're up to date with the latest version of AFJ."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"React Native",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/react-native@^0.3.0 @aries-framework/core@^0.3.0 indy-sdk-react-native@^0.3.0\n\n# or NPM\nnpn install @aries-framework/react-native@^0.3.0 @aries-framework/core@^0.3.0 indy-sdk-react-native@^0.3.0\n"))),(0,o.kt)(s.Z,{label:"Node",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/node@^0.3.0 @aries-framework/core@^0.3.0\n\n# or NPM\nnpm install @aries-framework/node@^0.3.0 @aries-framework/core@^0.3.0\n")))),(0,o.kt)("h2",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,o.kt)("p",null,"This section will list all breaking changes made to the public API of AFJ between version 0.2.x and 0.3.0."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here (e.g. see ",(0,o.kt)("a",{parentName:"p",href:"#Updating-Custom-Modules-to-the-new-Plugin-API"},"Updating Custom Modules to the Plugin API"),"), but it is possible some breaking changes are not documented here (feel free to open PRs).")),(0,o.kt)("h3",{id:"agent-creation"},"Agent creation"),(0,o.kt)("p",null,"The agent constructor has been updated to a single ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentOptions")," object that contains the config and dependencies properties."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const agent = new Agent(agentConfig, agentDependencies)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const agent = new Agent({ config: agentConfig, dependencies: agentDependencies })\n")))),(0,o.kt)("p",null,"This object contains:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"config: Agent's initial configuration"),(0,o.kt)("li",{parentName:"ul"},"dependencies: platform-specific Agent dependencies"),(0,o.kt)("li",{parentName:"ul"},"modules: optional field for internal module configuration and custom module registration")),(0,o.kt)("p",null,"For easy migration, you can simply construct ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentOptions")," by putting current InitConfig into ",(0,o.kt)("inlineCode",{parentName:"p"},"config")," key and agentDependencies into ",(0,o.kt)("inlineCode",{parentName:"p"},"dependencies")," key."),(0,o.kt)("p",null,"Note that, if you are defining ",(0,o.kt)("inlineCode",{parentName:"p"},"indyLedgers")," configuration, you should set the indyNamespace for every ledger, as explained in ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.3/tutorials/agent-config/#indyledgers"},"Agent Config tutorial"),"."),(0,o.kt)("h3",{id:"didkey-usage-in-protocols"},"did:key usage in protocols"),(0,o.kt)("p",null,"In accordance with ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/tree/b3a3942ef052039e73cd23d847f42947f8287da2/features/0360-use-did-key"},"Aries RFC 0360"),", since 0.2.5 there is a configuration parameter called ",(0,o.kt)("inlineCode",{parentName:"p"},"useDidKeyInProtocols")," which, when enabled, will encode keys in did:key instead of previous base58 format, unless the other party has started a protocol and is using base58."),(0,o.kt)("p",null,"This parameter was previously disabled by default and now it is enabled. If your agent only interacts with modern agents (e.g. AFJ 0.2.5 and newer) this will not represent any issue. Otherwise it is safer to explicitly set it to ",(0,o.kt)("inlineCode",{parentName:"p"},"false"),". However, keep in mind that we expect this setting to be deprecated in the future, so we encourage you to update all your agents to use did:key."),(0,o.kt)("h3",{id:"modules-extracted-from-the-core"},"Modules extracted from the core"),(0,o.kt)("p",null,"In this release two modules were extracted from the core and published as separate, optional packages:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"actionMenu has been moved to @aries-framework/action-menu"),(0,o.kt)("li",{parentName:"ul"},"questionAnswer has been moved to @aries-framework/question-answer")),(0,o.kt)("p",null,"If you want to use them, you can integrate in an Agent instance by injecting them in constructor, as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { ActionMenuModule } from '@aries-framework/action-menu'\nimport { QuestionAnswerModule } from '@aries-framework/question-answer'\n\nconst agent = new Agent({\n config: {\n /* config */\n },\n dependencies: agentDependencies,\n modules: {\n actionMenu: new ActionMenuModule(),\n questionAnswer: new QuestionAnswerModule(),\n /* other custom modules */\n },\n})\n")),(0,o.kt)("p",null,"As they are now considered custom modules, their API can be accessed in ",(0,o.kt)("inlineCode",{parentName:"p"},"modules")," namespace, so you should add it to every call to them."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.questionAnswer.sendQuestion(connectionId, {\n question: 'Do you want to play?',\n validResponses: [{ text: 'Yes' }, { text: 'No' }],\n})\n\nawait agent.questionAnswer.sendAnswer(questionAnswerRecordId, 'Yes')\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.modules.questionAnswer.sendQuestion(connectionId, {\n question: 'Do you want to play?',\n validResponses: [{ text: 'Yes' }, { text: 'No' }],\n})\n\nawait agent.modules.questionAnswer.sendAnswer(questionAnswerRecordId, 'Yes')\n")))),(0,o.kt)("h3",{id:"discover-features-module"},"Discover Features Module"),(0,o.kt)("p",null,"This module now supports both Discover Features V1 and V2, and as it happened to other modules, ",(0,o.kt)("inlineCode",{parentName:"p"},"queryFeatures")," method parameters have been unified to a single object and requires to specify the version of Discover Features protocol to be used. Note that ",(0,o.kt)("inlineCode",{parentName:"p"},"query")," property has been replaced by the more general ",(0,o.kt)("inlineCode",{parentName:"p"},"queries")," which accepts multiple features to be search for. To convert a query to this new format you simply need to create a single-object array whose unique object whose ",(0,o.kt)("inlineCode",{parentName:"p"},"featureType")," field is 'protocol' and ",(0,o.kt)("inlineCode",{parentName:"p"},"match")," field is the query itself."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.discovery.queryFeatures(connectionId, {\n query: 'https://didcomm.org/messagepickup/2.0',\n comment: 'Detect if protocol is supported',\n})\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.discovery.queryFeatures({\n connectionId,\n protocolVersion: 'v1',\n queries: [{ featureType: 'protocol', match: 'https://didcomm.org/messagepickup/2.0' }],\n comment: 'Detect if protocol is supported',\n})\n")))),(0,o.kt)("p",null,"The convenience method ",(0,o.kt)("strong",{parentName:"p"},"isProtocolSupported")," has been replaced by the more general synchronous mode of queryFeatures, which works when awaitDisclosures in options is set. Instead of returning a boolean, it returns an object with matching features:"),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const isPickUpV2Supported = await agent.discovery.isProtocolSupported(connectionId, StatusRequestMessage)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const discloseForPickupV2 = await agent.discovery.queryFeatures({\n connectionId: connectionId,\n protocolVersion: 'v1',\n queries: [{ featureType: 'protocol', match: StatusMessage.type.protocolUri }],\n awaitDisclosures: true,\n awaitDisclosuresTimeoutMs: 7000,\n})\n\nconst isPickUpV2Supported = discloseForPickupV2.features?.length === 1\n")))),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"Discover Features module does not rely anymore on Agent ",(0,o.kt)("inlineCode",{parentName:"p"},"Dispatcher")," to determine protocol support. Instead, it uses the new Feature Registry, where any custom modules implementing protocols must register them."),(0,o.kt)("p",{parentName:"admonition"},"This procedure can be done in module's ",(0,o.kt)("inlineCode",{parentName:"p"},"register(dependencyManager, featureRegistry)"),".")),(0,o.kt)("h3",{id:"ledger-module"},"Ledger Module"),(0,o.kt)("p",null,"Apart from the aforementioned indyLedgers configuration, you should also ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.3/tutorials/issue-a-credential#side-notes"},"note a slight change")," in behavior when attempting to register credential definitions that already exists on the ledger but not in the wallet."),(0,o.kt)("h3",{id:"proofs-module"},"Proofs Module"),(0,o.kt)("h4",{id:"module-api-updates"},"Module API Updates"),(0,o.kt)("p",null,"Much in the same way as in 0.2.0 release when ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.3/updating/versions/0.1-to-0.2#module-api-updates"},"Issue Credential V2 protocol")," has been added, now that Present Proof V2 is supported, we introduced changes to proofs module."),(0,o.kt)("p",null,"Basically, for all methods in the proofs module you should take the following steps to update your code:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Move all function parameters into a single object. All module methods now take a single object that contain all properties."),(0,o.kt)("li",{parentName:"ol"},"For methods that initiate proposals, requests or presentations (",(0,o.kt)("inlineCode",{parentName:"li"},"proposeProof"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"acceptProposal"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"requestProof"),", ",(0,o.kt)("inlineCode",{parentName:"li"},"acceptPresentation"),", etc.), you should pass ",(0,o.kt)("inlineCode",{parentName:"li"},"protocolVersion: 'v1'")," to indicate we should use the v1 protocol"),(0,o.kt)("li",{parentName:"ol"},"All indy specific attributes (e.g. Presentation Preview) should be passed in the ",(0,o.kt)("inlineCode",{parentName:"li"},"proofFormats.indy")," object."),(0,o.kt)("li",{parentName:"ol"},"Some indy objects, as the preview should now be passed only as their attributes (i.e. no need of creating the object instance) and provided in the ",(0,o.kt)("inlineCode",{parentName:"li"},"proofFormats.indy")," object.")),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.proofs.proposeProof(\n 'connectionId',\n new PresentationPreview({\n attributes: [new PresentationPreviewAttribute({ name: 'key', value: 'value' })],\n predicates: [\n new PresentationPreviewPredicate({\n name: 'age',\n credentialDefinitionId,\n predicate: PredicateType.GreaterThanOrEqualTo,\n threshold: 50,\n }),\n ],\n })\n)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.proofs.proposeProof({\n connectionId: connection.id,\n protocolVersion: 'v1',\n proofFormats: {\n indy: {\n attributes: [{ name: 'key', value: 'value' }],\n predicates: [{name: 'age', credentialDefinitionId, predicate: PredicateType.GreaterThanOrEqualTo, threshold: 50, ]\n },\n },\n comment: 'Propose proof comment',\n})\n")))),(0,o.kt)("h4",{id:"messages-extracted-from-proof-exchange-record"},"Messages Extracted from Proof Exchange Record"),(0,o.kt)("p",null,"The DIDComm messages that were previously stored on the proof record, have been extracted to separate DIDComm message records. This makes it easier to work with multiple versions of the protocol internally, and keeps the proof exchange record agnostic of the protocol version. Instead of accessing the messages through the ",(0,o.kt)("inlineCode",{parentName:"p"},"proposalMessage"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"requestMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"presentationMessage")," parameters, we now expose dedicated methods on the proofs module to retrieve the message."),(0,o.kt)("p",null,"With the addition of the v2 messages, all v1 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," while v2 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V2")," (",(0,o.kt)("inlineCode",{parentName:"p"},"V1RequestPresentationMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"V2RequestPresentationMessage"),"). If you were using these messages classes throughout your codebase, update them to use the ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," prefix."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const proofRecord = await agent.proofs.getById('proofRecordId')\n\nconst proposalMessage = proofRecord.proposalMessage\nconst requestMessage = proofRecord.requestMessage\nconst presentationMessage = proofRecord.presentationMessage\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const proofRecord = await agent.proofs.getById('proofRecordId')\n\nconst proposalMessage = await agent.proofs.findProposalMessage('proofRecordId')\nconst requestMessage = await agent.proofs.findRequestMessage('proofRecordId')\nconst presentationMessage = await agent.proofs.findPresentationMessage('proofRecordId')\n")),(0,o.kt)("p",null,"Because AFJ now also supports the present proof v2 protocol, the return type of this protocol has been changed to ",(0,o.kt)("inlineCode",{parentName:"p"},"V1XXXMessage | V2XXXMessage | null"),". Take this into account when working with the messages."),(0,o.kt)("p",null,"You can check if a message is a specific version by using the ",(0,o.kt)("inlineCode",{parentName:"p"},"instanceof")," operator:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"if (proposalMessage instanceof V1RequestPresentationMessage) {\n // do something\n}\n")))),(0,o.kt)("h3",{id:"out-of-band-proofs-and-credentials"},"Out Of Band Proofs and Credentials"),(0,o.kt)("p",null,"With the addition of the out of band module, the creation of connection-less messages has been split into two steps, allowing for better control and flexibility. The previous ",(0,o.kt)("inlineCode",{parentName:"p"},"agent.proofs.createOutOfBandRequest")," has been replaced by the ",(0,o.kt)("inlineCode",{parentName:"p"},"agent.proofs.createRequest")," method. This new method creates a proof request that is not tied to any connection."),(0,o.kt)("p",null,"What you can now do is call ",(0,o.kt)("inlineCode",{parentName:"p"},"agent.oob.createLegacyConnectionlessInvitation")," to attach the service decorator to the message and get a legacy connectionless message."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { requestMessage, proofRecord } = await agent.proofs.createOutOfBandRequest({\n requestedAttributes: {\n group1: {\n name: 'dateOfBirth',\n restrictions: [{ schemaId: 'F72i3Y3Q4i466efjYJYCHM:2:aha_cert:4.1.1' }],\n },\n },\n})\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { message, proofRecord } = await agent.proofs.createRequest({\n protocolVersion: 'v1',\n proofFormats: {\n indy: {\n requestedAttributes: {\n group1: {\n name: 'dateOfBirth',\n restrictions: [\n {\n schemaId: 'F72i3Y3Q4i466efjYJYCHM:2:aha_cert:4.1.1',\n },\n ],\n },\n },\n },\n },\n})\n\nconst { invitationUrl, message: messageWithServiceDecorator } = await agent.oob.createLegacyConnectionlessInvitation({\n recordId: proofRecord.id,\n domain: 'https://google.com',\n message,\n})\n")))),(0,o.kt)("p",null,"Out of band invitations are the new way to send messages out of band. You can use it for connection-less exchanges, but also for exchanges that you want to establish a connection for first. Here's an example on how to use the out of band module to create a connection-less invitation for a proof request:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const outOfBandRecord = await agent.oob.createInvitation({\n handshake: false, // set to true if you want to create a connection\n messages: [message],\n})\n\nconst invitationUrl = outOfBandRecord.outOfBandInvitation.toUrl({\n domain: 'https://afj.com',\n})\n")),(0,o.kt)("p",null,"As you can see, there's now a lot more ways to use a message not tied to a connection. By splitting the creation of the message from the creation of the invitation, we can now create a message not bound to a connection (at time of creation) for multiple use cases."),(0,o.kt)("h3",{id:"updating-custom-modules-to-the-new-plugin-api"},"Updating Custom Modules to the new Plugin API"),(0,o.kt)("p",null,"Although this isn't a breaking change to the public API of the framework, it is something that you will need to take into account if you have custom modules and want to upgrade them to make compatible with AFJ 0.3.0."),(0,o.kt)("h4",{id:"renaming-handler-classes"},"Renaming handler classes"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"Handler")," has been have been renamed to ",(0,o.kt)("inlineCode",{parentName:"p"},"MessageHandler")," to be be more descriptive, along with related types and methods. This means:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Handler")," is now ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandler")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"HandlerInboundMessage")," is now ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandlerInboundMessage")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"Dispatcher.registerHandler")," is now ",(0,o.kt)("inlineCode",{parentName:"li"},"Dispatcher.registerMessageHandler")," and is marked as deprecated. The recommended way of registering handlers is by using the new ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandlerRegistry")," object by calling ",(0,o.kt)("inlineCode",{parentName:"li"},"MessageHandlerRegistry.registerMessageHandler"),".")),(0,o.kt)("p",null,"If your custom module include message handlers, you must update them accordingly."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"export class MyHandler implements Handler {\n public supportedMessages = [MyMessage]\n\n public async handle(inboundMessage: HandlerInboundMessage) {\n ...\n }\n}\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"export class MyHandler implements MessageHandler {\n public supportedMessages = [MyMessage]\n\n public async handle(inboundMessage: MessageHandlerInboundMessage) {\n ...\n }\n}\n")))),(0,o.kt)("h4",{id:"using-agentcontext"},"Using AgentContext"),(0,o.kt)("p",null,"First of all, it's worth noting that now all services and repositories have been made stateless. A new ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentContext")," is introduced that holds the current context, which is passed to each method call. Therefore, you'll need to update every call to services, repositories and also eventEmitter methods to pass ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentContext")," object as first argument."),(0,o.kt)("p",null,"AgentContext can be obtained from either:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"MessageContext used by message handlers (accesed as messageContext.agentContext)"),(0,o.kt)("li",{parentName:"ul"},"Injected in your API constructor: you can store the instance and pass it to all your service and repository calls")),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"}," public async createRequest(options: CreateRequestOptions) {\n const message = new RequestMessage({\n parentThreadId: options.parentThreadId,\n })\n\n const record = new MyRecord({\n connectionId: options.connectionRecord.id,\n threadId: message.id,\n parentThreadId: options.parentThreadId,\n })\n\n await this.myRecordRepository.save(record)\n\n this.eventEmitter.emit({\n type: MyRecordEventTypes.StateChanged,\n payload: {\n myRecord: record,\n previousState: null,\n },\n })\n\n return { record, message }\n }\n\n public async processRequest(messageContext: HandlerInboundMessage) {\n const { message } = messageContext\n\n const record = new MyRecord({\n connectionId: connection.id,\n threadId: messageContext.message.id,\n parentThreadId: messageContext.message.thread?.parentThreadId,\n })\n\n await this.myRepository.save(record)\n\n return record\n }\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"}," public async createRequest(agentContext: AgentContext, options: CreateRequestOptions) {\n const message = new RequestMessage({\n parentThreadId: options.parentThreadId,\n })\n\n const record = new MyRecord({\n connectionId: options.connectionRecord.id,\n threadId: message.id,\n parentThreadId: options.parentThreadId,\n })\n\n await this.myRecordRepository.save(agentContext, record)\n\n this.eventEmitter.emit(agentContext, {\n type: MyRecordEventTypes.StateChanged,\n payload: {\n myRecord: record,\n previousState: null,\n },\n })\n\n return { record, message }\n }\n\n public async processRequest(messageContext: MessageHandlerInboundMessage) {\n const { message } = messageContext\n\n const record = new MyRecord({\n connectionId: connection.id,\n threadId: messageContext.message.id,\n parentThreadId: messageContext.message.thread?.parentThreadId,\n })\n\n await this.myRepository.save(messageContext.agentContext, record)\n\n return record\n }\n")))),(0,o.kt)("h4",{id:"using-outboundmessagecontext"},"Using OutboundMessageContext"),(0,o.kt)("p",null,"If your module implements a protocol that sends messages to other agents, you will notice that Agent's ",(0,o.kt)("inlineCode",{parentName:"p"},"MessageSender")," now receives the more generic ",(0,o.kt)("inlineCode",{parentName:"p"},"OutboundMessageContext")," class, which replaces previous helper method ",(0,o.kt)("inlineCode",{parentName:"p"},"createOutboundMessage"),"."),(0,o.kt)("p",null,"You can take advantage of this new mechanism to associate a record to the context, in order to do specific actions to it when outbound message state changes (e.g. a ",(0,o.kt)("inlineCode",{parentName:"p"},"MessageSendingError")," is thrown or ",(0,o.kt)("inlineCode",{parentName:"p"},"AgentMessageSentEvent")," is emitted)."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { createOutboundMessage } from '@aries-framework/core'\n\nconst outboundMessage = createOutboundMessage(connection, message)\nawait this.messageSender.sendMessage(outboundMessage)\n"))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { OutboundMessageContext } from '@aries-framework/core'\n\nconst outboundMessageContext = new OutboundMessageContext(message, {\n agentContext: this.agentContext,\n connection,\n // optional, if you want to link the message to a related record\n associatedRecord: record,\n})\n\nawait this.messageSender.sendMessage(outboundMessageContext)\n")))),(0,o.kt)("h4",{id:"updating-module-structure-to-register-in-new-plugin-api"},"Updating module structure to register in new Plugin API"),(0,o.kt)("p",null,"Existing modules can benefit from the new Plugin API mechanism by doing the following modifications:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Rename Module class (e.g. MyModule) to API class (MyApi) and add @injectable decorator. Inject AgentContext in order to pass it to any services or repositories it might call. For instance:")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { injectable } from '@aries-framework/core'\n\n@injectable() // <-- Add this\nexport class MyApi {\n private messageSender: MessageSender\n private myService: MyService\n private connectionService: ConnectionService\n private agentContext: AgentContext // <-- Add this\n\n public constructor(\n messageHandlerRegistry: MessageHandlerRegistry, // <-- use this instead of Dispatcher\n messageSender: MessageSender,\n myService: MyService,\n connectionService: ConnectionService,\n agentContext: AgentContext // <-- Add this\n ) {\n this.messageSender = messageSender\n this.myService = myService\n this.connectionService = connectionService\n this.agentContext = agentContext // <-- Add this\n this.registerHandlers(messageHandlerRegistry) // <-- use messageHandlerRegistry instead of dispatcher\n }\n")),(0,o.kt)("ol",{start:2},(0,o.kt)("li",{parentName:"ol"},"Create a new Module class that implements Module interface and registers the dependencies and features. For instance:")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import type { DependencyManager, FeatureRegistry, Module } from '@aries-framework/core'\n\nimport { Protocol } from '@aries-framework/core'\n\nexport class MyModule implements Module {\n public readonly api = MyApi // the one we've just renamed from MyModule\n\n public register(dependencyManager: DependencyManager, featureRegistry: FeatureRegistry) {\n // Api\n dependencyManager.registerContextScoped(MyApi)\n\n // Services\n dependencyManager.registerSingleton(MyService)\n\n // Repositories\n dependencyManager.registerSingleton(MyRepository)\n\n // Feature Registry: don't forget to register your protocols and other features your module may add\n featureRegistry.register(\n new Protocol({\n id: 'https://didcomm.org/my-protocol/1.0',\n roles: [MyRole.Sender, MyRole.Receiver],\n })\n )\n }\n")),(0,o.kt)("p",null,"After doing this, you can add your module to agent constructor like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const agent = new Agent({\n config: {\n /* config */\n },\n dependencies: agentDependencies,\n modules: {\n myModule: new MyModule(),\n /* other custom modules */\n },\n})\n\n// MyModule API can be accessed in agent.modules namespace\nawait agent.modules.myModule.doSomething()\n\nawait agent.modules.myModule.doAnotherThing()\n")),(0,o.kt)("h2",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,o.kt)("p",null,"The 0.3.0 release introduces some breaking changes to the storage format, mainly related to Proof Exchanges."),(0,o.kt)("p",null,"Below all breaking storage changes are explained in as much detail as possible. The update assistant provides all tools to migrate without a hassle, but it is important to know what has changed. All examples only show the keys that have changed, unrelated keys in records have been omitted."),(0,o.kt)("p",null,"See the ",(0,o.kt)("a",{parentName:"p",href:"/guides/updating/update-assistant"},"Update Assistant")," documentation for a guide on how to use the update assistant."),(0,o.kt)("p",null,"There are no config parameters to be provided to the update assistant to migrate from 0.2.x to 0.3.x."),(0,o.kt)("h3",{id:"migrate-proof-record-properties"},"Migrate Proof Record Properties"),(0,o.kt)("p",null,"In 0.3.0 the v1 DIDComm messages have been moved out of the proof record into separate records using the DidCommMessageRepository. The migration scripts extracts all messages (proposalMessage, requestMessage, presentationMessage) and moves them into the DidCommMessageRepository. With the addition of support for different protocol versions the proof record now stores the protocol version."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "proposalMessage": { ... },\n "requestMessage": { ... },\n "presentationMessage": { ... },\n}\n'))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "protocolVersion": "v1"\n}\n')))),(0,o.kt)("h3",{id:"migrate-connection-record-properties"},"Migrate Connection Record properties"),(0,o.kt)("p",null,"The recently introduced ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionType")," tag has been pluralized to reflect the fact that more than a single connection type can be defined for a given connection. Also, it is now available as a direct record property (e.g. can be queried and set by using ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionRecord.connectionTypes"),") apart from the tag for efficient search."),(0,o.kt)("p",null,"The migration script renames ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionType")," to ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionTypes")," in all connections, and also searches for any mediation connection and adds ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionType.Mediator")," as one of its types."),(0,o.kt)("h3",{id:"migrate-did-record-properties"},"Migrate Did Record properties"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"didRecord.id")," was previously the did itself. However to allow for connecting with self, where multiple did records are created for the same did, the id property is now an uuid and a separate did property is added."),(0,o.kt)("p",null,"The migration script generates a new ID for each did record and stores its did into didRecord.did property."),(0,o.kt)(r.Z,{mdxType:"Tabs"},(0,o.kt)(s.Z,{label:"0.2.x",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": "did"\n}\n'))),(0,o.kt)(s.Z,{label:"0.3.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "id": "uuid",\n "did": "did"\n}\n')))))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/4a99cab5.6b42005a.js b/assets/js/4a99cab5.c04f495d.js similarity index 58% rename from assets/js/4a99cab5.6b42005a.js rename to assets/js/4a99cab5.c04f495d.js index 133c9901..ab361b1a 100644 --- a/assets/js/4a99cab5.6b42005a.js +++ b/assets/js/4a99cab5.c04f495d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4378],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,s=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=c(n),m=a,h=d["".concat(l,".").concat(m)]||d[m]||p[m]||s;return n?r.createElement(h,o(o({ref:t},u),{},{components:n})):r.createElement(h,o({ref:t},u))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=n.length,o=new Array(s);o[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[d]="string"==typeof e?e:a,o[1]=i;for(var c=2;c{n.d(t,{Z:()=>g});var r=n(7294),a=n(6010),s=n(3438),o=n(9960),i=n(3919),l=n(5999);const c={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function u(e){let{href:t,children:n}=e;return r.createElement(o.Z,{href:t,className:(0,a.Z)("card padding--lg",c.cardContainer)},n)}function d(e){let{href:t,icon:n,title:s,description:o}=e;return r.createElement(u,{href:t},r.createElement("h2",{className:(0,a.Z)("text--truncate",c.cardTitle),title:s},n," ",s),o&&r.createElement("p",{className:(0,a.Z)("text--truncate",c.cardDescription),title:o},o))}function p(e){let{item:t}=e;const n=(0,s.Wl)(t);return n?r.createElement(d,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,l.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function m(e){let{item:t}=e;const n=(0,i.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",a=(0,s.xz)(t.docId??void 0);return r.createElement(d,{href:t.href,icon:n,title:t.label,description:a?.description})}function h(e){let{item:t}=e;switch(t.type){case"link":return r.createElement(m,{item:t});case"category":return r.createElement(p,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function f(e){let{className:t}=e;const n=(0,s.jA)();return r.createElement(g,{items:n.items,className:t})}function g(e){const{items:t,className:n}=e;if(!t)return r.createElement(f,e);const o=(0,s.MN)(t);return r.createElement("section",{className:(0,a.Z)("row",n)},o.map(((e,t)=>r.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},r.createElement(h,{item:e})))))}},5162:(e,t,n)=>{n.d(t,{Z:()=>o});var r=n(7294),a=n(6010);const s={tabItem:"tabItem_Ymn6"};function o(e){let{children:t,hidden:n,className:o}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(s.tabItem,o),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var r=n(7462),a=n(7294),s=n(6010),o=n(2466),i=n(6550),l=n(1980),c=n(7392),u=n(12);function d(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function p(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??d(n);return function(e){const t=(0,c.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const r=(0,i.k6)(),s=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,l._X)(s),(0,a.useCallback)((e=>{if(!s)return;const t=new URLSearchParams(r.location.search);t.set(s,e),r.replace({...r.location,search:t.toString()})}),[s,r])]}function f(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,s=p(e),[o,i]=(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(!m({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 r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:s}))),[l,c]=h({queryString:n,groupId:r}),[d,f]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,s]=(0,u.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&s.set(e)}),[n,s])]}({groupId:r}),g=(()=>{const e=l??d;return m({value:e,tabValues:s})?e:null})();(0,a.useLayoutEffect)((()=>{g&&i(g)}),[g]);return{selectedValue:o,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:s}))throw new Error(`Can't select invalid tab value=${e}`);i(e),c(e),f(e)}),[c,f,s]),tabValues:s}}var g=n(2389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:n,selectedValue:i,selectValue:l,tabValues:c}=e;const u=[],{blockElementScrollPositionUntilNextRender:d}=(0,o.o5)(),p=e=>{const t=e.currentTarget,n=u.indexOf(t),r=c[n].value;r!==i&&(d(t),l(r))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=u.indexOf(e.currentTarget)+1;t=u[n]??u[0];break}case"ArrowLeft":{const n=u.indexOf(e.currentTarget)-1;t=u[n]??u[u.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.Z)("tabs",{"tabs--block":n},t)},c.map((e=>{let{value:t,label:n,attributes:o}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>u.push(e),onKeyDown:m,onClick:p},o,{className:(0,s.Z)("tabs__item",b.tabItem,o?.className,{"tabs__item--active":i===t})}),n??t)})))}function v(e){let{lazy:t,children:n,selectedValue:r}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function y(e){const t=f(e);return a.createElement("div",{className:(0,s.Z)("tabs-container",b.tabList)},a.createElement(k,(0,r.Z)({},e,t)),a.createElement(v,(0,r.Z)({},e,t)))}function w(e){const t=(0,g.Z)();return a.createElement(y,(0,r.Z)({key:String(t)},e))}},2655:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>d});var r=n(7462),a=(n(7294),n(3905)),s=n(4866),o=n(5162);n(2991);const i={},l="cheqd",c={unversionedId:"getting-started/set-up/cheqd/index",id:"version-0.4/getting-started/set-up/cheqd/index",title:"cheqd",description:"cheqd is a blockchain network, built in the Cosmos ecosystem for Self-Sovereign Identity (SSI). The cheqd Network leverages the cheqd DID method and enables DID-Linked Resources to be written to the network, associated with a DID and controlled using the verification methods in the DID Document.",source:"@site/versioned_docs/version-0.4/getting-started/set-up/cheqd/index.md",sourceDirName:"getting-started/set-up/cheqd",slug:"/getting-started/set-up/cheqd/",permalink:"/guides/getting-started/set-up/cheqd/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Indy VDR",permalink:"/guides/getting-started/set-up/indy-vdr"},next:{title:"Concepts",permalink:"/guides/concepts/"}},u={},d=[{value:"Installing cheqd",id:"installing-cheqd",level:3},{value:"React Native",id:"react-native",level:4},{value:"Adding the cheqd to the Agent",id:"adding-the-cheqd-to-the-agent",level:3},{value:"Tutorials",id:"tutorials",level:3}],p={toc:d},m="wrapper";function h(e){let{components:t,...n}=e;return(0,a.kt)(m,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"cheqd"},"cheqd"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/cheqd/sdk"},"cheqd")," is a blockchain network, built in the Cosmos ecosystem for Self-Sovereign Identity (SSI). The cheqd Network leverages the ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cheqd.io/identity/architecture/adr-list/adr-001-cheqd-did-method"},"cheqd DID method")," and enables ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cheqd.io/identity/architecture/adr-list/adr-002-did-linked-resources"},"DID-Linked Resources")," to be written to the network, associated with a DID and controlled using the verification methods in the DID Document."),(0,a.kt)("p",null,"Through this approach, the cheqd Network is able to natively support the ",(0,a.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-spec/"},"Ledger Agnostic AnonCreds Specification (v1.0)")," through its ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cheqd.io/identity/guides/anoncreds"},"AnonCreds Object Method")," (as well as VC-JWT and JSON-LD)."),(0,a.kt)("p",null,"cheqd also has a dedicated token, $CHEQ, used for identity writes to the network, voting in a decentralised governance framework as well as for various payment flows between verifiers, holders and issuers of Verifiable Credentials."),(0,a.kt)("h3",{id:"installing-cheqd"},"Installing cheqd"),(0,a.kt)("p",null,"When using Aries Framework JavaScript with the cheqd, there's a few extra dependencies that need to be installed. We need to install the ",(0,a.kt)("inlineCode",{parentName:"p"},"@aries-framework/cheqd")," package, which implements the needed interfaces for the agent."),(0,a.kt)("h4",{id:"react-native"},"React Native"),(0,a.kt)("p",null,"To enable react-native support we need to follow the steps below"),(0,a.kt)("p",null,"In the package.json file add the below code snippet, which replaces the cosmjs dependencies witht he cosmjs-rn packages"),(0,a.kt)(s.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{label:"NPM",value:"tab1",mdxType:"TabItem"},(0,a.kt)("p",null,"Using ",(0,a.kt)("a",{parentName:"p",href:"https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides"},"NPM ",(0,a.kt)("inlineCode",{parentName:"a"},"overrides"))," we can point the ",(0,a.kt)("inlineCode",{parentName:"p"},"cosmjs")," packages to ",(0,a.kt)("inlineCode",{parentName:"p"},"cosmjs-rn"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'{\n "overrides": {\n "@cosmjs/amino": "npm:@cosmjs-rn/amino@^0.27.1",\n "@cosmjs/encoding": "npm:@cosmjs-rn/encoding@^0.27.1",\n "@cosmjs/math": "npm:@cosmjs-rn/math@^0.27.1",\n "@cosmjs/stargate": "npm:@cosmjs-rn/stargate@^0.27.1",\n "@cosmjs/tendermint-rpc": "npm:@cosmjs-rn/tendermint-rpc@^0.27.1",\n "@cosmjs/utils": "npm:@cosmjs-rn/utils@^0.27.1",\n "@cosmjs/proto-signing": "npm:@cosmjs-rn/proto-signing@^0.27.1",\n "@cosmjs/crypto": "npm:@cosmjs-rn/crypto@^0.27.1"\n }\n}\n'))),(0,a.kt)(o.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,a.kt)("p",null,"Using ",(0,a.kt)("a",{parentName:"p",href:"https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/"},"Yarn ",(0,a.kt)("inlineCode",{parentName:"a"},"resolutions"))," we can point the ",(0,a.kt)("inlineCode",{parentName:"p"},"cosmjs")," packages to ",(0,a.kt)("inlineCode",{parentName:"p"},"cosmjs-rn"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'{\n "resolutions": {\n "@cosmjs/amino": "npm:@cosmjs-rn/amino@^0.27.1",\n "@cosmjs/encoding": "npm:@cosmjs-rn/encoding@^0.27.1",\n "@cosmjs/math": "npm:@cosmjs-rn/math@^0.27.1",\n "@cosmjs/stargate": "npm:@cosmjs-rn/stargate@^0.27.1",\n "@cosmjs/tendermint-rpc": "npm:@cosmjs-rn/tendermint-rpc@^0.27.1",\n "@cosmjs/utils": "npm:@cosmjs-rn/utils@^0.27.1",\n "@cosmjs/proto-signing": "npm:@cosmjs-rn/proto-signing@^0.27.1",\n "@cosmjs/crypto": "npm:@cosmjs-rn/crypto@^0.27.1"\n }\n}\n')))),(0,a.kt)("p",null,"Following that we need to add a buffer polyfill"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add buffer\n")),(0,a.kt)("p",null,"create a shim.js file with the below code snippet"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"import { Buffer } from 'buffer'\nglobal.Buffer = Buffer\n")),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"import shim.js")," file into your file where the App is imported"),(0,a.kt)("h3",{id:"adding-the-cheqd-to-the-agent"},"Adding the cheqd to the Agent"),(0,a.kt)("p",null,"After installing the dependencies, we can register the cheqd Module on the agent by adding the below code snippet to the agent constructor."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-cheqd.ts section-1",showLineNumbers:!0,"set-up-cheqd.ts":!0,"section-1":!0},"")),(0,a.kt)("p",null,"The cosmosPayerSeed can be a 32-bit seed value or a mnemonic, which can be managed using Keplr wallet which can be installed on a mobile or as a browser extension in chrome or safari which allows user's to create accounts, exchange tokens etc. To setup keplr wallet for cheqd follow this ",(0,a.kt)("a",{parentName:"p",href:"https://learn.cheqd.io/getting-set-up-on-cheqd/cheqd-supported-wallets/keplr-wallet"},"tutorial")),(0,a.kt)(s.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{label:"Tutorials",value:"tab1",mdxType:"TabItem"},(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/tutorials/cheqd/"},"Cheqd DID Module")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/tutorials/registering-schema-and-credential-definition"},"Register Schema and Credential Definition")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/tutorials/issue-a-credential"},"Issue a Credential"))))))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4378],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,s=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=c(n),m=a,h=d["".concat(l,".").concat(m)]||d[m]||p[m]||s;return n?r.createElement(h,o(o({ref:t},u),{},{components:n})):r.createElement(h,o({ref:t},u))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=n.length,o=new Array(s);o[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[d]="string"==typeof e?e:a,o[1]=i;for(var c=2;c{n.d(t,{Z:()=>g});var r=n(7294),a=n(6010),s=n(3438),o=n(9960),i=n(3919),l=n(5999);const c={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function u(e){let{href:t,children:n}=e;return r.createElement(o.Z,{href:t,className:(0,a.Z)("card padding--lg",c.cardContainer)},n)}function d(e){let{href:t,icon:n,title:s,description:o}=e;return r.createElement(u,{href:t},r.createElement("h2",{className:(0,a.Z)("text--truncate",c.cardTitle),title:s},n," ",s),o&&r.createElement("p",{className:(0,a.Z)("text--truncate",c.cardDescription),title:o},o))}function p(e){let{item:t}=e;const n=(0,s.Wl)(t);return n?r.createElement(d,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,l.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function m(e){let{item:t}=e;const n=(0,i.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",a=(0,s.xz)(t.docId??void 0);return r.createElement(d,{href:t.href,icon:n,title:t.label,description:a?.description})}function h(e){let{item:t}=e;switch(t.type){case"link":return r.createElement(m,{item:t});case"category":return r.createElement(p,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function f(e){let{className:t}=e;const n=(0,s.jA)();return r.createElement(g,{items:n.items,className:t})}function g(e){const{items:t,className:n}=e;if(!t)return r.createElement(f,e);const o=(0,s.MN)(t);return r.createElement("section",{className:(0,a.Z)("row",n)},o.map(((e,t)=>r.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},r.createElement(h,{item:e})))))}},5162:(e,t,n)=>{n.d(t,{Z:()=>o});var r=n(7294),a=n(6010);const s={tabItem:"tabItem_Ymn6"};function o(e){let{children:t,hidden:n,className:o}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(s.tabItem,o),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var r=n(7462),a=n(7294),s=n(6010),o=n(2466),i=n(6550),l=n(1980),c=n(7392),u=n(12);function d(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function p(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??d(n);return function(e){const t=(0,c.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const r=(0,i.k6)(),s=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,l._X)(s),(0,a.useCallback)((e=>{if(!s)return;const t=new URLSearchParams(r.location.search);t.set(s,e),r.replace({...r.location,search:t.toString()})}),[s,r])]}function f(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,s=p(e),[o,i]=(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(!m({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 r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:s}))),[l,c]=h({queryString:n,groupId:r}),[d,f]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,s]=(0,u.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&s.set(e)}),[n,s])]}({groupId:r}),g=(()=>{const e=l??d;return m({value:e,tabValues:s})?e:null})();(0,a.useLayoutEffect)((()=>{g&&i(g)}),[g]);return{selectedValue:o,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:s}))throw new Error(`Can't select invalid tab value=${e}`);i(e),c(e),f(e)}),[c,f,s]),tabValues:s}}var g=n(2389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:n,selectedValue:i,selectValue:l,tabValues:c}=e;const u=[],{blockElementScrollPositionUntilNextRender:d}=(0,o.o5)(),p=e=>{const t=e.currentTarget,n=u.indexOf(t),r=c[n].value;r!==i&&(d(t),l(r))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=u.indexOf(e.currentTarget)+1;t=u[n]??u[0];break}case"ArrowLeft":{const n=u.indexOf(e.currentTarget)-1;t=u[n]??u[u.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.Z)("tabs",{"tabs--block":n},t)},c.map((e=>{let{value:t,label:n,attributes:o}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>u.push(e),onKeyDown:m,onClick:p},o,{className:(0,s.Z)("tabs__item",b.tabItem,o?.className,{"tabs__item--active":i===t})}),n??t)})))}function v(e){let{lazy:t,children:n,selectedValue:r}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function y(e){const t=f(e);return a.createElement("div",{className:(0,s.Z)("tabs-container",b.tabList)},a.createElement(k,(0,r.Z)({},e,t)),a.createElement(v,(0,r.Z)({},e,t)))}function w(e){const t=(0,g.Z)();return a.createElement(y,(0,r.Z)({key:String(t)},e))}},2655:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>d});var r=n(7462),a=(n(7294),n(3905)),s=n(4866),o=n(5162);n(2991);const i={},l="cheqd",c={unversionedId:"getting-started/set-up/cheqd/index",id:"version-0.4/getting-started/set-up/cheqd/index",title:"cheqd",description:"cheqd is a blockchain network, built in the Cosmos ecosystem for Self-Sovereign Identity (SSI). The cheqd Network leverages the cheqd DID method and enables DID-Linked Resources to be written to the network, associated with a DID and controlled using the verification methods in the DID Document.",source:"@site/versioned_docs/version-0.4/getting-started/set-up/cheqd/index.md",sourceDirName:"getting-started/set-up/cheqd",slug:"/getting-started/set-up/cheqd/",permalink:"/guides/0.4/getting-started/set-up/cheqd/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Indy VDR",permalink:"/guides/0.4/getting-started/set-up/indy-vdr"},next:{title:"Concepts",permalink:"/guides/0.4/concepts/"}},u={},d=[{value:"Installing cheqd",id:"installing-cheqd",level:3},{value:"React Native",id:"react-native",level:4},{value:"Adding the cheqd to the Agent",id:"adding-the-cheqd-to-the-agent",level:3},{value:"Tutorials",id:"tutorials",level:3}],p={toc:d},m="wrapper";function h(e){let{components:t,...n}=e;return(0,a.kt)(m,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"cheqd"},"cheqd"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/cheqd/sdk"},"cheqd")," is a blockchain network, built in the Cosmos ecosystem for Self-Sovereign Identity (SSI). The cheqd Network leverages the ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cheqd.io/identity/architecture/adr-list/adr-001-cheqd-did-method"},"cheqd DID method")," and enables ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cheqd.io/identity/architecture/adr-list/adr-002-did-linked-resources"},"DID-Linked Resources")," to be written to the network, associated with a DID and controlled using the verification methods in the DID Document."),(0,a.kt)("p",null,"Through this approach, the cheqd Network is able to natively support the ",(0,a.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-spec/"},"Ledger Agnostic AnonCreds Specification (v1.0)")," through its ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cheqd.io/identity/guides/anoncreds"},"AnonCreds Object Method")," (as well as VC-JWT and JSON-LD)."),(0,a.kt)("p",null,"cheqd also has a dedicated token, $CHEQ, used for identity writes to the network, voting in a decentralised governance framework as well as for various payment flows between verifiers, holders and issuers of Verifiable Credentials."),(0,a.kt)("h3",{id:"installing-cheqd"},"Installing cheqd"),(0,a.kt)("p",null,"When using Aries Framework JavaScript with the cheqd, there's a few extra dependencies that need to be installed. We need to install the ",(0,a.kt)("inlineCode",{parentName:"p"},"@aries-framework/cheqd")," package, which implements the needed interfaces for the agent."),(0,a.kt)("h4",{id:"react-native"},"React Native"),(0,a.kt)("p",null,"To enable react-native support we need to follow the steps below"),(0,a.kt)("p",null,"In the package.json file add the below code snippet, which replaces the cosmjs dependencies witht he cosmjs-rn packages"),(0,a.kt)(s.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{label:"NPM",value:"tab1",mdxType:"TabItem"},(0,a.kt)("p",null,"Using ",(0,a.kt)("a",{parentName:"p",href:"https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides"},"NPM ",(0,a.kt)("inlineCode",{parentName:"a"},"overrides"))," we can point the ",(0,a.kt)("inlineCode",{parentName:"p"},"cosmjs")," packages to ",(0,a.kt)("inlineCode",{parentName:"p"},"cosmjs-rn"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'{\n "overrides": {\n "@cosmjs/amino": "npm:@cosmjs-rn/amino@^0.27.1",\n "@cosmjs/encoding": "npm:@cosmjs-rn/encoding@^0.27.1",\n "@cosmjs/math": "npm:@cosmjs-rn/math@^0.27.1",\n "@cosmjs/stargate": "npm:@cosmjs-rn/stargate@^0.27.1",\n "@cosmjs/tendermint-rpc": "npm:@cosmjs-rn/tendermint-rpc@^0.27.1",\n "@cosmjs/utils": "npm:@cosmjs-rn/utils@^0.27.1",\n "@cosmjs/proto-signing": "npm:@cosmjs-rn/proto-signing@^0.27.1",\n "@cosmjs/crypto": "npm:@cosmjs-rn/crypto@^0.27.1"\n }\n}\n'))),(0,a.kt)(o.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,a.kt)("p",null,"Using ",(0,a.kt)("a",{parentName:"p",href:"https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/"},"Yarn ",(0,a.kt)("inlineCode",{parentName:"a"},"resolutions"))," we can point the ",(0,a.kt)("inlineCode",{parentName:"p"},"cosmjs")," packages to ",(0,a.kt)("inlineCode",{parentName:"p"},"cosmjs-rn"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'{\n "resolutions": {\n "@cosmjs/amino": "npm:@cosmjs-rn/amino@^0.27.1",\n "@cosmjs/encoding": "npm:@cosmjs-rn/encoding@^0.27.1",\n "@cosmjs/math": "npm:@cosmjs-rn/math@^0.27.1",\n "@cosmjs/stargate": "npm:@cosmjs-rn/stargate@^0.27.1",\n "@cosmjs/tendermint-rpc": "npm:@cosmjs-rn/tendermint-rpc@^0.27.1",\n "@cosmjs/utils": "npm:@cosmjs-rn/utils@^0.27.1",\n "@cosmjs/proto-signing": "npm:@cosmjs-rn/proto-signing@^0.27.1",\n "@cosmjs/crypto": "npm:@cosmjs-rn/crypto@^0.27.1"\n }\n}\n')))),(0,a.kt)("p",null,"Following that we need to add a buffer polyfill"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add buffer\n")),(0,a.kt)("p",null,"create a shim.js file with the below code snippet"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"import { Buffer } from 'buffer'\nglobal.Buffer = Buffer\n")),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"import shim.js")," file into your file where the App is imported"),(0,a.kt)("h3",{id:"adding-the-cheqd-to-the-agent"},"Adding the cheqd to the Agent"),(0,a.kt)("p",null,"After installing the dependencies, we can register the cheqd Module on the agent by adding the below code snippet to the agent constructor."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-cheqd.ts section-1",showLineNumbers:!0,"set-up-cheqd.ts":!0,"section-1":!0},"")),(0,a.kt)("p",null,"The cosmosPayerSeed can be a 32-bit seed value or a mnemonic, which can be managed using Keplr wallet which can be installed on a mobile or as a browser extension in chrome or safari which allows user's to create accounts, exchange tokens etc. To setup keplr wallet for cheqd follow this ",(0,a.kt)("a",{parentName:"p",href:"https://learn.cheqd.io/getting-set-up-on-cheqd/cheqd-supported-wallets/keplr-wallet"},"tutorial")),(0,a.kt)(s.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{label:"Tutorials",value:"tab1",mdxType:"TabItem"},(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/0.4/tutorials/cheqd/"},"Cheqd DID Module")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/0.4/tutorials/registering-schema-and-credential-definition"},"Register Schema and Credential Definition")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/0.4/tutorials/issue-a-credential"},"Issue a Credential"))))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/514aaf1d.75bf6933.js b/assets/js/514aaf1d.75bf6933.js new file mode 100644 index 00000000..279379e6 --- /dev/null +++ b/assets/js/514aaf1d.75bf6933.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[2050],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>f});var a=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function o(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var s=a.createContext({}),p=function(e){var t=a.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},d=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},c=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,i=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),m=p(r),c=n,f=m["".concat(s,".").concat(c)]||m[c]||u[c]||i;return r?a.createElement(f,o(o({ref:t},d),{},{components:r})):a.createElement(f,o({ref:t},d))}));function f(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=r.length,o=new Array(i);o[0]=c;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[m]="string"==typeof e?e:n,o[1]=l;for(var p=2;p{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>p});var a=r(7462),n=(r(7294),r(3905));const i={},o="Hyperledger Aries and Aries Interop Profile",l={unversionedId:"features/aries",id:"features/aries",title:"Hyperledger Aries and Aries Interop Profile",description:"Initially, Credo was built as an Hyperledger Aries framework, focusing on implementing the Aries RFCs and supporting the Aries Interop Profile.",source:"@site/guides/features/aries.md",sourceDirName:"features",slug:"/features/aries",permalink:"/guides/features/aries",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Supported Features",permalink:"/guides/features/"},next:{title:"OpenID for Verifiable Credentials",permalink:"/guides/features/openid4vc"}},s={},p=[{value:"Aries Interop Profile",id:"aries-interop-profile",level:2},{value:"Additional Aries RFCs",id:"additional-aries-rfcs",level:2},{value:"Divergence from Aries RFCs",id:"divergence-from-aries-rfcs",level:2}],d={toc:p},m="wrapper";function u(e){let{components:t,...r}=e;return(0,n.kt)(m,(0,a.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"hyperledger-aries-and-aries-interop-profile"},"Hyperledger Aries and Aries Interop Profile"),(0,n.kt)("p",null,"Initially, Credo was built as an Hyperledger Aries framework, focusing on implementing the ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs"},"Aries RFCs")," and supporting the ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0302-aries-interop-profile"},"Aries Interop Profile"),"."),(0,n.kt)("p",null,"Support for Hyperledger Aries, DIDComm and AnonCreds is at the core of Credo, and thus if you're building an identity solution supporting these standards, Credo is a great fit."),(0,n.kt)("h2",{id:"aries-interop-profile"},"Aries Interop Profile"),(0,n.kt)("p",null,"Credo currently has ",(0,n.kt)("strong",{parentName:"p"},"full support for ",(0,n.kt)("a",{parentName:"strong",href:"https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0302-aries-interop-profile#aries-interop-profile-version-10"},"Aries Interop Profile 1.0")," (AIP 1)")," as well as ",(0,n.kt)("strong",{parentName:"p"},"most of the features from ",(0,n.kt)("a",{parentName:"strong",href:"https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0302-aries-interop-profile#aries-interop-profile-version-20"},"Aries Interop Profile 2.0")," (AIP 2)")),(0,n.kt)("p",null,"The following table lists which parts of AIP 2 are supported by Credo:"),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Feature"),(0,n.kt)("th",{parentName:"tr",align:null},"Support"),(0,n.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0302-aries-interop-profile#base-requirements"},"Base Requirements")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0302-aries-interop-profile#mediate-mediator-coordination"},"Mediator Coordination")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0302-aries-interop-profile#indycred-indy-based-credentials"},"Indy Based Credentials")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null},"Also support for the newer ledger-agnostic ",(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0771-anoncreds-attachments"},"AnonCreds attachment format"))),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0771-anoncreds-attachments"},"JSON-LD Based Credentials")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0302-aries-interop-profile#bbscred-bbs-based-credentials"},"BBS+ Based Credentials")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0302-aries-interop-profile#chat-chat-related-features"},"Chat related features")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0302-aries-interop-profile#didcommv2prep-didcomm-v2-prep"},"DIDCommm v2 Prep")),(0,n.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,n.kt)("td",{parentName:"tr",align:null})))),(0,n.kt)("h2",{id:"additional-aries-rfcs"},"Additional Aries RFCs"),(0,n.kt)("p",null,"In addition to the Aries RFCs listed by the Aries Interop Profile, Credo also supports the following Aries RFCs:"),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Aries RFC"),(0,n.kt)("th",{parentName:"tr",align:null},"Support"),(0,n.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0212-pickup"},"Aries RFC 0212 Pickup V1")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0685-pickup-v2"},"Aries RFC 0685 Pickup V2")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/be8c7bf856577745e0165e9cda0918fa554d120e/features/0721-revocation-notification-v2"},"Aries RFC 0721 Revocation Notification V2")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/be8c7bf856577745e0165e9cda0918fa554d120e/features/0771-anoncreds-attachments"},"Aries RFC 0771: AnonCreds Attachment Format")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0794-did-rotate/README.md"},"Aries RFC 0794: DID Rotate V1")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null})))),(0,n.kt)("h2",{id:"divergence-from-aries-rfcs"},"Divergence from Aries RFCs"),(0,n.kt)("p",null,"Although Credo tries to follow the standards as described in the Aries RFCs as much as possible, some features in Credo slightly diverge from the written spec. Below is an overview of the features that diverge from the spec, their impact and the reasons for diverging."),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Feature"),(0,n.kt)("th",{parentName:"tr",align:null},"Impact"),(0,n.kt)("th",{parentName:"tr",align:null},"Reason"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"Support for ",(0,n.kt)("inlineCode",{parentName:"td"},"imageUrl")," attribute in connection invitation and connection request"),(0,n.kt)("td",{parentName:"tr",align:null},"Properties that are not recognized should be ignored, meaning this shouldn't limit interoperability between agents. As the image url is self-attested it could give a false sense of trust. Better, credential based, method for visually identifying an entity are not present yet."),(0,n.kt)("td",{parentName:"tr",align:null},"Even though not documented, almost all agents support this feature. Not including this feature means Credo is lacking in features in comparison to other implementations.")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"Revocation Notification v1 uses a different ",(0,n.kt)("inlineCode",{parentName:"td"},"thread_id")," format ( ",(0,n.kt)("inlineCode",{parentName:"td"},"indy::::"),") than specified in the Aries RFC"),(0,n.kt)("td",{parentName:"tr",align:null},"Any agents adhering to the ",(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0183-revocation-notification"},"revocation notification v1 RFC")," will not be interoperable with Credo. However, revocation notification is considered an optional portion of revocation, therefore this will not break core revocation behavior. Ideally agents should use and implement revocation notification v2."),(0,n.kt)("td",{parentName:"tr",align:null},"Actual implementations (ACA-Py) of revocation notification v1 so far have implemented this different format, so this format change was made to remain interoperable.")))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/514aaf1d.c14f0a5d.js b/assets/js/514aaf1d.c14f0a5d.js deleted file mode 100644 index 0ba66d9f..00000000 --- a/assets/js/514aaf1d.c14f0a5d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[2050],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>f});var a=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function o(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var s=a.createContext({}),p=function(e){var t=a.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},d=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},c=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,i=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),m=p(r),c=n,f=m["".concat(s,".").concat(c)]||m[c]||u[c]||i;return r?a.createElement(f,o(o({ref:t},d),{},{components:r})):a.createElement(f,o({ref:t},d))}));function f(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=r.length,o=new Array(i);o[0]=c;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[m]="string"==typeof e?e:n,o[1]=l;for(var p=2;p{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>p});var a=r(7462),n=(r(7294),r(3905));const i={},o="Hyperledger Aries and Aries Interop Profile",l={unversionedId:"features/aries",id:"features/aries",title:"Hyperledger Aries and Aries Interop Profile",description:"Initially, Credo was built as an Hyperledger Aries framework, focusing on implementing the Aries RFCs and supporting the Aries Interop Profile.",source:"@site/guides/features/aries.md",sourceDirName:"features",slug:"/features/aries",permalink:"/guides/0.5/features/aries",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Supported Features",permalink:"/guides/0.5/features/"},next:{title:"OpenID for Verifiable Credentials",permalink:"/guides/0.5/features/openid4vc"}},s={},p=[{value:"Aries Interop Profile",id:"aries-interop-profile",level:2},{value:"Additional Aries RFCs",id:"additional-aries-rfcs",level:2},{value:"Divergence from Aries RFCs",id:"divergence-from-aries-rfcs",level:2}],d={toc:p},m="wrapper";function u(e){let{components:t,...r}=e;return(0,n.kt)(m,(0,a.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"hyperledger-aries-and-aries-interop-profile"},"Hyperledger Aries and Aries Interop Profile"),(0,n.kt)("p",null,"Initially, Credo was built as an Hyperledger Aries framework, focusing on implementing the ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs"},"Aries RFCs")," and supporting the ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0302-aries-interop-profile"},"Aries Interop Profile"),"."),(0,n.kt)("p",null,"Support for Hyperledger Aries, DIDComm and AnonCreds is at the core of Credo, and thus if you're building an identity solution supporting these standards, Credo is a great fit."),(0,n.kt)("h2",{id:"aries-interop-profile"},"Aries Interop Profile"),(0,n.kt)("p",null,"Credo currently has ",(0,n.kt)("strong",{parentName:"p"},"full support for ",(0,n.kt)("a",{parentName:"strong",href:"https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0302-aries-interop-profile#aries-interop-profile-version-10"},"Aries Interop Profile 1.0")," (AIP 1)")," as well as ",(0,n.kt)("strong",{parentName:"p"},"most of the features from ",(0,n.kt)("a",{parentName:"strong",href:"https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0302-aries-interop-profile#aries-interop-profile-version-20"},"Aries Interop Profile 2.0")," (AIP 2)")),(0,n.kt)("p",null,"The following table lists which parts of AIP 2 are supported by Credo:"),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Feature"),(0,n.kt)("th",{parentName:"tr",align:null},"Support"),(0,n.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0302-aries-interop-profile#base-requirements"},"Base Requirements")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0302-aries-interop-profile#mediate-mediator-coordination"},"Mediator Coordination")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0302-aries-interop-profile#indycred-indy-based-credentials"},"Indy Based Credentials")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null},"Also support for the newer ledger-agnostic ",(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0771-anoncreds-attachments"},"AnonCreds attachment format"))),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0771-anoncreds-attachments"},"JSON-LD Based Credentials")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0302-aries-interop-profile#bbscred-bbs-based-credentials"},"BBS+ Based Credentials")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0302-aries-interop-profile#chat-chat-related-features"},"Chat related features")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0302-aries-interop-profile#didcommv2prep-didcomm-v2-prep"},"DIDCommm v2 Prep")),(0,n.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,n.kt)("td",{parentName:"tr",align:null})))),(0,n.kt)("h2",{id:"additional-aries-rfcs"},"Additional Aries RFCs"),(0,n.kt)("p",null,"In addition to the Aries RFCs listed by the Aries Interop Profile, Credo also supports the following Aries RFCs:"),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Aries RFC"),(0,n.kt)("th",{parentName:"tr",align:null},"Support"),(0,n.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0212-pickup"},"Aries RFC 0212 Pickup V1")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0685-pickup-v2"},"Aries RFC 0685 Pickup V2")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/be8c7bf856577745e0165e9cda0918fa554d120e/features/0721-revocation-notification-v2"},"Aries RFC 0721 Revocation Notification V2")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/be8c7bf856577745e0165e9cda0918fa554d120e/features/0771-anoncreds-attachments"},"Aries RFC 0771: AnonCreds Attachment Format")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0794-did-rotate/README.md"},"Aries RFC 0794: DID Rotate V1")),(0,n.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,n.kt)("td",{parentName:"tr",align:null})))),(0,n.kt)("h2",{id:"divergence-from-aries-rfcs"},"Divergence from Aries RFCs"),(0,n.kt)("p",null,"Although Credo tries to follow the standards as described in the Aries RFCs as much as possible, some features in Credo slightly diverge from the written spec. Below is an overview of the features that diverge from the spec, their impact and the reasons for diverging."),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Feature"),(0,n.kt)("th",{parentName:"tr",align:null},"Impact"),(0,n.kt)("th",{parentName:"tr",align:null},"Reason"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"Support for ",(0,n.kt)("inlineCode",{parentName:"td"},"imageUrl")," attribute in connection invitation and connection request"),(0,n.kt)("td",{parentName:"tr",align:null},"Properties that are not recognized should be ignored, meaning this shouldn't limit interoperability between agents. As the image url is self-attested it could give a false sense of trust. Better, credential based, method for visually identifying an entity are not present yet."),(0,n.kt)("td",{parentName:"tr",align:null},"Even though not documented, almost all agents support this feature. Not including this feature means Credo is lacking in features in comparison to other implementations.")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"Revocation Notification v1 uses a different ",(0,n.kt)("inlineCode",{parentName:"td"},"thread_id")," format ( ",(0,n.kt)("inlineCode",{parentName:"td"},"indy::::"),") than specified in the Aries RFC"),(0,n.kt)("td",{parentName:"tr",align:null},"Any agents adhering to the ",(0,n.kt)("a",{parentName:"td",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0183-revocation-notification"},"revocation notification v1 RFC")," will not be interoperable with Credo. However, revocation notification is considered an optional portion of revocation, therefore this will not break core revocation behavior. Ideally agents should use and implement revocation notification v2."),(0,n.kt)("td",{parentName:"tr",align:null},"Actual implementations (ACA-Py) of revocation notification v1 so far have implemented this different format, so this format change was made to remain interoperable.")))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/52db191f.38b67940.js b/assets/js/52db191f.38b67940.js new file mode 100644 index 00000000..03dad0d5 --- /dev/null +++ b/assets/js/52db191f.38b67940.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[6059],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>c});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var p=a.createContext({}),s=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},d=function(e){var t=s(e.components);return a.createElement(p.Provider,{value:t},e.children)},m="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,p=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),m=s(n),u=i,c=m["".concat(p,".").concat(u)]||m[u]||g[u]||r;return n?a.createElement(c,o(o({ref:t},d),{},{components:n})):a.createElement(c,o({ref:t},d))}));function c(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=u;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l[m]="string"==typeof e?e:i,o[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>g,frontMatter:()=>r,metadata:()=>l,toc:()=>s});var a=n(7462),i=(n(7294),n(3905));const r={},o="Agent Config",l={unversionedId:"tutorials/agent-config/index",id:"version-0.4/tutorials/agent-config/index",title:"Agent Config",description:"The Aries agent provided by [Aries Framework",source:"@site/versioned_docs/version-0.4/tutorials/agent-config/index.md",sourceDirName:"tutorials/agent-config",slug:"/tutorials/agent-config/",permalink:"/guides/0.4/tutorials/agent-config/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Tutorials",permalink:"/guides/0.4/tutorials/"},next:{title:"Logging",permalink:"/guides/0.4/tutorials/agent-config/logging"}},p={},s=[{value:"label*",id:"label",level:2},{value:"walletConfig",id:"walletconfig",level:2},{value:"walletConfig.id*",id:"walletconfigid",level:3},{value:"walletConfig.key*",id:"walletconfigkey",level:3},{value:"walletConfig.keyDerivationMethod",id:"walletconfigkeyderivationmethod",level:3},{value:"walletConfig.storage",id:"walletconfigstorage",level:3},{value:"endpoints",id:"endpoints",level:2},{value:"logger",id:"logger",level:2},{value:"didCommMimeType",id:"didcommmimetype",level:2},{value:"useDidSovPrefixWhereAllowed",id:"usedidsovprefixwhereallowed",level:2},{value:"useDidKeyInProtocols",id:"usedidkeyinprotocols",level:2},{value:"connectionImageUrl",id:"connectionimageurl",level:2},{value:"autoUpdateStorageOnStartup",id:"autoupdatestorageonstartup",level:2}],d={toc:s},m="wrapper";function g(e){let{components:t,...n}=e;return(0,i.kt)(m,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"agent-config"},"Agent Config"),(0,i.kt)("p",null,"The Aries agent provided by ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript"},"Aries Framework\nJavaScript")," is very\nextensible. These are all the configuration options with a short description:"),(0,i.kt)("h2",{id:"label"},(0,i.kt)("inlineCode",{parentName:"h2"},"label"),"*"),(0,i.kt)("p",null,"The label is seen by other users when creating a connection. This should not\nbe used as a base for authenticity, as it is entirely up to the user to\nset this."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"string")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"label: 'my-demo-agent'\n")),(0,i.kt)("hr",null),(0,i.kt)("h2",{id:"walletconfig"},(0,i.kt)("inlineCode",{parentName:"h2"},"walletConfig")),(0,i.kt)("p",null,"Configuration for the setup of the wallet. Including this in the agent\nconfiguration makes it possible that, when initializing the agent, the wallet\nwill also be initialized. When an application requires the agent without an\ninitialized wallet for any reason, this can be omitted and later on the wallet\ncan be initialized separately."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"WalletConfig")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"import { KeyDerivationMethod } from '@aries-framework/core'\n\nwalletConfig: {\n id: 'foo',\n key: 'testkey000000000000000000000',\n keyDerivationMethod: KeyDerivationMethod.Argon2IMod,\n storage: {\n type: 'postgres_storage',\n ... // depends on the storage type\n }\n}\n")),(0,i.kt)("h3",{id:"walletconfigid"},(0,i.kt)("inlineCode",{parentName:"h3"},"walletConfig.id"),"*"),(0,i.kt)("p",null,"Identifier string. Using another value here will open a new wallet."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"string")),(0,i.kt)("h3",{id:"walletconfigkey"},(0,i.kt)("inlineCode",{parentName:"h3"},"walletConfig.key"),"*"),(0,i.kt)("p",null,"Key to unlock the wallet with. This value MUST be kept as a secret and should\nbe seem like a password."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"string")),(0,i.kt)("h3",{id:"walletconfigkeyderivationmethod"},(0,i.kt)("inlineCode",{parentName:"h3"},"walletConfig.keyDerivationMethod")),(0,i.kt)("p",null,"The method used for key derivation of the\n",(0,i.kt)("a",{parentName:"p",href:"#walletconfigkey"},(0,i.kt)("inlineCode",{parentName:"a"},"walletConfig.key")),"."),(0,i.kt)("p",null,"When using ",(0,i.kt)("inlineCode",{parentName:"p"},"KeyDerivationMethod.Raw"),", it is strongly recommended to get the raw\nkey via\n",(0,i.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk/blob/1c7096dd95d0fd53881070f66907df4b9e61b874/libindy/src/api/wallet.rs#L560"},(0,i.kt)("inlineCode",{parentName:"a"},"indy_generate_wallet_key")),".\nIf you really must implement your own key generation, it is required to be a\nbase58-encoded\n",(0,i.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/ChaCha20-Poly1305"},"ChaCha20-Poly1305")," key."),(0,i.kt)("blockquote",null,(0,i.kt)("p",{parentName:"blockquote"},"For the advanced readers\n",(0,i.kt)("a",{parentName:"p",href:"https://www.password-hashing.net/argon2-specs.pdf"},"here")," is the\nspecification of Argon2.")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"enum KeyDerivationMethod")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Default"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"KeyDerivationMethod.Argon2IMod")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Members"),":"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},(0,i.kt)("inlineCode",{parentName:"strong"},"KeyDerivationMethod.Argon2IMod"))),(0,i.kt)("p",null,"\xa0","\xa0","\xa0"," uses Argon2I modular (most secure option, but slower)"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},(0,i.kt)("inlineCode",{parentName:"strong"},"KeyDerivationMethod.Argon2Int"))),(0,i.kt)("p",null,"\xa0","\xa0","\xa0"," uses Argon2 integer (less secure, but faster)"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},(0,i.kt)("inlineCode",{parentName:"strong"},"KeyDerivationMethod.Raw"))),(0,i.kt)("p",null,"\xa0","\xa0","\xa0"," uses no derivation method.\nIt is recommended to use the\n",(0,i.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk/blob/1c7096dd95d0fd53881070f66907df4b9e61b874/libindy/src/api/wallet.rs#L560"},(0,i.kt)("inlineCode",{parentName:"a"},"indy_generate_wallet_key")),"\nfor key generation."),(0,i.kt)("h3",{id:"walletconfigstorage"},(0,i.kt)("inlineCode",{parentName:"h3"},"walletConfig.storage")),(0,i.kt)("p",null,"Specify which storage is being used for the wallet. The default is an SQLite\ndatabase, but a Postgres database could be used as well."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"object")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Default"),": An SQLite database"),(0,i.kt)("hr",null),(0,i.kt)("h2",{id:"endpoints"},(0,i.kt)("inlineCode",{parentName:"h2"},"endpoints")),(0,i.kt)("p",null,"A list of endpoints (schema + host + port) used for invitations and where other\nagents might reach you. This could be used to host a website that would\nredirect, for example with deep linking, to a wallet where the invitation can be\naccepted."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"string")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"endpoints: ['https://example.org:3000']\n")),(0,i.kt)("hr",null),(0,i.kt)("h2",{id:"logger"},(0,i.kt)("inlineCode",{parentName:"h2"},"logger")),(0,i.kt)("p",null,"A logger instance that implements the ",(0,i.kt)("inlineCode",{parentName:"p"},"Logger")," interface. This can be extremely\nhelpful for debugging. Aries Framework JavaScript exposes a ",(0,i.kt)("inlineCode",{parentName:"p"},"ConsoleLogger"),"\nthat can be used for simple logs. See ",(0,i.kt)("a",{parentName:"p",href:"./logging"},"Logging")," for more details on creating your own logger instance."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"Logger")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"import { ConsoleLogger, LogLevel } from '@aries-framework/core'\n\nlogger: new ConsoleLogger(LogLevel.info)\n")),(0,i.kt)("hr",null),(0,i.kt)("h2",{id:"didcommmimetype"},(0,i.kt)("inlineCode",{parentName:"h2"},"didCommMimeType")),(0,i.kt)("p",null,"The mime-type used for sending and receiving messages. ",(0,i.kt)("inlineCode",{parentName:"p"},"application/jwe")," and\n",(0,i.kt)("inlineCode",{parentName:"p"},"application/json")," are used as fallback but are less desirable as they are\nmuch more ambiguous in their specification."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"enum DidCommMimeType")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Default"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"DidCommMimeType.V1")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Members"),":"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},(0,i.kt)("inlineCode",{parentName:"strong"},"DidCommMimeType.V0"))),(0,i.kt)("p",null,"\xa0","\xa0","\xa0",' "application/ssi-agent-wire"'),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},(0,i.kt)("inlineCode",{parentName:"strong"},"DidCommMimeType.V1"))),(0,i.kt)("p",null,"\xa0","\xa0","\xa0",' "application/didcomm-envelope-enc"'),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"import { DidCommMimeType } from '@aries-framework/core'\n\ndidCommMimeType: DidCommMimeType.V1\n")),(0,i.kt)("hr",null),(0,i.kt)("h2",{id:"usedidsovprefixwhereallowed"},(0,i.kt)("inlineCode",{parentName:"h2"},"useDidSovPrefixWhereAllowed")),(0,i.kt)("p",null,"Whether to emit the legacy did:sov prefix ",(0,i.kt)("inlineCode",{parentName:"p"},"did:sov:BzCbsNYhMrjHiqZDTUASHg;spec")," in the ",(0,i.kt)("inlineCode",{parentName:"p"},"@type")," of messages for messages that allow it. A message can allow emitting the legacy prefix by setting the ",(0,i.kt)("inlineCode",{parentName:"p"},"allowDidSovPrefix")," on the message class. This is the case for all core messages that have been defined before the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0348-transition-msg-type-to-https/README.md"},"Migration to ",(0,i.kt)("inlineCode",{parentName:"a"},"https://didcomm.org")," message type"),", to allow for the best possible interoperability with other agents."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"boolean")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Default"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"false")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"useDidSovPrefixWhereAllowed: true\n")),(0,i.kt)("hr",null),(0,i.kt)("h2",{id:"usedidkeyinprotocols"},(0,i.kt)("inlineCode",{parentName:"h2"},"useDidKeyInProtocols")),(0,i.kt)("p",null,"Whether to use ",(0,i.kt)("inlineCode",{parentName:"p"},"did:key")," in protocols by default as defined in ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0360-use-did-key/README.md"},"RFC 0360: did:key Usage"),". Adopting this RFC can break interop with agents that haven't adopted this RFC yet. The framework does it best to automatically detect whether the other agent supports ",(0,i.kt)("inlineCode",{parentName:"p"},"did:key"),", however in some cases we can't determine this. In those cases this parameter can be used to force the framework to use ",(0,i.kt)("inlineCode",{parentName:"p"},"did:key")," or not."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"boolean")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Default"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"true")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"useDidKeyInProtocols: true\n")),(0,i.kt)("hr",null),(0,i.kt)("h2",{id:"connectionimageurl"},(0,i.kt)("inlineCode",{parentName:"h2"},"connectionImageUrl")),(0,i.kt)("p",null,"A URL to an image used so that other agents can display this. Like the\n",(0,i.kt)("a",{parentName:"p",href:"#label"},(0,i.kt)("inlineCode",{parentName:"a"},"Label"))," this is completely up to the user to define\nthis. It MUST not be used got any base of authenticity."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"string")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"connectionImageUrl: 'https://picsum.photos/200'\n")),(0,i.kt)("hr",null),(0,i.kt)("h2",{id:"autoupdatestorageonstartup"},(0,i.kt)("inlineCode",{parentName:"h2"},"autoUpdateStorageOnStartup")),(0,i.kt)("p",null,"Whether the storage should automatically be updated when a newer version of\n",(0,i.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript"},"Aries Framework\nJavaScript")," is used."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"boolean")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Default"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"false")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"autoUpdateStorageOnStartup: true\n")),(0,i.kt)("hr",null))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/52db191f.b0b7b954.js b/assets/js/52db191f.b0b7b954.js deleted file mode 100644 index ddce075a..00000000 --- a/assets/js/52db191f.b0b7b954.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[6059],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>c});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var p=a.createContext({}),s=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},d=function(e){var t=s(e.components);return a.createElement(p.Provider,{value:t},e.children)},m="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,p=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),m=s(n),u=i,c=m["".concat(p,".").concat(u)]||m[u]||g[u]||r;return n?a.createElement(c,o(o({ref:t},d),{},{components:n})):a.createElement(c,o({ref:t},d))}));function c(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=u;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l[m]="string"==typeof e?e:i,o[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>g,frontMatter:()=>r,metadata:()=>l,toc:()=>s});var a=n(7462),i=(n(7294),n(3905));const r={},o="Agent Config",l={unversionedId:"tutorials/agent-config/index",id:"version-0.4/tutorials/agent-config/index",title:"Agent Config",description:"The Aries agent provided by [Aries Framework",source:"@site/versioned_docs/version-0.4/tutorials/agent-config/index.md",sourceDirName:"tutorials/agent-config",slug:"/tutorials/agent-config/",permalink:"/guides/tutorials/agent-config/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Tutorials",permalink:"/guides/tutorials/"},next:{title:"Logging",permalink:"/guides/tutorials/agent-config/logging"}},p={},s=[{value:"label*",id:"label",level:2},{value:"walletConfig",id:"walletconfig",level:2},{value:"walletConfig.id*",id:"walletconfigid",level:3},{value:"walletConfig.key*",id:"walletconfigkey",level:3},{value:"walletConfig.keyDerivationMethod",id:"walletconfigkeyderivationmethod",level:3},{value:"walletConfig.storage",id:"walletconfigstorage",level:3},{value:"endpoints",id:"endpoints",level:2},{value:"logger",id:"logger",level:2},{value:"didCommMimeType",id:"didcommmimetype",level:2},{value:"useDidSovPrefixWhereAllowed",id:"usedidsovprefixwhereallowed",level:2},{value:"useDidKeyInProtocols",id:"usedidkeyinprotocols",level:2},{value:"connectionImageUrl",id:"connectionimageurl",level:2},{value:"autoUpdateStorageOnStartup",id:"autoupdatestorageonstartup",level:2}],d={toc:s},m="wrapper";function g(e){let{components:t,...n}=e;return(0,i.kt)(m,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"agent-config"},"Agent Config"),(0,i.kt)("p",null,"The Aries agent provided by ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript"},"Aries Framework\nJavaScript")," is very\nextensible. These are all the configuration options with a short description:"),(0,i.kt)("h2",{id:"label"},(0,i.kt)("inlineCode",{parentName:"h2"},"label"),"*"),(0,i.kt)("p",null,"The label is seen by other users when creating a connection. This should not\nbe used as a base for authenticity, as it is entirely up to the user to\nset this."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"string")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"label: 'my-demo-agent'\n")),(0,i.kt)("hr",null),(0,i.kt)("h2",{id:"walletconfig"},(0,i.kt)("inlineCode",{parentName:"h2"},"walletConfig")),(0,i.kt)("p",null,"Configuration for the setup of the wallet. Including this in the agent\nconfiguration makes it possible that, when initializing the agent, the wallet\nwill also be initialized. When an application requires the agent without an\ninitialized wallet for any reason, this can be omitted and later on the wallet\ncan be initialized separately."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"WalletConfig")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"import { KeyDerivationMethod } from '@aries-framework/core'\n\nwalletConfig: {\n id: 'foo',\n key: 'testkey000000000000000000000',\n keyDerivationMethod: KeyDerivationMethod.Argon2IMod,\n storage: {\n type: 'postgres_storage',\n ... // depends on the storage type\n }\n}\n")),(0,i.kt)("h3",{id:"walletconfigid"},(0,i.kt)("inlineCode",{parentName:"h3"},"walletConfig.id"),"*"),(0,i.kt)("p",null,"Identifier string. Using another value here will open a new wallet."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"string")),(0,i.kt)("h3",{id:"walletconfigkey"},(0,i.kt)("inlineCode",{parentName:"h3"},"walletConfig.key"),"*"),(0,i.kt)("p",null,"Key to unlock the wallet with. This value MUST be kept as a secret and should\nbe seem like a password."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"string")),(0,i.kt)("h3",{id:"walletconfigkeyderivationmethod"},(0,i.kt)("inlineCode",{parentName:"h3"},"walletConfig.keyDerivationMethod")),(0,i.kt)("p",null,"The method used for key derivation of the\n",(0,i.kt)("a",{parentName:"p",href:"#walletconfigkey"},(0,i.kt)("inlineCode",{parentName:"a"},"walletConfig.key")),"."),(0,i.kt)("p",null,"When using ",(0,i.kt)("inlineCode",{parentName:"p"},"KeyDerivationMethod.Raw"),", it is strongly recommended to get the raw\nkey via\n",(0,i.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk/blob/1c7096dd95d0fd53881070f66907df4b9e61b874/libindy/src/api/wallet.rs#L560"},(0,i.kt)("inlineCode",{parentName:"a"},"indy_generate_wallet_key")),".\nIf you really must implement your own key generation, it is required to be a\nbase58-encoded\n",(0,i.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/ChaCha20-Poly1305"},"ChaCha20-Poly1305")," key."),(0,i.kt)("blockquote",null,(0,i.kt)("p",{parentName:"blockquote"},"For the advanced readers\n",(0,i.kt)("a",{parentName:"p",href:"https://www.password-hashing.net/argon2-specs.pdf"},"here")," is the\nspecification of Argon2.")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"enum KeyDerivationMethod")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Default"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"KeyDerivationMethod.Argon2IMod")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Members"),":"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},(0,i.kt)("inlineCode",{parentName:"strong"},"KeyDerivationMethod.Argon2IMod"))),(0,i.kt)("p",null,"\xa0","\xa0","\xa0"," uses Argon2I modular (most secure option, but slower)"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},(0,i.kt)("inlineCode",{parentName:"strong"},"KeyDerivationMethod.Argon2Int"))),(0,i.kt)("p",null,"\xa0","\xa0","\xa0"," uses Argon2 integer (less secure, but faster)"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},(0,i.kt)("inlineCode",{parentName:"strong"},"KeyDerivationMethod.Raw"))),(0,i.kt)("p",null,"\xa0","\xa0","\xa0"," uses no derivation method.\nIt is recommended to use the\n",(0,i.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk/blob/1c7096dd95d0fd53881070f66907df4b9e61b874/libindy/src/api/wallet.rs#L560"},(0,i.kt)("inlineCode",{parentName:"a"},"indy_generate_wallet_key")),"\nfor key generation."),(0,i.kt)("h3",{id:"walletconfigstorage"},(0,i.kt)("inlineCode",{parentName:"h3"},"walletConfig.storage")),(0,i.kt)("p",null,"Specify which storage is being used for the wallet. The default is an SQLite\ndatabase, but a Postgres database could be used as well."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"object")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Default"),": An SQLite database"),(0,i.kt)("hr",null),(0,i.kt)("h2",{id:"endpoints"},(0,i.kt)("inlineCode",{parentName:"h2"},"endpoints")),(0,i.kt)("p",null,"A list of endpoints (schema + host + port) used for invitations and where other\nagents might reach you. This could be used to host a website that would\nredirect, for example with deep linking, to a wallet where the invitation can be\naccepted."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"string")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"endpoints: ['https://example.org:3000']\n")),(0,i.kt)("hr",null),(0,i.kt)("h2",{id:"logger"},(0,i.kt)("inlineCode",{parentName:"h2"},"logger")),(0,i.kt)("p",null,"A logger instance that implements the ",(0,i.kt)("inlineCode",{parentName:"p"},"Logger")," interface. This can be extremely\nhelpful for debugging. Aries Framework JavaScript exposes a ",(0,i.kt)("inlineCode",{parentName:"p"},"ConsoleLogger"),"\nthat can be used for simple logs. See ",(0,i.kt)("a",{parentName:"p",href:"./logging"},"Logging")," for more details on creating your own logger instance."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"Logger")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"import { ConsoleLogger, LogLevel } from '@aries-framework/core'\n\nlogger: new ConsoleLogger(LogLevel.info)\n")),(0,i.kt)("hr",null),(0,i.kt)("h2",{id:"didcommmimetype"},(0,i.kt)("inlineCode",{parentName:"h2"},"didCommMimeType")),(0,i.kt)("p",null,"The mime-type used for sending and receiving messages. ",(0,i.kt)("inlineCode",{parentName:"p"},"application/jwe")," and\n",(0,i.kt)("inlineCode",{parentName:"p"},"application/json")," are used as fallback but are less desirable as they are\nmuch more ambiguous in their specification."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"enum DidCommMimeType")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Default"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"DidCommMimeType.V1")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Members"),":"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},(0,i.kt)("inlineCode",{parentName:"strong"},"DidCommMimeType.V0"))),(0,i.kt)("p",null,"\xa0","\xa0","\xa0",' "application/ssi-agent-wire"'),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},(0,i.kt)("inlineCode",{parentName:"strong"},"DidCommMimeType.V1"))),(0,i.kt)("p",null,"\xa0","\xa0","\xa0",' "application/didcomm-envelope-enc"'),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"import { DidCommMimeType } from '@aries-framework/core'\n\ndidCommMimeType: DidCommMimeType.V1\n")),(0,i.kt)("hr",null),(0,i.kt)("h2",{id:"usedidsovprefixwhereallowed"},(0,i.kt)("inlineCode",{parentName:"h2"},"useDidSovPrefixWhereAllowed")),(0,i.kt)("p",null,"Whether to emit the legacy did:sov prefix ",(0,i.kt)("inlineCode",{parentName:"p"},"did:sov:BzCbsNYhMrjHiqZDTUASHg;spec")," in the ",(0,i.kt)("inlineCode",{parentName:"p"},"@type")," of messages for messages that allow it. A message can allow emitting the legacy prefix by setting the ",(0,i.kt)("inlineCode",{parentName:"p"},"allowDidSovPrefix")," on the message class. This is the case for all core messages that have been defined before the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0348-transition-msg-type-to-https/README.md"},"Migration to ",(0,i.kt)("inlineCode",{parentName:"a"},"https://didcomm.org")," message type"),", to allow for the best possible interoperability with other agents."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"boolean")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Default"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"false")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"useDidSovPrefixWhereAllowed: true\n")),(0,i.kt)("hr",null),(0,i.kt)("h2",{id:"usedidkeyinprotocols"},(0,i.kt)("inlineCode",{parentName:"h2"},"useDidKeyInProtocols")),(0,i.kt)("p",null,"Whether to use ",(0,i.kt)("inlineCode",{parentName:"p"},"did:key")," in protocols by default as defined in ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0360-use-did-key/README.md"},"RFC 0360: did:key Usage"),". Adopting this RFC can break interop with agents that haven't adopted this RFC yet. The framework does it best to automatically detect whether the other agent supports ",(0,i.kt)("inlineCode",{parentName:"p"},"did:key"),", however in some cases we can't determine this. In those cases this parameter can be used to force the framework to use ",(0,i.kt)("inlineCode",{parentName:"p"},"did:key")," or not."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"boolean")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Default"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"true")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"useDidKeyInProtocols: true\n")),(0,i.kt)("hr",null),(0,i.kt)("h2",{id:"connectionimageurl"},(0,i.kt)("inlineCode",{parentName:"h2"},"connectionImageUrl")),(0,i.kt)("p",null,"A URL to an image used so that other agents can display this. Like the\n",(0,i.kt)("a",{parentName:"p",href:"#label"},(0,i.kt)("inlineCode",{parentName:"a"},"Label"))," this is completely up to the user to define\nthis. It MUST not be used got any base of authenticity."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"string")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"connectionImageUrl: 'https://picsum.photos/200'\n")),(0,i.kt)("hr",null),(0,i.kt)("h2",{id:"autoupdatestorageonstartup"},(0,i.kt)("inlineCode",{parentName:"h2"},"autoUpdateStorageOnStartup")),(0,i.kt)("p",null,"Whether the storage should automatically be updated when a newer version of\n",(0,i.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript"},"Aries Framework\nJavaScript")," is used."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Type"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"boolean")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Default"),": ",(0,i.kt)("inlineCode",{parentName:"p"},"false")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"autoUpdateStorageOnStartup: true\n")),(0,i.kt)("hr",null))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/58e9d200.998e9a7f.js b/assets/js/58e9d200.998e9a7f.js new file mode 100644 index 00000000..51e9f8c9 --- /dev/null +++ b/assets/js/58e9d200.998e9a7f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[6974],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>m});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var d=n.createContext({}),l=function(e){var t=n.useContext(d),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=l(e.components);return n.createElement(d.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,d=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),c=l(a),h=r,m=c["".concat(d,".").concat(h)]||c[h]||u[h]||i;return a?n.createElement(m,o(o({ref:t},p),{},{components:a})):n.createElement(m,o({ref:t},p))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=h;var s={};for(var d in t)hasOwnProperty.call(t,d)&&(s[d]=t[d]);s.originalType=e,s[c]="string"==typeof e?e:r,o[1]=s;for(var l=2;l{a.r(t),a.d(t,{assets:()=>d,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=a(7462),r=(a(7294),a(3905));const i={},o="Migrating from an Indy SDK Wallet to Aries Askar",s={unversionedId:"updating/update-indy-sdk-to-askar",id:"version-0.4/updating/update-indy-sdk-to-askar",title:"Migrating from an Indy SDK Wallet to Aries Askar",description:"This documentation explains the process of migrating your Indy SDK wallet to Aries Askar.",source:"@site/versioned_docs/version-0.4/updating/update-indy-sdk-to-askar.md",sourceDirName:"updating",slug:"/updating/update-indy-sdk-to-askar",permalink:"/guides/0.4/updating/update-indy-sdk-to-askar",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Update Assistant",permalink:"/guides/0.4/updating/update-assistant"},next:{title:"Migrating from AFJ 0.1.0 to 0.2.x",permalink:"/guides/0.4/updating/versions/0.1-to-0.2"}},d={},l=[{value:"What does the migration do internally?",id:"what-does-the-migration-do-internally",level:2},{value:"Create a backup",id:"create-a-backup",level:3},{value:"Migrate the database to an Aries Askar structure",id:"migrate-the-database-to-an-aries-askar-structure",level:3},{value:"Try to open the wallet in the new Aries Askar structure",id:"try-to-open-the-wallet-in-the-new-aries-askar-structure",level:3},{value:"Update the keys",id:"update-the-keys",level:3},{value:"Update the DIDs",id:"update-the-dids",level:3},{value:"Update the credential definitions",id:"update-the-credential-definitions",level:3},{value:"Update the link secret(s) (master secret)",id:"update-the-link-secrets-master-secret",level:3},{value:"Update the credentials",id:"update-the-credentials",level:3},{value:"All the other records",id:"all-the-other-records",level:3},{value:"How to update",id:"how-to-update",level:2},{value:"add the required dependencies:",id:"add-the-required-dependencies",level:3},{value:"Getting the database path",id:"getting-the-database-path",level:3},{value:"Android",id:"android",level:4},{value:"iOS",id:"ios",level:4}],p={toc:l},c="wrapper";function u(e){let{components:t,...a}=e;return(0,r.kt)(c,(0,n.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"migrating-from-an-indy-sdk-wallet-to-aries-askar"},"Migrating from an Indy SDK Wallet to Aries Askar"),(0,r.kt)("p",null,"This documentation explains the process of migrating your Indy SDK wallet to ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-askar"},"Aries Askar"),"."),(0,r.kt)("admonition",{type:"danger"},(0,r.kt)("p",{parentName:"admonition"},"While the migration script technically works on node.js, it is strongly advised not to use it, yet. The migration of issuer records (such as Schemas and Credential Definitions) is not implemented yet. When a credential definition is detected it will revert the migration process and no harm is done.")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Postgres is not supported. If you are using postgres with Indy SDK and need to update to Aries Askar, please open an issue on ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript"},"GitHub"),".")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"The migration script is supported to run on 0.3.x before migrating from 0.3.x to 0.4.x. Please refer to ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.4/updating/versions/0.3-to-0.4"},"Migrating from AFJ 0.3.x to 0.4.x")," to get to 0.4.x afterwards."),(0,r.kt)("p",{parentName:"admonition"},"It is important to note that this script must be ran before you update from 0.3.x to 0.4.x.")),(0,r.kt)("h2",{id:"what-does-the-migration-do-internally"},"What does the migration do internally?"),(0,r.kt)("p",null,"The migration script does the following to make sure everything is migrated properly, and if anything goes wrong, it will revert back to a working state."),(0,r.kt)("h3",{id:"create-a-backup"},"Create a backup"),(0,r.kt)("p",null,"Because undefined behavior might occur, we create a backup in the new ",(0,r.kt)("inlineCode",{parentName:"p"},"tmp")," directory from Aries Framework JavaScript. if some error occurs, it will be reverted back to the backed-up state and if no error occurs, it will delete the backup from the temporary directory."),(0,r.kt)("h3",{id:"migrate-the-database-to-an-aries-askar-structure"},"Migrate the database to an Aries Askar structure"),(0,r.kt)("p",null,"The Indy-sdk and Aries Askar have different database structures. So first of all we need to change some table names, decrypt all the items with the old Indy keys, encrypt the items with the new Aries Askar keys and store them inside the new structure."),(0,r.kt)("h3",{id:"try-to-open-the-wallet-in-the-new-aries-askar-structure"},"Try to open the wallet in the new Aries Askar structure"),(0,r.kt)("p",null,"When the wallet is correctly transformed, the wallet will be attempted to be opened."),(0,r.kt)("h3",{id:"update-the-keys"},"Update the keys"),(0,r.kt)("p",null,"Aries Askar has a specific way to store keys and every key, defined by the category of ",(0,r.kt)("inlineCode",{parentName:"p"},"Indy::Key")," will be migrated."),(0,r.kt)("h3",{id:"update-the-dids"},"Update the DIDs"),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"This update script does not transform did records. This is fine for something like ",(0,r.kt)("inlineCode",{parentName:"p"},"did:peer"),", but will cause issues with ",(0,r.kt)("inlineCode",{parentName:"p"},"indy")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"sov")," DIDs. For more information, please check out the ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.4/updating/versions/0.3-to-0.4#removal-of-publicdidseed-and-publicdid"},"Migrating from AFJ 0.3.x to 0.4.x"))),(0,r.kt)("h3",{id:"update-the-credential-definitions"},"Update the credential definitions"),(0,r.kt)("admonition",{type:"danger"},(0,r.kt)("p",{parentName:"admonition"},"Updating of credential definitions is not yet supported. This is why it is strongly advised not to run this script in a node.js environment.")),(0,r.kt)("h3",{id:"update-the-link-secrets-master-secret"},"Update the link secret(s) (master secret)"),(0,r.kt)("p",null,"The link secrets, identified by the category ",(0,r.kt)("inlineCode",{parentName:"p"},"Indy::MasterSecret"),", are updated next. They are stored inside a new ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsLinkSecretRecord"),"."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Since we have to set a default link secret, some additional logic is added to detect this. You can either supply a ",(0,r.kt)("inlineCode",{parentName:"p"},"defaultLinkSercetId")," as a constructor parameter or it will be based on your ",(0,r.kt)("inlineCode",{parentName:"p"},"walletId"),"."),(0,r.kt)("p",{parentName:"admonition"},"If there is no Indy record with the ",(0,r.kt)("inlineCode",{parentName:"p"},"defaultLinkSecretId")," or the ",(0,r.kt)("inlineCode",{parentName:"p"},"walletId"),", an error will be thrown and the migration will be restored.")),(0,r.kt)("h3",{id:"update-the-credentials"},"Update the credentials"),(0,r.kt)("p",null,"The credentials, identified by the category ",(0,r.kt)("inlineCode",{parentName:"p"},"Indy::Credential")," are updated last. They are stored in the new ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsCredentialRecord")," as a one-to-one copy. This means that they now support more tags and will make querying a lot easier."),(0,r.kt)("h3",{id:"all-the-other-records"},"All the other records"),(0,r.kt)("p",null,"All the other records will be transferred without any updates as they are not Indy specific."),(0,r.kt)("h2",{id:"how-to-update"},"How to update"),(0,r.kt)("p",null,"Updating does not require a lot of code, but must be done with caution."),(0,r.kt)("p",null,"It is very important to note that the migration script only has to be run once. If it runs for a second time, it will error saying that the database is already migrated. Also, when the migration is finished, it is common practice to store this state in your persistent app storage. This script does not provide a way to detect if an update has happened, so storing this value will prevent the script from running every time. For more information regarding this topic, please check out ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.4/updating/update-assistant#storing-the-agent-storage-version-outside-of-the-agent-storage"},"Update Assistant"),"."),(0,r.kt)("h3",{id:"add-the-required-dependencies"},"add the required dependencies:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @hyperledger/aries-askar-react-native @aries-framework/indy-sdk-to-askar-migration react-native-fs\n")),(0,r.kt)("p",null,"Below is the minimal code required for the migration to work. It is recommended to turn the logger on as it gives a lot of information regarding the migration."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"The agent is not allowed to be initialized to run this script. This makes sure nothing else happens during the migration.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript"},"import { agentDependencies } from '@aries-framework/react-native'\nimport { AskarModule } from '@aries-framework/askar'\nimport { IndySdkToAskarMigrationUpdater } from '@aries-framework/indy-sdk-to-askar-migration'\nimport { ariesAskar } from '@hyperledger/aries-askar-react-native'\n\nconst oldAgent = new Agent({\n config: {\n /* ... */\n },\n modules: {\n ariesAskar: new AskarModule({\n ariesAskar,\n }),\n },\n dependencies: agentDependencies,\n})\n\nconst dbPath = '' // see section below\n\nconst updater = await IndySdkToAskarMigrationUpdater.initialize({ dbPath, agent })\nawait updater.update()\n")),(0,r.kt)("h3",{id:"getting-the-database-path"},"Getting the database path"),(0,r.kt)("h4",{id:"android"},"Android"),(0,r.kt)("p",null,"On android, the database is commonly located under the ",(0,r.kt)("inlineCode",{parentName:"p"},"ExternalDirectoryPath"),"."),(0,r.kt)("p",null,"If you did not follow the default indy-sdk for React Native setup, your path might differ. Check out ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk-react-native#5-load-indy-library"},"step 5 of the Android setup for Indy SDK React Native")," for the default behavior."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript"},"import fs from 'react-native-fs'\n\nconst base = fs.ExternalDirectoryPath\nconst indyClient = '.indy_client'\nconst wallet = 'wallet'\nconst walletId = agent.config.walletConfig.id\nconst file = 'sqlite.db'\n\nconst dbPath = `${base}/${indyClient}/${wallet}/${walletId}/${file}`\n")),(0,r.kt)("h4",{id:"ios"},"iOS"),(0,r.kt)("p",null,"On iOS, the database is commonly located under the ",(0,r.kt)("inlineCode",{parentName:"p"},"DocumentDirectoryPath"),"."),(0,r.kt)("p",null,"For iOS this can only change if your phone does not have the ",(0,r.kt)("inlineCode",{parentName:"p"},"HOME")," environment variable set. This is not usual behavior, and if ",(0,r.kt)("inlineCode",{parentName:"p"},"HOME")," is not set, the ",(0,r.kt)("inlineCode",{parentName:"p"},"base")," in the code section below will be ",(0,r.kt)("inlineCode",{parentName:"p"},"/home/indy/Documents"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript"},"import fs from 'react-native-fs'\n\nconst base = fs.DocumentDirectoryPath\nconst indyClient = '.indy_client'\nconst wallet = 'wallet'\nconst walletId = agent.config.walletConfig.id\nconst file = 'sqlite.db'\n\nconst dbPath = `${base}/${indyClient}/${wallet}/${walletId}/${file}`\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/58e9d200.bca41dd1.js b/assets/js/58e9d200.bca41dd1.js deleted file mode 100644 index 96ca9548..00000000 --- a/assets/js/58e9d200.bca41dd1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[6974],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>m});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var d=n.createContext({}),l=function(e){var t=n.useContext(d),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=l(e.components);return n.createElement(d.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,d=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),c=l(a),h=r,m=c["".concat(d,".").concat(h)]||c[h]||u[h]||i;return a?n.createElement(m,o(o({ref:t},p),{},{components:a})):n.createElement(m,o({ref:t},p))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=h;var s={};for(var d in t)hasOwnProperty.call(t,d)&&(s[d]=t[d]);s.originalType=e,s[c]="string"==typeof e?e:r,o[1]=s;for(var l=2;l{a.r(t),a.d(t,{assets:()=>d,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=a(7462),r=(a(7294),a(3905));const i={},o="Migrating from an Indy SDK Wallet to Aries Askar",s={unversionedId:"updating/update-indy-sdk-to-askar",id:"version-0.4/updating/update-indy-sdk-to-askar",title:"Migrating from an Indy SDK Wallet to Aries Askar",description:"This documentation explains the process of migrating your Indy SDK wallet to Aries Askar.",source:"@site/versioned_docs/version-0.4/updating/update-indy-sdk-to-askar.md",sourceDirName:"updating",slug:"/updating/update-indy-sdk-to-askar",permalink:"/guides/updating/update-indy-sdk-to-askar",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Update Assistant",permalink:"/guides/updating/update-assistant"},next:{title:"Migrating from AFJ 0.1.0 to 0.2.x",permalink:"/guides/updating/versions/0.1-to-0.2"}},d={},l=[{value:"What does the migration do internally?",id:"what-does-the-migration-do-internally",level:2},{value:"Create a backup",id:"create-a-backup",level:3},{value:"Migrate the database to an Aries Askar structure",id:"migrate-the-database-to-an-aries-askar-structure",level:3},{value:"Try to open the wallet in the new Aries Askar structure",id:"try-to-open-the-wallet-in-the-new-aries-askar-structure",level:3},{value:"Update the keys",id:"update-the-keys",level:3},{value:"Update the DIDs",id:"update-the-dids",level:3},{value:"Update the credential definitions",id:"update-the-credential-definitions",level:3},{value:"Update the link secret(s) (master secret)",id:"update-the-link-secrets-master-secret",level:3},{value:"Update the credentials",id:"update-the-credentials",level:3},{value:"All the other records",id:"all-the-other-records",level:3},{value:"How to update",id:"how-to-update",level:2},{value:"add the required dependencies:",id:"add-the-required-dependencies",level:3},{value:"Getting the database path",id:"getting-the-database-path",level:3},{value:"Android",id:"android",level:4},{value:"iOS",id:"ios",level:4}],p={toc:l},c="wrapper";function u(e){let{components:t,...a}=e;return(0,r.kt)(c,(0,n.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"migrating-from-an-indy-sdk-wallet-to-aries-askar"},"Migrating from an Indy SDK Wallet to Aries Askar"),(0,r.kt)("p",null,"This documentation explains the process of migrating your Indy SDK wallet to ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-askar"},"Aries Askar"),"."),(0,r.kt)("admonition",{type:"danger"},(0,r.kt)("p",{parentName:"admonition"},"While the migration script technically works on node.js, it is strongly advised not to use it, yet. The migration of issuer records (such as Schemas and Credential Definitions) is not implemented yet. When a credential definition is detected it will revert the migration process and no harm is done.")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Postgres is not supported. If you are using postgres with Indy SDK and need to update to Aries Askar, please open an issue on ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript"},"GitHub"),".")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"The migration script is supported to run on 0.3.x before migrating from 0.3.x to 0.4.x. Please refer to ",(0,r.kt)("a",{parentName:"p",href:"/guides/updating/versions/0.3-to-0.4"},"Migrating from AFJ 0.3.x to 0.4.x")," to get to 0.4.x afterwards."),(0,r.kt)("p",{parentName:"admonition"},"It is important to note that this script must be ran before you update from 0.3.x to 0.4.x.")),(0,r.kt)("h2",{id:"what-does-the-migration-do-internally"},"What does the migration do internally?"),(0,r.kt)("p",null,"The migration script does the following to make sure everything is migrated properly, and if anything goes wrong, it will revert back to a working state."),(0,r.kt)("h3",{id:"create-a-backup"},"Create a backup"),(0,r.kt)("p",null,"Because undefined behavior might occur, we create a backup in the new ",(0,r.kt)("inlineCode",{parentName:"p"},"tmp")," directory from Aries Framework JavaScript. if some error occurs, it will be reverted back to the backed-up state and if no error occurs, it will delete the backup from the temporary directory."),(0,r.kt)("h3",{id:"migrate-the-database-to-an-aries-askar-structure"},"Migrate the database to an Aries Askar structure"),(0,r.kt)("p",null,"The Indy-sdk and Aries Askar have different database structures. So first of all we need to change some table names, decrypt all the items with the old Indy keys, encrypt the items with the new Aries Askar keys and store them inside the new structure."),(0,r.kt)("h3",{id:"try-to-open-the-wallet-in-the-new-aries-askar-structure"},"Try to open the wallet in the new Aries Askar structure"),(0,r.kt)("p",null,"When the wallet is correctly transformed, the wallet will be attempted to be opened."),(0,r.kt)("h3",{id:"update-the-keys"},"Update the keys"),(0,r.kt)("p",null,"Aries Askar has a specific way to store keys and every key, defined by the category of ",(0,r.kt)("inlineCode",{parentName:"p"},"Indy::Key")," will be migrated."),(0,r.kt)("h3",{id:"update-the-dids"},"Update the DIDs"),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"This update script does not transform did records. This is fine for something like ",(0,r.kt)("inlineCode",{parentName:"p"},"did:peer"),", but will cause issues with ",(0,r.kt)("inlineCode",{parentName:"p"},"indy")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"sov")," DIDs. For more information, please check out the ",(0,r.kt)("a",{parentName:"p",href:"/guides/updating/versions/0.3-to-0.4#removal-of-publicdidseed-and-publicdid"},"Migrating from AFJ 0.3.x to 0.4.x"))),(0,r.kt)("h3",{id:"update-the-credential-definitions"},"Update the credential definitions"),(0,r.kt)("admonition",{type:"danger"},(0,r.kt)("p",{parentName:"admonition"},"Updating of credential definitions is not yet supported. This is why it is strongly advised not to run this script in a node.js environment.")),(0,r.kt)("h3",{id:"update-the-link-secrets-master-secret"},"Update the link secret(s) (master secret)"),(0,r.kt)("p",null,"The link secrets, identified by the category ",(0,r.kt)("inlineCode",{parentName:"p"},"Indy::MasterSecret"),", are updated next. They are stored inside a new ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsLinkSecretRecord"),"."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Since we have to set a default link secret, some additional logic is added to detect this. You can either supply a ",(0,r.kt)("inlineCode",{parentName:"p"},"defaultLinkSercetId")," as a constructor parameter or it will be based on your ",(0,r.kt)("inlineCode",{parentName:"p"},"walletId"),"."),(0,r.kt)("p",{parentName:"admonition"},"If there is no Indy record with the ",(0,r.kt)("inlineCode",{parentName:"p"},"defaultLinkSecretId")," or the ",(0,r.kt)("inlineCode",{parentName:"p"},"walletId"),", an error will be thrown and the migration will be restored.")),(0,r.kt)("h3",{id:"update-the-credentials"},"Update the credentials"),(0,r.kt)("p",null,"The credentials, identified by the category ",(0,r.kt)("inlineCode",{parentName:"p"},"Indy::Credential")," are updated last. They are stored in the new ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsCredentialRecord")," as a one-to-one copy. This means that they now support more tags and will make querying a lot easier."),(0,r.kt)("h3",{id:"all-the-other-records"},"All the other records"),(0,r.kt)("p",null,"All the other records will be transferred without any updates as they are not Indy specific."),(0,r.kt)("h2",{id:"how-to-update"},"How to update"),(0,r.kt)("p",null,"Updating does not require a lot of code, but must be done with caution."),(0,r.kt)("p",null,"It is very important to note that the migration script only has to be run once. If it runs for a second time, it will error saying that the database is already migrated. Also, when the migration is finished, it is common practice to store this state in your persistent app storage. This script does not provide a way to detect if an update has happened, so storing this value will prevent the script from running every time. For more information regarding this topic, please check out ",(0,r.kt)("a",{parentName:"p",href:"/guides/updating/update-assistant#storing-the-agent-storage-version-outside-of-the-agent-storage"},"Update Assistant"),"."),(0,r.kt)("h3",{id:"add-the-required-dependencies"},"add the required dependencies:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @hyperledger/aries-askar-react-native @aries-framework/indy-sdk-to-askar-migration react-native-fs\n")),(0,r.kt)("p",null,"Below is the minimal code required for the migration to work. It is recommended to turn the logger on as it gives a lot of information regarding the migration."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"The agent is not allowed to be initialized to run this script. This makes sure nothing else happens during the migration.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript"},"import { agentDependencies } from '@aries-framework/react-native'\nimport { AskarModule } from '@aries-framework/askar'\nimport { IndySdkToAskarMigrationUpdater } from '@aries-framework/indy-sdk-to-askar-migration'\nimport { ariesAskar } from '@hyperledger/aries-askar-react-native'\n\nconst oldAgent = new Agent({\n config: {\n /* ... */\n },\n modules: {\n ariesAskar: new AskarModule({\n ariesAskar,\n }),\n },\n dependencies: agentDependencies,\n})\n\nconst dbPath = '' // see section below\n\nconst updater = await IndySdkToAskarMigrationUpdater.initialize({ dbPath, agent })\nawait updater.update()\n")),(0,r.kt)("h3",{id:"getting-the-database-path"},"Getting the database path"),(0,r.kt)("h4",{id:"android"},"Android"),(0,r.kt)("p",null,"On android, the database is commonly located under the ",(0,r.kt)("inlineCode",{parentName:"p"},"ExternalDirectoryPath"),"."),(0,r.kt)("p",null,"If you did not follow the default indy-sdk for React Native setup, your path might differ. Check out ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk-react-native#5-load-indy-library"},"step 5 of the Android setup for Indy SDK React Native")," for the default behavior."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript"},"import fs from 'react-native-fs'\n\nconst base = fs.ExternalDirectoryPath\nconst indyClient = '.indy_client'\nconst wallet = 'wallet'\nconst walletId = agent.config.walletConfig.id\nconst file = 'sqlite.db'\n\nconst dbPath = `${base}/${indyClient}/${wallet}/${walletId}/${file}`\n")),(0,r.kt)("h4",{id:"ios"},"iOS"),(0,r.kt)("p",null,"On iOS, the database is commonly located under the ",(0,r.kt)("inlineCode",{parentName:"p"},"DocumentDirectoryPath"),"."),(0,r.kt)("p",null,"For iOS this can only change if your phone does not have the ",(0,r.kt)("inlineCode",{parentName:"p"},"HOME")," environment variable set. This is not usual behavior, and if ",(0,r.kt)("inlineCode",{parentName:"p"},"HOME")," is not set, the ",(0,r.kt)("inlineCode",{parentName:"p"},"base")," in the code section below will be ",(0,r.kt)("inlineCode",{parentName:"p"},"/home/indy/Documents"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript"},"import fs from 'react-native-fs'\n\nconst base = fs.DocumentDirectoryPath\nconst indyClient = '.indy_client'\nconst wallet = 'wallet'\nconst walletId = agent.config.walletConfig.id\nconst file = 'sqlite.db'\n\nconst dbPath = `${base}/${indyClient}/${wallet}/${walletId}/${file}`\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5a512b94.3326e94c.js b/assets/js/5a512b94.3326e94c.js new file mode 100644 index 00000000..62c1acff --- /dev/null +++ b/assets/js/5a512b94.3326e94c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4602],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var a=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function i(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=a.createContext({}),u=function(e){var t=a.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=u(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,s=e.originalType,l=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),c=u(r),m=n,f=c["".concat(l,".").concat(m)]||c[m]||d[m]||s;return r?a.createElement(f,i(i({ref:t},p),{},{components:r})):a.createElement(f,i({ref:t},p))}));function f(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var s=r.length,i=new Array(s);i[0]=m;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[c]="string"==typeof e?e:n,i[1]=o;for(var u=2;u{r.d(t,{Z:()=>i});var a=r(7294),n=r(6010);const s={tabItem:"tabItem_Ymn6"};function i(e){let{children:t,hidden:r,className:i}=e;return a.createElement("div",{role:"tabpanel",className:(0,n.Z)(s.tabItem,i),hidden:r},t)}},4866:(e,t,r)=>{r.d(t,{Z:()=>N});var a=r(7462),n=r(7294),s=r(6010),i=r(2466),o=r(6550),l=r(1980),u=r(7392),p=r(12);function c(e){return function(e){return n.Children.map(e,(e=>{if((0,n.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:r,attributes:a,default:n}}=e;return{value:t,label:r,attributes:a,default:n}}))}function d(e){const{values:t,children:r}=e;return(0,n.useMemo)((()=>{const e=t??c(r);return function(e){const t=(0,u.l)(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,r])}function m(e){let{value:t,tabValues:r}=e;return r.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:r}=e;const a=(0,o.k6)(),s=function(e){let{queryString:t=!1,groupId:r}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!r)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 r??null}({queryString:t,groupId:r});return[(0,l._X)(s),(0,n.useCallback)((e=>{if(!s)return;const t=new URLSearchParams(a.location.search);t.set(s,e),a.replace({...a.location,search:t.toString()})}),[s,a])]}function g(e){const{defaultValue:t,queryString:r=!1,groupId:a}=e,s=d(e),[i,o]=(0,n.useState)((()=>function(e){let{defaultValue:t,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:r}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const a=r.find((e=>e.default))??r[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:t,tabValues:s}))),[l,u]=f({queryString:r,groupId:a}),[c,g]=function(e){let{groupId:t}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,s]=(0,p.Nk)(r);return[a,(0,n.useCallback)((e=>{r&&s.set(e)}),[r,s])]}({groupId:a}),k=(()=>{const e=l??c;return m({value:e,tabValues:s})?e:null})();(0,n.useLayoutEffect)((()=>{k&&o(k)}),[k]);return{selectedValue:i,selectValue:(0,n.useCallback)((e=>{if(!m({value:e,tabValues:s}))throw new Error(`Can't select invalid tab value=${e}`);o(e),u(e),g(e)}),[u,g,s]),tabValues:s}}var k=r(2389);const h={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function b(e){let{className:t,block:r,selectedValue:o,selectValue:l,tabValues:u}=e;const p=[],{blockElementScrollPositionUntilNextRender:c}=(0,i.o5)(),d=e=>{const t=e.currentTarget,r=p.indexOf(t),a=u[r].value;a!==o&&(c(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const r=p.indexOf(e.currentTarget)+1;t=p[r]??p[0];break}case"ArrowLeft":{const r=p.indexOf(e.currentTarget)-1;t=p[r]??p[p.length-1];break}}t?.focus()};return n.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.Z)("tabs",{"tabs--block":r},t)},u.map((e=>{let{value:t,label:r,attributes:i}=e;return n.createElement("li",(0,a.Z)({role:"tab",tabIndex:o===t?0:-1,"aria-selected":o===t,key:t,ref:e=>p.push(e),onKeyDown:m,onClick:d},i,{className:(0,s.Z)("tabs__item",h.tabItem,i?.className,{"tabs__item--active":o===t})}),r??t)})))}function y(e){let{lazy:t,children:r,selectedValue:a}=e;if(r=Array.isArray(r)?r:[r],t){const e=r.find((e=>e.props.value===a));return e?(0,n.cloneElement)(e,{className:"margin-top--md"}):null}return n.createElement("div",{className:"margin-top--md"},r.map(((e,t)=>(0,n.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function v(e){const t=g(e);return n.createElement("div",{className:(0,s.Z)("tabs-container",h.tabList)},n.createElement(b,(0,a.Z)({},e,t)),n.createElement(y,(0,a.Z)({},e,t)))}function N(e){const t=(0,k.Z)();return n.createElement(v,(0,a.Z)({key:String(t)},e))}},1548:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>f,frontMatter:()=>o,metadata:()=>u,toc:()=>c});var a=r(7462),n=(r(7294),r(3905)),s=r(4866),i=r(5162);const o={},l="Aries Askar",u={unversionedId:"getting-started/set-up/aries-askar",id:"version-0.4/getting-started/set-up/aries-askar",title:"Aries Askar",description:"Aries Askar provides secure, encrypted storage and cryptographic support for encrypting, decrypting, signing and verifying data. It also provides both the Wallet and StorageService implementations for the agent.",source:"@site/versioned_docs/version-0.4/getting-started/set-up/aries-askar.md",sourceDirName:"getting-started/set-up",slug:"/getting-started/set-up/aries-askar",permalink:"/guides/0.4/getting-started/set-up/aries-askar",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Agent Setup",permalink:"/guides/0.4/getting-started/set-up/"},next:{title:"Indy SDK",permalink:"/guides/0.4/getting-started/set-up/indy-sdk/"}},p={},c=[{value:"Installing Aries Askar",id:"installing-aries-askar",level:3},{value:"Adding Aries Askar to the Agent",id:"adding-aries-askar-to-the-agent",level:3},{value:"Supported Node.JS versions for Aries Askar",id:"supported-nodejs-versions-for-aries-askar",level:3}],d={toc:c},m="wrapper";function f(e){let{components:t,...r}=e;return(0,n.kt)(m,(0,a.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"aries-askar"},"Aries Askar"),(0,n.kt)("p",null,(0,n.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-askar"},"Aries Askar")," provides secure, encrypted storage and cryptographic support for encrypting, decrypting, signing and verifying data. It also provides both the ",(0,n.kt)("inlineCode",{parentName:"p"},"Wallet")," and ",(0,n.kt)("inlineCode",{parentName:"p"},"StorageService")," implementations for the agent."),(0,n.kt)("admonition",{type:"caution"},(0,n.kt)("p",{parentName:"admonition"},"Although Aries Askar is stable and already used in production in agents such as ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-cloudagent-python"},"Aries Cloud Agent Python"),", support for Aries Askar in Aries Framework JavaScript is currently experimental. We recommend new projects to use Aries Askar from the start, and also to migrate existing projects to Aries Askar. However, projects may experience some issues. If you encounter any issues, please ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript/issues/new"},"open an issue"),"."),(0,n.kt)("p",{parentName:"admonition"},"Currently, there are few limitations to using Aries Askar."),(0,n.kt)("ul",{parentName:"admonition"},(0,n.kt)("li",{parentName:"ul"},"When running in Node.JS, only Node.JS 18 is supported for now. See ",(0,n.kt)("a",{parentName:"li",href:"#supported-nodejs-versions-for-aries-askar"},"Supported Node.JS versions for Aries Askar")),(0,n.kt)("li",{parentName:"ul"},"Install scripts rely on bash command substitution to get the proper binaries for each system architecture and platform. Therefore, if you are under Windows, you must configure ",(0,n.kt)("inlineCode",{parentName:"li"},"npm")," or ",(0,n.kt)("inlineCode",{parentName:"li"},"yarn")," to use a bash-compliant shell (e.g. ",(0,n.kt)("inlineCode",{parentName:"li"},'npm config set script-shell "C:\\\\Program Files\\\\git\\\\bin\\\\bash.exe"'),")"))),(0,n.kt)("admonition",{type:"tip"},(0,n.kt)("p",{parentName:"admonition"},"If you're upgrading from the Indy SDK to Aries Askar, see ",(0,n.kt)("a",{parentName:"p",href:"../updating/update-indy-sdk-to-askar"},"Migrating from an Indy SDK Wallet to Aries Askar"))),(0,n.kt)("h3",{id:"installing-aries-askar"},"Installing Aries Askar"),(0,n.kt)("p",null,"When using Aries Framework JavaScript with Aries Askar, there are a few extra dependencies that need to be installed. We need to install the ",(0,n.kt)("inlineCode",{parentName:"p"},"@aries-framework/askar")," package, which implements the needed interfaces for the agent. Secondly, we need to add native bindings for the specific platform ",(0,n.kt)("inlineCode",{parentName:"p"},"@hyperledger/aries-askar-"),". Currently there are bindings for Node.JS, as ",(0,n.kt)("inlineCode",{parentName:"p"},"@hyperledger/aries-askar-nodejs"),", and React Native as ",(0,n.kt)("inlineCode",{parentName:"p"},"@hyperlegder/aries-askar-react-native"),"."),(0,n.kt)(s.Z,{mdxType:"Tabs"},(0,n.kt)(i.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @aries-framework/askar@^0.4.0 @hyperledger/aries-askar-nodejs@^0.1.0\n"))),(0,n.kt)(i.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @aries-framework/askar@^0.4.0 @hyperledger/aries-askar-react-native@^0.1.0\n")))),(0,n.kt)("h3",{id:"adding-aries-askar-to-the-agent"},"Adding Aries Askar to the Agent"),(0,n.kt)("p",null,"After installing the dependencies, we can register the Askar Module on the agent."),(0,n.kt)(s.Z,{mdxType:"Tabs"},(0,n.kt)(i.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-askar.ts section-1",showLineNumbers:!0,"set-up-askar.ts":!0,"section-1":!0},""))),(0,n.kt)(i.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-askar-rn.ts section-1",showLineNumbers:!0,"set-up-askar-rn.ts":!0,"section-1":!0},"")))),(0,n.kt)("h3",{id:"supported-nodejs-versions-for-aries-askar"},"Supported Node.JS versions for Aries Askar"),(0,n.kt)("p",null,"Due to an issue in ",(0,n.kt)("inlineCode",{parentName:"p"},"ref-napi")," (which is used in the Node.JS bindings for Aries Askar), performance for Aries Askar in Node.JS is not as expected. A patched version for ",(0,n.kt)("inlineCode",{parentName:"p"},"ref-napi")," has been published that fixes this issue, but this only works in Node.JS 18+."),(0,n.kt)("p",null,"To use Aries Askar in Node.JS, make sure you're using Node.JS 18 and patch the ",(0,n.kt)("inlineCode",{parentName:"p"},"ref-napi")," package to point towards ",(0,n.kt)("inlineCode",{parentName:"p"},"@2060.io/ref-napi")," in your ",(0,n.kt)("inlineCode",{parentName:"p"},"package.json"),":"),(0,n.kt)(s.Z,{mdxType:"Tabs"},(0,n.kt)(i.Z,{label:"NPM",value:"tab1",mdxType:"TabItem"},(0,n.kt)("p",null,"Using ",(0,n.kt)("a",{parentName:"p",href:"https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides"},"NPM ",(0,n.kt)("inlineCode",{parentName:"a"},"overrides"))," we can point the ",(0,n.kt)("inlineCode",{parentName:"p"},"ref-napi")," package to ",(0,n.kt)("inlineCode",{parentName:"p"},"@2060.io/ref-napi"),"."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-json"},'{\n "overrides": {\n "ref-napi": "npm:@2060.io/ref-napi"\n }\n}\n'))),(0,n.kt)(i.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,n.kt)("p",null,"Using ",(0,n.kt)("a",{parentName:"p",href:"https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/"},"Yarn ",(0,n.kt)("inlineCode",{parentName:"a"},"resolutions"))," we can point the ",(0,n.kt)("inlineCode",{parentName:"p"},"ref-napi")," package to ",(0,n.kt)("inlineCode",{parentName:"p"},"@2060.io/ref-napi"),"."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-json"},'{\n "resolutions": {\n "ref-napi": "npm:@2060.io/ref-napi"\n }\n}\n')))),(0,n.kt)("admonition",{type:"info"},(0,n.kt)("p",{parentName:"admonition"},"See the following issues for more information on the performance bottleneck"),(0,n.kt)("ul",{parentName:"admonition"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-askar/issues/76"},"https://github.com/hyperledger/aries-askar/issues/76")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/node-ffi-napi/ref-napi/issues/72"},"https://github.com/node-ffi-napi/ref-napi/issues/72")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/node-ffi-napi/ref-napi/pull/73"},"https://github.com/node-ffi-napi/ref-napi/pull/73")))))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5a512b94.8d4761ec.js b/assets/js/5a512b94.8d4761ec.js deleted file mode 100644 index 7d0d8aff..00000000 --- a/assets/js/5a512b94.8d4761ec.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4602],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var a=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function i(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=a.createContext({}),u=function(e){var t=a.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=u(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,s=e.originalType,l=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),c=u(r),m=n,f=c["".concat(l,".").concat(m)]||c[m]||d[m]||s;return r?a.createElement(f,i(i({ref:t},p),{},{components:r})):a.createElement(f,i({ref:t},p))}));function f(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var s=r.length,i=new Array(s);i[0]=m;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[c]="string"==typeof e?e:n,i[1]=o;for(var u=2;u{r.d(t,{Z:()=>i});var a=r(7294),n=r(6010);const s={tabItem:"tabItem_Ymn6"};function i(e){let{children:t,hidden:r,className:i}=e;return a.createElement("div",{role:"tabpanel",className:(0,n.Z)(s.tabItem,i),hidden:r},t)}},4866:(e,t,r)=>{r.d(t,{Z:()=>N});var a=r(7462),n=r(7294),s=r(6010),i=r(2466),o=r(6550),l=r(1980),u=r(7392),p=r(12);function c(e){return function(e){return n.Children.map(e,(e=>{if((0,n.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:r,attributes:a,default:n}}=e;return{value:t,label:r,attributes:a,default:n}}))}function d(e){const{values:t,children:r}=e;return(0,n.useMemo)((()=>{const e=t??c(r);return function(e){const t=(0,u.l)(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,r])}function m(e){let{value:t,tabValues:r}=e;return r.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:r}=e;const a=(0,o.k6)(),s=function(e){let{queryString:t=!1,groupId:r}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!r)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 r??null}({queryString:t,groupId:r});return[(0,l._X)(s),(0,n.useCallback)((e=>{if(!s)return;const t=new URLSearchParams(a.location.search);t.set(s,e),a.replace({...a.location,search:t.toString()})}),[s,a])]}function g(e){const{defaultValue:t,queryString:r=!1,groupId:a}=e,s=d(e),[i,o]=(0,n.useState)((()=>function(e){let{defaultValue:t,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:r}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const a=r.find((e=>e.default))??r[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:t,tabValues:s}))),[l,u]=f({queryString:r,groupId:a}),[c,g]=function(e){let{groupId:t}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,s]=(0,p.Nk)(r);return[a,(0,n.useCallback)((e=>{r&&s.set(e)}),[r,s])]}({groupId:a}),k=(()=>{const e=l??c;return m({value:e,tabValues:s})?e:null})();(0,n.useLayoutEffect)((()=>{k&&o(k)}),[k]);return{selectedValue:i,selectValue:(0,n.useCallback)((e=>{if(!m({value:e,tabValues:s}))throw new Error(`Can't select invalid tab value=${e}`);o(e),u(e),g(e)}),[u,g,s]),tabValues:s}}var k=r(2389);const h={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function b(e){let{className:t,block:r,selectedValue:o,selectValue:l,tabValues:u}=e;const p=[],{blockElementScrollPositionUntilNextRender:c}=(0,i.o5)(),d=e=>{const t=e.currentTarget,r=p.indexOf(t),a=u[r].value;a!==o&&(c(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const r=p.indexOf(e.currentTarget)+1;t=p[r]??p[0];break}case"ArrowLeft":{const r=p.indexOf(e.currentTarget)-1;t=p[r]??p[p.length-1];break}}t?.focus()};return n.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.Z)("tabs",{"tabs--block":r},t)},u.map((e=>{let{value:t,label:r,attributes:i}=e;return n.createElement("li",(0,a.Z)({role:"tab",tabIndex:o===t?0:-1,"aria-selected":o===t,key:t,ref:e=>p.push(e),onKeyDown:m,onClick:d},i,{className:(0,s.Z)("tabs__item",h.tabItem,i?.className,{"tabs__item--active":o===t})}),r??t)})))}function y(e){let{lazy:t,children:r,selectedValue:a}=e;if(r=Array.isArray(r)?r:[r],t){const e=r.find((e=>e.props.value===a));return e?(0,n.cloneElement)(e,{className:"margin-top--md"}):null}return n.createElement("div",{className:"margin-top--md"},r.map(((e,t)=>(0,n.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function v(e){const t=g(e);return n.createElement("div",{className:(0,s.Z)("tabs-container",h.tabList)},n.createElement(b,(0,a.Z)({},e,t)),n.createElement(y,(0,a.Z)({},e,t)))}function N(e){const t=(0,k.Z)();return n.createElement(v,(0,a.Z)({key:String(t)},e))}},1548:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>f,frontMatter:()=>o,metadata:()=>u,toc:()=>c});var a=r(7462),n=(r(7294),r(3905)),s=r(4866),i=r(5162);const o={},l="Aries Askar",u={unversionedId:"getting-started/set-up/aries-askar",id:"version-0.4/getting-started/set-up/aries-askar",title:"Aries Askar",description:"Aries Askar provides secure, encrypted storage and cryptographic support for encrypting, decrypting, signing and verifying data. It also provides both the Wallet and StorageService implementations for the agent.",source:"@site/versioned_docs/version-0.4/getting-started/set-up/aries-askar.md",sourceDirName:"getting-started/set-up",slug:"/getting-started/set-up/aries-askar",permalink:"/guides/getting-started/set-up/aries-askar",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Agent Setup",permalink:"/guides/getting-started/set-up/"},next:{title:"Indy SDK",permalink:"/guides/getting-started/set-up/indy-sdk/"}},p={},c=[{value:"Installing Aries Askar",id:"installing-aries-askar",level:3},{value:"Adding Aries Askar to the Agent",id:"adding-aries-askar-to-the-agent",level:3},{value:"Supported Node.JS versions for Aries Askar",id:"supported-nodejs-versions-for-aries-askar",level:3}],d={toc:c},m="wrapper";function f(e){let{components:t,...r}=e;return(0,n.kt)(m,(0,a.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"aries-askar"},"Aries Askar"),(0,n.kt)("p",null,(0,n.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-askar"},"Aries Askar")," provides secure, encrypted storage and cryptographic support for encrypting, decrypting, signing and verifying data. It also provides both the ",(0,n.kt)("inlineCode",{parentName:"p"},"Wallet")," and ",(0,n.kt)("inlineCode",{parentName:"p"},"StorageService")," implementations for the agent."),(0,n.kt)("admonition",{type:"caution"},(0,n.kt)("p",{parentName:"admonition"},"Although Aries Askar is stable and already used in production in agents such as ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-cloudagent-python"},"Aries Cloud Agent Python"),", support for Aries Askar in Aries Framework JavaScript is currently experimental. We recommend new projects to use Aries Askar from the start, and also to migrate existing projects to Aries Askar. However, projects may experience some issues. If you encounter any issues, please ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript/issues/new"},"open an issue"),"."),(0,n.kt)("p",{parentName:"admonition"},"Currently, there are few limitations to using Aries Askar."),(0,n.kt)("ul",{parentName:"admonition"},(0,n.kt)("li",{parentName:"ul"},"When running in Node.JS, only Node.JS 18 is supported for now. See ",(0,n.kt)("a",{parentName:"li",href:"#supported-nodejs-versions-for-aries-askar"},"Supported Node.JS versions for Aries Askar")),(0,n.kt)("li",{parentName:"ul"},"Install scripts rely on bash command substitution to get the proper binaries for each system architecture and platform. Therefore, if you are under Windows, you must configure ",(0,n.kt)("inlineCode",{parentName:"li"},"npm")," or ",(0,n.kt)("inlineCode",{parentName:"li"},"yarn")," to use a bash-compliant shell (e.g. ",(0,n.kt)("inlineCode",{parentName:"li"},'npm config set script-shell "C:\\\\Program Files\\\\git\\\\bin\\\\bash.exe"'),")"))),(0,n.kt)("admonition",{type:"tip"},(0,n.kt)("p",{parentName:"admonition"},"If you're upgrading from the Indy SDK to Aries Askar, see ",(0,n.kt)("a",{parentName:"p",href:"../updating/update-indy-sdk-to-askar"},"Migrating from an Indy SDK Wallet to Aries Askar"))),(0,n.kt)("h3",{id:"installing-aries-askar"},"Installing Aries Askar"),(0,n.kt)("p",null,"When using Aries Framework JavaScript with Aries Askar, there are a few extra dependencies that need to be installed. We need to install the ",(0,n.kt)("inlineCode",{parentName:"p"},"@aries-framework/askar")," package, which implements the needed interfaces for the agent. Secondly, we need to add native bindings for the specific platform ",(0,n.kt)("inlineCode",{parentName:"p"},"@hyperledger/aries-askar-"),". Currently there are bindings for Node.JS, as ",(0,n.kt)("inlineCode",{parentName:"p"},"@hyperledger/aries-askar-nodejs"),", and React Native as ",(0,n.kt)("inlineCode",{parentName:"p"},"@hyperlegder/aries-askar-react-native"),"."),(0,n.kt)(s.Z,{mdxType:"Tabs"},(0,n.kt)(i.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @aries-framework/askar@^0.4.0 @hyperledger/aries-askar-nodejs@^0.1.0\n"))),(0,n.kt)(i.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @aries-framework/askar@^0.4.0 @hyperledger/aries-askar-react-native@^0.1.0\n")))),(0,n.kt)("h3",{id:"adding-aries-askar-to-the-agent"},"Adding Aries Askar to the Agent"),(0,n.kt)("p",null,"After installing the dependencies, we can register the Askar Module on the agent."),(0,n.kt)(s.Z,{mdxType:"Tabs"},(0,n.kt)(i.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-askar.ts section-1",showLineNumbers:!0,"set-up-askar.ts":!0,"section-1":!0},""))),(0,n.kt)(i.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-askar-rn.ts section-1",showLineNumbers:!0,"set-up-askar-rn.ts":!0,"section-1":!0},"")))),(0,n.kt)("h3",{id:"supported-nodejs-versions-for-aries-askar"},"Supported Node.JS versions for Aries Askar"),(0,n.kt)("p",null,"Due to an issue in ",(0,n.kt)("inlineCode",{parentName:"p"},"ref-napi")," (which is used in the Node.JS bindings for Aries Askar), performance for Aries Askar in Node.JS is not as expected. A patched version for ",(0,n.kt)("inlineCode",{parentName:"p"},"ref-napi")," has been published that fixes this issue, but this only works in Node.JS 18+."),(0,n.kt)("p",null,"To use Aries Askar in Node.JS, make sure you're using Node.JS 18 and patch the ",(0,n.kt)("inlineCode",{parentName:"p"},"ref-napi")," package to point towards ",(0,n.kt)("inlineCode",{parentName:"p"},"@2060.io/ref-napi")," in your ",(0,n.kt)("inlineCode",{parentName:"p"},"package.json"),":"),(0,n.kt)(s.Z,{mdxType:"Tabs"},(0,n.kt)(i.Z,{label:"NPM",value:"tab1",mdxType:"TabItem"},(0,n.kt)("p",null,"Using ",(0,n.kt)("a",{parentName:"p",href:"https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides"},"NPM ",(0,n.kt)("inlineCode",{parentName:"a"},"overrides"))," we can point the ",(0,n.kt)("inlineCode",{parentName:"p"},"ref-napi")," package to ",(0,n.kt)("inlineCode",{parentName:"p"},"@2060.io/ref-napi"),"."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-json"},'{\n "overrides": {\n "ref-napi": "npm:@2060.io/ref-napi"\n }\n}\n'))),(0,n.kt)(i.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,n.kt)("p",null,"Using ",(0,n.kt)("a",{parentName:"p",href:"https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/"},"Yarn ",(0,n.kt)("inlineCode",{parentName:"a"},"resolutions"))," we can point the ",(0,n.kt)("inlineCode",{parentName:"p"},"ref-napi")," package to ",(0,n.kt)("inlineCode",{parentName:"p"},"@2060.io/ref-napi"),"."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-json"},'{\n "resolutions": {\n "ref-napi": "npm:@2060.io/ref-napi"\n }\n}\n')))),(0,n.kt)("admonition",{type:"info"},(0,n.kt)("p",{parentName:"admonition"},"See the following issues for more information on the performance bottleneck"),(0,n.kt)("ul",{parentName:"admonition"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-askar/issues/76"},"https://github.com/hyperledger/aries-askar/issues/76")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/node-ffi-napi/ref-napi/issues/72"},"https://github.com/node-ffi-napi/ref-napi/issues/72")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/node-ffi-napi/ref-napi/pull/73"},"https://github.com/node-ffi-napi/ref-napi/pull/73")))))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5d1c397c.f13ab292.js b/assets/js/5d1c397c.f643f855.js similarity index 51% rename from assets/js/5d1c397c.f13ab292.js rename to assets/js/5d1c397c.f643f855.js index 871d62e9..a3adf479 100644 --- a/assets/js/5d1c397c.f13ab292.js +++ b/assets/js/5d1c397c.f643f855.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[6840],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>f});var o=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function g(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=o.createContext({}),s=function(e){var n=o.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):g(g({},n),e)),t},c=function(e){var n=s(e.components);return o.createElement(l.Provider,{value:n},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,r=e.mdxType,a=e.originalType,l=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),u=s(t),d=r,f=u["".concat(l,".").concat(d)]||u[d]||p[d]||a;return t?o.createElement(f,g(g({ref:n},c),{},{components:t})):o.createElement(f,g({ref:n},c))}));function f(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var a=t.length,g=new Array(a);g[0]=d;var i={};for(var l in n)hasOwnProperty.call(n,l)&&(i[l]=n[l]);i.originalType=e,i[u]="string"==typeof e?e:r,g[1]=i;for(var s=2;s{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>g,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>s});var o=t(7462),r=(t(7294),t(3905));const a={},g="Logging",i={unversionedId:"tutorials/agent-config/logging",id:"tutorials/agent-config/logging",title:"Logging",description:"Using the Default ConsoleLogger",source:"@site/guides/tutorials/agent-config/logging.md",sourceDirName:"tutorials/agent-config",slug:"/tutorials/agent-config/logging",permalink:"/guides/0.5/tutorials/agent-config/logging",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Agent Config",permalink:"/guides/0.5/tutorials/agent-config/"},next:{title:"Create a connection",permalink:"/guides/0.5/tutorials/create-a-connection"}},l={},s=[{value:"Using the Default ConsoleLogger",id:"using-the-default-consolelogger",level:2},{value:"Creating your own Logger",id:"creating-your-own-logger",level:2}],c={toc:s},u="wrapper";function p(e){let{components:n,...t}=e;return(0,r.kt)(u,(0,o.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"logging"},"Logging"),(0,r.kt)("h2",{id:"using-the-default-consolelogger"},"Using the Default ConsoleLogger"),(0,r.kt)("p",null,"To enable logging inside the framework a logger must be passed to the agent config. A simple ",(0,r.kt)("inlineCode",{parentName:"p"},"ConsoleLogger")," can be imported from the framework."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import type { InitConfig } from '@credo-ts/core'\nimport { ConsoleLogger, LogLevel } from '@credo-ts/core'\n\nconst agentConfig: InitConfig = {\n // ... other config properties ...\n logger: new ConsoleLogger(LogLevel.info),\n}\n")),(0,r.kt)("h2",{id:"creating-your-own-logger"},"Creating your own Logger"),(0,r.kt)("p",null,"For more advanced use cases the ",(0,r.kt)("inlineCode",{parentName:"p"},"Logger")," interface can be implemented. See the example below."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Logger, LogLevel } from '@credo-ts/core'\n\nclass MyCustomLogger implements Logger {\n public logLevel: LogLevel\n\n public constructor(logLevel: LogLevel = LogLevel.off) {\n this.logLevel = logLevel\n }\n\n public test(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public trace(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public debug(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public info(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public warn(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public error(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public fatal(message: string, data?: Record): void {\n console.log(message, data)\n }\n}\n")))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[6840],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>f});var o=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function g(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=o.createContext({}),s=function(e){var n=o.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):g(g({},n),e)),t},c=function(e){var n=s(e.components);return o.createElement(l.Provider,{value:n},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,r=e.mdxType,a=e.originalType,l=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),u=s(t),d=r,f=u["".concat(l,".").concat(d)]||u[d]||p[d]||a;return t?o.createElement(f,g(g({ref:n},c),{},{components:t})):o.createElement(f,g({ref:n},c))}));function f(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var a=t.length,g=new Array(a);g[0]=d;var i={};for(var l in n)hasOwnProperty.call(n,l)&&(i[l]=n[l]);i.originalType=e,i[u]="string"==typeof e?e:r,g[1]=i;for(var s=2;s{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>g,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>s});var o=t(7462),r=(t(7294),t(3905));const a={},g="Logging",i={unversionedId:"tutorials/agent-config/logging",id:"tutorials/agent-config/logging",title:"Logging",description:"Using the Default ConsoleLogger",source:"@site/guides/tutorials/agent-config/logging.md",sourceDirName:"tutorials/agent-config",slug:"/tutorials/agent-config/logging",permalink:"/guides/tutorials/agent-config/logging",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Agent Config",permalink:"/guides/tutorials/agent-config/"},next:{title:"Create a connection",permalink:"/guides/tutorials/create-a-connection"}},l={},s=[{value:"Using the Default ConsoleLogger",id:"using-the-default-consolelogger",level:2},{value:"Creating your own Logger",id:"creating-your-own-logger",level:2}],c={toc:s},u="wrapper";function p(e){let{components:n,...t}=e;return(0,r.kt)(u,(0,o.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"logging"},"Logging"),(0,r.kt)("h2",{id:"using-the-default-consolelogger"},"Using the Default ConsoleLogger"),(0,r.kt)("p",null,"To enable logging inside the framework a logger must be passed to the agent config. A simple ",(0,r.kt)("inlineCode",{parentName:"p"},"ConsoleLogger")," can be imported from the framework."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import type { InitConfig } from '@credo-ts/core'\nimport { ConsoleLogger, LogLevel } from '@credo-ts/core'\n\nconst agentConfig: InitConfig = {\n // ... other config properties ...\n logger: new ConsoleLogger(LogLevel.info),\n}\n")),(0,r.kt)("h2",{id:"creating-your-own-logger"},"Creating your own Logger"),(0,r.kt)("p",null,"For more advanced use cases the ",(0,r.kt)("inlineCode",{parentName:"p"},"Logger")," interface can be implemented. See the example below."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Logger, LogLevel } from '@credo-ts/core'\n\nclass MyCustomLogger implements Logger {\n public logLevel: LogLevel\n\n public constructor(logLevel: LogLevel = LogLevel.off) {\n this.logLevel = logLevel\n }\n\n public test(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public trace(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public debug(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public info(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public warn(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public error(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public fatal(message: string, data?: Record): void {\n console.log(message, data)\n }\n}\n")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5d8cec60.ee7969e5.js b/assets/js/5d8cec60.8aaa2354.js similarity index 58% rename from assets/js/5d8cec60.ee7969e5.js rename to assets/js/5d8cec60.8aaa2354.js index b70ec89d..ca70445b 100644 --- a/assets/js/5d8cec60.ee7969e5.js +++ b/assets/js/5d8cec60.8aaa2354.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[6751],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(r),u=a,f=d["".concat(c,".").concat(u)]||d[u]||m[u]||o;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=u;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:a,i[1]=s;for(var l=2;l{r.d(t,{Z:()=>g});var n=r(7294),a=r(6010),o=r(3438),i=r(9960),s=r(3919),c=r(5999);const l={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function p(e){let{href:t,children:r}=e;return n.createElement(i.Z,{href:t,className:(0,a.Z)("card padding--lg",l.cardContainer)},r)}function d(e){let{href:t,icon:r,title:o,description:i}=e;return n.createElement(p,{href:t},n.createElement("h2",{className:(0,a.Z)("text--truncate",l.cardTitle),title:o},r," ",o),i&&n.createElement("p",{className:(0,a.Z)("text--truncate",l.cardDescription),title:i},i))}function m(e){let{item:t}=e;const r=(0,o.Wl)(t);return r?n.createElement(d,{href:r,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,c.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function u(e){let{item:t}=e;const r=(0,s.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",a=(0,o.xz)(t.docId??void 0);return n.createElement(d,{href:t.href,icon:r,title:t.label,description:a?.description})}function f(e){let{item:t}=e;switch(t.type){case"link":return n.createElement(u,{item:t});case"category":return n.createElement(m,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function h(e){let{className:t}=e;const r=(0,o.jA)();return n.createElement(g,{items:r.items,className:t})}function g(e){const{items:t,className:r}=e;if(!t)return n.createElement(h,e);const i=(0,o.MN)(t);return n.createElement("section",{className:(0,a.Z)("row",r)},i.map(((e,t)=>n.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},n.createElement(f,{item:e})))))}},1156:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var n=r(7462),a=(r(7294),r(3905)),o=r(2991);const i={},s="Extensions",c={unversionedId:"extensions/index",id:"extensions/index",title:"Extensions",description:"Credo Extensions is an extensions repository to Credo. It hosts libraries built on top of Credo that don't necessarily belong to the core of the project.",source:"@site/guides/extensions/index.md",sourceDirName:"extensions",slug:"/extensions/",permalink:"/guides/0.5/extensions/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"The Credo Ecosystem",permalink:"/guides/0.5/ecosystem/"},next:{title:"REST API",permalink:"/guides/0.5/extensions/rest"}},l={},p=[],d={toc:p},m="wrapper";function u(e){let{components:t,...r}=e;return(0,a.kt)(m,(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"extensions"},"Extensions"),(0,a.kt)("p",null,"Credo Extensions is an extensions repository to Credo. It hosts libraries built on top of Credo that don't necessarily belong to the core of the project."),(0,a.kt)("p",null,"Currently, there are four packages in the extension repository. Example extension libraries include React Hooks for Credo and a REST API wrapper."),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Package"),(0,a.kt)("th",{parentName:"tr",align:null},"Version"),(0,a.kt)("th",{parentName:"tr",align:null},"Description"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"https://www.npmjs.com/package/@credo-ts/redux-store"},(0,a.kt)("inlineCode",{parentName:"a"},"@credo-ts/redux-store"))),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("img",{parentName:"td",src:"https://img.shields.io/npm/v/@credo-ts/redux-store",alt:"@credo-ts/redux-store version"})),(0,a.kt)("td",{parentName:"tr",align:null},"Redux toolkit wrapper around Credo")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"https://www.npmjs.com/package/@credo-ts/rest"},(0,a.kt)("inlineCode",{parentName:"a"},"@credo-ts/rest"))),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("img",{parentName:"td",src:"https://img.shields.io/npm/v/@credo-ts/rest",alt:"@credo-ts/rest version"})),(0,a.kt)("td",{parentName:"tr",align:null},"Rest endpoint wrapper for using your agent over HTTP")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"https://www.npmjs.com/package/@credo-ts/react-hooks"},(0,a.kt)("inlineCode",{parentName:"a"},"@credo-ts/react-hooks"))),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("img",{parentName:"td",src:"https://img.shields.io/npm/v/@credo-ts/react-hooks",alt:"@credo-ts/react-hooks version"})),(0,a.kt)("td",{parentName:"tr",align:null},"React Hooks for data handling and agent interaction")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"https://www.npmjs.com/package/@credo-ts/push-notifications"},(0,a.kt)("inlineCode",{parentName:"a"},"@credo-ts/push-notifications"))),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("img",{parentName:"td",src:"https://img.shields.io/npm/v/@credo-ts/push-notifications",alt:"@credo-ts/push-notifications version"})),(0,a.kt)("td",{parentName:"tr",align:null},"Push notification plugin for Credo")))),(0,a.kt)(o.Z,{mdxType:"DocCardList"}))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[6751],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(r),u=a,f=d["".concat(c,".").concat(u)]||d[u]||m[u]||o;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=u;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:a,i[1]=s;for(var l=2;l{r.d(t,{Z:()=>g});var n=r(7294),a=r(6010),o=r(3438),i=r(9960),s=r(3919),c=r(5999);const l={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function p(e){let{href:t,children:r}=e;return n.createElement(i.Z,{href:t,className:(0,a.Z)("card padding--lg",l.cardContainer)},r)}function d(e){let{href:t,icon:r,title:o,description:i}=e;return n.createElement(p,{href:t},n.createElement("h2",{className:(0,a.Z)("text--truncate",l.cardTitle),title:o},r," ",o),i&&n.createElement("p",{className:(0,a.Z)("text--truncate",l.cardDescription),title:i},i))}function m(e){let{item:t}=e;const r=(0,o.Wl)(t);return r?n.createElement(d,{href:r,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,c.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function u(e){let{item:t}=e;const r=(0,s.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",a=(0,o.xz)(t.docId??void 0);return n.createElement(d,{href:t.href,icon:r,title:t.label,description:a?.description})}function f(e){let{item:t}=e;switch(t.type){case"link":return n.createElement(u,{item:t});case"category":return n.createElement(m,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function h(e){let{className:t}=e;const r=(0,o.jA)();return n.createElement(g,{items:r.items,className:t})}function g(e){const{items:t,className:r}=e;if(!t)return n.createElement(h,e);const i=(0,o.MN)(t);return n.createElement("section",{className:(0,a.Z)("row",r)},i.map(((e,t)=>n.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},n.createElement(f,{item:e})))))}},1156:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var n=r(7462),a=(r(7294),r(3905)),o=r(2991);const i={},s="Extensions",c={unversionedId:"extensions/index",id:"extensions/index",title:"Extensions",description:"Credo Extensions is an extensions repository to Credo. It hosts libraries built on top of Credo that don't necessarily belong to the core of the project.",source:"@site/guides/extensions/index.md",sourceDirName:"extensions",slug:"/extensions/",permalink:"/guides/extensions/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"The Credo Ecosystem",permalink:"/guides/ecosystem/"},next:{title:"REST API",permalink:"/guides/extensions/rest"}},l={},p=[],d={toc:p},m="wrapper";function u(e){let{components:t,...r}=e;return(0,a.kt)(m,(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"extensions"},"Extensions"),(0,a.kt)("p",null,"Credo Extensions is an extensions repository to Credo. It hosts libraries built on top of Credo that don't necessarily belong to the core of the project."),(0,a.kt)("p",null,"Currently, there are four packages in the extension repository. Example extension libraries include React Hooks for Credo and a REST API wrapper."),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Package"),(0,a.kt)("th",{parentName:"tr",align:null},"Version"),(0,a.kt)("th",{parentName:"tr",align:null},"Description"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"https://www.npmjs.com/package/@credo-ts/redux-store"},(0,a.kt)("inlineCode",{parentName:"a"},"@credo-ts/redux-store"))),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("img",{parentName:"td",src:"https://img.shields.io/npm/v/@credo-ts/redux-store",alt:"@credo-ts/redux-store version"})),(0,a.kt)("td",{parentName:"tr",align:null},"Redux toolkit wrapper around Credo")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"https://www.npmjs.com/package/@credo-ts/rest"},(0,a.kt)("inlineCode",{parentName:"a"},"@credo-ts/rest"))),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("img",{parentName:"td",src:"https://img.shields.io/npm/v/@credo-ts/rest",alt:"@credo-ts/rest version"})),(0,a.kt)("td",{parentName:"tr",align:null},"Rest endpoint wrapper for using your agent over HTTP")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"https://www.npmjs.com/package/@credo-ts/react-hooks"},(0,a.kt)("inlineCode",{parentName:"a"},"@credo-ts/react-hooks"))),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("img",{parentName:"td",src:"https://img.shields.io/npm/v/@credo-ts/react-hooks",alt:"@credo-ts/react-hooks version"})),(0,a.kt)("td",{parentName:"tr",align:null},"React Hooks for data handling and agent interaction")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"https://www.npmjs.com/package/@credo-ts/push-notifications"},(0,a.kt)("inlineCode",{parentName:"a"},"@credo-ts/push-notifications"))),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("img",{parentName:"td",src:"https://img.shields.io/npm/v/@credo-ts/push-notifications",alt:"@credo-ts/push-notifications version"})),(0,a.kt)("td",{parentName:"tr",align:null},"Push notification plugin for Credo")))),(0,a.kt)(o.Z,{mdxType:"DocCardList"}))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/60053357.203ae6de.js b/assets/js/60053357.203ae6de.js deleted file mode 100644 index 7f8a1e14..00000000 --- a/assets/js/60053357.203ae6de.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[6266],{3905:(e,t,a)=>{a.d(t,{Zo:()=>u,kt:()=>h});var i=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,i)}return a}function r(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var l=i.createContext({}),d=function(e){var t=i.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):r(r({},t),e)),a},u=function(e){var t=d(e.components);return i.createElement(l.Provider,{value:t},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},c=i.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=d(a),c=n,h=p["".concat(l,".").concat(c)]||p[c]||m[c]||o;return a?i.createElement(h,r(r({ref:t},u),{},{components:a})):i.createElement(h,r({ref:t},u))}));function h(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,r=new Array(o);r[0]=c;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:n,r[1]=s;for(var d=2;d{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var i=a(7462),n=(a(7294),a(3905));const o={},r="Mediation",s={unversionedId:"tutorials/mediation",id:"tutorials/mediation",title:"Mediation",description:"This section assumes that you have:",source:"@site/guides/tutorials/mediation.md",sourceDirName:"tutorials",slug:"/tutorials/mediation",permalink:"/guides/0.5/tutorials/mediation",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Issue a credential",permalink:"/guides/0.5/tutorials/issue-a-credential"},next:{title:"Updating Credo",permalink:"/guides/0.5/updating/"}},l={},d=[{value:"What is a mediator, and Why should I use one?",id:"what-is-a-mediator-and-why-should-i-use-one",level:3},{value:"1. Mediator setup",id:"1-mediator-setup",level:3},{value:"2. Recipient (Alice) setup",id:"2-recipient-alice-setup",level:3},{value:"3. Message exchange",id:"3-message-exchange",level:3},{value:"Useful resources",id:"useful-resources",level:3}],u={toc:d},p="wrapper";function m(e){let{components:t,...a}=e;return(0,n.kt)(p,(0,i.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"mediation"},"Mediation"),(0,n.kt)("blockquote",null,(0,n.kt)("p",{parentName:"blockquote"},"This section assumes that you have:"),(0,n.kt)("ol",{parentName:"blockquote"},(0,n.kt)("li",{parentName:"ol"},"Set up a ",(0,n.kt)("a",{parentName:"li",href:"../getting-started/installation"},"valid environment")," for development"),(0,n.kt)("li",{parentName:"ol"},"Basic knowledge of the required fields in the ",(0,n.kt)("a",{parentName:"li",href:"./agent-config"},"agent\nconfig"))),(0,n.kt)("p",{parentName:"blockquote"},"The agent setup varies depending on your target environment, React Native or Node.js.",(0,n.kt)("br",{parentName:"p"}),"\n","This tutorial assumes a Node.js environment for all agents (Alice, Bob, Meditator).")),(0,n.kt)("p",null,"This tutorial shows how to set up a mediator, how to configure an agent to use a mediator, and how agents exchange messages with a mediator in place.\nConcepts are explained in isolation:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"/guides/0.5/tutorials/mediation#1-mediator-setup"},"First"),", it is shown how to set up a mediator."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"/guides/0.5/tutorials/mediation#2-recipient-alice-setup"},"Second"),", it is demonstrated how to use a mediator."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"/guides/0.5/tutorials/mediation#3-message-exchange"},"Third"),", the message exchange between agents with a mediator in place is explained.")),(0,n.kt)("h3",{id:"what-is-a-mediator-and-why-should-i-use-one"},"What is a mediator, and Why should I use one?"),(0,n.kt)("p",null,"A mediator is just a special type of agent."),(0,n.kt)("admonition",{type:"info"},(0,n.kt)("p",{parentName:"admonition"},"\"When we describe agent-to-agent communication, it is convenient to think of an interaction only in terms of Alice and Bob and their agents. We say things like: \"Alice's agent sends a message to Bob's agent\" -- or perhaps \"Alice's edge agent sends a message to Bob's cloud agent, which forwards it to Bob's edge agent\"."),(0,n.kt)("p",{parentName:"admonition"},"Such statements adopt a useful level of abstraction--one that's highly recommended for most discussions. However, they make a number of simplifications. By modeling the roles of mediators and relays in routing, we can support routes that use multiple transports, routes that are not fully known (or knowable) to the sender, routes that pass through mix networks, and other advanced and powerful concepts.\"",(0,n.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0046-mediators-and-relays/README.md#aries-rfc-0046-mediators-and-relays"},"Aries RFC 0046: Mediators and Relays"))),(0,n.kt)("p",null,'A practical example where the use of mediators is beneficial can be found in a mobile environment. A mobile agent, aka. your mobile wallet, receives messages from other agents. Technically, sending HTTP messages to a mobile agent is impossible because the agent does not have a public IP. As you have probably seen in previous examples, a workaround for this scenario is to use ngrok. Another option is to use a mediator. When an agent is configured to use a mediator, messages to that agent are routed through the mediator and from there to its destination. Thus, a mobile agent can use a "public" mediator to receive messages on its behalf and poll them from time to time.'),(0,n.kt)("p",null,"This is just one example of how a mediator can be used. Further resources about mediators can be found ",(0,n.kt)("a",{parentName:"p",href:"/guides/0.5/tutorials/mediation#useful-resources"},"here"),"."),(0,n.kt)("admonition",{type:"tip"},(0,n.kt)("p",{parentName:"admonition"},"With mediators, WebSockets come in handy. In a production environment, it is recommendable to register a ",(0,n.kt)("inlineCode",{parentName:"p"},"WsInboundTransport()")," for Alice and a ",(0,n.kt)("inlineCode",{parentName:"p"},"WsOutboundTransport()")," for the mediator. These WebSocket transports allow the mediator to push messages to Alice instead of having Alice pull messages from the mediator repeatedly.")),(0,n.kt)("h3",{id:"1-mediator-setup"},"1. Mediator setup"),(0,n.kt)("p",null,"The first part shows how to set up a mediator agent. Generally, there are two ways to do that: deploying it from scratch or using a third-party mediator. This section focuses on the former approach, setting up the mediator from scratch."),(0,n.kt)("p",null,"The mediator is set up on port 3001 and creates an Out-of-Band invitation that allows multiple other agents to connect to the mediator. Configuring an agent as a mediator demands utilizing the ",(0,n.kt)("inlineCode",{parentName:"p"},"MediatorModule"),". In this example, the ",(0,n.kt)("inlineCode",{parentName:"p"},"autoAcceptMediationRequests")," flag is set to true to accept mediation requests automatically."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers mediator-setup.ts section-1",showLineNumbers:!0,"mediator-setup.ts":!0,"section-1":!0},"")),(0,n.kt)("h3",{id:"2-recipient-alice-setup"},"2. Recipient (Alice) setup"),(0,n.kt)("p",null,"The second part shows how to use a mediator. Becoming a recipient of a mediator requires using the ",(0,n.kt)("inlineCode",{parentName:"p"},"MediationRecipientModule"),". The setup is the same whether you use your own or a third-party mediator."),(0,n.kt)("p",null,"The easiest way to set everything up is by configuring the ",(0,n.kt)("inlineCode",{parentName:"p"},"MediationRecipientModule")," to connect to the mediator on agent startup. This can be done by constructing the module with the ",(0,n.kt)("inlineCode",{parentName:"p"},"mediatorInvitationUrl"),". You can get the mediatorInvitationUrl either from ",(0,n.kt)("a",{parentName:"p",href:"/guides/0.5/tutorials/mediation#1-mediator-setup"},"part one")," by running a mediator yourself or from a public mediator such as the Animo-mediator. The following snippet uses the latter approach."),(0,n.kt)("p",null,"The ",(0,n.kt)("inlineCode",{parentName:"p"},"ConnectionsModule")," used in this snippet serves the sole purpose of automatically accepting connections and thus simplifying setup."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers mediation-recipient.ts section-1",showLineNumbers:!0,"mediation-recipient.ts":!0,"section-1":!0},"")),(0,n.kt)("admonition",{type:"info"},(0,n.kt)("p",{parentName:"admonition"},"In case you are using a third-party mediator and cannot create an invitationUrl, it is common practice for mediators to provide an endpoint from which the invitationUrl can be fetched.")),(0,n.kt)("h3",{id:"3-message-exchange"},"3. Message exchange"),(0,n.kt)("p",null,"This section explains the message exchange between agents when a mediator is in place. The process is illustrated using the diagram below. Parts ",(0,n.kt)("a",{parentName:"p",href:"/guides/0.5/tutorials/mediation#1-mediator-setup"},"one")," and ",(0,n.kt)("a",{parentName:"p",href:"/guides/0.5/tutorials/mediation#2-recipient-alice-setup"},"two")," of this tutorial showed how to set up and use a mediator. If the ",(0,n.kt)("inlineCode",{parentName:"p"},"mediatorInvitationUrl")," is specified when constructing the ",(0,n.kt)("inlineCode",{parentName:"p"},"MediationRecipientModule")," (as in ",(0,n.kt)("a",{parentName:"p",href:"/guides/0.5/tutorials/mediation#2-recipient-alice-setup"},"Part two"),"), the mediation request and grant ",(0,n.kt)("em",{parentName:"p"},"(1-2)")," between Alice and the mediator will be performed automatically when Alice's agent is started."),(0,n.kt)("p",null,"If Alice establishes a connection with another fictional agent, say, Bob's agent, who is not using any mediators ",(0,n.kt)("em",{parentName:"p"},"(3-6)"),". (Connection establishment is no different when a mediator is involved). Then, messages from Alice to Bob ",(0,n.kt)("em",{parentName:"p"},"(7)")," are routed directly to Bob, while messages from Bob to Alice ",(0,n.kt)("em",{parentName:"p"},"(8-9)")," are routed through the intermediary."),(0,n.kt)("mermaid",{value:"sequenceDiagram\n autonumber\n participant Alice\n participant Mediator\n participant Bob\n Note over Mediator: Start\n Note over Alice: Start\n Alice->>Mediator: Request Mediation\n Mediator->>Alice: Grant Mediation\n Note over Bob: Start\n Alice->>Alice: CreateInvitation\n Alice --\x3e Bob: (Send Invitation to Bob)\n Bob->>Bob: RecieveInvitation\n Alice->>Bob: WaitForConnection\n Alice->>Bob: SendMessage Alice->Bob\n Bob->>Mediator: SendMessage Bob->Alice (Mediator)\n Mediator->>Alice: ForwardMessage Bob->Alice (Mediator)"}),(0,n.kt)("h3",{id:"useful-resources"},"Useful resources"),(0,n.kt)("p",null,"For more information about mediator refer to:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0211-route-coordination"},"Aries Mediator Coordination Protocol")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://indicio-tech.github.io/mediator"},"Indicio Public Mediator")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/animo/animo-mediator"},"Setup your own Credo Mediator")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0046-mediators-and-relays/README.md#aries-rfc-0046-mediators-and-relays"},"Aries RFC 0046: Mediators and Relays"))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/60053357.e53157e4.js b/assets/js/60053357.e53157e4.js new file mode 100644 index 00000000..28b9d46d --- /dev/null +++ b/assets/js/60053357.e53157e4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[6266],{3905:(e,t,a)=>{a.d(t,{Zo:()=>u,kt:()=>h});var i=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,i)}return a}function r(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var l=i.createContext({}),d=function(e){var t=i.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):r(r({},t),e)),a},u=function(e){var t=d(e.components);return i.createElement(l.Provider,{value:t},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},c=i.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=d(a),c=n,h=p["".concat(l,".").concat(c)]||p[c]||m[c]||o;return a?i.createElement(h,r(r({ref:t},u),{},{components:a})):i.createElement(h,r({ref:t},u))}));function h(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,r=new Array(o);r[0]=c;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:n,r[1]=s;for(var d=2;d{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var i=a(7462),n=(a(7294),a(3905));const o={},r="Mediation",s={unversionedId:"tutorials/mediation",id:"tutorials/mediation",title:"Mediation",description:"This section assumes that you have:",source:"@site/guides/tutorials/mediation.md",sourceDirName:"tutorials",slug:"/tutorials/mediation",permalink:"/guides/tutorials/mediation",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Issue a credential",permalink:"/guides/tutorials/issue-a-credential"},next:{title:"Updating Credo",permalink:"/guides/updating/"}},l={},d=[{value:"What is a mediator, and Why should I use one?",id:"what-is-a-mediator-and-why-should-i-use-one",level:3},{value:"1. Mediator setup",id:"1-mediator-setup",level:3},{value:"2. Recipient (Alice) setup",id:"2-recipient-alice-setup",level:3},{value:"3. Message exchange",id:"3-message-exchange",level:3},{value:"Useful resources",id:"useful-resources",level:3}],u={toc:d},p="wrapper";function m(e){let{components:t,...a}=e;return(0,n.kt)(p,(0,i.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"mediation"},"Mediation"),(0,n.kt)("blockquote",null,(0,n.kt)("p",{parentName:"blockquote"},"This section assumes that you have:"),(0,n.kt)("ol",{parentName:"blockquote"},(0,n.kt)("li",{parentName:"ol"},"Set up a ",(0,n.kt)("a",{parentName:"li",href:"../getting-started/installation"},"valid environment")," for development"),(0,n.kt)("li",{parentName:"ol"},"Basic knowledge of the required fields in the ",(0,n.kt)("a",{parentName:"li",href:"./agent-config"},"agent\nconfig"))),(0,n.kt)("p",{parentName:"blockquote"},"The agent setup varies depending on your target environment, React Native or Node.js.",(0,n.kt)("br",{parentName:"p"}),"\n","This tutorial assumes a Node.js environment for all agents (Alice, Bob, Meditator).")),(0,n.kt)("p",null,"This tutorial shows how to set up a mediator, how to configure an agent to use a mediator, and how agents exchange messages with a mediator in place.\nConcepts are explained in isolation:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"/guides/tutorials/mediation#1-mediator-setup"},"First"),", it is shown how to set up a mediator."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"/guides/tutorials/mediation#2-recipient-alice-setup"},"Second"),", it is demonstrated how to use a mediator."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"/guides/tutorials/mediation#3-message-exchange"},"Third"),", the message exchange between agents with a mediator in place is explained.")),(0,n.kt)("h3",{id:"what-is-a-mediator-and-why-should-i-use-one"},"What is a mediator, and Why should I use one?"),(0,n.kt)("p",null,"A mediator is just a special type of agent."),(0,n.kt)("admonition",{type:"info"},(0,n.kt)("p",{parentName:"admonition"},"\"When we describe agent-to-agent communication, it is convenient to think of an interaction only in terms of Alice and Bob and their agents. We say things like: \"Alice's agent sends a message to Bob's agent\" -- or perhaps \"Alice's edge agent sends a message to Bob's cloud agent, which forwards it to Bob's edge agent\"."),(0,n.kt)("p",{parentName:"admonition"},"Such statements adopt a useful level of abstraction--one that's highly recommended for most discussions. However, they make a number of simplifications. By modeling the roles of mediators and relays in routing, we can support routes that use multiple transports, routes that are not fully known (or knowable) to the sender, routes that pass through mix networks, and other advanced and powerful concepts.\"",(0,n.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0046-mediators-and-relays/README.md#aries-rfc-0046-mediators-and-relays"},"Aries RFC 0046: Mediators and Relays"))),(0,n.kt)("p",null,'A practical example where the use of mediators is beneficial can be found in a mobile environment. A mobile agent, aka. your mobile wallet, receives messages from other agents. Technically, sending HTTP messages to a mobile agent is impossible because the agent does not have a public IP. As you have probably seen in previous examples, a workaround for this scenario is to use ngrok. Another option is to use a mediator. When an agent is configured to use a mediator, messages to that agent are routed through the mediator and from there to its destination. Thus, a mobile agent can use a "public" mediator to receive messages on its behalf and poll them from time to time.'),(0,n.kt)("p",null,"This is just one example of how a mediator can be used. Further resources about mediators can be found ",(0,n.kt)("a",{parentName:"p",href:"/guides/tutorials/mediation#useful-resources"},"here"),"."),(0,n.kt)("admonition",{type:"tip"},(0,n.kt)("p",{parentName:"admonition"},"With mediators, WebSockets come in handy. In a production environment, it is recommendable to register a ",(0,n.kt)("inlineCode",{parentName:"p"},"WsInboundTransport()")," for Alice and a ",(0,n.kt)("inlineCode",{parentName:"p"},"WsOutboundTransport()")," for the mediator. These WebSocket transports allow the mediator to push messages to Alice instead of having Alice pull messages from the mediator repeatedly.")),(0,n.kt)("h3",{id:"1-mediator-setup"},"1. Mediator setup"),(0,n.kt)("p",null,"The first part shows how to set up a mediator agent. Generally, there are two ways to do that: deploying it from scratch or using a third-party mediator. This section focuses on the former approach, setting up the mediator from scratch."),(0,n.kt)("p",null,"The mediator is set up on port 3001 and creates an Out-of-Band invitation that allows multiple other agents to connect to the mediator. Configuring an agent as a mediator demands utilizing the ",(0,n.kt)("inlineCode",{parentName:"p"},"MediatorModule"),". In this example, the ",(0,n.kt)("inlineCode",{parentName:"p"},"autoAcceptMediationRequests")," flag is set to true to accept mediation requests automatically."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers mediator-setup.ts section-1",showLineNumbers:!0,"mediator-setup.ts":!0,"section-1":!0},"")),(0,n.kt)("h3",{id:"2-recipient-alice-setup"},"2. Recipient (Alice) setup"),(0,n.kt)("p",null,"The second part shows how to use a mediator. Becoming a recipient of a mediator requires using the ",(0,n.kt)("inlineCode",{parentName:"p"},"MediationRecipientModule"),". The setup is the same whether you use your own or a third-party mediator."),(0,n.kt)("p",null,"The easiest way to set everything up is by configuring the ",(0,n.kt)("inlineCode",{parentName:"p"},"MediationRecipientModule")," to connect to the mediator on agent startup. This can be done by constructing the module with the ",(0,n.kt)("inlineCode",{parentName:"p"},"mediatorInvitationUrl"),". You can get the mediatorInvitationUrl either from ",(0,n.kt)("a",{parentName:"p",href:"/guides/tutorials/mediation#1-mediator-setup"},"part one")," by running a mediator yourself or from a public mediator such as the Animo-mediator. The following snippet uses the latter approach."),(0,n.kt)("p",null,"The ",(0,n.kt)("inlineCode",{parentName:"p"},"ConnectionsModule")," used in this snippet serves the sole purpose of automatically accepting connections and thus simplifying setup."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers mediation-recipient.ts section-1",showLineNumbers:!0,"mediation-recipient.ts":!0,"section-1":!0},"")),(0,n.kt)("admonition",{type:"info"},(0,n.kt)("p",{parentName:"admonition"},"In case you are using a third-party mediator and cannot create an invitationUrl, it is common practice for mediators to provide an endpoint from which the invitationUrl can be fetched.")),(0,n.kt)("h3",{id:"3-message-exchange"},"3. Message exchange"),(0,n.kt)("p",null,"This section explains the message exchange between agents when a mediator is in place. The process is illustrated using the diagram below. Parts ",(0,n.kt)("a",{parentName:"p",href:"/guides/tutorials/mediation#1-mediator-setup"},"one")," and ",(0,n.kt)("a",{parentName:"p",href:"/guides/tutorials/mediation#2-recipient-alice-setup"},"two")," of this tutorial showed how to set up and use a mediator. If the ",(0,n.kt)("inlineCode",{parentName:"p"},"mediatorInvitationUrl")," is specified when constructing the ",(0,n.kt)("inlineCode",{parentName:"p"},"MediationRecipientModule")," (as in ",(0,n.kt)("a",{parentName:"p",href:"/guides/tutorials/mediation#2-recipient-alice-setup"},"Part two"),"), the mediation request and grant ",(0,n.kt)("em",{parentName:"p"},"(1-2)")," between Alice and the mediator will be performed automatically when Alice's agent is started."),(0,n.kt)("p",null,"If Alice establishes a connection with another fictional agent, say, Bob's agent, who is not using any mediators ",(0,n.kt)("em",{parentName:"p"},"(3-6)"),". (Connection establishment is no different when a mediator is involved). Then, messages from Alice to Bob ",(0,n.kt)("em",{parentName:"p"},"(7)")," are routed directly to Bob, while messages from Bob to Alice ",(0,n.kt)("em",{parentName:"p"},"(8-9)")," are routed through the intermediary."),(0,n.kt)("mermaid",{value:"sequenceDiagram\n autonumber\n participant Alice\n participant Mediator\n participant Bob\n Note over Mediator: Start\n Note over Alice: Start\n Alice->>Mediator: Request Mediation\n Mediator->>Alice: Grant Mediation\n Note over Bob: Start\n Alice->>Alice: CreateInvitation\n Alice --\x3e Bob: (Send Invitation to Bob)\n Bob->>Bob: RecieveInvitation\n Alice->>Bob: WaitForConnection\n Alice->>Bob: SendMessage Alice->Bob\n Bob->>Mediator: SendMessage Bob->Alice (Mediator)\n Mediator->>Alice: ForwardMessage Bob->Alice (Mediator)"}),(0,n.kt)("h3",{id:"useful-resources"},"Useful resources"),(0,n.kt)("p",null,"For more information about mediator refer to:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0211-route-coordination"},"Aries Mediator Coordination Protocol")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://indicio-tech.github.io/mediator"},"Indicio Public Mediator")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/animo/animo-mediator"},"Setup your own Credo Mediator")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0046-mediators-and-relays/README.md#aries-rfc-0046-mediators-and-relays"},"Aries RFC 0046: Mediators and Relays"))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/636a146f.2a3dd0a4.js b/assets/js/636a146f.2a3dd0a4.js new file mode 100644 index 00000000..76e07b5a --- /dev/null +++ b/assets/js/636a146f.2a3dd0a4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[5313],{3905:(e,t,o)=>{o.d(t,{Zo:()=>p,kt:()=>h});var r=o(7294);function n(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,r)}return o}function a(e){for(var t=1;t=0||(n[o]=e[o]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(n[o]=e[o])}return n}var l=r.createContext({}),c=function(e){var t=r.useContext(l),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var o=e.components,n=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(o),m=n,h=u["".concat(l,".").concat(m)]||u[m]||d[m]||i;return o?r.createElement(h,a(a({ref:t},p),{},{components:o})):r.createElement(h,a({ref:t},p))}));function h(e,t){var o=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=o.length,a=new Array(i);a[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:n,a[1]=s;for(var c=2;c{o.r(t),o.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var r=o(7462),n=(o(7294),o(3905));const i={},a="The Credo Ecosystem",s={unversionedId:"ecosystem/index",id:"ecosystem/index",title:"The Credo Ecosystem",description:"The Credo ecosystem includes various components that are spread across multiple repositories. In this section we'll go over what these components are and how the relate to one another.",source:"@site/guides/ecosystem/index.md",sourceDirName:"ecosystem",slug:"/ecosystem/",permalink:"/guides/ecosystem/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Migrating from Credo 0.3.x to 0.4.x",permalink:"/guides/updating/versions/0.3-to-0.4"},next:{title:"Extensions",permalink:"/guides/extensions/"}},l={},c=[{value:"Repositories",id:"repositories",level:2},{value:"Documentation",id:"documentation",level:2},{value:"Credo",id:"credo",level:3},{value:"Contributing in the Credo Ecosystem",id:"contributing-in-the-credo-ecosystem",level:2},{value:"Developer Contributions",id:"developer-contributions",level:3}],p={toc:c},u="wrapper";function d(e){let{components:t,...o}=e;return(0,n.kt)(u,(0,r.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"the-credo-ecosystem"},"The Credo Ecosystem"),(0,n.kt)("p",null,"The Credo ecosystem includes various components that are spread across multiple repositories. In this section we'll go over what these components are and how the relate to one another."),(0,n.kt)("h2",{id:"repositories"},"Repositories"),(0,n.kt)("p",null,"Currently, Credo is composed out of two separate repositories:"),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/openwallet-foundation/credo-ts"},"Credo")),(0,n.kt)("li",{parentName:"ol"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/openwallet-foundation/credo-ts-ext"},"Credo Extensions"))),(0,n.kt)("p",null,"In addition, there are several open-source applications and building blocks built on top of Credo. One example is ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-mobile-agent-react-native"},"Aries Mobile Agent React Native (Bifold)"),", which is a white-label mobile wallet you can use to bootstrap your own custom wallet."),(0,n.kt)("h2",{id:"documentation"},"Documentation"),(0,n.kt)("p",null,"You can find their documentation here:"),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},(0,n.kt)("a",{parentName:"li",href:"https://credo.js.org/guides"},"Credo (core)")),(0,n.kt)("li",{parentName:"ol"},(0,n.kt)("a",{parentName:"li",href:"https://credo.js.org/guides/extensions"},"Credo Extensions"))),(0,n.kt)("h3",{id:"credo"},"Credo"),(0,n.kt)("p",null,"Credo (core) is at the core of the Credo ecosystem. Credo provides all the functionality related to cryptography, storage, messaging and more that is required"),(0,n.kt)("h2",{id:"contributing-in-the-credo-ecosystem"},"Contributing in the Credo Ecosystem"),(0,n.kt)("p",null,"Consider attending our weekly meetings to become aware of the current development cadence."),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/openwallet-foundation/credo-ts/wiki/Meeting-Information"},"Credo Working Group Meeting")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://wiki.hyperledger.org/display/ARIES/Aries+Working+Group"},"Aries Working Group Meeting"))),(0,n.kt)("h3",{id:"developer-contributions"},"Developer Contributions"),(0,n.kt)("p",null,"Each project maintains its own CONTRIBUTING guidance:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/openwallet-foundation/credo-ts/blob/main/CONTRIBUTING.md"},"Credo CONTRIBUTING.md")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/openwallet-foundation/credo-ts-ext/blob/main/CONTRIBUTING.md"},"Credo Extensions CONTRIBUTING.md"))),(0,n.kt)("p",null,"Each project has a significant set of developer conventions, checklists, templates, and actions to provide guidance and boundaries for a contribution.\nConsider looking at previous issues and their corresponding PRs to get a sense of the latest."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/636a146f.2e4e84b8.js b/assets/js/636a146f.2e4e84b8.js deleted file mode 100644 index 858b5e46..00000000 --- a/assets/js/636a146f.2e4e84b8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[5313],{3905:(e,t,o)=>{o.d(t,{Zo:()=>p,kt:()=>h});var r=o(7294);function n(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,r)}return o}function a(e){for(var t=1;t=0||(n[o]=e[o]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(n[o]=e[o])}return n}var l=r.createContext({}),c=function(e){var t=r.useContext(l),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var o=e.components,n=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(o),m=n,h=u["".concat(l,".").concat(m)]||u[m]||d[m]||i;return o?r.createElement(h,a(a({ref:t},p),{},{components:o})):r.createElement(h,a({ref:t},p))}));function h(e,t){var o=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=o.length,a=new Array(i);a[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:n,a[1]=s;for(var c=2;c{o.r(t),o.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var r=o(7462),n=(o(7294),o(3905));const i={},a="The Credo Ecosystem",s={unversionedId:"ecosystem/index",id:"ecosystem/index",title:"The Credo Ecosystem",description:"The Credo ecosystem includes various components that are spread across multiple repositories. In this section we'll go over what these components are and how the relate to one another.",source:"@site/guides/ecosystem/index.md",sourceDirName:"ecosystem",slug:"/ecosystem/",permalink:"/guides/0.5/ecosystem/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Migrating from Credo 0.3.x to 0.4.x",permalink:"/guides/0.5/updating/versions/0.3-to-0.4"},next:{title:"Extensions",permalink:"/guides/0.5/extensions/"}},l={},c=[{value:"Repositories",id:"repositories",level:2},{value:"Documentation",id:"documentation",level:2},{value:"Credo",id:"credo",level:3},{value:"Contributing in the Credo Ecosystem",id:"contributing-in-the-credo-ecosystem",level:2},{value:"Developer Contributions",id:"developer-contributions",level:3}],p={toc:c},u="wrapper";function d(e){let{components:t,...o}=e;return(0,n.kt)(u,(0,r.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"the-credo-ecosystem"},"The Credo Ecosystem"),(0,n.kt)("p",null,"The Credo ecosystem includes various components that are spread across multiple repositories. In this section we'll go over what these components are and how the relate to one another."),(0,n.kt)("h2",{id:"repositories"},"Repositories"),(0,n.kt)("p",null,"Currently, Credo is composed out of two separate repositories:"),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/openwallet-foundation/credo-ts"},"Credo")),(0,n.kt)("li",{parentName:"ol"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/openwallet-foundation/credo-ts-ext"},"Credo Extensions"))),(0,n.kt)("p",null,"In addition, there are several open-source applications and building blocks built on top of Credo. One example is ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-mobile-agent-react-native"},"Aries Mobile Agent React Native (Bifold)"),", which is a white-label mobile wallet you can use to bootstrap your own custom wallet."),(0,n.kt)("h2",{id:"documentation"},"Documentation"),(0,n.kt)("p",null,"You can find their documentation here:"),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},(0,n.kt)("a",{parentName:"li",href:"https://credo.js.org/guides"},"Credo (core)")),(0,n.kt)("li",{parentName:"ol"},(0,n.kt)("a",{parentName:"li",href:"https://credo.js.org/guides/extensions"},"Credo Extensions"))),(0,n.kt)("h3",{id:"credo"},"Credo"),(0,n.kt)("p",null,"Credo (core) is at the core of the Credo ecosystem. Credo provides all the functionality related to cryptography, storage, messaging and more that is required"),(0,n.kt)("h2",{id:"contributing-in-the-credo-ecosystem"},"Contributing in the Credo Ecosystem"),(0,n.kt)("p",null,"Consider attending our weekly meetings to become aware of the current development cadence."),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/openwallet-foundation/credo-ts/wiki/Meeting-Information"},"Credo Working Group Meeting")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://wiki.hyperledger.org/display/ARIES/Aries+Working+Group"},"Aries Working Group Meeting"))),(0,n.kt)("h3",{id:"developer-contributions"},"Developer Contributions"),(0,n.kt)("p",null,"Each project maintains its own CONTRIBUTING guidance:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/openwallet-foundation/credo-ts/blob/main/CONTRIBUTING.md"},"Credo CONTRIBUTING.md")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/openwallet-foundation/credo-ts-ext/blob/main/CONTRIBUTING.md"},"Credo Extensions CONTRIBUTING.md"))),(0,n.kt)("p",null,"Each project has a significant set of developer conventions, checklists, templates, and actions to provide guidance and boundaries for a contribution.\nConsider looking at previous issues and their corresponding PRs to get a sense of the latest."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6414033c.82b49c2d.js b/assets/js/6414033c.f3854a93.js similarity index 85% rename from assets/js/6414033c.82b49c2d.js rename to assets/js/6414033c.f3854a93.js index 625b808b..b78da500 100644 --- a/assets/js/6414033c.82b49c2d.js +++ b/assets/js/6414033c.f3854a93.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4226],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),d=l(r),f=a,m=d["".concat(s,".").concat(f)]||d[f]||p[f]||o;return r?n.createElement(m,i(i({ref:t},u),{},{components:r})):n.createElement(m,i({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=f;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[d]="string"==typeof e?e:a,i[1]=c;for(var l=2;l{r.d(t,{Z:()=>g});var n=r(7294),a=r(6010),o=r(3438),i=r(9960),c=r(3919),s=r(5999);const l={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function u(e){let{href:t,children:r}=e;return n.createElement(i.Z,{href:t,className:(0,a.Z)("card padding--lg",l.cardContainer)},r)}function d(e){let{href:t,icon:r,title:o,description:i}=e;return n.createElement(u,{href:t},n.createElement("h2",{className:(0,a.Z)("text--truncate",l.cardTitle),title:o},r," ",o),i&&n.createElement("p",{className:(0,a.Z)("text--truncate",l.cardDescription),title:i},i))}function p(e){let{item:t}=e;const r=(0,o.Wl)(t);return r?n.createElement(d,{href:r,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,s.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function f(e){let{item:t}=e;const r=(0,c.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",a=(0,o.xz)(t.docId??void 0);return n.createElement(d,{href:t.href,icon:r,title:t.label,description:a?.description})}function m(e){let{item:t}=e;switch(t.type){case"link":return n.createElement(f,{item:t});case"category":return n.createElement(p,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function y(e){let{className:t}=e;const r=(0,o.jA)();return n.createElement(g,{items:r.items,className:t})}function g(e){const{items:t,className:r}=e;if(!t)return n.createElement(y,e);const i=(0,o.MN)(t);return n.createElement("section",{className:(0,a.Z)("row",r)},i.map(((e,t)=>n.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},n.createElement(m,{item:e})))))}},7574:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>f,frontMatter:()=>i,metadata:()=>s,toc:()=>u});var n=r(7462),a=(r(7294),r(3905)),o=r(2991);const i={},c="Supported Features",s={unversionedId:"features/index",id:"features/index",title:"Supported Features",description:"This section tries to list all the standards and features that are supported by Credo.",source:"@site/guides/features/index.md",sourceDirName:"features",slug:"/features/",permalink:"/guides/0.5/features/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Platform and Environment",permalink:"/guides/0.5/concepts/platform-and-environment"},next:{title:"Hyperledger Aries and Aries Interop Profile",permalink:"/guides/0.5/features/aries"}},l={},u=[],d={toc:u},p="wrapper";function f(e){let{components:t,...r}=e;return(0,a.kt)(p,(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"supported-features"},"Supported Features"),(0,a.kt)("p",null,"This section tries to list all the standards and features that are supported by Credo."),(0,a.kt)(o.Z,{mdxType:"DocCardList"}))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4226],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),d=l(r),f=a,m=d["".concat(s,".").concat(f)]||d[f]||p[f]||o;return r?n.createElement(m,i(i({ref:t},u),{},{components:r})):n.createElement(m,i({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=f;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[d]="string"==typeof e?e:a,i[1]=c;for(var l=2;l{r.d(t,{Z:()=>g});var n=r(7294),a=r(6010),o=r(3438),i=r(9960),c=r(3919),s=r(5999);const l={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function u(e){let{href:t,children:r}=e;return n.createElement(i.Z,{href:t,className:(0,a.Z)("card padding--lg",l.cardContainer)},r)}function d(e){let{href:t,icon:r,title:o,description:i}=e;return n.createElement(u,{href:t},n.createElement("h2",{className:(0,a.Z)("text--truncate",l.cardTitle),title:o},r," ",o),i&&n.createElement("p",{className:(0,a.Z)("text--truncate",l.cardDescription),title:i},i))}function p(e){let{item:t}=e;const r=(0,o.Wl)(t);return r?n.createElement(d,{href:r,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,s.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function f(e){let{item:t}=e;const r=(0,c.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",a=(0,o.xz)(t.docId??void 0);return n.createElement(d,{href:t.href,icon:r,title:t.label,description:a?.description})}function m(e){let{item:t}=e;switch(t.type){case"link":return n.createElement(f,{item:t});case"category":return n.createElement(p,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function y(e){let{className:t}=e;const r=(0,o.jA)();return n.createElement(g,{items:r.items,className:t})}function g(e){const{items:t,className:r}=e;if(!t)return n.createElement(y,e);const i=(0,o.MN)(t);return n.createElement("section",{className:(0,a.Z)("row",r)},i.map(((e,t)=>n.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},n.createElement(m,{item:e})))))}},7574:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>f,frontMatter:()=>i,metadata:()=>s,toc:()=>u});var n=r(7462),a=(r(7294),r(3905)),o=r(2991);const i={},c="Supported Features",s={unversionedId:"features/index",id:"features/index",title:"Supported Features",description:"This section tries to list all the standards and features that are supported by Credo.",source:"@site/guides/features/index.md",sourceDirName:"features",slug:"/features/",permalink:"/guides/features/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Platform and Environment",permalink:"/guides/concepts/platform-and-environment"},next:{title:"Hyperledger Aries and Aries Interop Profile",permalink:"/guides/features/aries"}},l={},u=[],d={toc:u},p="wrapper";function f(e){let{components:t,...r}=e;return(0,a.kt)(p,(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"supported-features"},"Supported Features"),(0,a.kt)("p",null,"This section tries to list all the standards and features that are supported by Credo."),(0,a.kt)(o.Z,{mdxType:"DocCardList"}))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/65c86d7b.328e5b53.js b/assets/js/65c86d7b.328e5b53.js deleted file mode 100644 index e017b058..00000000 --- a/assets/js/65c86d7b.328e5b53.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[6295],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=a.createContext({}),d=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=d(e.components);return a.createElement(s.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),p=d(n),m=o,h=p["".concat(s,".").concat(m)]||p[m]||u[m]||i;return n?a.createElement(h,r(r({ref:t},c),{},{components:n})):a.createElement(h,r({ref:t},c))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:o,r[1]=l;for(var d=2;d{n.d(t,{Z:()=>r});var a=n(7294),o=n(6010);const i={tabItem:"tabItem_Ymn6"};function r(e){let{children:t,hidden:n,className:r}=e;return a.createElement("div",{role:"tabpanel",className:(0,o.Z)(i.tabItem,r),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),o=n(7294),i=n(6010),r=n(2466),l=n(6550),s=n(1980),d=n(7392),c=n(12);function p(e){return function(e){return o.Children.map(e,(e=>{if((0,o.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:o}}=e;return{value:t,label:n,attributes:a,default:o}}))}function u(e){const{values:t,children:n}=e;return(0,o.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,d.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const a=(0,l.k6)(),i=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._X)(i),(0,o.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(a.location.search);t.set(i,e),a.replace({...a.location,search:t.toString()})}),[i,a])]}function g(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,i=u(e),[r,l]=(0,o.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(!m({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:i}))),[s,d]=h({queryString:n,groupId:a}),[p,g]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,i]=(0,c.Nk)(n);return[a,(0,o.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:a}),f=(()=>{const e=s??p;return m({value:e,tabValues:i})?e:null})();(0,o.useLayoutEffect)((()=>{f&&l(f)}),[f]);return{selectedValue:r,selectValue:(0,o.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);l(e),d(e),g(e)}),[d,g,i]),tabValues:i}}var f=n(2389);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:n,selectedValue:l,selectValue:s,tabValues:d}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,r.o5)(),u=e=>{const t=e.currentTarget,n=c.indexOf(t),a=d[n].value;a!==l&&(p(t),s(a))},m=e=>{let t=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return o.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},d.map((e=>{let{value:t,label:n,attributes:r}=e;return o.createElement("li",(0,a.Z)({role:"tab",tabIndex:l===t?0:-1,"aria-selected":l===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:u},r,{className:(0,i.Z)("tabs__item",v.tabItem,r?.className,{"tabs__item--active":l===t})}),n??t)})))}function b(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,o.cloneElement)(e,{className:"margin-top--md"}):null}return o.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,o.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function y(e){const t=g(e);return o.createElement("div",{className:(0,i.Z)("tabs-container",v.tabList)},o.createElement(k,(0,a.Z)({},e,t)),o.createElement(b,(0,a.Z)({},e,t)))}function w(e){const t=(0,f.Z)();return o.createElement(y,(0,a.Z)({key:String(t)},e))}},9234:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>l,metadata:()=>d,toc:()=>p});var a=n(7462),o=(n(7294),n(3905)),i=n(4866),r=n(5162);const l={},s="Migrating from Credo 0.1.0 to 0.2.x",d={unversionedId:"updating/versions/0.1-to-0.2",id:"updating/versions/0.1-to-0.2",title:"Migrating from Credo 0.1.0 to 0.2.x",description:"This document describes everything you need to know for updating Credo 0.1.0 to 0.2.x. If you're not aware of how updating in Credo works make sure to first read the guide on Updating Credo.",source:"@site/guides/updating/versions/0.1-to-0.2.md",sourceDirName:"updating/versions",slug:"/updating/versions/0.1-to-0.2",permalink:"/guides/0.5/updating/versions/0.1-to-0.2",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Migrating from an Indy SDK Wallet to Aries Askar",permalink:"/guides/0.5/updating/update-indy-sdk-to-askar"},next:{title:"Migrating from Credo 0.2.x to 0.3.x",permalink:"/guides/0.5/updating/versions/0.2-to-0.3"}},c={},p=[{value:"React Native",id:"react-native",level:4},{value:"Node",id:"node",level:4},{value:"Breaking Code Changes",id:"breaking-code-changes",level:2},{value:"Credentials Module",id:"credentials-module",level:3},{value:"Module API Updates",id:"module-api-updates",level:4},{value:"0.1.0",id:"010",level:5},{value:"0.2.x",id:"02x",level:5},{value:"Data from Received Messages only Stored in Record after Accepting",id:"data-from-received-messages-only-stored-in-record-after-accepting",level:4},{value:"0.1.0",id:"010-1",level:5},{value:"0.2.x",id:"02x-1",level:5},{value:"Messages Extracted from Credential Record",id:"messages-extracted-from-credential-record",level:4},{value:"0.1.0",id:"010-2",level:5},{value:"0.2.x",id:"02x-2",level:5},{value:"Connections Module",id:"connections-module",level:3},{value:"Creating a Legacy Invitation",id:"creating-a-legacy-invitation",level:4},{value:"0.1.0",id:"010-3",level:5},{value:"0.2.x",id:"02x-3",level:5},{value:"Receiving a Legacy Invitation",id:"receiving-a-legacy-invitation",level:4},{value:"0.1.0",id:"010-4",level:5},{value:"0.2.x",id:"02x-4",level:5},{value:"Updating to use DidExchangeState",id:"updating-to-use-didexchangestate",level:4},{value:"Updating Custom Messages to the New Message Type Objects",id:"updating-custom-messages-to-the-new-message-type-objects",level:3},{value:"0.1.0",id:"010-5",level:4},{value:"0.2.x",id:"02x-5",level:4},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:2},{value:"Credential Metadata",id:"credential-metadata",level:3},{value:"0.1.0",id:"010-6",level:4},{value:"0.2.x",id:"02x-6",level:4},{value:"Migrate Credential Record Properties",id:"migrate-credential-record-properties",level:3},{value:"0.1.0",id:"010-7",level:4},{value:"0.2.x",id:"02x-7",level:4},{value:"Mediation Record Role",id:"mediation-record-role",level:3},{value:"Extracting Did Documents to Did Repository",id:"extracting-did-documents-to-did-repository",level:3},{value:"0.1.0",id:"010-8",level:4},{value:"0.2.x",id:"02x-8",level:4},{value:"Migrating to the Out of Band Record",id:"migrating-to-the-out-of-band-record",level:3},{value:"0.1.0",id:"010-9",level:4},{value:"0.2.x",id:"02x-9",level:4},{value:"Unifying Connection States and Roles",id:"unifying-connection-states-and-roles",level:3},{value:"0.1.0",id:"010-10",level:4},{value:"0.2.0",id:"020",level:4}],u={toc:p},m="wrapper";function h(e){let{components:t,...n}=e;return(0,o.kt)(m,(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"migrating-from-credo-010-to-02x"},"Migrating from Credo 0.1.0 to 0.2.x"),(0,o.kt)("p",null,"This document describes everything you need to know for updating Credo 0.1.0 to 0.2.x. If you're not aware of how updating in Credo works make sure to first read the guide on ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.5/updating/"},"Updating Credo"),"."),(0,o.kt)("p",null,"First of all, update you dependencies to the 0.2.x versions. This will also update the needed peer depedencnies. ",(0,o.kt)("strong",{parentName:"p"},"Extension packages are not updated with this command"),". You need to update these manually, and make sure they're up to date with the latest version of Credo."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"React Native",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/react-native@^0.2.0 @aries-framework/core@^0.2.0 indy-sdk-react-native@^0.2.0\n\n# or NPM\nnpn install @aries-framework/react-native@^0.2.0 @aries-framework/core@^0.2.0 indy-sdk-react-native@^0.2.0\n"))),(0,o.kt)(r.Z,{label:"Node",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/node@^0.2.0 @aries-framework/core@^0.2.0\n\n# or NPM\nnpm install @aries-framework/node@^0.2.0 @aries-framework/core@^0.2.0\n")))),(0,o.kt)("h2",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,o.kt)("p",null,"This section will list all breaking changes made to the public API of Credo between version 0.1.0 and 0.2.0."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here (e.g. see ",(0,o.kt)("a",{parentName:"p",href:"#updating-custom-messages-to-the-new-message-type-objects"},"Updating Custom Messages to the New Message Type Objects"),"), but it is possible some breaking changes are not documented here (feel free to open PRs).")),(0,o.kt)("h3",{id:"credentials-module"},"Credentials Module"),(0,o.kt)("h4",{id:"module-api-updates"},"Module API Updates"),(0,o.kt)("p",null,"With the addition of the issue credential v2 protocol and the preparation for multiple attachment formats (to be added in a later release), we've made some big changes to the credentials module API. Most changes are related to structure, so updating your code to the new API should be straightforward."),(0,o.kt)("p",null,"Basically for all methods in the credential module you should take the following steps to update your code:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Move all function parameters into a single object. All module methods now take a single object that contain all properties."),(0,o.kt)("li",{parentName:"ol"},"For methods that initiate a protocol (starting from offer, proposal), you should pass ",(0,o.kt)("inlineCode",{parentName:"li"},"protocolVersion: 'v1'")," to indicate we should use the v1 protocol. (v2 is also supported, but this focuses on the breaking changes, not the new features)."),(0,o.kt)("li",{parentName:"ol"},"All indy specific attributes (e.g. credentialDefinitionId) should be passed in the ",(0,o.kt)("inlineCode",{parentName:"li"},"credentialFormats.indy")," object."),(0,o.kt)("li",{parentName:"ol"},"The preview should now be passed as only the preview attributes (the the full preview) and provided in the ",(0,o.kt)("inlineCode",{parentName:"li"},"credentialFormats.indy")," object.")),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.credentials.offerCredential('connectionId', {\n autoAcceptCredential: AutoAcceptCredential.Always,\n comment: 'hello',\n\n credentialDefinitionId: 'credentialDefinitionId',\n preview: new CredentialPreview({\n attributes: [new CredentialPreviewAttribute({ name: 'key', value: 'value' })],\n }),\n})\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.credentials.offerCredential({\n connectionId: 'connectionId',\n protocolVersion: 'v1',\n\n autoAcceptCredential: AutoAcceptCredential.Always,\n comment: 'hello',\n\n credentialFormats: {\n indy: {\n credentialDefinitionId: 'credentialDefinitionId',\n attributes: [{ name: 'key', value: 'value' }],\n },\n },\n})\n")))),(0,o.kt)("h4",{id:"data-from-received-messages-only-stored-in-record-after-accepting"},"Data from Received Messages only Stored in Record after Accepting"),(0,o.kt)("p",null,"Previously when we received a message from another connection we would store the relevant data from the exchange in the credential record. The values we would store were the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialDefinitionId")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"schemaId")," in the credential metadata, and the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialAttributes")," field."),(0,o.kt)("p",null,"Starting with Credo 0.2.0 the values are not stored in the credential record until after the message content has been accepted (in the case of an offer this means after sending the request message). This is to avoid ambiguity of the values in the credential record. If I have sent a proposal and then receive an offer, should the credential record contain the values from the proposal or the values from the offer? The first one reflects our view on what the data should be, the second one reflects the latest data."),(0,o.kt)("p",null,"We decided to make the record properties always hold our view of what the data should be, and only update it after accepting the contents of a received message (either using auto accept, or by calling the ",(0,o.kt)("inlineCode",{parentName:"p"},"acceptXXX")," methods on the credential module)."),(0,o.kt)("p",null,"This is an important change and requires some updates to how you extract the relevant data from the offer (or other messages such the proposal). We've added a new ",(0,o.kt)("inlineCode",{parentName:"p"},"getFormatData")," method on the credentials module that allows you to retrieve the attributes and format data for all messages in an exchange. One of the advantages of this approach is that we don't have to store all relevant data in the credential record anymore, which helps when adding new formats that don't match with the attributes used for indy credentials. In addition, the return value for this method is the same whether v1 or v2 of the protocol is used. This means your code should only care about the credential format (indy in this case) and doesn't have to worry about the protocol version."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"agent.events.on(\n CredentialEventTypes.CredentialStateChanged,\n ({ payload: { credentialRecord } }) => {\n const indyCredentialMetadata = credentialRecord.metadata.get(CredentialMetadataKeys.IndyCredential)\n\n // Get credential definition id, schema id and attributes from offer\n const credentialDefinitionId = indyCredentialMetadata?.credentialDefinitionId\n const schemaId = indyCredentialMetadata?.schemaId\n const attributes = credentialRecord.credentialAttributes\n }\n)\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"agent.events.on(\n CredentialEventTypes.CredentialStateChanged,\n async ({ payload: { credentialRecord } }) => {\n const formatData = await agent.credentials.getFormatData(credentialRecord.id)\n\n // Get credential definition id, schema id and attributes from offer\n const credentialDefinitionId = formatData.offer?.indy?.cred_def_id\n const schemaId = formatData.offer?.indy?.schema_id\n const attributes = formatData.offerAttributes\n }\n)\n")),(0,o.kt)("p",null,"The return value of the ",(0,o.kt)("inlineCode",{parentName:"p"},"getFormatData")," method is fully typed an directly returns the format data as encoded in the attachment. It also returns the ",(0,o.kt)("inlineCode",{parentName:"p"},"proposalAttributes")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"offerAttributes")," values which contain the attributes for the indy credential. This is not part of the attachment data itself, but can be seen as the format data for the credential."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"{\n proposalAttributes: [{ name: 'key', value: 'value' mimeType: 'text/plain' }],\n proposal: {\n indy: { } // indy proposal as described in RFC 0592\n },\n offerAttributes: [{ name: 'key', value: 'value' mimeType: 'text/plain' }],\n offer: {\n indy: { } // indy offer as described in RFC 0592\n },\n request: {\n indy: { } // indy request as described in RFC 0592\n }\n credential: {\n indy: { } // indy credential as described in RFC 0592\n }\n}\n")))),(0,o.kt)("h4",{id:"messages-extracted-from-credential-record"},"Messages Extracted from Credential Record"),(0,o.kt)("p",null,"The DIDComm messages that were previously stored on the credential record, have been extracted to separate DIDComm message records. This makes it easier to work with multiple versions of the protocol internally, and keeps the credential exchange record agnostic of the protocol version. Instead of accessing the messages through the ",(0,o.kt)("inlineCode",{parentName:"p"},"proposalMessage"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"offerMessage"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"requestMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialMessage")," parameters, we now expose dedicated methods on the credentials module to retrieve the message."),(0,o.kt)("p",null,"With the addition of the v2 messages, all v1 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," while v2 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V2")," (",(0,o.kt)("inlineCode",{parentName:"p"},"V1ProposeCredentialMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"V2ProposeCredentialMessage"),"). If you were using these messages classes throughout your codebase, update them to use the ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," prefix."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const credentialRecord = await agent.credentials.getById('credentialRecordId')\n\nconst proposalMessage = credentialRecord.proposalMessage\nconst offerMessage = credentialRecord.offerMessage\nconst requestMessage = credentialRecord.requestMessage\nconst credentialMessage = credentialRecord.credentialMessage\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const credentialRecord = await agent.credentials.getById('credentialRecordId')\n\nconst proposalMessage = await agent.credentials.findProposalMessage('credentialRecordId')\nconst offerMessage = await agent.credentials.findOfferMessage('credentialRecordId')\nconst requestMessage = await agent.credentials.findRequestMessage('credentialRecordId')\nconst credentialMessage = await agent.credentials.findCredentialMessage('credentialRecordId')\n")),(0,o.kt)("p",null,"Because Credo now also supports the issue credential v2 protocol, the return type of this protocol has been changed to ",(0,o.kt)("inlineCode",{parentName:"p"},"V1XXXMessage | V2XXXMessage | null"),". Take this into account when working with the messages."),(0,o.kt)("p",null,"You can check if a message is a specific version by using the ",(0,o.kt)("inlineCode",{parentName:"p"},"instanceof")," operator:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"if (proposalMessage instanceof V1ProposeCredentialMessage) {\n // do something\n}\n")),(0,o.kt)("p",null,"Shared properties (e.g. the proposal messages for v1 and v2 both have the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialPreview")," property) can be accessed without doing an instance check."))),(0,o.kt)("h3",{id:"connections-module"},"Connections Module"),(0,o.kt)("p",null,"Version 0.2.0 added support for the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md"},"Out of Band protocol")," with support for the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0023-did-exchange"},"DID Exchange protocol"),". Internally Credo now uses out of band invitations for all connections, even if you're connecting using the old invitations from the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0160-connection-protocol"},"Connection protocol"),"."),(0,o.kt)("h4",{id:"creating-a-legacy-invitation"},"Creating a Legacy Invitation"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"createInvitation")," method on the connections module has been moved to the out of band module and renamed to ",(0,o.kt)("inlineCode",{parentName:"p"},"createLegacyInvitation"),". The method is not planned to be removed in the near future, the legacy merely indicates this will create an RFC 0160 connection invitation. Internally Credo creates an out of band invitation and transforms it into a legacy invitation. If you want to create an out of band invitation instead, you should use ",(0,o.kt)("inlineCode",{parentName:"p"},"oob.createInvitation"),"."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { connectionRecord, invitation } = await agent.connections.createInvitation({\n /* config */\n})\n\nconst invitationUrl = invitation.toUrl({ domain: 'https://example.com' })\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { outOfBandRecord, invitation } = await agent.oob.createLegacyInvitation({\n /* config */\n})\n\nconst invitationUrl = invitation.toUrl({ domain: 'https://example.com' })\n")),(0,o.kt)("p",null,"Important thing to note here is that the ",(0,o.kt)("inlineCode",{parentName:"p"},"oob.createLegacyInvitation")," does not return a connection record, but rather an out of band record. Because out of band also supports connection-less scenarios, a connection record is not created until a connection request is received (or sent in the case of the invitee role)."),(0,o.kt)("p",null,"You can listen for connection state change events that are associated with a specific out of band id. This allows you to link a connection to an invitation you created."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"// Listen for connection state changed events associated with the out of band record\nagent.events.on(ConnectionEventTypes.ConnectionStateChanged, (event) => {\n if (event.payload.connectionRecord.outOfBandId === outOfBandRecord.id) {\n console.log(`Connection state changed for connection with out of band id ${outOfBandRecord.id}`)\n }\n})\n")),(0,o.kt)("p",null,"It is also possible to retrieve all connection records associated with an out of band invitation. Because of multi use invitations, there could be multiple connection records associated with a single out of band invitation. Instead of having a separate connection record that will always stay in the invited state, the out of band record will now handle the multi use capabilities of an invitation."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"// Retrieve all connections associated with an out of band id\nconst connections = await agent.connections.findAllByOutOfBandId(outOfBandRecord.id)\n")))),(0,o.kt)("h4",{id:"receiving-a-legacy-invitation"},"Receiving a Legacy Invitation"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"receiveInvitation")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"receiveInvitationFromUrl")," methods on the connections module have also been moved to the out of band module. Both methods support the new out of band invitations and the legacy RFC 0160 connection invitations. Internally Credo converts the old invitations to out of band invitations."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const invitationUrl = 'https://example.com?c_i=eyXXX'\n\n// Receive invitation directly from url\nconst connectionRecord = await agent.connections.receiveInvitationFromUrl(invitationUrl, {\n /* config */\n})\n\n// Parse invitation and receive invitation\nconst parsedInvitation = await ConnectionInvitationMessage.fromUrl(invitationUrl)\nconst connectionRecord = await agent.connections.receiveInvitation(parsedInvitation, {\n /* config */\n})\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const invitationUrl = 'https://example.com?c_i=eyXXX'\n\n// Receive invitation directly from url\nconst { outOfBandRecord, connectionRecord } = await agent.oob.receiveInvitationFromUrl(invitationUrl, {\n /* config */\n})\n\n// Parse invitation and receive invitation\nconst parsedInvitation = await agent.oob.parseInvitation(invitationUrl)\nconst secondConnectionRecord = await agent.oob.receiveInvitation(parsedInvitation, {\n /* config */\n})\n")),(0,o.kt)("p",null,"The new receive invitation methods on the out of band module won't always return a connection record anymore. The out of band invitation may not contain any handshake protocols. In the case of receiving a connection invitation you will always receive a connection record though, as you can't use it for connection-less invitations."))),(0,o.kt)("h4",{id:"updating-to-use-didexchangestate"},"Updating to use ",(0,o.kt)("inlineCode",{parentName:"h4"},"DidExchangeState")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," that was previously used for the state of the ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionRecord")," has been changed to use the ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," for both connections made using the RFC 0160 Connection Protocol, as well as the RFC 0023 DID Exchange Protocol."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," has the following values:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.Start"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.InvitationSent"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.InvitationReceived"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.RequestSent"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.RequestReceived"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.ResponseSent"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.ResponseReceived"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.Abandoned"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.Completed"))),(0,o.kt)("p",null,"If you still need to access the old ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," you can do so by accessing the computed ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionRecord.rfc0160State")," property. This will return the old ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," value."),(0,o.kt)("h3",{id:"updating-custom-messages-to-the-new-message-type-objects"},"Updating Custom Messages to the New Message Type Objects"),(0,o.kt)("p",null,"Although this isn't a breaking change to the public API of the framework, it is something that you will need to take into account when creating custom modules. Starting from Credo 0.2.0 we now support handling messages with different minor versions (e.g. receive a message with ",(0,o.kt)("inlineCode",{parentName:"p"},"@type")," version 1.1 while we only support 1.0). With this change messages must now declare the message type as an ",(0,o.kt)("inlineCode",{parentName:"p"},"ParsedMessageType")," object. We've added an ",(0,o.kt)("inlineCode",{parentName:"p"},"parseMessageType")," util method that can help with this."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { AgentMessage } from '@aries-framework/core'\nimport { Equals } from 'class-validator'\n\nclass MyMessage extends AgentMessage {\n @Equals(MyMessage.type)\n public readonly type = MyMessage.type\n public static readonly type = 'https://didcomm.org/my-protocol/1.0/my-type'\n}\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { AgentMessage, IsValidMessageType, parseMessageType } from '@aries-framework/core'\nimport { Equals } from 'class-validator'\n\nclass MyMessage extends AgentMessage {\n // use IsValidMessageType instead of Equals\n @IsValidMessageType(MyMessage.type)\n // append .messageTypeUri to get the actual URI when instantiating a message\n public readonly type = MyMessage.type.messageTypeUri\n // use parseMessageType to get the message type object from a type. You can declare the object yourself, but this is the recommended way\n public static readonly type = parseMessageType('https://didcomm.org/my-protocol/1.0/my-type')\n}\n")))),(0,o.kt)("h2",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,o.kt)("p",null,"The 0.2.0 release is heavy on breaking changes to the storage format. This is not what we intend to do with every release. But as there's not that many people yet using the framework in production, and there were a lot of changes needed to keep the API straightforward, we decided to bundle a lot of breaking changes in this one release."),(0,o.kt)("p",null,"Below all breaking storage changes are explained in as much detail as possible. The update assistant provides all tools to migrate without a hassle, but it is important to know what has changed. All examples only show the keys that have changed, unrelated keys in records have been omitted."),(0,o.kt)("p",null,"See the ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.5/updating/update-assistant"},"Update Assistant")," documentation for a guide on how to use the update assistant."),(0,o.kt)("p",null,"The following config can be provided to the update assistant to migrate from 0.1.0 to 0.2.0:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "v0_1ToV0_2": {\n "mediationRoleUpdateStrategy": ""\n }\n}\n')),(0,o.kt)("h3",{id:"credential-metadata"},"Credential Metadata"),(0,o.kt)("p",null,"The credential record had a custom ",(0,o.kt)("inlineCode",{parentName:"p"},"metadata")," property in pre-0.1.0 storage that contained the ",(0,o.kt)("inlineCode",{parentName:"p"},"requestMetadata"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"schemaId")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialDefinition")," properties. Later a generic metadata API was added that only allows objects to be stored. Therefore the properties were moved into a different structure."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "requestMetadata": ,\n "schemaId": "",\n "credentialDefinitionId": ""\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "_internal/indyRequest": ,\n "_internal/indyCredential": {\n "schemaId": "",\n "credentialDefinitionId": ""\n }\n}\n')),(0,o.kt)("p",null,"Accessing the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialDefinitionId")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"schemaId")," properties will now be done by retrieving the ",(0,o.kt)("inlineCode",{parentName:"p"},"CredentialMetadataKeys.IndyCredential")," metadata key."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const indyCredential = credentialRecord.metadata.get(CredentialMetadataKeys.IndyCredential)\n\n// both properties are optional\nindyCredential?.credentialDefinitionId\nindyCredential?.schemaId\n")))),(0,o.kt)("h3",{id:"migrate-credential-record-properties"},"Migrate Credential Record Properties"),(0,o.kt)("p",null,"In 0.2.0 the v1 DIDComm messages have been moved out of the credential record into separate records using the DidCommMessageRepository. The migration scripts extracts all messages (proposalMessage, offerMessage, requestMessage, credentialMessage) and moves them into the DidCommMessageRepository."),(0,o.kt)("p",null,"With the addition of support for different protocol versions the credential record now stores the protocol version. With the addition of issue credential v2 support, other credential formats than indy can be used, and multiple credentials can be issued at once. To account for this the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialId")," has been replaced by the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentials")," array. This is an array of objects containing the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialRecordId")," and the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialRecordType"),". For all current credentials the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialRecordType")," will always be ",(0,o.kt)("inlineCode",{parentName:"p"},"indy"),"."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "credentialId": "09e46da9-a575-4909-b016-040e96c3c539",\n "proposalMessage": { ... },\n "offerMessage": { ... },\n "requestMessage": { ... },\n "credentialMessage": { ... },\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "protocolVersion": "v1",\n "credentials": [\n {\n "credentialRecordId": "09e46da9-a575-4909-b016-040e96c3c539",\n "credentialRecordType": "indy"\n }\n ]\n}\n')))),(0,o.kt)("h3",{id:"mediation-record-role"},"Mediation Record Role"),(0,o.kt)("p",null,"The role in the mediation record was always being set to ",(0,o.kt)("inlineCode",{parentName:"p"},"MediationRole.Mediator")," for both mediators and recipients. This didn't cause any issues, but would return the wrong role for recipients."),(0,o.kt)("p",null,"In 0.2 a check is added to make sure the role of a mediation record matches with actions (e.g. a recipient can't grant mediation), which means it will throw an error if the role is not set correctly."),(0,o.kt)("p",null,"Because it's not always possible detect whether the role should actually be mediator or recipient, a number of configuration options are provided on how the role should be updated using the ",(0,o.kt)("inlineCode",{parentName:"p"},"v0_1ToV0_2.mediationRoleUpdateStrategy")," option:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"allMediator"),": The role is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Mediator")," for both mediators and recipients"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"allRecipient"),": The role is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Recipient")," for both mediators and recipients"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"recipientIfEndpoint")," (",(0,o.kt)("strong",{parentName:"li"},"default"),"): The role is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Recipient")," if their is an ",(0,o.kt)("inlineCode",{parentName:"li"},"endpoint")," configured on the record. The endpoint is not set when running as a mediator. There is one case where this could be problematic when the role should be recipient, if the mediation grant hasn't actually occurred (meaning the endpoint is not set). This is probably the best approach\notherwise it is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Mediator")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"doNotChange"),": The role is not changed")),(0,o.kt)("p",null,"Most agents only act as either the role of mediator or recipient, in which case the ",(0,o.kt)("inlineCode",{parentName:"p"},"allMediator")," or ",(0,o.kt)("inlineCode",{parentName:"p"},"allRecipient")," configuration is the most appropriate. If your agent acts as both a recipient and mediator, the ",(0,o.kt)("inlineCode",{parentName:"p"},"recipientIfEndpoint")," configuration is the most appropriate. The ",(0,o.kt)("inlineCode",{parentName:"p"},"doNotChange")," options is not recommended and can lead to errors if the role is not set correctly."),(0,o.kt)("h3",{id:"extracting-did-documents-to-did-repository"},"Extracting Did Documents to Did Repository"),(0,o.kt)("p",null,"The connection record previously stored both did documents from a connection in the connection record itself. Version 0.2.0 added a generic did storage that can be used for numerous usages, one of which is the storage of did documents for connection records."),(0,o.kt)("p",null,"The migration script extracts the did documents from the ",(0,o.kt)("inlineCode",{parentName:"p"},"didDoc")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"theirDidDoc")," properties from the connection record, updates them to did documents compliant with the did core spec, and stores them in the did repository. By doing so it also updates the unqualified dids in the ",(0,o.kt)("inlineCode",{parentName:"p"},"did")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"theirDid")," fields generated by the indy-sdk to fully qualified ",(0,o.kt)("inlineCode",{parentName:"p"},"did:peer")," dids compliant with the ",(0,o.kt)("a",{parentName:"p",href:"https://identity.foundation/peer-did-method-spec/"},"Peer DID Method Specification"),"."),(0,o.kt)("p",null,"To account for the fact that the mechanism to migrate legacy did document to peer did documents is not defined yet, the legacy did and did document are stored in the did record metadata. This will be deleted later if we can be certain the did doc conversion to a ",(0,o.kt)("inlineCode",{parentName:"p"},"did:peer")," did document is correct."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "did": "BBPoJqRKatdcfLEAFL7exC",\n "theirDid": "UppcJ5APts7ot5WX25943F",\n "verkey": "GAb4NUvpBcHVCvtP45vTVa5Bp74vFg3iXzdp1Gbd68Wf",\n "didDoc": ,\n "theirDidDoc": ,\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "did": "did:peer:1zQmXUaPPhPCbUVZ3hGYmQmGxWTwyDfhqESXCpMFhKaF9Y2A",\n "theirDid": "did:peer:1zQmZMygzYqNwU6Uhmewx5Xepf2VLp5S4HLSwwgf2aiKZuwa"\n}\n')))),(0,o.kt)("h3",{id:"migrating-to-the-out-of-band-record"},"Migrating to the Out of Band Record"),(0,o.kt)("p",null,"With the addition of the out of band protocol, invitations are now stored in the ",(0,o.kt)("inlineCode",{parentName:"p"},"OutOfBandRecord"),". In addition a new field ",(0,o.kt)("inlineCode",{parentName:"p"},"invitationDid")," is added to the connection record that is generated based on the invitation service or did. This allows to reuse existing connections."),(0,o.kt)("p",null,"The migration script extracts the invitation and other relevant data into a separate ",(0,o.kt)("inlineCode",{parentName:"p"},"OutOfBandRecord"),". By doing so it converts the old connection protocol invitation into the new Out of band invitation message. Based on the service or did of the invitation, the ",(0,o.kt)("inlineCode",{parentName:"p"},"invitationDid")," is populated."),(0,o.kt)("p",null,"Previously when creating a multi use invitation, a connection record would be created with the ",(0,o.kt)("inlineCode",{parentName:"p"},"multiUseInvitation")," set to true. The connection record would always be in state ",(0,o.kt)("inlineCode",{parentName:"p"},"invited"),". If a request for the multi use invitation came in, a new connection record would be created. With the addition of the out of band module, no connection records are created until a request is received. So for multi use invitation this means that the connection record with multiUseInvitation=true will be deleted, and instead all connections created using that out of band invitation will contain the ",(0,o.kt)("inlineCode",{parentName:"p"},"outOfBandId")," of the multi use invitation."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "invitation": {\n "@type": "https://didcomm.org/connections/1.0/invitation",\n "@id": "04a2c382-999e-4de9-a1d2-9dec0b2fa5e4",\n "recipientKeys": ["E6D1m3eERqCueX4ZgMCY14B4NceAr6XP2HyVqt55gDhu"],\n "serviceEndpoint": "https://example.com",\n "label": "test"\n },\n "multiUseInvitation": "false"\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "invitationDid": "did:peer:2.Ez6MksYU4MHtfmNhNm1uGMvANr9j4CBv2FymjiJtRgA36bSVH.SeyJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbSJ9",\n "outOfBandId": "04a2c382-999e-4de9-a1d2-9dec0b2fa5e4"\n}\n')))),(0,o.kt)("h3",{id:"unifying-connection-states-and-roles"},"Unifying Connection States and Roles"),(0,o.kt)("p",null,"With the addition of the did exchange protocol there are now two states and roles related to the connection record; for the did exchange protocol and for the connection protocol. To keep it easy to work with the connection record, all state and role values are updated to those of the ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeRole")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," enums."),(0,o.kt)("p",null,"The migration script transforms all connection record state and role values to their respective values of the ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeRole")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," enums. For convenience a getter\nproperty ",(0,o.kt)("inlineCode",{parentName:"p"},"rfc0160ConnectionState")," is added to the connection record which returns the ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," value."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "state": "invited",\n "role": "inviter"\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.0",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "state": "invitation-sent",\n "role": "responder"\n}\n')))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/65c86d7b.c8dd4dd0.js b/assets/js/65c86d7b.c8dd4dd0.js new file mode 100644 index 00000000..b772ff45 --- /dev/null +++ b/assets/js/65c86d7b.c8dd4dd0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[6295],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=a.createContext({}),d=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=d(e.components);return a.createElement(s.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),p=d(n),m=o,h=p["".concat(s,".").concat(m)]||p[m]||u[m]||i;return n?a.createElement(h,r(r({ref:t},c),{},{components:n})):a.createElement(h,r({ref:t},c))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:o,r[1]=l;for(var d=2;d{n.d(t,{Z:()=>r});var a=n(7294),o=n(6010);const i={tabItem:"tabItem_Ymn6"};function r(e){let{children:t,hidden:n,className:r}=e;return a.createElement("div",{role:"tabpanel",className:(0,o.Z)(i.tabItem,r),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),o=n(7294),i=n(6010),r=n(2466),l=n(6550),s=n(1980),d=n(7392),c=n(12);function p(e){return function(e){return o.Children.map(e,(e=>{if((0,o.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:o}}=e;return{value:t,label:n,attributes:a,default:o}}))}function u(e){const{values:t,children:n}=e;return(0,o.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,d.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const a=(0,l.k6)(),i=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._X)(i),(0,o.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(a.location.search);t.set(i,e),a.replace({...a.location,search:t.toString()})}),[i,a])]}function g(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,i=u(e),[r,l]=(0,o.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(!m({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:i}))),[s,d]=h({queryString:n,groupId:a}),[p,g]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,i]=(0,c.Nk)(n);return[a,(0,o.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:a}),f=(()=>{const e=s??p;return m({value:e,tabValues:i})?e:null})();(0,o.useLayoutEffect)((()=>{f&&l(f)}),[f]);return{selectedValue:r,selectValue:(0,o.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);l(e),d(e),g(e)}),[d,g,i]),tabValues:i}}var f=n(2389);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:n,selectedValue:l,selectValue:s,tabValues:d}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,r.o5)(),u=e=>{const t=e.currentTarget,n=c.indexOf(t),a=d[n].value;a!==l&&(p(t),s(a))},m=e=>{let t=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return o.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},d.map((e=>{let{value:t,label:n,attributes:r}=e;return o.createElement("li",(0,a.Z)({role:"tab",tabIndex:l===t?0:-1,"aria-selected":l===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:u},r,{className:(0,i.Z)("tabs__item",v.tabItem,r?.className,{"tabs__item--active":l===t})}),n??t)})))}function b(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,o.cloneElement)(e,{className:"margin-top--md"}):null}return o.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,o.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function y(e){const t=g(e);return o.createElement("div",{className:(0,i.Z)("tabs-container",v.tabList)},o.createElement(k,(0,a.Z)({},e,t)),o.createElement(b,(0,a.Z)({},e,t)))}function w(e){const t=(0,f.Z)();return o.createElement(y,(0,a.Z)({key:String(t)},e))}},9234:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>l,metadata:()=>d,toc:()=>p});var a=n(7462),o=(n(7294),n(3905)),i=n(4866),r=n(5162);const l={},s="Migrating from Credo 0.1.0 to 0.2.x",d={unversionedId:"updating/versions/0.1-to-0.2",id:"updating/versions/0.1-to-0.2",title:"Migrating from Credo 0.1.0 to 0.2.x",description:"This document describes everything you need to know for updating Credo 0.1.0 to 0.2.x. If you're not aware of how updating in Credo works make sure to first read the guide on Updating Credo.",source:"@site/guides/updating/versions/0.1-to-0.2.md",sourceDirName:"updating/versions",slug:"/updating/versions/0.1-to-0.2",permalink:"/guides/updating/versions/0.1-to-0.2",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Migrating from an Indy SDK Wallet to Aries Askar",permalink:"/guides/updating/update-indy-sdk-to-askar"},next:{title:"Migrating from Credo 0.2.x to 0.3.x",permalink:"/guides/updating/versions/0.2-to-0.3"}},c={},p=[{value:"React Native",id:"react-native",level:4},{value:"Node",id:"node",level:4},{value:"Breaking Code Changes",id:"breaking-code-changes",level:2},{value:"Credentials Module",id:"credentials-module",level:3},{value:"Module API Updates",id:"module-api-updates",level:4},{value:"0.1.0",id:"010",level:5},{value:"0.2.x",id:"02x",level:5},{value:"Data from Received Messages only Stored in Record after Accepting",id:"data-from-received-messages-only-stored-in-record-after-accepting",level:4},{value:"0.1.0",id:"010-1",level:5},{value:"0.2.x",id:"02x-1",level:5},{value:"Messages Extracted from Credential Record",id:"messages-extracted-from-credential-record",level:4},{value:"0.1.0",id:"010-2",level:5},{value:"0.2.x",id:"02x-2",level:5},{value:"Connections Module",id:"connections-module",level:3},{value:"Creating a Legacy Invitation",id:"creating-a-legacy-invitation",level:4},{value:"0.1.0",id:"010-3",level:5},{value:"0.2.x",id:"02x-3",level:5},{value:"Receiving a Legacy Invitation",id:"receiving-a-legacy-invitation",level:4},{value:"0.1.0",id:"010-4",level:5},{value:"0.2.x",id:"02x-4",level:5},{value:"Updating to use DidExchangeState",id:"updating-to-use-didexchangestate",level:4},{value:"Updating Custom Messages to the New Message Type Objects",id:"updating-custom-messages-to-the-new-message-type-objects",level:3},{value:"0.1.0",id:"010-5",level:4},{value:"0.2.x",id:"02x-5",level:4},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:2},{value:"Credential Metadata",id:"credential-metadata",level:3},{value:"0.1.0",id:"010-6",level:4},{value:"0.2.x",id:"02x-6",level:4},{value:"Migrate Credential Record Properties",id:"migrate-credential-record-properties",level:3},{value:"0.1.0",id:"010-7",level:4},{value:"0.2.x",id:"02x-7",level:4},{value:"Mediation Record Role",id:"mediation-record-role",level:3},{value:"Extracting Did Documents to Did Repository",id:"extracting-did-documents-to-did-repository",level:3},{value:"0.1.0",id:"010-8",level:4},{value:"0.2.x",id:"02x-8",level:4},{value:"Migrating to the Out of Band Record",id:"migrating-to-the-out-of-band-record",level:3},{value:"0.1.0",id:"010-9",level:4},{value:"0.2.x",id:"02x-9",level:4},{value:"Unifying Connection States and Roles",id:"unifying-connection-states-and-roles",level:3},{value:"0.1.0",id:"010-10",level:4},{value:"0.2.0",id:"020",level:4}],u={toc:p},m="wrapper";function h(e){let{components:t,...n}=e;return(0,o.kt)(m,(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"migrating-from-credo-010-to-02x"},"Migrating from Credo 0.1.0 to 0.2.x"),(0,o.kt)("p",null,"This document describes everything you need to know for updating Credo 0.1.0 to 0.2.x. If you're not aware of how updating in Credo works make sure to first read the guide on ",(0,o.kt)("a",{parentName:"p",href:"/guides/updating/"},"Updating Credo"),"."),(0,o.kt)("p",null,"First of all, update you dependencies to the 0.2.x versions. This will also update the needed peer depedencnies. ",(0,o.kt)("strong",{parentName:"p"},"Extension packages are not updated with this command"),". You need to update these manually, and make sure they're up to date with the latest version of Credo."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"React Native",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/react-native@^0.2.0 @aries-framework/core@^0.2.0 indy-sdk-react-native@^0.2.0\n\n# or NPM\nnpn install @aries-framework/react-native@^0.2.0 @aries-framework/core@^0.2.0 indy-sdk-react-native@^0.2.0\n"))),(0,o.kt)(r.Z,{label:"Node",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/node@^0.2.0 @aries-framework/core@^0.2.0\n\n# or NPM\nnpm install @aries-framework/node@^0.2.0 @aries-framework/core@^0.2.0\n")))),(0,o.kt)("h2",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,o.kt)("p",null,"This section will list all breaking changes made to the public API of Credo between version 0.1.0 and 0.2.0."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here (e.g. see ",(0,o.kt)("a",{parentName:"p",href:"#updating-custom-messages-to-the-new-message-type-objects"},"Updating Custom Messages to the New Message Type Objects"),"), but it is possible some breaking changes are not documented here (feel free to open PRs).")),(0,o.kt)("h3",{id:"credentials-module"},"Credentials Module"),(0,o.kt)("h4",{id:"module-api-updates"},"Module API Updates"),(0,o.kt)("p",null,"With the addition of the issue credential v2 protocol and the preparation for multiple attachment formats (to be added in a later release), we've made some big changes to the credentials module API. Most changes are related to structure, so updating your code to the new API should be straightforward."),(0,o.kt)("p",null,"Basically for all methods in the credential module you should take the following steps to update your code:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Move all function parameters into a single object. All module methods now take a single object that contain all properties."),(0,o.kt)("li",{parentName:"ol"},"For methods that initiate a protocol (starting from offer, proposal), you should pass ",(0,o.kt)("inlineCode",{parentName:"li"},"protocolVersion: 'v1'")," to indicate we should use the v1 protocol. (v2 is also supported, but this focuses on the breaking changes, not the new features)."),(0,o.kt)("li",{parentName:"ol"},"All indy specific attributes (e.g. credentialDefinitionId) should be passed in the ",(0,o.kt)("inlineCode",{parentName:"li"},"credentialFormats.indy")," object."),(0,o.kt)("li",{parentName:"ol"},"The preview should now be passed as only the preview attributes (the the full preview) and provided in the ",(0,o.kt)("inlineCode",{parentName:"li"},"credentialFormats.indy")," object.")),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.credentials.offerCredential('connectionId', {\n autoAcceptCredential: AutoAcceptCredential.Always,\n comment: 'hello',\n\n credentialDefinitionId: 'credentialDefinitionId',\n preview: new CredentialPreview({\n attributes: [new CredentialPreviewAttribute({ name: 'key', value: 'value' })],\n }),\n})\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.credentials.offerCredential({\n connectionId: 'connectionId',\n protocolVersion: 'v1',\n\n autoAcceptCredential: AutoAcceptCredential.Always,\n comment: 'hello',\n\n credentialFormats: {\n indy: {\n credentialDefinitionId: 'credentialDefinitionId',\n attributes: [{ name: 'key', value: 'value' }],\n },\n },\n})\n")))),(0,o.kt)("h4",{id:"data-from-received-messages-only-stored-in-record-after-accepting"},"Data from Received Messages only Stored in Record after Accepting"),(0,o.kt)("p",null,"Previously when we received a message from another connection we would store the relevant data from the exchange in the credential record. The values we would store were the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialDefinitionId")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"schemaId")," in the credential metadata, and the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialAttributes")," field."),(0,o.kt)("p",null,"Starting with Credo 0.2.0 the values are not stored in the credential record until after the message content has been accepted (in the case of an offer this means after sending the request message). This is to avoid ambiguity of the values in the credential record. If I have sent a proposal and then receive an offer, should the credential record contain the values from the proposal or the values from the offer? The first one reflects our view on what the data should be, the second one reflects the latest data."),(0,o.kt)("p",null,"We decided to make the record properties always hold our view of what the data should be, and only update it after accepting the contents of a received message (either using auto accept, or by calling the ",(0,o.kt)("inlineCode",{parentName:"p"},"acceptXXX")," methods on the credential module)."),(0,o.kt)("p",null,"This is an important change and requires some updates to how you extract the relevant data from the offer (or other messages such the proposal). We've added a new ",(0,o.kt)("inlineCode",{parentName:"p"},"getFormatData")," method on the credentials module that allows you to retrieve the attributes and format data for all messages in an exchange. One of the advantages of this approach is that we don't have to store all relevant data in the credential record anymore, which helps when adding new formats that don't match with the attributes used for indy credentials. In addition, the return value for this method is the same whether v1 or v2 of the protocol is used. This means your code should only care about the credential format (indy in this case) and doesn't have to worry about the protocol version."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"agent.events.on(\n CredentialEventTypes.CredentialStateChanged,\n ({ payload: { credentialRecord } }) => {\n const indyCredentialMetadata = credentialRecord.metadata.get(CredentialMetadataKeys.IndyCredential)\n\n // Get credential definition id, schema id and attributes from offer\n const credentialDefinitionId = indyCredentialMetadata?.credentialDefinitionId\n const schemaId = indyCredentialMetadata?.schemaId\n const attributes = credentialRecord.credentialAttributes\n }\n)\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"agent.events.on(\n CredentialEventTypes.CredentialStateChanged,\n async ({ payload: { credentialRecord } }) => {\n const formatData = await agent.credentials.getFormatData(credentialRecord.id)\n\n // Get credential definition id, schema id and attributes from offer\n const credentialDefinitionId = formatData.offer?.indy?.cred_def_id\n const schemaId = formatData.offer?.indy?.schema_id\n const attributes = formatData.offerAttributes\n }\n)\n")),(0,o.kt)("p",null,"The return value of the ",(0,o.kt)("inlineCode",{parentName:"p"},"getFormatData")," method is fully typed an directly returns the format data as encoded in the attachment. It also returns the ",(0,o.kt)("inlineCode",{parentName:"p"},"proposalAttributes")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"offerAttributes")," values which contain the attributes for the indy credential. This is not part of the attachment data itself, but can be seen as the format data for the credential."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"{\n proposalAttributes: [{ name: 'key', value: 'value' mimeType: 'text/plain' }],\n proposal: {\n indy: { } // indy proposal as described in RFC 0592\n },\n offerAttributes: [{ name: 'key', value: 'value' mimeType: 'text/plain' }],\n offer: {\n indy: { } // indy offer as described in RFC 0592\n },\n request: {\n indy: { } // indy request as described in RFC 0592\n }\n credential: {\n indy: { } // indy credential as described in RFC 0592\n }\n}\n")))),(0,o.kt)("h4",{id:"messages-extracted-from-credential-record"},"Messages Extracted from Credential Record"),(0,o.kt)("p",null,"The DIDComm messages that were previously stored on the credential record, have been extracted to separate DIDComm message records. This makes it easier to work with multiple versions of the protocol internally, and keeps the credential exchange record agnostic of the protocol version. Instead of accessing the messages through the ",(0,o.kt)("inlineCode",{parentName:"p"},"proposalMessage"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"offerMessage"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"requestMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialMessage")," parameters, we now expose dedicated methods on the credentials module to retrieve the message."),(0,o.kt)("p",null,"With the addition of the v2 messages, all v1 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," while v2 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V2")," (",(0,o.kt)("inlineCode",{parentName:"p"},"V1ProposeCredentialMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"V2ProposeCredentialMessage"),"). If you were using these messages classes throughout your codebase, update them to use the ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," prefix."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const credentialRecord = await agent.credentials.getById('credentialRecordId')\n\nconst proposalMessage = credentialRecord.proposalMessage\nconst offerMessage = credentialRecord.offerMessage\nconst requestMessage = credentialRecord.requestMessage\nconst credentialMessage = credentialRecord.credentialMessage\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const credentialRecord = await agent.credentials.getById('credentialRecordId')\n\nconst proposalMessage = await agent.credentials.findProposalMessage('credentialRecordId')\nconst offerMessage = await agent.credentials.findOfferMessage('credentialRecordId')\nconst requestMessage = await agent.credentials.findRequestMessage('credentialRecordId')\nconst credentialMessage = await agent.credentials.findCredentialMessage('credentialRecordId')\n")),(0,o.kt)("p",null,"Because Credo now also supports the issue credential v2 protocol, the return type of this protocol has been changed to ",(0,o.kt)("inlineCode",{parentName:"p"},"V1XXXMessage | V2XXXMessage | null"),". Take this into account when working with the messages."),(0,o.kt)("p",null,"You can check if a message is a specific version by using the ",(0,o.kt)("inlineCode",{parentName:"p"},"instanceof")," operator:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"if (proposalMessage instanceof V1ProposeCredentialMessage) {\n // do something\n}\n")),(0,o.kt)("p",null,"Shared properties (e.g. the proposal messages for v1 and v2 both have the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialPreview")," property) can be accessed without doing an instance check."))),(0,o.kt)("h3",{id:"connections-module"},"Connections Module"),(0,o.kt)("p",null,"Version 0.2.0 added support for the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md"},"Out of Band protocol")," with support for the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0023-did-exchange"},"DID Exchange protocol"),". Internally Credo now uses out of band invitations for all connections, even if you're connecting using the old invitations from the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0160-connection-protocol"},"Connection protocol"),"."),(0,o.kt)("h4",{id:"creating-a-legacy-invitation"},"Creating a Legacy Invitation"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"createInvitation")," method on the connections module has been moved to the out of band module and renamed to ",(0,o.kt)("inlineCode",{parentName:"p"},"createLegacyInvitation"),". The method is not planned to be removed in the near future, the legacy merely indicates this will create an RFC 0160 connection invitation. Internally Credo creates an out of band invitation and transforms it into a legacy invitation. If you want to create an out of band invitation instead, you should use ",(0,o.kt)("inlineCode",{parentName:"p"},"oob.createInvitation"),"."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { connectionRecord, invitation } = await agent.connections.createInvitation({\n /* config */\n})\n\nconst invitationUrl = invitation.toUrl({ domain: 'https://example.com' })\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { outOfBandRecord, invitation } = await agent.oob.createLegacyInvitation({\n /* config */\n})\n\nconst invitationUrl = invitation.toUrl({ domain: 'https://example.com' })\n")),(0,o.kt)("p",null,"Important thing to note here is that the ",(0,o.kt)("inlineCode",{parentName:"p"},"oob.createLegacyInvitation")," does not return a connection record, but rather an out of band record. Because out of band also supports connection-less scenarios, a connection record is not created until a connection request is received (or sent in the case of the invitee role)."),(0,o.kt)("p",null,"You can listen for connection state change events that are associated with a specific out of band id. This allows you to link a connection to an invitation you created."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"// Listen for connection state changed events associated with the out of band record\nagent.events.on(ConnectionEventTypes.ConnectionStateChanged, (event) => {\n if (event.payload.connectionRecord.outOfBandId === outOfBandRecord.id) {\n console.log(`Connection state changed for connection with out of band id ${outOfBandRecord.id}`)\n }\n})\n")),(0,o.kt)("p",null,"It is also possible to retrieve all connection records associated with an out of band invitation. Because of multi use invitations, there could be multiple connection records associated with a single out of band invitation. Instead of having a separate connection record that will always stay in the invited state, the out of band record will now handle the multi use capabilities of an invitation."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"// Retrieve all connections associated with an out of band id\nconst connections = await agent.connections.findAllByOutOfBandId(outOfBandRecord.id)\n")))),(0,o.kt)("h4",{id:"receiving-a-legacy-invitation"},"Receiving a Legacy Invitation"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"receiveInvitation")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"receiveInvitationFromUrl")," methods on the connections module have also been moved to the out of band module. Both methods support the new out of band invitations and the legacy RFC 0160 connection invitations. Internally Credo converts the old invitations to out of band invitations."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const invitationUrl = 'https://example.com?c_i=eyXXX'\n\n// Receive invitation directly from url\nconst connectionRecord = await agent.connections.receiveInvitationFromUrl(invitationUrl, {\n /* config */\n})\n\n// Parse invitation and receive invitation\nconst parsedInvitation = await ConnectionInvitationMessage.fromUrl(invitationUrl)\nconst connectionRecord = await agent.connections.receiveInvitation(parsedInvitation, {\n /* config */\n})\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const invitationUrl = 'https://example.com?c_i=eyXXX'\n\n// Receive invitation directly from url\nconst { outOfBandRecord, connectionRecord } = await agent.oob.receiveInvitationFromUrl(invitationUrl, {\n /* config */\n})\n\n// Parse invitation and receive invitation\nconst parsedInvitation = await agent.oob.parseInvitation(invitationUrl)\nconst secondConnectionRecord = await agent.oob.receiveInvitation(parsedInvitation, {\n /* config */\n})\n")),(0,o.kt)("p",null,"The new receive invitation methods on the out of band module won't always return a connection record anymore. The out of band invitation may not contain any handshake protocols. In the case of receiving a connection invitation you will always receive a connection record though, as you can't use it for connection-less invitations."))),(0,o.kt)("h4",{id:"updating-to-use-didexchangestate"},"Updating to use ",(0,o.kt)("inlineCode",{parentName:"h4"},"DidExchangeState")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," that was previously used for the state of the ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionRecord")," has been changed to use the ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," for both connections made using the RFC 0160 Connection Protocol, as well as the RFC 0023 DID Exchange Protocol."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," has the following values:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.Start"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.InvitationSent"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.InvitationReceived"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.RequestSent"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.RequestReceived"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.ResponseSent"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.ResponseReceived"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.Abandoned"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.Completed"))),(0,o.kt)("p",null,"If you still need to access the old ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," you can do so by accessing the computed ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionRecord.rfc0160State")," property. This will return the old ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," value."),(0,o.kt)("h3",{id:"updating-custom-messages-to-the-new-message-type-objects"},"Updating Custom Messages to the New Message Type Objects"),(0,o.kt)("p",null,"Although this isn't a breaking change to the public API of the framework, it is something that you will need to take into account when creating custom modules. Starting from Credo 0.2.0 we now support handling messages with different minor versions (e.g. receive a message with ",(0,o.kt)("inlineCode",{parentName:"p"},"@type")," version 1.1 while we only support 1.0). With this change messages must now declare the message type as an ",(0,o.kt)("inlineCode",{parentName:"p"},"ParsedMessageType")," object. We've added an ",(0,o.kt)("inlineCode",{parentName:"p"},"parseMessageType")," util method that can help with this."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { AgentMessage } from '@aries-framework/core'\nimport { Equals } from 'class-validator'\n\nclass MyMessage extends AgentMessage {\n @Equals(MyMessage.type)\n public readonly type = MyMessage.type\n public static readonly type = 'https://didcomm.org/my-protocol/1.0/my-type'\n}\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { AgentMessage, IsValidMessageType, parseMessageType } from '@aries-framework/core'\nimport { Equals } from 'class-validator'\n\nclass MyMessage extends AgentMessage {\n // use IsValidMessageType instead of Equals\n @IsValidMessageType(MyMessage.type)\n // append .messageTypeUri to get the actual URI when instantiating a message\n public readonly type = MyMessage.type.messageTypeUri\n // use parseMessageType to get the message type object from a type. You can declare the object yourself, but this is the recommended way\n public static readonly type = parseMessageType('https://didcomm.org/my-protocol/1.0/my-type')\n}\n")))),(0,o.kt)("h2",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,o.kt)("p",null,"The 0.2.0 release is heavy on breaking changes to the storage format. This is not what we intend to do with every release. But as there's not that many people yet using the framework in production, and there were a lot of changes needed to keep the API straightforward, we decided to bundle a lot of breaking changes in this one release."),(0,o.kt)("p",null,"Below all breaking storage changes are explained in as much detail as possible. The update assistant provides all tools to migrate without a hassle, but it is important to know what has changed. All examples only show the keys that have changed, unrelated keys in records have been omitted."),(0,o.kt)("p",null,"See the ",(0,o.kt)("a",{parentName:"p",href:"/guides/updating/update-assistant"},"Update Assistant")," documentation for a guide on how to use the update assistant."),(0,o.kt)("p",null,"The following config can be provided to the update assistant to migrate from 0.1.0 to 0.2.0:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "v0_1ToV0_2": {\n "mediationRoleUpdateStrategy": ""\n }\n}\n')),(0,o.kt)("h3",{id:"credential-metadata"},"Credential Metadata"),(0,o.kt)("p",null,"The credential record had a custom ",(0,o.kt)("inlineCode",{parentName:"p"},"metadata")," property in pre-0.1.0 storage that contained the ",(0,o.kt)("inlineCode",{parentName:"p"},"requestMetadata"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"schemaId")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialDefinition")," properties. Later a generic metadata API was added that only allows objects to be stored. Therefore the properties were moved into a different structure."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "requestMetadata": ,\n "schemaId": "",\n "credentialDefinitionId": ""\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "_internal/indyRequest": ,\n "_internal/indyCredential": {\n "schemaId": "",\n "credentialDefinitionId": ""\n }\n}\n')),(0,o.kt)("p",null,"Accessing the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialDefinitionId")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"schemaId")," properties will now be done by retrieving the ",(0,o.kt)("inlineCode",{parentName:"p"},"CredentialMetadataKeys.IndyCredential")," metadata key."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const indyCredential = credentialRecord.metadata.get(CredentialMetadataKeys.IndyCredential)\n\n// both properties are optional\nindyCredential?.credentialDefinitionId\nindyCredential?.schemaId\n")))),(0,o.kt)("h3",{id:"migrate-credential-record-properties"},"Migrate Credential Record Properties"),(0,o.kt)("p",null,"In 0.2.0 the v1 DIDComm messages have been moved out of the credential record into separate records using the DidCommMessageRepository. The migration scripts extracts all messages (proposalMessage, offerMessage, requestMessage, credentialMessage) and moves them into the DidCommMessageRepository."),(0,o.kt)("p",null,"With the addition of support for different protocol versions the credential record now stores the protocol version. With the addition of issue credential v2 support, other credential formats than indy can be used, and multiple credentials can be issued at once. To account for this the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialId")," has been replaced by the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentials")," array. This is an array of objects containing the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialRecordId")," and the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialRecordType"),". For all current credentials the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialRecordType")," will always be ",(0,o.kt)("inlineCode",{parentName:"p"},"indy"),"."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "credentialId": "09e46da9-a575-4909-b016-040e96c3c539",\n "proposalMessage": { ... },\n "offerMessage": { ... },\n "requestMessage": { ... },\n "credentialMessage": { ... },\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "protocolVersion": "v1",\n "credentials": [\n {\n "credentialRecordId": "09e46da9-a575-4909-b016-040e96c3c539",\n "credentialRecordType": "indy"\n }\n ]\n}\n')))),(0,o.kt)("h3",{id:"mediation-record-role"},"Mediation Record Role"),(0,o.kt)("p",null,"The role in the mediation record was always being set to ",(0,o.kt)("inlineCode",{parentName:"p"},"MediationRole.Mediator")," for both mediators and recipients. This didn't cause any issues, but would return the wrong role for recipients."),(0,o.kt)("p",null,"In 0.2 a check is added to make sure the role of a mediation record matches with actions (e.g. a recipient can't grant mediation), which means it will throw an error if the role is not set correctly."),(0,o.kt)("p",null,"Because it's not always possible detect whether the role should actually be mediator or recipient, a number of configuration options are provided on how the role should be updated using the ",(0,o.kt)("inlineCode",{parentName:"p"},"v0_1ToV0_2.mediationRoleUpdateStrategy")," option:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"allMediator"),": The role is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Mediator")," for both mediators and recipients"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"allRecipient"),": The role is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Recipient")," for both mediators and recipients"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"recipientIfEndpoint")," (",(0,o.kt)("strong",{parentName:"li"},"default"),"): The role is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Recipient")," if their is an ",(0,o.kt)("inlineCode",{parentName:"li"},"endpoint")," configured on the record. The endpoint is not set when running as a mediator. There is one case where this could be problematic when the role should be recipient, if the mediation grant hasn't actually occurred (meaning the endpoint is not set). This is probably the best approach\notherwise it is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Mediator")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"doNotChange"),": The role is not changed")),(0,o.kt)("p",null,"Most agents only act as either the role of mediator or recipient, in which case the ",(0,o.kt)("inlineCode",{parentName:"p"},"allMediator")," or ",(0,o.kt)("inlineCode",{parentName:"p"},"allRecipient")," configuration is the most appropriate. If your agent acts as both a recipient and mediator, the ",(0,o.kt)("inlineCode",{parentName:"p"},"recipientIfEndpoint")," configuration is the most appropriate. The ",(0,o.kt)("inlineCode",{parentName:"p"},"doNotChange")," options is not recommended and can lead to errors if the role is not set correctly."),(0,o.kt)("h3",{id:"extracting-did-documents-to-did-repository"},"Extracting Did Documents to Did Repository"),(0,o.kt)("p",null,"The connection record previously stored both did documents from a connection in the connection record itself. Version 0.2.0 added a generic did storage that can be used for numerous usages, one of which is the storage of did documents for connection records."),(0,o.kt)("p",null,"The migration script extracts the did documents from the ",(0,o.kt)("inlineCode",{parentName:"p"},"didDoc")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"theirDidDoc")," properties from the connection record, updates them to did documents compliant with the did core spec, and stores them in the did repository. By doing so it also updates the unqualified dids in the ",(0,o.kt)("inlineCode",{parentName:"p"},"did")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"theirDid")," fields generated by the indy-sdk to fully qualified ",(0,o.kt)("inlineCode",{parentName:"p"},"did:peer")," dids compliant with the ",(0,o.kt)("a",{parentName:"p",href:"https://identity.foundation/peer-did-method-spec/"},"Peer DID Method Specification"),"."),(0,o.kt)("p",null,"To account for the fact that the mechanism to migrate legacy did document to peer did documents is not defined yet, the legacy did and did document are stored in the did record metadata. This will be deleted later if we can be certain the did doc conversion to a ",(0,o.kt)("inlineCode",{parentName:"p"},"did:peer")," did document is correct."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "did": "BBPoJqRKatdcfLEAFL7exC",\n "theirDid": "UppcJ5APts7ot5WX25943F",\n "verkey": "GAb4NUvpBcHVCvtP45vTVa5Bp74vFg3iXzdp1Gbd68Wf",\n "didDoc": ,\n "theirDidDoc": ,\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "did": "did:peer:1zQmXUaPPhPCbUVZ3hGYmQmGxWTwyDfhqESXCpMFhKaF9Y2A",\n "theirDid": "did:peer:1zQmZMygzYqNwU6Uhmewx5Xepf2VLp5S4HLSwwgf2aiKZuwa"\n}\n')))),(0,o.kt)("h3",{id:"migrating-to-the-out-of-band-record"},"Migrating to the Out of Band Record"),(0,o.kt)("p",null,"With the addition of the out of band protocol, invitations are now stored in the ",(0,o.kt)("inlineCode",{parentName:"p"},"OutOfBandRecord"),". In addition a new field ",(0,o.kt)("inlineCode",{parentName:"p"},"invitationDid")," is added to the connection record that is generated based on the invitation service or did. This allows to reuse existing connections."),(0,o.kt)("p",null,"The migration script extracts the invitation and other relevant data into a separate ",(0,o.kt)("inlineCode",{parentName:"p"},"OutOfBandRecord"),". By doing so it converts the old connection protocol invitation into the new Out of band invitation message. Based on the service or did of the invitation, the ",(0,o.kt)("inlineCode",{parentName:"p"},"invitationDid")," is populated."),(0,o.kt)("p",null,"Previously when creating a multi use invitation, a connection record would be created with the ",(0,o.kt)("inlineCode",{parentName:"p"},"multiUseInvitation")," set to true. The connection record would always be in state ",(0,o.kt)("inlineCode",{parentName:"p"},"invited"),". If a request for the multi use invitation came in, a new connection record would be created. With the addition of the out of band module, no connection records are created until a request is received. So for multi use invitation this means that the connection record with multiUseInvitation=true will be deleted, and instead all connections created using that out of band invitation will contain the ",(0,o.kt)("inlineCode",{parentName:"p"},"outOfBandId")," of the multi use invitation."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "invitation": {\n "@type": "https://didcomm.org/connections/1.0/invitation",\n "@id": "04a2c382-999e-4de9-a1d2-9dec0b2fa5e4",\n "recipientKeys": ["E6D1m3eERqCueX4ZgMCY14B4NceAr6XP2HyVqt55gDhu"],\n "serviceEndpoint": "https://example.com",\n "label": "test"\n },\n "multiUseInvitation": "false"\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "invitationDid": "did:peer:2.Ez6MksYU4MHtfmNhNm1uGMvANr9j4CBv2FymjiJtRgA36bSVH.SeyJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbSJ9",\n "outOfBandId": "04a2c382-999e-4de9-a1d2-9dec0b2fa5e4"\n}\n')))),(0,o.kt)("h3",{id:"unifying-connection-states-and-roles"},"Unifying Connection States and Roles"),(0,o.kt)("p",null,"With the addition of the did exchange protocol there are now two states and roles related to the connection record; for the did exchange protocol and for the connection protocol. To keep it easy to work with the connection record, all state and role values are updated to those of the ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeRole")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," enums."),(0,o.kt)("p",null,"The migration script transforms all connection record state and role values to their respective values of the ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeRole")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," enums. For convenience a getter\nproperty ",(0,o.kt)("inlineCode",{parentName:"p"},"rfc0160ConnectionState")," is added to the connection record which returns the ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," value."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "state": "invited",\n "role": "inviter"\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.0",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "state": "invitation-sent",\n "role": "responder"\n}\n')))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/67da112e.350de119.js b/assets/js/67da112e.350de119.js new file mode 100644 index 00000000..94fa9136 --- /dev/null +++ b/assets/js/67da112e.350de119.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[5666],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>c});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=a.createContext({}),s=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},d=function(e){var t=s(e.components);return a.createElement(p.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},g=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),m=s(n),g=o,c=m["".concat(p,".").concat(g)]||m[g]||u[g]||i;return n?a.createElement(c,r(r({ref:t},d),{},{components:n})):a.createElement(c,r({ref:t},d))}));function c(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=g;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l[m]="string"==typeof e?e:o,r[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>r,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var a=n(7462),o=(n(7294),n(3905));const i={},r="Agent Config",l={unversionedId:"tutorials/agent-config/index",id:"tutorials/agent-config/index",title:"Agent Config",description:"The Credo agent is very extensible. These are all the configuration options with a short description:",source:"@site/guides/tutorials/agent-config/index.md",sourceDirName:"tutorials/agent-config",slug:"/tutorials/agent-config/",permalink:"/guides/tutorials/agent-config/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Tutorials",permalink:"/guides/tutorials/"},next:{title:"Logging",permalink:"/guides/tutorials/agent-config/logging"}},p={},s=[{value:"label*",id:"label",level:2},{value:"walletConfig",id:"walletconfig",level:2},{value:"walletConfig.id*",id:"walletconfigid",level:3},{value:"walletConfig.key*",id:"walletconfigkey",level:3},{value:"walletConfig.keyDerivationMethod",id:"walletconfigkeyderivationmethod",level:3},{value:"walletConfig.storage",id:"walletconfigstorage",level:3},{value:"endpoints",id:"endpoints",level:2},{value:"logger",id:"logger",level:2},{value:"didCommMimeType",id:"didcommmimetype",level:2},{value:"useDidSovPrefixWhereAllowed",id:"usedidsovprefixwhereallowed",level:2},{value:"useDidKeyInProtocols",id:"usedidkeyinprotocols",level:2},{value:"connectionImageUrl",id:"connectionimageurl",level:2},{value:"autoUpdateStorageOnStartup",id:"autoupdatestorageonstartup",level:2}],d={toc:s},m="wrapper";function u(e){let{components:t,...n}=e;return(0,o.kt)(m,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"agent-config"},"Agent Config"),(0,o.kt)("p",null,"The Credo agent is very extensible. These are all the configuration options with a short description:"),(0,o.kt)("h2",{id:"label"},(0,o.kt)("inlineCode",{parentName:"h2"},"label"),"*"),(0,o.kt)("p",null,"The label is seen by other users when creating a connection. This should not\nbe used as a base for authenticity, as it is entirely up to the user to\nset this."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"string")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"label: 'my-demo-agent'\n")),(0,o.kt)("hr",null),(0,o.kt)("h2",{id:"walletconfig"},(0,o.kt)("inlineCode",{parentName:"h2"},"walletConfig")),(0,o.kt)("p",null,"Configuration for the setup of the wallet. Including this in the agent\nconfiguration makes it possible that, when initializing the agent, the wallet\nwill also be initialized. When an application requires the agent without an\ninitialized wallet for any reason, this can be omitted and later on the wallet\ncan be initialized separately."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"WalletConfig")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"import { KeyDerivationMethod } from '@credo-ts/core'\n\nwalletConfig: {\n id: 'foo',\n key: 'testkey000000000000000000000',\n keyDerivationMethod: KeyDerivationMethod.Argon2IMod,\n storage: {\n type: 'postgres_storage',\n ... // depends on the storage type\n }\n}\n")),(0,o.kt)("h3",{id:"walletconfigid"},(0,o.kt)("inlineCode",{parentName:"h3"},"walletConfig.id"),"*"),(0,o.kt)("p",null,"Identifier string. Using another value here will open a new wallet."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"string")),(0,o.kt)("h3",{id:"walletconfigkey"},(0,o.kt)("inlineCode",{parentName:"h3"},"walletConfig.key"),"*"),(0,o.kt)("p",null,"Key to unlock the wallet with. This value MUST be kept as a secret and should\nbe seem like a password."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"string")),(0,o.kt)("h3",{id:"walletconfigkeyderivationmethod"},(0,o.kt)("inlineCode",{parentName:"h3"},"walletConfig.keyDerivationMethod")),(0,o.kt)("p",null,"The method used for key derivation of the\n",(0,o.kt)("a",{parentName:"p",href:"#walletconfigkey"},(0,o.kt)("inlineCode",{parentName:"a"},"walletConfig.key")),"."),(0,o.kt)("p",null,"When using ",(0,o.kt)("inlineCode",{parentName:"p"},"KeyDerivationMethod.Raw"),", the key must be a base58-encoded\n",(0,o.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/ChaCha20-Poly1305"},"ChaCha20-Poly1305")," key."),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"For the advanced readers\n",(0,o.kt)("a",{parentName:"p",href:"https://www.password-hashing.net/argon2-specs.pdf"},"here")," is the\nspecification of Argon2.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"enum KeyDerivationMethod")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Default"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"KeyDerivationMethod.Argon2IMod")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Members"),":"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"KeyDerivationMethod.Argon2IMod"))),(0,o.kt)("p",null,"\xa0","\xa0","\xa0"," uses Argon2I modular (most secure option, but slower)"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"KeyDerivationMethod.Argon2Int"))),(0,o.kt)("p",null,"\xa0","\xa0","\xa0"," uses Argon2 integer (less secure, but faster)"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"KeyDerivationMethod.Raw"))),(0,o.kt)("p",null,"\xa0","\xa0","\xa0"," uses no derivation method and the key must be a base58-encoded ",(0,o.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/ChaCha20-Poly1305"},"ChaCha20-Poly1305")," key."),(0,o.kt)("h3",{id:"walletconfigstorage"},(0,o.kt)("inlineCode",{parentName:"h3"},"walletConfig.storage")),(0,o.kt)("p",null,"Specify which storage is being used for the wallet. The default is an SQLite\ndatabase, but a Postgres database could be used as well."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"object")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Default"),": An SQLite database"),(0,o.kt)("hr",null),(0,o.kt)("h2",{id:"endpoints"},(0,o.kt)("inlineCode",{parentName:"h2"},"endpoints")),(0,o.kt)("p",null,"A list of endpoints (schema + host + port) used for invitations and where other\nagents might reach you. This could be used to host a website that would\nredirect, for example with deep linking, to a wallet where the invitation can be\naccepted."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"string")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"endpoints: ['https://example.org:3000']\n")),(0,o.kt)("hr",null),(0,o.kt)("h2",{id:"logger"},(0,o.kt)("inlineCode",{parentName:"h2"},"logger")),(0,o.kt)("p",null,"A logger instance that implements the ",(0,o.kt)("inlineCode",{parentName:"p"},"Logger")," interface. This can be extremely\nhelpful for debugging. Credo exposes a ",(0,o.kt)("inlineCode",{parentName:"p"},"ConsoleLogger"),"\nthat can be used for simple logs. See ",(0,o.kt)("a",{parentName:"p",href:"./logging"},"Logging")," for more details on creating your own logger instance."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"Logger")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"import { ConsoleLogger, LogLevel } from '@credo-ts/core'\n\nlogger: new ConsoleLogger(LogLevel.info)\n")),(0,o.kt)("hr",null),(0,o.kt)("h2",{id:"didcommmimetype"},(0,o.kt)("inlineCode",{parentName:"h2"},"didCommMimeType")),(0,o.kt)("p",null,"The mime-type used for sending and receiving messages. ",(0,o.kt)("inlineCode",{parentName:"p"},"application/jwe")," and\n",(0,o.kt)("inlineCode",{parentName:"p"},"application/json")," are used as fallback but are less desirable as they are\nmuch more ambiguous in their specification."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"enum DidCommMimeType")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Default"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"DidCommMimeType.V1")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Members"),":"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"DidCommMimeType.V0"))),(0,o.kt)("p",null,"\xa0","\xa0","\xa0",' "application/ssi-agent-wire"'),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"DidCommMimeType.V1"))),(0,o.kt)("p",null,"\xa0","\xa0","\xa0",' "application/didcomm-envelope-enc"'),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"import { DidCommMimeType } from '@credo-ts/core'\n\ndidCommMimeType: DidCommMimeType.V1\n")),(0,o.kt)("hr",null),(0,o.kt)("h2",{id:"usedidsovprefixwhereallowed"},(0,o.kt)("inlineCode",{parentName:"h2"},"useDidSovPrefixWhereAllowed")),(0,o.kt)("p",null,"Whether to emit the legacy did:sov prefix ",(0,o.kt)("inlineCode",{parentName:"p"},"did:sov:BzCbsNYhMrjHiqZDTUASHg;spec")," in the ",(0,o.kt)("inlineCode",{parentName:"p"},"@type")," of messages for messages that allow it. A message can allow emitting the legacy prefix by setting the ",(0,o.kt)("inlineCode",{parentName:"p"},"allowDidSovPrefix")," on the message class. This is the case for all core messages that have been defined before the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0348-transition-msg-type-to-https/README.md"},"Migration to ",(0,o.kt)("inlineCode",{parentName:"a"},"https://didcomm.org")," message type"),", to allow for the best possible interoperability with other agents."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"boolean")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Default"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"false")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"useDidSovPrefixWhereAllowed: true\n")),(0,o.kt)("hr",null),(0,o.kt)("h2",{id:"usedidkeyinprotocols"},(0,o.kt)("inlineCode",{parentName:"h2"},"useDidKeyInProtocols")),(0,o.kt)("p",null,"Whether to use ",(0,o.kt)("inlineCode",{parentName:"p"},"did:key")," in protocols by default as defined in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0360-use-did-key/README.md"},"RFC 0360: did:key Usage"),". Adopting this RFC can break interop with agents that haven't adopted this RFC yet. The framework does it best to automatically detect whether the other agent supports ",(0,o.kt)("inlineCode",{parentName:"p"},"did:key"),", however in some cases we can't determine this. In those cases this parameter can be used to force the framework to use ",(0,o.kt)("inlineCode",{parentName:"p"},"did:key")," or not."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"boolean")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Default"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"true")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"useDidKeyInProtocols: true\n")),(0,o.kt)("hr",null),(0,o.kt)("h2",{id:"connectionimageurl"},(0,o.kt)("inlineCode",{parentName:"h2"},"connectionImageUrl")),(0,o.kt)("p",null,"A URL to an image used so that other agents can display this. Like the\n",(0,o.kt)("a",{parentName:"p",href:"#label"},(0,o.kt)("inlineCode",{parentName:"a"},"Label"))," this is completely up to the user to define\nthis. It MUST not be used got any base of authenticity."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"string")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"connectionImageUrl: 'https://picsum.photos/200'\n")),(0,o.kt)("hr",null),(0,o.kt)("h2",{id:"autoupdatestorageonstartup"},(0,o.kt)("inlineCode",{parentName:"h2"},"autoUpdateStorageOnStartup")),(0,o.kt)("p",null,"Whether the storage should automatically be updated when a newer version of\n",(0,o.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts"},"Credo")," is used."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"boolean")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Default"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"false")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"autoUpdateStorageOnStartup: true\n")),(0,o.kt)("hr",null))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/67da112e.8bb35d6e.js b/assets/js/67da112e.8bb35d6e.js deleted file mode 100644 index e79015e5..00000000 --- a/assets/js/67da112e.8bb35d6e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[5666],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>c});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=a.createContext({}),s=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},d=function(e){var t=s(e.components);return a.createElement(p.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},g=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),m=s(n),g=o,c=m["".concat(p,".").concat(g)]||m[g]||u[g]||i;return n?a.createElement(c,r(r({ref:t},d),{},{components:n})):a.createElement(c,r({ref:t},d))}));function c(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=g;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l[m]="string"==typeof e?e:o,r[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>r,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var a=n(7462),o=(n(7294),n(3905));const i={},r="Agent Config",l={unversionedId:"tutorials/agent-config/index",id:"tutorials/agent-config/index",title:"Agent Config",description:"The Credo agent is very extensible. These are all the configuration options with a short description:",source:"@site/guides/tutorials/agent-config/index.md",sourceDirName:"tutorials/agent-config",slug:"/tutorials/agent-config/",permalink:"/guides/0.5/tutorials/agent-config/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Tutorials",permalink:"/guides/0.5/tutorials/"},next:{title:"Logging",permalink:"/guides/0.5/tutorials/agent-config/logging"}},p={},s=[{value:"label*",id:"label",level:2},{value:"walletConfig",id:"walletconfig",level:2},{value:"walletConfig.id*",id:"walletconfigid",level:3},{value:"walletConfig.key*",id:"walletconfigkey",level:3},{value:"walletConfig.keyDerivationMethod",id:"walletconfigkeyderivationmethod",level:3},{value:"walletConfig.storage",id:"walletconfigstorage",level:3},{value:"endpoints",id:"endpoints",level:2},{value:"logger",id:"logger",level:2},{value:"didCommMimeType",id:"didcommmimetype",level:2},{value:"useDidSovPrefixWhereAllowed",id:"usedidsovprefixwhereallowed",level:2},{value:"useDidKeyInProtocols",id:"usedidkeyinprotocols",level:2},{value:"connectionImageUrl",id:"connectionimageurl",level:2},{value:"autoUpdateStorageOnStartup",id:"autoupdatestorageonstartup",level:2}],d={toc:s},m="wrapper";function u(e){let{components:t,...n}=e;return(0,o.kt)(m,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"agent-config"},"Agent Config"),(0,o.kt)("p",null,"The Credo agent is very extensible. These are all the configuration options with a short description:"),(0,o.kt)("h2",{id:"label"},(0,o.kt)("inlineCode",{parentName:"h2"},"label"),"*"),(0,o.kt)("p",null,"The label is seen by other users when creating a connection. This should not\nbe used as a base for authenticity, as it is entirely up to the user to\nset this."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"string")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"label: 'my-demo-agent'\n")),(0,o.kt)("hr",null),(0,o.kt)("h2",{id:"walletconfig"},(0,o.kt)("inlineCode",{parentName:"h2"},"walletConfig")),(0,o.kt)("p",null,"Configuration for the setup of the wallet. Including this in the agent\nconfiguration makes it possible that, when initializing the agent, the wallet\nwill also be initialized. When an application requires the agent without an\ninitialized wallet for any reason, this can be omitted and later on the wallet\ncan be initialized separately."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"WalletConfig")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"import { KeyDerivationMethod } from '@credo-ts/core'\n\nwalletConfig: {\n id: 'foo',\n key: 'testkey000000000000000000000',\n keyDerivationMethod: KeyDerivationMethod.Argon2IMod,\n storage: {\n type: 'postgres_storage',\n ... // depends on the storage type\n }\n}\n")),(0,o.kt)("h3",{id:"walletconfigid"},(0,o.kt)("inlineCode",{parentName:"h3"},"walletConfig.id"),"*"),(0,o.kt)("p",null,"Identifier string. Using another value here will open a new wallet."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"string")),(0,o.kt)("h3",{id:"walletconfigkey"},(0,o.kt)("inlineCode",{parentName:"h3"},"walletConfig.key"),"*"),(0,o.kt)("p",null,"Key to unlock the wallet with. This value MUST be kept as a secret and should\nbe seem like a password."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"string")),(0,o.kt)("h3",{id:"walletconfigkeyderivationmethod"},(0,o.kt)("inlineCode",{parentName:"h3"},"walletConfig.keyDerivationMethod")),(0,o.kt)("p",null,"The method used for key derivation of the\n",(0,o.kt)("a",{parentName:"p",href:"#walletconfigkey"},(0,o.kt)("inlineCode",{parentName:"a"},"walletConfig.key")),"."),(0,o.kt)("p",null,"When using ",(0,o.kt)("inlineCode",{parentName:"p"},"KeyDerivationMethod.Raw"),", the key must be a base58-encoded\n",(0,o.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/ChaCha20-Poly1305"},"ChaCha20-Poly1305")," key."),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"For the advanced readers\n",(0,o.kt)("a",{parentName:"p",href:"https://www.password-hashing.net/argon2-specs.pdf"},"here")," is the\nspecification of Argon2.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"enum KeyDerivationMethod")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Default"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"KeyDerivationMethod.Argon2IMod")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Members"),":"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"KeyDerivationMethod.Argon2IMod"))),(0,o.kt)("p",null,"\xa0","\xa0","\xa0"," uses Argon2I modular (most secure option, but slower)"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"KeyDerivationMethod.Argon2Int"))),(0,o.kt)("p",null,"\xa0","\xa0","\xa0"," uses Argon2 integer (less secure, but faster)"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"KeyDerivationMethod.Raw"))),(0,o.kt)("p",null,"\xa0","\xa0","\xa0"," uses no derivation method and the key must be a base58-encoded ",(0,o.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/ChaCha20-Poly1305"},"ChaCha20-Poly1305")," key."),(0,o.kt)("h3",{id:"walletconfigstorage"},(0,o.kt)("inlineCode",{parentName:"h3"},"walletConfig.storage")),(0,o.kt)("p",null,"Specify which storage is being used for the wallet. The default is an SQLite\ndatabase, but a Postgres database could be used as well."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"object")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Default"),": An SQLite database"),(0,o.kt)("hr",null),(0,o.kt)("h2",{id:"endpoints"},(0,o.kt)("inlineCode",{parentName:"h2"},"endpoints")),(0,o.kt)("p",null,"A list of endpoints (schema + host + port) used for invitations and where other\nagents might reach you. This could be used to host a website that would\nredirect, for example with deep linking, to a wallet where the invitation can be\naccepted."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"string")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"endpoints: ['https://example.org:3000']\n")),(0,o.kt)("hr",null),(0,o.kt)("h2",{id:"logger"},(0,o.kt)("inlineCode",{parentName:"h2"},"logger")),(0,o.kt)("p",null,"A logger instance that implements the ",(0,o.kt)("inlineCode",{parentName:"p"},"Logger")," interface. This can be extremely\nhelpful for debugging. Credo exposes a ",(0,o.kt)("inlineCode",{parentName:"p"},"ConsoleLogger"),"\nthat can be used for simple logs. See ",(0,o.kt)("a",{parentName:"p",href:"./logging"},"Logging")," for more details on creating your own logger instance."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"Logger")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"import { ConsoleLogger, LogLevel } from '@credo-ts/core'\n\nlogger: new ConsoleLogger(LogLevel.info)\n")),(0,o.kt)("hr",null),(0,o.kt)("h2",{id:"didcommmimetype"},(0,o.kt)("inlineCode",{parentName:"h2"},"didCommMimeType")),(0,o.kt)("p",null,"The mime-type used for sending and receiving messages. ",(0,o.kt)("inlineCode",{parentName:"p"},"application/jwe")," and\n",(0,o.kt)("inlineCode",{parentName:"p"},"application/json")," are used as fallback but are less desirable as they are\nmuch more ambiguous in their specification."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"enum DidCommMimeType")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Default"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"DidCommMimeType.V1")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Members"),":"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"DidCommMimeType.V0"))),(0,o.kt)("p",null,"\xa0","\xa0","\xa0",' "application/ssi-agent-wire"'),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"DidCommMimeType.V1"))),(0,o.kt)("p",null,"\xa0","\xa0","\xa0",' "application/didcomm-envelope-enc"'),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"import { DidCommMimeType } from '@credo-ts/core'\n\ndidCommMimeType: DidCommMimeType.V1\n")),(0,o.kt)("hr",null),(0,o.kt)("h2",{id:"usedidsovprefixwhereallowed"},(0,o.kt)("inlineCode",{parentName:"h2"},"useDidSovPrefixWhereAllowed")),(0,o.kt)("p",null,"Whether to emit the legacy did:sov prefix ",(0,o.kt)("inlineCode",{parentName:"p"},"did:sov:BzCbsNYhMrjHiqZDTUASHg;spec")," in the ",(0,o.kt)("inlineCode",{parentName:"p"},"@type")," of messages for messages that allow it. A message can allow emitting the legacy prefix by setting the ",(0,o.kt)("inlineCode",{parentName:"p"},"allowDidSovPrefix")," on the message class. This is the case for all core messages that have been defined before the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0348-transition-msg-type-to-https/README.md"},"Migration to ",(0,o.kt)("inlineCode",{parentName:"a"},"https://didcomm.org")," message type"),", to allow for the best possible interoperability with other agents."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"boolean")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Default"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"false")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"useDidSovPrefixWhereAllowed: true\n")),(0,o.kt)("hr",null),(0,o.kt)("h2",{id:"usedidkeyinprotocols"},(0,o.kt)("inlineCode",{parentName:"h2"},"useDidKeyInProtocols")),(0,o.kt)("p",null,"Whether to use ",(0,o.kt)("inlineCode",{parentName:"p"},"did:key")," in protocols by default as defined in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0360-use-did-key/README.md"},"RFC 0360: did:key Usage"),". Adopting this RFC can break interop with agents that haven't adopted this RFC yet. The framework does it best to automatically detect whether the other agent supports ",(0,o.kt)("inlineCode",{parentName:"p"},"did:key"),", however in some cases we can't determine this. In those cases this parameter can be used to force the framework to use ",(0,o.kt)("inlineCode",{parentName:"p"},"did:key")," or not."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"boolean")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Default"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"true")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"useDidKeyInProtocols: true\n")),(0,o.kt)("hr",null),(0,o.kt)("h2",{id:"connectionimageurl"},(0,o.kt)("inlineCode",{parentName:"h2"},"connectionImageUrl")),(0,o.kt)("p",null,"A URL to an image used so that other agents can display this. Like the\n",(0,o.kt)("a",{parentName:"p",href:"#label"},(0,o.kt)("inlineCode",{parentName:"a"},"Label"))," this is completely up to the user to define\nthis. It MUST not be used got any base of authenticity."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"string")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"connectionImageUrl: 'https://picsum.photos/200'\n")),(0,o.kt)("hr",null),(0,o.kt)("h2",{id:"autoupdatestorageonstartup"},(0,o.kt)("inlineCode",{parentName:"h2"},"autoUpdateStorageOnStartup")),(0,o.kt)("p",null,"Whether the storage should automatically be updated when a newer version of\n",(0,o.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts"},"Credo")," is used."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Type"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"boolean")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Default"),": ",(0,o.kt)("inlineCode",{parentName:"p"},"false")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript",metastring:'title="example"',title:'"example"'},"autoUpdateStorageOnStartup: true\n")),(0,o.kt)("hr",null))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6c6797b5.440a306d.js b/assets/js/6c6797b5.440a306d.js deleted file mode 100644 index 381e1f96..00000000 --- a/assets/js/6c6797b5.440a306d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[1229],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),d=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=d(e.components);return r.createElement(c.Provider,{value:t},e.children)},m="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),m=d(n),u=o,f=m["".concat(c,".").concat(u)]||m[u]||p[u]||i;return n?r.createElement(f,a(a({ref:t},l),{},{components:n})):r.createElement(f,a({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=u;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[m]="string"==typeof e?e:o,a[1]=s;for(var d=2;d{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>d});var r=n(7462),o=(n(7294),n(3905));const i={},a="DIDs and DIDComm",s={unversionedId:"concepts/did-and-didcomm",id:"version-0.4/concepts/did-and-didcomm",title:"DIDs and DIDComm",description:"DIDs",source:"@site/versioned_docs/version-0.4/concepts/did-and-didcomm.md",sourceDirName:"concepts",slug:"/concepts/did-and-didcomm",permalink:"/guides/concepts/did-and-didcomm",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Agents",permalink:"/guides/concepts/agents"},next:{title:"Platform and Environment",permalink:"/guides/concepts/platform-and-environment"}},c={},d=[{value:"DIDs",id:"dids",level:3},{value:"DID Documents",id:"did-documents",level:3},{value:"DIDComm",id:"didcomm",level:3},{value:"Useful Resources",id:"useful-resources",level:3}],l={toc:d},m="wrapper";function p(e){let{components:t,...n}=e;return(0,o.kt)(m,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"dids-and-didcomm"},"DIDs and DIDComm"),(0,o.kt)("h3",{id:"dids"},"DIDs"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://www.w3.org/TR/did-core/"},"DIDs"),", short for Decentralized identifiers,\nare a type of identifier that enables verifiable, decentralized identity. A DID\ncan refer to any subject, a person, organization, etc. DIDs are decoupled from\ncentralized registries, identity providers and certificate authorities."),(0,o.kt)("h3",{id:"did-documents"},"DID Documents"),(0,o.kt)("p",null,"A DID by itself does not contain a lot of information. So in order to get some\nmetadata we have to resolve the DID to get a ",(0,o.kt)("a",{parentName:"p",href:"https://www.w3.org/TR/did-core/#dfn-did-documents"},"DID Document"),". With this\ndocument we can get data such as their public key, proof mechanisms and their\nservice endpoints. This means that we can check the validity, encrypt\none-to-one messages and send it to their service endpoint."),(0,o.kt)("h3",{id:"didcomm"},"DIDComm"),(0,o.kt)("p",null,"In the previous section sending a message to their service endpoint is\nmentioned. This is a nice feature, but is lacking a definition of how it should\nwork. ",(0,o.kt)("a",{parentName:"p",href:"https://identity.foundation/didcomm-messaging/spec/"},"DIDComm"),", we will\nonly discuss V1 here, defines this. DIDComm is designed to be private, secure,\ntransport-agnostic, interoperable and much more. This means that you can\nsecurely send a message from as Alice to Bob securely via bluetooth, HTTP,\nWebSockets, etc."),(0,o.kt)("p",null,"When working with the tools available inside the Aries JavaScript ecosystem,\ndeep knowledge of DIDComm is not required."),(0,o.kt)("h3",{id:"useful-resources"},"Useful Resources"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://www.w3.org/TR/did-core/"},"DID spec")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://identity.foundation/didcomm-messaging/spec/"},"DIDComm spec"))))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6c6797b5.f719a870.js b/assets/js/6c6797b5.f719a870.js new file mode 100644 index 00000000..57eca238 --- /dev/null +++ b/assets/js/6c6797b5.f719a870.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[1229],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),d=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=d(e.components);return r.createElement(c.Provider,{value:t},e.children)},m="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),m=d(n),u=o,f=m["".concat(c,".").concat(u)]||m[u]||p[u]||i;return n?r.createElement(f,a(a({ref:t},l),{},{components:n})):r.createElement(f,a({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=u;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[m]="string"==typeof e?e:o,a[1]=s;for(var d=2;d{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>d});var r=n(7462),o=(n(7294),n(3905));const i={},a="DIDs and DIDComm",s={unversionedId:"concepts/did-and-didcomm",id:"version-0.4/concepts/did-and-didcomm",title:"DIDs and DIDComm",description:"DIDs",source:"@site/versioned_docs/version-0.4/concepts/did-and-didcomm.md",sourceDirName:"concepts",slug:"/concepts/did-and-didcomm",permalink:"/guides/0.4/concepts/did-and-didcomm",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Agents",permalink:"/guides/0.4/concepts/agents"},next:{title:"Platform and Environment",permalink:"/guides/0.4/concepts/platform-and-environment"}},c={},d=[{value:"DIDs",id:"dids",level:3},{value:"DID Documents",id:"did-documents",level:3},{value:"DIDComm",id:"didcomm",level:3},{value:"Useful Resources",id:"useful-resources",level:3}],l={toc:d},m="wrapper";function p(e){let{components:t,...n}=e;return(0,o.kt)(m,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"dids-and-didcomm"},"DIDs and DIDComm"),(0,o.kt)("h3",{id:"dids"},"DIDs"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://www.w3.org/TR/did-core/"},"DIDs"),", short for Decentralized identifiers,\nare a type of identifier that enables verifiable, decentralized identity. A DID\ncan refer to any subject, a person, organization, etc. DIDs are decoupled from\ncentralized registries, identity providers and certificate authorities."),(0,o.kt)("h3",{id:"did-documents"},"DID Documents"),(0,o.kt)("p",null,"A DID by itself does not contain a lot of information. So in order to get some\nmetadata we have to resolve the DID to get a ",(0,o.kt)("a",{parentName:"p",href:"https://www.w3.org/TR/did-core/#dfn-did-documents"},"DID Document"),". With this\ndocument we can get data such as their public key, proof mechanisms and their\nservice endpoints. This means that we can check the validity, encrypt\none-to-one messages and send it to their service endpoint."),(0,o.kt)("h3",{id:"didcomm"},"DIDComm"),(0,o.kt)("p",null,"In the previous section sending a message to their service endpoint is\nmentioned. This is a nice feature, but is lacking a definition of how it should\nwork. ",(0,o.kt)("a",{parentName:"p",href:"https://identity.foundation/didcomm-messaging/spec/"},"DIDComm"),", we will\nonly discuss V1 here, defines this. DIDComm is designed to be private, secure,\ntransport-agnostic, interoperable and much more. This means that you can\nsecurely send a message from as Alice to Bob securely via bluetooth, HTTP,\nWebSockets, etc."),(0,o.kt)("p",null,"When working with the tools available inside the Aries JavaScript ecosystem,\ndeep knowledge of DIDComm is not required."),(0,o.kt)("h3",{id:"useful-resources"},"Useful Resources"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://www.w3.org/TR/did-core/"},"DID spec")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://identity.foundation/didcomm-messaging/spec/"},"DIDComm spec"))))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6d44cf95.55379d59.js b/assets/js/6d44cf95.0898caab.js similarity index 84% rename from assets/js/6d44cf95.55379d59.js rename to assets/js/6d44cf95.0898caab.js index e29c9c0d..e975ba1f 100644 --- a/assets/js/6d44cf95.55379d59.js +++ b/assets/js/6d44cf95.0898caab.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7798],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var l=n.createContext({}),s=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=s(e.components);return n.createElement(l.Provider,{value:t},e.children)},m="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),m=s(r),d=i,f=m["".concat(l,".").concat(d)]||m[d]||p[d]||o;return r?n.createElement(f,a(a({ref:t},u),{},{components:r})):n.createElement(f,a({ref:t},u))}));function f(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,a=new Array(o);a[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[m]="string"==typeof e?e:i,a[1]=c;for(var s=2;s{r.d(t,{Z:()=>g});var n=r(7294),i=r(6010),o=r(3438),a=r(9960),c=r(3919),l=r(5999);const s={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function u(e){let{href:t,children:r}=e;return n.createElement(a.Z,{href:t,className:(0,i.Z)("card padding--lg",s.cardContainer)},r)}function m(e){let{href:t,icon:r,title:o,description:a}=e;return n.createElement(u,{href:t},n.createElement("h2",{className:(0,i.Z)("text--truncate",s.cardTitle),title:o},r," ",o),a&&n.createElement("p",{className:(0,i.Z)("text--truncate",s.cardDescription),title:a},a))}function p(e){let{item:t}=e;const r=(0,o.Wl)(t);return r?n.createElement(m,{href:r,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,l.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function d(e){let{item:t}=e;const r=(0,c.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",i=(0,o.xz)(t.docId??void 0);return n.createElement(m,{href:t.href,icon:r,title:t.label,description:i?.description})}function f(e){let{item:t}=e;switch(t.type){case"link":return n.createElement(d,{item:t});case"category":return n.createElement(p,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function y(e){let{className:t}=e;const r=(0,o.jA)();return n.createElement(g,{items:r.items,className:t})}function g(e){const{items:t,className:r}=e;if(!t)return n.createElement(y,e);const a=(0,o.MN)(t);return n.createElement("section",{className:(0,i.Z)("row",r)},a.map(((e,t)=>n.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},n.createElement(f,{item:e})))))}},160:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>d,frontMatter:()=>a,metadata:()=>l,toc:()=>u});var n=r(7462),i=(r(7294),r(3905)),o=r(2991);const a={},c="Tutorials",l={unversionedId:"tutorials/index",id:"version-0.4/tutorials/index",title:"Tutorials",description:"In this section we will explain some features that everyone will use. This",source:"@site/versioned_docs/version-0.4/tutorials/index.md",sourceDirName:"tutorials",slug:"/tutorials/",permalink:"/guides/tutorials/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Platform and Environment",permalink:"/guides/concepts/platform-and-environment"},next:{title:"Agent Config",permalink:"/guides/tutorials/agent-config/"}},s={},u=[],m={toc:u},p="wrapper";function d(e){let{components:t,...r}=e;return(0,i.kt)(p,(0,n.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"tutorials"},"Tutorials"),(0,i.kt)("p",null,"In this section we will explain some features that everyone will use. This\nincludes setting up your Aries agent, creating a connection between Aries\nagents, issuing a credential and verifying a proof."),(0,i.kt)(o.Z,{mdxType:"DocCardList"}))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7798],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var l=n.createContext({}),s=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=s(e.components);return n.createElement(l.Provider,{value:t},e.children)},m="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),m=s(r),d=i,f=m["".concat(l,".").concat(d)]||m[d]||p[d]||o;return r?n.createElement(f,a(a({ref:t},u),{},{components:r})):n.createElement(f,a({ref:t},u))}));function f(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,a=new Array(o);a[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[m]="string"==typeof e?e:i,a[1]=c;for(var s=2;s{r.d(t,{Z:()=>g});var n=r(7294),i=r(6010),o=r(3438),a=r(9960),c=r(3919),l=r(5999);const s={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function u(e){let{href:t,children:r}=e;return n.createElement(a.Z,{href:t,className:(0,i.Z)("card padding--lg",s.cardContainer)},r)}function m(e){let{href:t,icon:r,title:o,description:a}=e;return n.createElement(u,{href:t},n.createElement("h2",{className:(0,i.Z)("text--truncate",s.cardTitle),title:o},r," ",o),a&&n.createElement("p",{className:(0,i.Z)("text--truncate",s.cardDescription),title:a},a))}function p(e){let{item:t}=e;const r=(0,o.Wl)(t);return r?n.createElement(m,{href:r,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,l.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function d(e){let{item:t}=e;const r=(0,c.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",i=(0,o.xz)(t.docId??void 0);return n.createElement(m,{href:t.href,icon:r,title:t.label,description:i?.description})}function f(e){let{item:t}=e;switch(t.type){case"link":return n.createElement(d,{item:t});case"category":return n.createElement(p,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function y(e){let{className:t}=e;const r=(0,o.jA)();return n.createElement(g,{items:r.items,className:t})}function g(e){const{items:t,className:r}=e;if(!t)return n.createElement(y,e);const a=(0,o.MN)(t);return n.createElement("section",{className:(0,i.Z)("row",r)},a.map(((e,t)=>n.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},n.createElement(f,{item:e})))))}},160:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>d,frontMatter:()=>a,metadata:()=>l,toc:()=>u});var n=r(7462),i=(r(7294),r(3905)),o=r(2991);const a={},c="Tutorials",l={unversionedId:"tutorials/index",id:"version-0.4/tutorials/index",title:"Tutorials",description:"In this section we will explain some features that everyone will use. This",source:"@site/versioned_docs/version-0.4/tutorials/index.md",sourceDirName:"tutorials",slug:"/tutorials/",permalink:"/guides/0.4/tutorials/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Platform and Environment",permalink:"/guides/0.4/concepts/platform-and-environment"},next:{title:"Agent Config",permalink:"/guides/0.4/tutorials/agent-config/"}},s={},u=[],m={toc:u},p="wrapper";function d(e){let{components:t,...r}=e;return(0,i.kt)(p,(0,n.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"tutorials"},"Tutorials"),(0,i.kt)("p",null,"In this section we will explain some features that everyone will use. This\nincludes setting up your Aries agent, creating a connection between Aries\nagents, issuing a credential and verifying a proof."),(0,i.kt)(o.Z,{mdxType:"DocCardList"}))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6d708c3d.c2aca059.js b/assets/js/6d708c3d.8b2bfaab.js similarity index 72% rename from assets/js/6d708c3d.c2aca059.js rename to assets/js/6d708c3d.8b2bfaab.js index 11b7a669..ab47a941 100644 --- a/assets/js/6d708c3d.c2aca059.js +++ b/assets/js/6d708c3d.8b2bfaab.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[3666],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>g});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(r),m=a,g=d["".concat(l,".").concat(m)]||d[m]||p[m]||i;return r?n.createElement(g,o(o({ref:t},u),{},{components:r})):n.createElement(g,o({ref:t},u))}));function g(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:a,o[1]=s;for(var c=2;c{r.d(t,{Z:()=>y});var n=r(7294),a=r(6010),i=r(3438),o=r(9960),s=r(3919),l=r(5999);const c={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function u(e){let{href:t,children:r}=e;return n.createElement(o.Z,{href:t,className:(0,a.Z)("card padding--lg",c.cardContainer)},r)}function d(e){let{href:t,icon:r,title:i,description:o}=e;return n.createElement(u,{href:t},n.createElement("h2",{className:(0,a.Z)("text--truncate",c.cardTitle),title:i},r," ",i),o&&n.createElement("p",{className:(0,a.Z)("text--truncate",c.cardDescription),title:o},o))}function p(e){let{item:t}=e;const r=(0,i.Wl)(t);return r?n.createElement(d,{href:r,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,l.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function m(e){let{item:t}=e;const r=(0,s.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",a=(0,i.xz)(t.docId??void 0);return n.createElement(d,{href:t.href,icon:r,title:t.label,description:a?.description})}function g(e){let{item:t}=e;switch(t.type){case"link":return n.createElement(m,{item:t});case"category":return n.createElement(p,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function f(e){let{className:t}=e;const r=(0,i.jA)();return n.createElement(y,{items:r.items,className:t})}function y(e){const{items:t,className:r}=e;if(!t)return n.createElement(f,e);const o=(0,i.MN)(t);return n.createElement("section",{className:(0,a.Z)("row",r)},o.map(((e,t)=>n.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},n.createElement(g,{item:e})))))}},7342:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>m,frontMatter:()=>o,metadata:()=>l,toc:()=>u});var n=r(7462),a=(r(7294),r(3905)),i=r(2991);const o={},s="Getting started",l={unversionedId:"getting-started/index",id:"version-0.4/getting-started/index",title:"Getting started",description:"In this section we will go over everything you need to get started on a technical level. First there are some general prerequisites for Node.JS and React Native. Aries Framework JavaScript works for creating both server-side applications (commonly but not always for creating issuer and verifier agents) and mobile applications (commonly holder agents).",source:"@site/versioned_docs/version-0.4/getting-started/index.md",sourceDirName:"getting-started",slug:"/getting-started/",permalink:"/guides/getting-started/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Intro",permalink:"/guides/"},next:{title:"Prerequisites",permalink:"/guides/getting-started/prerequisites"}},c={},u=[],d={toc:u},p="wrapper";function m(e){let{components:t,...r}=e;return(0,a.kt)(p,(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"getting-started"},"Getting started"),(0,a.kt)("p",null,"In this section we will go over everything you need to get started on a technical level. First there are some general prerequisites for Node.JS and React Native. Aries Framework JavaScript works for creating both server-side applications (commonly but not always for creating issuer and verifier agents) and mobile applications (commonly holder agents)."),(0,a.kt)("p",null,"Based on the platform you want to work on, the installation guides you should follow are the same, but some steps may differ."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Do you want to build a mobile app?")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Follow the ",(0,a.kt)("a",{parentName:"li",href:"/guides/getting-started/prerequisites"},"Prerequisites"),"."),(0,a.kt)("li",{parentName:"ul"},"Follow the ",(0,a.kt)("a",{parentName:"li",href:"/guides/getting-started/set-up/"},"Agent Setup")," guide.")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Do you want to build a server-side app?")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Follow the ",(0,a.kt)("a",{parentName:"li",href:"/guides/getting-started/prerequisites"},"Prerequisites"),"."),(0,a.kt)("li",{parentName:"ul"},"Follow the ",(0,a.kt)("a",{parentName:"li",href:"/guides/getting-started/set-up/"},"Agent Setup")," guide.")),(0,a.kt)(i.Z,{mdxType:"DocCardList"}))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[3666],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>g});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(r),m=a,g=d["".concat(l,".").concat(m)]||d[m]||p[m]||i;return r?n.createElement(g,o(o({ref:t},u),{},{components:r})):n.createElement(g,o({ref:t},u))}));function g(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:a,o[1]=s;for(var c=2;c{r.d(t,{Z:()=>y});var n=r(7294),a=r(6010),i=r(3438),o=r(9960),s=r(3919),l=r(5999);const c={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function u(e){let{href:t,children:r}=e;return n.createElement(o.Z,{href:t,className:(0,a.Z)("card padding--lg",c.cardContainer)},r)}function d(e){let{href:t,icon:r,title:i,description:o}=e;return n.createElement(u,{href:t},n.createElement("h2",{className:(0,a.Z)("text--truncate",c.cardTitle),title:i},r," ",i),o&&n.createElement("p",{className:(0,a.Z)("text--truncate",c.cardDescription),title:o},o))}function p(e){let{item:t}=e;const r=(0,i.Wl)(t);return r?n.createElement(d,{href:r,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,l.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function m(e){let{item:t}=e;const r=(0,s.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",a=(0,i.xz)(t.docId??void 0);return n.createElement(d,{href:t.href,icon:r,title:t.label,description:a?.description})}function g(e){let{item:t}=e;switch(t.type){case"link":return n.createElement(m,{item:t});case"category":return n.createElement(p,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function f(e){let{className:t}=e;const r=(0,i.jA)();return n.createElement(y,{items:r.items,className:t})}function y(e){const{items:t,className:r}=e;if(!t)return n.createElement(f,e);const o=(0,i.MN)(t);return n.createElement("section",{className:(0,a.Z)("row",r)},o.map(((e,t)=>n.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},n.createElement(g,{item:e})))))}},7342:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>m,frontMatter:()=>o,metadata:()=>l,toc:()=>u});var n=r(7462),a=(r(7294),r(3905)),i=r(2991);const o={},s="Getting started",l={unversionedId:"getting-started/index",id:"version-0.4/getting-started/index",title:"Getting started",description:"In this section we will go over everything you need to get started on a technical level. First there are some general prerequisites for Node.JS and React Native. Aries Framework JavaScript works for creating both server-side applications (commonly but not always for creating issuer and verifier agents) and mobile applications (commonly holder agents).",source:"@site/versioned_docs/version-0.4/getting-started/index.md",sourceDirName:"getting-started",slug:"/getting-started/",permalink:"/guides/0.4/getting-started/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Intro",permalink:"/guides/0.4/"},next:{title:"Prerequisites",permalink:"/guides/0.4/getting-started/prerequisites"}},c={},u=[],d={toc:u},p="wrapper";function m(e){let{components:t,...r}=e;return(0,a.kt)(p,(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"getting-started"},"Getting started"),(0,a.kt)("p",null,"In this section we will go over everything you need to get started on a technical level. First there are some general prerequisites for Node.JS and React Native. Aries Framework JavaScript works for creating both server-side applications (commonly but not always for creating issuer and verifier agents) and mobile applications (commonly holder agents)."),(0,a.kt)("p",null,"Based on the platform you want to work on, the installation guides you should follow are the same, but some steps may differ."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Do you want to build a mobile app?")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Follow the ",(0,a.kt)("a",{parentName:"li",href:"/guides/0.4/getting-started/prerequisites"},"Prerequisites"),"."),(0,a.kt)("li",{parentName:"ul"},"Follow the ",(0,a.kt)("a",{parentName:"li",href:"/guides/0.4/getting-started/set-up/"},"Agent Setup")," guide.")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Do you want to build a server-side app?")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Follow the ",(0,a.kt)("a",{parentName:"li",href:"/guides/0.4/getting-started/prerequisites"},"Prerequisites"),"."),(0,a.kt)("li",{parentName:"ul"},"Follow the ",(0,a.kt)("a",{parentName:"li",href:"/guides/0.4/getting-started/set-up/"},"Agent Setup")," guide.")),(0,a.kt)(i.Z,{mdxType:"DocCardList"}))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b1d5f389.8ed976d1.js b/assets/js/6e4808e6.022de701.js similarity index 59% rename from assets/js/b1d5f389.8ed976d1.js rename to assets/js/6e4808e6.022de701.js index 34af8eb9..5398f088 100644 --- a/assets/js/b1d5f389.8ed976d1.js +++ b/assets/js/6e4808e6.022de701.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[9843],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),u=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=u(e.components);return a.createElement(i.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),p=u(n),m=r,f=p["".concat(i,".").concat(m)]||p[m]||d[m]||o;return n?a.createElement(f,s(s({ref:t},c),{},{components:n})):a.createElement(f,s({ref:t},c))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,s=new Array(o);s[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l[p]="string"==typeof e?e:r,s[1]=l;for(var u=2;u{n.d(t,{Z:()=>s});var a=n(7294),r=n(6010);const o={tabItem:"tabItem_Ymn6"};function s(e){let{children:t,hidden:n,className:s}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(o.tabItem,s),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),r=n(7294),o=n(6010),s=n(2466),l=n(6550),i=n(1980),u=n(7392),c=n(12);function p(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function d(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,u.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:n}=e;const a=(0,l.k6)(),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,i._X)(o),(0,r.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(a.location.search);t.set(o,e),a.replace({...a.location,search:t.toString()})}),[o,a])]}function h(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,o=d(e),[s,l]=(0,r.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(!m({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}))),[i,u]=f({queryString:n,groupId:a}),[p,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,o]=(0,c.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:a}),k=(()=>{const e=i??p;return m({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{k&&l(k)}),[k]);return{selectedValue:s,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);l(e),u(e),h(e)}),[u,h,o]),tabValues:o}}var k=n(2389);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){let{className:t,block:n,selectedValue:l,selectValue:i,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,s.o5)(),d=e=>{const t=e.currentTarget,n=c.indexOf(t),a=u[n].value;a!==l&&(p(t),i(a))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},u.map((e=>{let{value:t,label:n,attributes:s}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:l===t?0:-1,"aria-selected":l===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},s,{className:(0,o.Z)("tabs__item",g.tabItem,s?.className,{"tabs__item--active":l===t})}),n??t)})))}function b(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function v(e){const t=h(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",g.tabList)},r.createElement(y,(0,a.Z)({},e,t)),r.createElement(b,(0,a.Z)({},e,t)))}function w(e){const t=(0,k.Z)();return r.createElement(v,(0,a.Z)({key:String(t)},e))}},6457:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>f,frontMatter:()=>l,metadata:()=>u,toc:()=>p});var a=n(7462),r=(n(7294),n(3905)),o=n(4866),s=n(5162);const l={},i="React Hooks",u={unversionedId:"extensions/react-hooks",id:"version-0.4/extensions/react-hooks",title:"React Hooks",description:"The React Hooks package exposes useful React hooks that allow you to easily interact with AFJ from a React client application.",source:"@site/versioned_docs/version-0.4/extensions/react-hooks.md",sourceDirName:"extensions",slug:"/extensions/react-hooks",permalink:"/guides/extensions/react-hooks",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"REST API",permalink:"/guides/extensions/rest"},next:{title:"Redux Store",permalink:"/guides/extensions/redux-store"}},c={},p=[{value:"Installation",id:"installation",level:2},{value:"npm",id:"npm",level:2},{value:"Yarn",id:"yarn",level:2},{value:"Usage",id:"usage",level:2}],d={toc:p},m="wrapper";function f(e){let{components:t,...n}=e;return(0,r.kt)(m,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"react-hooks"},"React Hooks"),(0,r.kt)("p",null,"The React Hooks package exposes useful React hooks that allow you to easily interact with AFJ from a React client application."),(0,r.kt)("p",null,"These hooks provide a simple way to query agent data in a client application, allowing you to focus on the user interface."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"This document is for version ",(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"0.5.x"))," of the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/react-hooks")," package, that works with ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/core")," version ",(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"0.4.x")),". Extension packages (such as React Hooks) are versioned separately from the core packages.")),(0,r.kt)("h2",{id:"installation"},"Installation"),(0,r.kt)("p",null,"To add the React Hooks package to your existing project simply run:"),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{label:"npm",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"npm i @aries-framework/react-hooks@^0.5\n"))),(0,r.kt)(s.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/react-hooks@^0.5\n")))),(0,r.kt)("h2",{id:"usage"},"Usage"),(0,r.kt)("p",null,"This package exposes useful React hooks that allow you to easily interact with AFJ."),(0,r.kt)("p",null,"Everything exported from Hooks:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import AgentProvider, {\n useAgent,\n useConnections,\n useConnectionById,\n useCredentials,\n useCredentialById,\n useCredentialByState,\n useProofs,\n useProofById,\n useProofByState,\n} from '@aries-framework/react-hooks'\n")),(0,r.kt)("p",null,"First step is to wrap your entire app in our ",(0,r.kt)("inlineCode",{parentName:"p"},""),". The provider takes an initialized agent. The base of your app should look something like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-tsx"},"import AgentProvider from '@aries-framework/react-hooks'\n\nconst App = () => {\n const [agent, setAgent] = useState(undefined)\n\n const initializeAgent = async () => {\n const appAgent = new Agent({\n /* agent options */\n })\n await appAgent.initialize()\n setAgent(appAgent)\n }\n\n useEffect(() => {\n initializeAgent()\n }, [])\n\n if (!agent) return \n\n return /* Your app here */\n}\n")),(0,r.kt)("p",null,"And that's it! Your app should be set up to receive all the necessary data your app will need! Now let's see how we actually get that data to our components."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"useAgent")," hook returns ",(0,r.kt)("inlineCode",{parentName:"p"},"{ agent, loading }")," so anytime you need access to any of the methods tied to the agent, you can ",(0,r.kt)("inlineCode",{parentName:"p"},"useAgent()")," anywhere."),(0,r.kt)("p",null,"The following is an example of how you could use the ",(0,r.kt)("inlineCode",{parentName:"p"},"useConnections")," hook to render a full list of all a user's connections."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { useConnections } from '@aries-framework/react-hooks'\n\nconst MyConnectionsComponent = () => {\n // all base hooks return an array of objects and a loading boolean\n const { connections, loading } = useConnections()\n\n return } />\n}\n")),(0,r.kt)("p",null,"The three base hooks: ",(0,r.kt)("inlineCode",{parentName:"p"},"useConnections"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"useCredentials"),", and ",(0,r.kt)("inlineCode",{parentName:"p"},"useProofs")," work just like the above! Just call the hook, destructure the data, and pass it through!"),(0,r.kt)("p",null,"Each base hook has a ",(0,r.kt)("inlineCode",{parentName:"p"},"ById")," version that returns a singular record. For example if I wanted only a specific connectionRecord, I'd do this."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"const connection = useConnectionById(id)\n")),(0,r.kt)("p",null,"More commonly, you'll want to get a filtered list of records based off of their state. Well, Hooray! We have a ",(0,r.kt)("inlineCode",{parentName:"p"},"ByState")," version as well. For example, you can do this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"const credentials = useCredentialByState(CredentialState.OfferReceived)\n")))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[1271],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),u=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=u(e.components);return a.createElement(i.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),p=u(n),m=r,f=p["".concat(i,".").concat(m)]||p[m]||d[m]||o;return n?a.createElement(f,s(s({ref:t},c),{},{components:n})):a.createElement(f,s({ref:t},c))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,s=new Array(o);s[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l[p]="string"==typeof e?e:r,s[1]=l;for(var u=2;u{n.d(t,{Z:()=>s});var a=n(7294),r=n(6010);const o={tabItem:"tabItem_Ymn6"};function s(e){let{children:t,hidden:n,className:s}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(o.tabItem,s),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),r=n(7294),o=n(6010),s=n(2466),l=n(6550),i=n(1980),u=n(7392),c=n(12);function p(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function d(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,u.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:n}=e;const a=(0,l.k6)(),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,i._X)(o),(0,r.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(a.location.search);t.set(o,e),a.replace({...a.location,search:t.toString()})}),[o,a])]}function h(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,o=d(e),[s,l]=(0,r.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(!m({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}))),[i,u]=f({queryString:n,groupId:a}),[p,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,o]=(0,c.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:a}),g=(()=>{const e=i??p;return m({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{g&&l(g)}),[g]);return{selectedValue:s,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);l(e),u(e),h(e)}),[u,h,o]),tabValues:o}}var g=n(2389);const k={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){let{className:t,block:n,selectedValue:l,selectValue:i,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,s.o5)(),d=e=>{const t=e.currentTarget,n=c.indexOf(t),a=u[n].value;a!==l&&(p(t),i(a))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},u.map((e=>{let{value:t,label:n,attributes:s}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:l===t?0:-1,"aria-selected":l===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},s,{className:(0,o.Z)("tabs__item",k.tabItem,s?.className,{"tabs__item--active":l===t})}),n??t)})))}function b(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function v(e){const t=h(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",k.tabList)},r.createElement(y,(0,a.Z)({},e,t)),r.createElement(b,(0,a.Z)({},e,t)))}function w(e){const t=(0,g.Z)();return r.createElement(v,(0,a.Z)({key:String(t)},e))}},1752:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>f,frontMatter:()=>l,metadata:()=>u,toc:()=>p});var a=n(7462),r=(n(7294),n(3905)),o=n(4866),s=n(5162);const l={},i="React Hooks",u={unversionedId:"extensions/react-hooks",id:"extensions/react-hooks",title:"React Hooks",description:"The React Hooks package exposes useful React hooks that allow you to easily interact with Credo from a React client application.",source:"@site/guides/extensions/react-hooks.md",sourceDirName:"extensions",slug:"/extensions/react-hooks",permalink:"/guides/extensions/react-hooks",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"REST API",permalink:"/guides/extensions/rest"},next:{title:"Redux Store",permalink:"/guides/extensions/redux-store"}},c={},p=[{value:"Installation",id:"installation",level:2},{value:"npm",id:"npm",level:2},{value:"Yarn",id:"yarn",level:2},{value:"Usage",id:"usage",level:2}],d={toc:p},m="wrapper";function f(e){let{components:t,...n}=e;return(0,r.kt)(m,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"react-hooks"},"React Hooks"),(0,r.kt)("p",null,"The React Hooks package exposes useful React hooks that allow you to easily interact with Credo from a React client application."),(0,r.kt)("p",null,"These hooks provide a simple way to query agent data in a client application, allowing you to focus on the user interface."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"This document is for version ",(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"0.5.x"))," of the ",(0,r.kt)("inlineCode",{parentName:"p"},"@credo-ts/react-hooks")," package, that works with ",(0,r.kt)("inlineCode",{parentName:"p"},"@credo-ts/core")," version ",(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"0.4.x")),". Extension packages (such as React Hooks) are versioned separately from the core packages.")),(0,r.kt)("h2",{id:"installation"},"Installation"),(0,r.kt)("p",null,"To add the React Hooks package to your existing project simply run:"),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{label:"npm",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"npm i @credo-ts/react-hooks@^0.5\n"))),(0,r.kt)(s.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @credo-ts/react-hooks@^0.5\n")))),(0,r.kt)("h2",{id:"usage"},"Usage"),(0,r.kt)("p",null,"This package exposes useful React hooks that allow you to easily interact with Credo."),(0,r.kt)("p",null,"Everything exported from Hooks:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import AgentProvider, {\n useAgent,\n useConnections,\n useConnectionById,\n useCredentials,\n useCredentialById,\n useCredentialByState,\n useProofs,\n useProofById,\n useProofByState,\n} from '@credo-ts/react-hooks'\n")),(0,r.kt)("p",null,"First step is to wrap your entire app in our ",(0,r.kt)("inlineCode",{parentName:"p"},""),". The provider takes an initialized agent. The base of your app should look something like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-tsx"},"import AgentProvider from '@credo-ts/react-hooks'\n\nconst App = () => {\n const [agent, setAgent] = useState(undefined)\n\n const initializeAgent = async () => {\n const appAgent = new Agent({\n /* agent options */\n })\n await appAgent.initialize()\n setAgent(appAgent)\n }\n\n useEffect(() => {\n initializeAgent()\n }, [])\n\n if (!agent) return \n\n return /* Your app here */\n}\n")),(0,r.kt)("p",null,"And that's it! Your app should be set up to receive all the necessary data your app will need! Now let's see how we actually get that data to our components."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"useAgent")," hook returns ",(0,r.kt)("inlineCode",{parentName:"p"},"{ agent, loading }")," so anytime you need access to any of the methods tied to the agent, you can ",(0,r.kt)("inlineCode",{parentName:"p"},"useAgent()")," anywhere."),(0,r.kt)("p",null,"The following is an example of how you could use the ",(0,r.kt)("inlineCode",{parentName:"p"},"useConnections")," hook to render a full list of all a user's connections."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { useConnections } from '@credo-ts/react-hooks'\n\nconst MyConnectionsComponent = () => {\n // all base hooks return an array of objects and a loading boolean\n const { connections, loading } = useConnections()\n\n return } />\n}\n")),(0,r.kt)("p",null,"The three base hooks: ",(0,r.kt)("inlineCode",{parentName:"p"},"useConnections"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"useCredentials"),", and ",(0,r.kt)("inlineCode",{parentName:"p"},"useProofs")," work just like the above! Just call the hook, destructure the data, and pass it through!"),(0,r.kt)("p",null,"Each base hook has a ",(0,r.kt)("inlineCode",{parentName:"p"},"ById")," version that returns a singular record. For example if I wanted only a specific connectionRecord, I'd do this."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"const connection = useConnectionById(id)\n")),(0,r.kt)("p",null,"More commonly, you'll want to get a filtered list of records based off of their state. Well, Hooray! We have a ",(0,r.kt)("inlineCode",{parentName:"p"},"ByState")," version as well. For example, you can do this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"const credentials = useCredentialByState(CredentialState.OfferReceived)\n")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/7697e6e6.f034b44e.js b/assets/js/7697e6e6.f034b44e.js new file mode 100644 index 00000000..c6366fe2 --- /dev/null +++ b/assets/js/7697e6e6.f034b44e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7867],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>m});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},d=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=c(r),f=a,m=p["".concat(l,".").concat(f)]||p[f]||u[f]||i;return r?n.createElement(m,o(o({ref:t},d),{},{components:r})):n.createElement(m,o({ref:t},d))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=f;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:a,o[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var n=r(7462),a=(r(7294),r(3905));const i={},o="Verifiable Credentials",s={unversionedId:"features/credentials",id:"features/credentials",title:"Verifiable Credentials",description:"One of the main features of Credo is the issuance and verification of Verifiable Credentials.",source:"@site/guides/features/credentials.md",sourceDirName:"features",slug:"/features/credentials",permalink:"/guides/features/credentials",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Decentralized Identifiers",permalink:"/guides/features/dids"},next:{title:"Tutorials",permalink:"/guides/tutorials/"}},l={},c=[{value:"W3C Verifiable Credentials",id:"w3c-verifiable-credentials",level:2},{value:"SD-JWT VC",id:"sd-jwt-vc",level:2},{value:"AnonCreds",id:"anoncreds",level:2}],d={toc:c},p="wrapper";function u(e){let{components:t,...r}=e;return(0,a.kt)(p,(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"verifiable-credentials"},"Verifiable Credentials"),(0,a.kt)("p",null,"One of the main features of Credo is the issuance and verification of Verifiable Credentials."),(0,a.kt)("h2",{id:"w3c-verifiable-credentials"},"W3C Verifiable Credentials"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://www.w3.org/TR/vc-data-model/"},"W3C Verifiable Credentials")," are probably the most widely known credential format, and defined the World Wide Web Consortium (W3C)."),(0,a.kt)("p",null,"Credo currently supports the issuance and verification of W3C Verifiable Credentials according to the ",(0,a.kt)("strong",{parentName:"p"},"Data Model v1.1"),", and support both the ",(0,a.kt)("strong",{parentName:"p"},"Linked Data Proof")," and ",(0,a.kt)("strong",{parentName:"p"},"Json Web Token (JWT)")," proof formats."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Issuance of W3C JWT credentials is not supported over DIDComm"),", while verification ",(0,a.kt)("strong",{parentName:"p"},"is supported")),(0,a.kt)("h2",{id:"sd-jwt-vc"},"SD-JWT VC"),(0,a.kt)("p",null,"Selective Disclosure JWT Verifiable Credentials are a special type of JWT Verifiable Credentials, that allow for selective disclosure of the claims in the credential."),(0,a.kt)("p",null,"Credo currently supports ",(0,a.kt)("a",{parentName:"p",href:"https://www.ietf.org/archive/id/draft-ietf-oauth-sd-jwt-vc-01.html"},"SD-JWT-based Verifiable Credentials (SD-JWT VC) - Draft 01"),"."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Issuance of SD-JWT credentials is not supported over DIDComm"),", while verification ",(0,a.kt)("strong",{parentName:"p"},"is supported"),"."),(0,a.kt)("h2",{id:"anoncreds"},"AnonCreds"),(0,a.kt)("p",null,"Credo supports the issuance and verification of ",(0,a.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-spec/"},"AnonCreds")," credentials. AnonCreds credentials are a bit 'heavier' to implement and support than other credential formats, but allow for the best unlinkability."),(0,a.kt)("p",null,"Issuance and verification of AnonCreds credentials is ",(0,a.kt)("strong",{parentName:"p"},"only available over DIDComm"),"."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/7697e6e6.ff268635.js b/assets/js/7697e6e6.ff268635.js deleted file mode 100644 index ebcf22ab..00000000 --- a/assets/js/7697e6e6.ff268635.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7867],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>m});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},d=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=c(r),f=a,m=p["".concat(l,".").concat(f)]||p[f]||u[f]||i;return r?n.createElement(m,o(o({ref:t},d),{},{components:r})):n.createElement(m,o({ref:t},d))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=f;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:a,o[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var n=r(7462),a=(r(7294),r(3905));const i={},o="Verifiable Credentials",s={unversionedId:"features/credentials",id:"features/credentials",title:"Verifiable Credentials",description:"One of the main features of Credo is the issuance and verification of Verifiable Credentials.",source:"@site/guides/features/credentials.md",sourceDirName:"features",slug:"/features/credentials",permalink:"/guides/0.5/features/credentials",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Decentralized Identifiers",permalink:"/guides/0.5/features/dids"},next:{title:"Tutorials",permalink:"/guides/0.5/tutorials/"}},l={},c=[{value:"W3C Verifiable Credentials",id:"w3c-verifiable-credentials",level:2},{value:"SD-JWT VC",id:"sd-jwt-vc",level:2},{value:"AnonCreds",id:"anoncreds",level:2}],d={toc:c},p="wrapper";function u(e){let{components:t,...r}=e;return(0,a.kt)(p,(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"verifiable-credentials"},"Verifiable Credentials"),(0,a.kt)("p",null,"One of the main features of Credo is the issuance and verification of Verifiable Credentials."),(0,a.kt)("h2",{id:"w3c-verifiable-credentials"},"W3C Verifiable Credentials"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://www.w3.org/TR/vc-data-model/"},"W3C Verifiable Credentials")," are probably the most widely known credential format, and defined the World Wide Web Consortium (W3C)."),(0,a.kt)("p",null,"Credo currently supports the issuance and verification of W3C Verifiable Credentials according to the ",(0,a.kt)("strong",{parentName:"p"},"Data Model v1.1"),", and support both the ",(0,a.kt)("strong",{parentName:"p"},"Linked Data Proof")," and ",(0,a.kt)("strong",{parentName:"p"},"Json Web Token (JWT)")," proof formats."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Issuance of W3C JWT credentials is not supported over DIDComm"),", while verification ",(0,a.kt)("strong",{parentName:"p"},"is supported")),(0,a.kt)("h2",{id:"sd-jwt-vc"},"SD-JWT VC"),(0,a.kt)("p",null,"Selective Disclosure JWT Verifiable Credentials are a special type of JWT Verifiable Credentials, that allow for selective disclosure of the claims in the credential."),(0,a.kt)("p",null,"Credo currently supports ",(0,a.kt)("a",{parentName:"p",href:"https://www.ietf.org/archive/id/draft-ietf-oauth-sd-jwt-vc-01.html"},"SD-JWT-based Verifiable Credentials (SD-JWT VC) - Draft 01"),"."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Issuance of SD-JWT credentials is not supported over DIDComm"),", while verification ",(0,a.kt)("strong",{parentName:"p"},"is supported"),"."),(0,a.kt)("h2",{id:"anoncreds"},"AnonCreds"),(0,a.kt)("p",null,"Credo supports the issuance and verification of ",(0,a.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-spec/"},"AnonCreds")," credentials. AnonCreds credentials are a bit 'heavier' to implement and support than other credential formats, but allow for the best unlinkability."),(0,a.kt)("p",null,"Issuance and verification of AnonCreds credentials is ",(0,a.kt)("strong",{parentName:"p"},"only available over DIDComm"),"."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/76f8726c.3f42a1d2.js b/assets/js/76f8726c.3f42a1d2.js deleted file mode 100644 index 0917d445..00000000 --- a/assets/js/76f8726c.3f42a1d2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8440],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>h});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var d=i.createContext({}),p=function(e){var t=i.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},s=function(e){var t=p(e.components);return i.createElement(d.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},m=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,d=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),c=p(n),m=a,h=c["".concat(d,".").concat(m)]||c[m]||u[m]||r;return n?i.createElement(h,o(o({ref:t},s),{},{components:n})):i.createElement(h,o({ref:t},s))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,o=new Array(r);o[0]=m;var l={};for(var d in t)hasOwnProperty.call(t,d)&&(l[d]=t[d]);l.originalType=e,l[c]="string"==typeof e?e:a,o[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var i=n(7462),a=(n(7294),n(3905));const r={},o="Cheqd Did Module",l={unversionedId:"tutorials/cheqd/index",id:"tutorials/cheqd/index",title:"Cheqd Did Module",description:"In this tutorial we will see how to use the cheqd modules in detail",source:"@site/guides/tutorials/cheqd/index.md",sourceDirName:"tutorials/cheqd",slug:"/tutorials/cheqd/",permalink:"/guides/0.5/tutorials/cheqd/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Create a connection",permalink:"/guides/0.5/tutorials/create-a-connection"},next:{title:"Registering a schema and credential definition on an AnonCreds Registry",permalink:"/guides/0.5/tutorials/registering-schema-and-credential-definition"}},d={},p=[{value:"DID Module",id:"did-module",level:2},{value:"Create DID",id:"create-did",level:3},{value:"Parameters",id:"parameters",level:4},{value:"Option 1",id:"option-1",level:5},{value:"Option 2",id:"option-2",level:5},{value:"Update DID",id:"update-did",level:3},{value:"Parameters",id:"parameters-1",level:4},{value:"Deactivate DID",id:"deactivate-did",level:3},{value:"Parameters",id:"parameters-2",level:4},{value:"Types",id:"types",level:3},{value:"secret.verificationMethod",id:"secretverificationmethod",level:4},{value:"verificationMethod.id*",id:"verificationmethodid",level:5},{value:"verificationMethod.type*",id:"verificationmethodtype",level:5},{value:"verificationMethod.privateKey",id:"verificationmethodprivatekey",level:5},{value:"options.methodSpecificIdAlgo",id:"optionsmethodspecificidalgo",level:4},{value:"options.network*",id:"optionsnetwork",level:4},{value:"options.versionId",id:"optionsversionid",level:4}],s={toc:p},c="wrapper";function u(e){let{components:t,...n}=e;return(0,a.kt)(c,(0,i.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"cheqd-did-module"},"Cheqd Did Module"),(0,a.kt)("p",null,"In this tutorial we will see how to use the cheqd modules in detail"),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"This section assumes that"),(0,a.kt)("ol",{parentName:"admonition"},(0,a.kt)("li",{parentName:"ol"},"You have ",(0,a.kt)("a",{parentName:"li",href:"../../getting-started"},"set-up your develoment environment"),"."),(0,a.kt)("li",{parentName:"ol"},"You have setup the cheqd module ",(0,a.kt)("a",{parentName:"li",href:"/guides/0.5/getting-started/set-up/cheqd/"},"setup cheqd")))),(0,a.kt)("h2",{id:"did-module"},"DID Module"),(0,a.kt)("p",null,'The cheqd DID module facilitates the Create, Read, Update, and Delete (CRUD) operations for did:cheqd identifiers. To learn more about "did:cheqd," please refer to the ',(0,a.kt)("a",{parentName:"p",href:"https://github.com/cheqd/identity-docs/blob/main/architecture/adr-list/adr-001-cheqd-did-method.md"},"specification")),(0,a.kt)("h3",{id:"create-did"},"Create DID"),(0,a.kt)("p",null,"The DID can be created in two different ways"),(0,a.kt)("h4",{id:"parameters"},"Parameters"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"method"),"*",": ",(0,a.kt)("inlineCode",{parentName:"li"},"cheqd")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"secret")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"options"),"*"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"didDocument"))),(0,a.kt)("h5",{id:"option-1"},"Option 1"),(0,a.kt)("p",null,"Provide a DID Document payload according to the w3c did core specification in the request body. This is possible when the keys corresponding to the verification methods provided in the DID Document are already created in the wallet"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-cheqd.ts section-2",showLineNumbers:!0,"set-up-cheqd.ts":!0,"section-2":!0},"")),(0,a.kt)("h5",{id:"option-2"},"Option 2"),(0,a.kt)("p",null,"If a DID Document is not passed to the registrar, it requires the secret parameter with a verificationMethod to construct the DID Document."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-cheqd.ts section-3",showLineNumbers:!0,"set-up-cheqd.ts":!0,"section-3":!0},"")),(0,a.kt)("h3",{id:"update-did"},"Update DID"),(0,a.kt)("p",null,"To update a DID Document, fetch the body of the DID Document you want to change from the DID Resolver, make the relevant updates and pass it as the parameter"),(0,a.kt)("h4",{id:"parameters-1"},"Parameters"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"did"),"*"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"didDocument"),"*",": The updated DID Document"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"options")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"secret"))),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-cheqd.ts section-4",showLineNumbers:!0,"set-up-cheqd.ts":!0,"section-4":!0},"")),(0,a.kt)("h3",{id:"deactivate-did"},"Deactivate DID"),(0,a.kt)("p",null,"A DID can be deactivated, it can still be resolved"),(0,a.kt)("h4",{id:"parameters-2"},"Parameters"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"did"),"*"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"options"))),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-cheqd.ts section-5",showLineNumbers:!0,"set-up-cheqd.ts":!0,"section-5":!0},"")),(0,a.kt)("h3",{id:"types"},"Types"),(0,a.kt)("hr",null),(0,a.kt)("h4",{id:"secretverificationmethod"},(0,a.kt)("inlineCode",{parentName:"h4"},"secret.verificationMethod")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"verificationMethod")),(0,a.kt)("h5",{id:"verificationmethodid"},(0,a.kt)("inlineCode",{parentName:"h5"},"verificationMethod.id"),"*"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("h5",{id:"verificationmethodtype"},(0,a.kt)("inlineCode",{parentName:"h5"},"verificationMethod.type"),"*"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Default"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"Ed25519VerificationKey2020")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Members"),":"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"Ed25519VerificationKey2020")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"Ed25519VerificationKey2018")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"JsonWebKey2020"))),(0,a.kt)("h5",{id:"verificationmethodprivatekey"},(0,a.kt)("inlineCode",{parentName:"h5"},"verificationMethod.privateKey")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("hr",null),(0,a.kt)("h4",{id:"optionsmethodspecificidalgo"},(0,a.kt)("inlineCode",{parentName:"h4"},"options.methodSpecificIdAlgo")),(0,a.kt)("p",null,"Specifies what type of method specific identifier is needed for your DID"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Default"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"uuid")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Members"),":"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"uuid")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"base58btc"))),(0,a.kt)("hr",null),(0,a.kt)("h4",{id:"optionsnetwork"},(0,a.kt)("inlineCode",{parentName:"h4"},"options.network"),"*"),(0,a.kt)("p",null,"Specifies the cheqd network name to be published"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Default"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"testnet")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Members"),":"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"testnet")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"mainnet"))),(0,a.kt)("hr",null),(0,a.kt)("h4",{id:"optionsversionid"},(0,a.kt)("inlineCode",{parentName:"h4"},"options.versionId")),(0,a.kt)("p",null,"Specifies the version of the DID Document to be published"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/76f8726c.b857ad29.js b/assets/js/76f8726c.b857ad29.js new file mode 100644 index 00000000..96e7a407 --- /dev/null +++ b/assets/js/76f8726c.b857ad29.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8440],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>h});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var d=i.createContext({}),p=function(e){var t=i.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},s=function(e){var t=p(e.components);return i.createElement(d.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},m=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,d=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),c=p(n),m=a,h=c["".concat(d,".").concat(m)]||c[m]||u[m]||r;return n?i.createElement(h,o(o({ref:t},s),{},{components:n})):i.createElement(h,o({ref:t},s))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,o=new Array(r);o[0]=m;var l={};for(var d in t)hasOwnProperty.call(t,d)&&(l[d]=t[d]);l.originalType=e,l[c]="string"==typeof e?e:a,o[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var i=n(7462),a=(n(7294),n(3905));const r={},o="Cheqd Did Module",l={unversionedId:"tutorials/cheqd/index",id:"tutorials/cheqd/index",title:"Cheqd Did Module",description:"In this tutorial we will see how to use the cheqd modules in detail",source:"@site/guides/tutorials/cheqd/index.md",sourceDirName:"tutorials/cheqd",slug:"/tutorials/cheqd/",permalink:"/guides/tutorials/cheqd/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Create a connection",permalink:"/guides/tutorials/create-a-connection"},next:{title:"Registering a schema and credential definition on an AnonCreds Registry",permalink:"/guides/tutorials/registering-schema-and-credential-definition"}},d={},p=[{value:"DID Module",id:"did-module",level:2},{value:"Create DID",id:"create-did",level:3},{value:"Parameters",id:"parameters",level:4},{value:"Option 1",id:"option-1",level:5},{value:"Option 2",id:"option-2",level:5},{value:"Update DID",id:"update-did",level:3},{value:"Parameters",id:"parameters-1",level:4},{value:"Deactivate DID",id:"deactivate-did",level:3},{value:"Parameters",id:"parameters-2",level:4},{value:"Types",id:"types",level:3},{value:"secret.verificationMethod",id:"secretverificationmethod",level:4},{value:"verificationMethod.id*",id:"verificationmethodid",level:5},{value:"verificationMethod.type*",id:"verificationmethodtype",level:5},{value:"verificationMethod.privateKey",id:"verificationmethodprivatekey",level:5},{value:"options.methodSpecificIdAlgo",id:"optionsmethodspecificidalgo",level:4},{value:"options.network*",id:"optionsnetwork",level:4},{value:"options.versionId",id:"optionsversionid",level:4}],s={toc:p},c="wrapper";function u(e){let{components:t,...n}=e;return(0,a.kt)(c,(0,i.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"cheqd-did-module"},"Cheqd Did Module"),(0,a.kt)("p",null,"In this tutorial we will see how to use the cheqd modules in detail"),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"This section assumes that"),(0,a.kt)("ol",{parentName:"admonition"},(0,a.kt)("li",{parentName:"ol"},"You have ",(0,a.kt)("a",{parentName:"li",href:"../../getting-started"},"set-up your develoment environment"),"."),(0,a.kt)("li",{parentName:"ol"},"You have setup the cheqd module ",(0,a.kt)("a",{parentName:"li",href:"/guides/getting-started/set-up/cheqd/"},"setup cheqd")))),(0,a.kt)("h2",{id:"did-module"},"DID Module"),(0,a.kt)("p",null,'The cheqd DID module facilitates the Create, Read, Update, and Delete (CRUD) operations for did:cheqd identifiers. To learn more about "did:cheqd," please refer to the ',(0,a.kt)("a",{parentName:"p",href:"https://github.com/cheqd/identity-docs/blob/main/architecture/adr-list/adr-001-cheqd-did-method.md"},"specification")),(0,a.kt)("h3",{id:"create-did"},"Create DID"),(0,a.kt)("p",null,"The DID can be created in two different ways"),(0,a.kt)("h4",{id:"parameters"},"Parameters"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"method"),"*",": ",(0,a.kt)("inlineCode",{parentName:"li"},"cheqd")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"secret")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"options"),"*"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"didDocument"))),(0,a.kt)("h5",{id:"option-1"},"Option 1"),(0,a.kt)("p",null,"Provide a DID Document payload according to the w3c did core specification in the request body. This is possible when the keys corresponding to the verification methods provided in the DID Document are already created in the wallet"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-cheqd.ts section-2",showLineNumbers:!0,"set-up-cheqd.ts":!0,"section-2":!0},"")),(0,a.kt)("h5",{id:"option-2"},"Option 2"),(0,a.kt)("p",null,"If a DID Document is not passed to the registrar, it requires the secret parameter with a verificationMethod to construct the DID Document."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-cheqd.ts section-3",showLineNumbers:!0,"set-up-cheqd.ts":!0,"section-3":!0},"")),(0,a.kt)("h3",{id:"update-did"},"Update DID"),(0,a.kt)("p",null,"To update a DID Document, fetch the body of the DID Document you want to change from the DID Resolver, make the relevant updates and pass it as the parameter"),(0,a.kt)("h4",{id:"parameters-1"},"Parameters"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"did"),"*"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"didDocument"),"*",": The updated DID Document"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"options")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"secret"))),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-cheqd.ts section-4",showLineNumbers:!0,"set-up-cheqd.ts":!0,"section-4":!0},"")),(0,a.kt)("h3",{id:"deactivate-did"},"Deactivate DID"),(0,a.kt)("p",null,"A DID can be deactivated, it can still be resolved"),(0,a.kt)("h4",{id:"parameters-2"},"Parameters"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"did"),"*"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"options"))),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-cheqd.ts section-5",showLineNumbers:!0,"set-up-cheqd.ts":!0,"section-5":!0},"")),(0,a.kt)("h3",{id:"types"},"Types"),(0,a.kt)("hr",null),(0,a.kt)("h4",{id:"secretverificationmethod"},(0,a.kt)("inlineCode",{parentName:"h4"},"secret.verificationMethod")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"verificationMethod")),(0,a.kt)("h5",{id:"verificationmethodid"},(0,a.kt)("inlineCode",{parentName:"h5"},"verificationMethod.id"),"*"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("h5",{id:"verificationmethodtype"},(0,a.kt)("inlineCode",{parentName:"h5"},"verificationMethod.type"),"*"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Default"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"Ed25519VerificationKey2020")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Members"),":"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"Ed25519VerificationKey2020")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"Ed25519VerificationKey2018")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"JsonWebKey2020"))),(0,a.kt)("h5",{id:"verificationmethodprivatekey"},(0,a.kt)("inlineCode",{parentName:"h5"},"verificationMethod.privateKey")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("hr",null),(0,a.kt)("h4",{id:"optionsmethodspecificidalgo"},(0,a.kt)("inlineCode",{parentName:"h4"},"options.methodSpecificIdAlgo")),(0,a.kt)("p",null,"Specifies what type of method specific identifier is needed for your DID"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Default"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"uuid")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Members"),":"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"uuid")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"base58btc"))),(0,a.kt)("hr",null),(0,a.kt)("h4",{id:"optionsnetwork"},(0,a.kt)("inlineCode",{parentName:"h4"},"options.network"),"*"),(0,a.kt)("p",null,"Specifies the cheqd network name to be published"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Default"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"testnet")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Members"),":"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"testnet")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"mainnet"))),(0,a.kt)("hr",null),(0,a.kt)("h4",{id:"optionsversionid"},(0,a.kt)("inlineCode",{parentName:"h4"},"options.versionId")),(0,a.kt)("p",null,"Specifies the version of the DID Document to be published"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Type"),": ",(0,a.kt)("inlineCode",{parentName:"p"},"string")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/7852f2cc.01b0177d.js b/assets/js/7852f2cc.01b0177d.js deleted file mode 100644 index ef93e2c5..00000000 --- a/assets/js/7852f2cc.01b0177d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[9910],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var r=n(7294);function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},d=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},c=r.forwardRef((function(e,t){var n=e.components,s=e.mdxType,i=e.originalType,l=e.parentName,d=a(e,["components","mdxType","originalType","parentName"]),u=p(n),c=s,m=u["".concat(l,".").concat(c)]||u[c]||g[c]||i;return n?r.createElement(m,o(o({ref:t},d),{},{components:n})):r.createElement(m,o({ref:t},d))}));function m(e,t){var n=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var i=n.length,o=new Array(i);o[0]=c;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a[u]="string"==typeof e?e:s,o[1]=a;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>g,frontMatter:()=>i,metadata:()=>a,toc:()=>p});var r=n(7462),s=(n(7294),n(3905));const i={},o="Postgres Setup for macOS",a={unversionedId:"tutorials/indy-sdk-postgres-database-nodejs/macos",id:"version-0.4/tutorials/indy-sdk-postgres-database-nodejs/macos",title:"Postgres Setup for macOS",description:"Prerequisites",source:"@site/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/macos.md",sourceDirName:"tutorials/indy-sdk-postgres-database-nodejs",slug:"/tutorials/indy-sdk-postgres-database-nodejs/macos",permalink:"/guides/tutorials/indy-sdk-postgres-database-nodejs/macos",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Postgres Setup for Linux",permalink:"/guides/tutorials/indy-sdk-postgres-database-nodejs/linux"},next:{title:"Postgres Setup for windows",permalink:"/guides/tutorials/indy-sdk-postgres-database-nodejs/windows"}},l={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Step 1: installing the dependencies using brew",id:"step-1-installing-the-dependencies-using-brew",level:2},{value:"Step 2: Build Postgres plugin",id:"step-2-build-postgres-plugin",level:2},{value:"Step 2.1: Cloning the indy-sdk",id:"step-21-cloning-the-indy-sdk",level:3},{value:"Step 2.2: Building Postgres plugin",id:"step-22-building-postgres-plugin",level:3},{value:"Step 2.3: Moving the file",id:"step-23-moving-the-file",level:3}],d={toc:p},u="wrapper";function g(e){let{components:t,...n}=e;return(0,s.kt)(u,(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"postgres-setup-for-macos"},"Postgres Setup for macOS"),(0,s.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},"Homebrew"),(0,s.kt)("li",{parentName:"ul"},"Cargo (We have to build Postgres plugin from source)"),(0,s.kt)("li",{parentName:"ul"},"git (to clone a repo, could also be done with downloading the zip from the GitHub page)")),(0,s.kt)("h2",{id:"step-1-installing-the-dependencies-using-brew"},"Step 1: installing the dependencies using brew"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"brew install libsodium zeromq\n")),(0,s.kt)("h2",{id:"step-2-build-postgres-plugin"},"Step 2: Build Postgres plugin"),(0,s.kt)("p",null,"Building Postgres plugin from the indy-sdk repo with cargo."),(0,s.kt)("h3",{id:"step-21-cloning-the-indy-sdk"},"Step 2.1: Cloning the indy-sdk"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"git clone https://github.com/hyperledger/indy-sdk.git\n\ncd indy-sdk/experimental/plugins/postgres_storage\n")),(0,s.kt)("h3",{id:"step-22-building-postgres-plugin"},"Step 2.2: Building Postgres plugin"),(0,s.kt)("p",null,"If this step throws any errors, it might be because you miss some packages. Step 1 of this guide provided the dependencies that are required, but it also assumed that you have some basic development packages installed. If you are missing some packages, you can install them with your package manager."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"pwd\n\n# OUTPUT: .../indy-sdk/experimental/plugins/postgres_storage\n\ncargo build --release\n")),(0,s.kt)("h3",{id:"step-23-moving-the-file"},"Step 2.3: Moving the file"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"pwd\n\n# OUTPUT: .../indy-sdk/experimental/plugins/postgres_storage\n\nsudo mv ./target/release/libindystrgpostgres.dylib /usr/local/lib/libindystrgpostgres.dylib\n")))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/7852f2cc.58d6c026.js b/assets/js/7852f2cc.58d6c026.js new file mode 100644 index 00000000..6f068167 --- /dev/null +++ b/assets/js/7852f2cc.58d6c026.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[9910],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var r=n(7294);function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},d=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},c=r.forwardRef((function(e,t){var n=e.components,s=e.mdxType,i=e.originalType,l=e.parentName,d=a(e,["components","mdxType","originalType","parentName"]),u=p(n),c=s,m=u["".concat(l,".").concat(c)]||u[c]||g[c]||i;return n?r.createElement(m,o(o({ref:t},d),{},{components:n})):r.createElement(m,o({ref:t},d))}));function m(e,t){var n=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var i=n.length,o=new Array(i);o[0]=c;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a[u]="string"==typeof e?e:s,o[1]=a;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>g,frontMatter:()=>i,metadata:()=>a,toc:()=>p});var r=n(7462),s=(n(7294),n(3905));const i={},o="Postgres Setup for macOS",a={unversionedId:"tutorials/indy-sdk-postgres-database-nodejs/macos",id:"version-0.4/tutorials/indy-sdk-postgres-database-nodejs/macos",title:"Postgres Setup for macOS",description:"Prerequisites",source:"@site/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/macos.md",sourceDirName:"tutorials/indy-sdk-postgres-database-nodejs",slug:"/tutorials/indy-sdk-postgres-database-nodejs/macos",permalink:"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/macos",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Postgres Setup for Linux",permalink:"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/linux"},next:{title:"Postgres Setup for windows",permalink:"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/windows"}},l={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Step 1: installing the dependencies using brew",id:"step-1-installing-the-dependencies-using-brew",level:2},{value:"Step 2: Build Postgres plugin",id:"step-2-build-postgres-plugin",level:2},{value:"Step 2.1: Cloning the indy-sdk",id:"step-21-cloning-the-indy-sdk",level:3},{value:"Step 2.2: Building Postgres plugin",id:"step-22-building-postgres-plugin",level:3},{value:"Step 2.3: Moving the file",id:"step-23-moving-the-file",level:3}],d={toc:p},u="wrapper";function g(e){let{components:t,...n}=e;return(0,s.kt)(u,(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"postgres-setup-for-macos"},"Postgres Setup for macOS"),(0,s.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},"Homebrew"),(0,s.kt)("li",{parentName:"ul"},"Cargo (We have to build Postgres plugin from source)"),(0,s.kt)("li",{parentName:"ul"},"git (to clone a repo, could also be done with downloading the zip from the GitHub page)")),(0,s.kt)("h2",{id:"step-1-installing-the-dependencies-using-brew"},"Step 1: installing the dependencies using brew"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"brew install libsodium zeromq\n")),(0,s.kt)("h2",{id:"step-2-build-postgres-plugin"},"Step 2: Build Postgres plugin"),(0,s.kt)("p",null,"Building Postgres plugin from the indy-sdk repo with cargo."),(0,s.kt)("h3",{id:"step-21-cloning-the-indy-sdk"},"Step 2.1: Cloning the indy-sdk"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"git clone https://github.com/hyperledger/indy-sdk.git\n\ncd indy-sdk/experimental/plugins/postgres_storage\n")),(0,s.kt)("h3",{id:"step-22-building-postgres-plugin"},"Step 2.2: Building Postgres plugin"),(0,s.kt)("p",null,"If this step throws any errors, it might be because you miss some packages. Step 1 of this guide provided the dependencies that are required, but it also assumed that you have some basic development packages installed. If you are missing some packages, you can install them with your package manager."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"pwd\n\n# OUTPUT: .../indy-sdk/experimental/plugins/postgres_storage\n\ncargo build --release\n")),(0,s.kt)("h3",{id:"step-23-moving-the-file"},"Step 2.3: Moving the file"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"pwd\n\n# OUTPUT: .../indy-sdk/experimental/plugins/postgres_storage\n\nsudo mv ./target/release/libindystrgpostgres.dylib /usr/local/lib/libindystrgpostgres.dylib\n")))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/7d0a541a.9d9520e5.js b/assets/js/7d0a541a.984a2442.js similarity index 85% rename from assets/js/7d0a541a.9d9520e5.js rename to assets/js/7d0a541a.984a2442.js index 273ec880..87cde197 100644 --- a/assets/js/7d0a541a.9d9520e5.js +++ b/assets/js/7d0a541a.984a2442.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[397],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);function c(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(c[n]=e[n]);return c}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(c[n]=e[n])}return c}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,c=e.mdxType,i=e.originalType,s=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),u=l(n),m=c,f=u["".concat(s,".").concat(m)]||u[m]||d[m]||i;return n?r.createElement(f,o(o({ref:t},p),{},{components:n})):r.createElement(f,o({ref:t},p))}));function f(e,t){var n=arguments,c=t&&t.mdxType;if("string"==typeof e||c){var i=n.length,o=new Array(i);o[0]=m;var a={};for(var s in t)hasOwnProperty.call(t,s)&&(a[s]=t[s]);a.originalType=e,a[u]="string"==typeof e?e:c,o[1]=a;for(var l=2;l{n.d(t,{Z:()=>h});var r=n(7294),c=n(6010),i=n(3438),o=n(9960),a=n(3919),s=n(5999);const l={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function p(e){let{href:t,children:n}=e;return r.createElement(o.Z,{href:t,className:(0,c.Z)("card padding--lg",l.cardContainer)},n)}function u(e){let{href:t,icon:n,title:i,description:o}=e;return r.createElement(p,{href:t},r.createElement("h2",{className:(0,c.Z)("text--truncate",l.cardTitle),title:i},n," ",i),o&&r.createElement("p",{className:(0,c.Z)("text--truncate",l.cardDescription),title:o},o))}function d(e){let{item:t}=e;const n=(0,i.Wl)(t);return n?r.createElement(u,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,s.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function m(e){let{item:t}=e;const n=(0,a.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",c=(0,i.xz)(t.docId??void 0);return r.createElement(u,{href:t.href,icon:n,title:t.label,description:c?.description})}function f(e){let{item:t}=e;switch(t.type){case"link":return r.createElement(m,{item:t});case"category":return r.createElement(d,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function y(e){let{className:t}=e;const n=(0,i.jA)();return r.createElement(h,{items:n.items,className:t})}function h(e){const{items:t,className:n}=e;if(!t)return r.createElement(y,e);const o=(0,i.MN)(t);return r.createElement("section",{className:(0,c.Z)("row",n)},o.map(((e,t)=>r.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},r.createElement(f,{item:e})))))}},4689:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=n(7462),c=(n(7294),n(3905)),i=n(2991);const o={},a="Concepts",s={unversionedId:"concepts/index",id:"version-0.4/concepts/index",title:"Concepts",description:"In this section we will discuss the general concepts that are used inside the",source:"@site/versioned_docs/version-0.4/concepts/index.md",sourceDirName:"concepts",slug:"/concepts/",permalink:"/guides/concepts/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"cheqd",permalink:"/guides/getting-started/set-up/cheqd/"},next:{title:"Agents",permalink:"/guides/concepts/agents"}},l={},p=[],u={toc:p},d="wrapper";function m(e){let{components:t,...n}=e;return(0,c.kt)(d,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,c.kt)("h1",{id:"concepts"},"Concepts"),(0,c.kt)("p",null,"In this section we will discuss the general concepts that are used inside the\naries-javascript ecosystem. These concepts will help you understand the basics\non a high level."),(0,c.kt)(i.Z,{mdxType:"DocCardList"}))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[397],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);function c(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(c[n]=e[n]);return c}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(c[n]=e[n])}return c}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,c=e.mdxType,i=e.originalType,s=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),u=l(n),m=c,f=u["".concat(s,".").concat(m)]||u[m]||d[m]||i;return n?r.createElement(f,o(o({ref:t},p),{},{components:n})):r.createElement(f,o({ref:t},p))}));function f(e,t){var n=arguments,c=t&&t.mdxType;if("string"==typeof e||c){var i=n.length,o=new Array(i);o[0]=m;var a={};for(var s in t)hasOwnProperty.call(t,s)&&(a[s]=t[s]);a.originalType=e,a[u]="string"==typeof e?e:c,o[1]=a;for(var l=2;l{n.d(t,{Z:()=>h});var r=n(7294),c=n(6010),i=n(3438),o=n(9960),a=n(3919),s=n(5999);const l={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function p(e){let{href:t,children:n}=e;return r.createElement(o.Z,{href:t,className:(0,c.Z)("card padding--lg",l.cardContainer)},n)}function u(e){let{href:t,icon:n,title:i,description:o}=e;return r.createElement(p,{href:t},r.createElement("h2",{className:(0,c.Z)("text--truncate",l.cardTitle),title:i},n," ",i),o&&r.createElement("p",{className:(0,c.Z)("text--truncate",l.cardDescription),title:o},o))}function d(e){let{item:t}=e;const n=(0,i.Wl)(t);return n?r.createElement(u,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,s.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function m(e){let{item:t}=e;const n=(0,a.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",c=(0,i.xz)(t.docId??void 0);return r.createElement(u,{href:t.href,icon:n,title:t.label,description:c?.description})}function f(e){let{item:t}=e;switch(t.type){case"link":return r.createElement(m,{item:t});case"category":return r.createElement(d,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function y(e){let{className:t}=e;const n=(0,i.jA)();return r.createElement(h,{items:n.items,className:t})}function h(e){const{items:t,className:n}=e;if(!t)return r.createElement(y,e);const o=(0,i.MN)(t);return r.createElement("section",{className:(0,c.Z)("row",n)},o.map(((e,t)=>r.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},r.createElement(f,{item:e})))))}},4689:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=n(7462),c=(n(7294),n(3905)),i=n(2991);const o={},a="Concepts",s={unversionedId:"concepts/index",id:"version-0.4/concepts/index",title:"Concepts",description:"In this section we will discuss the general concepts that are used inside the",source:"@site/versioned_docs/version-0.4/concepts/index.md",sourceDirName:"concepts",slug:"/concepts/",permalink:"/guides/0.4/concepts/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"cheqd",permalink:"/guides/0.4/getting-started/set-up/cheqd/"},next:{title:"Agents",permalink:"/guides/0.4/concepts/agents"}},l={},p=[],u={toc:p},d="wrapper";function m(e){let{components:t,...n}=e;return(0,c.kt)(d,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,c.kt)("h1",{id:"concepts"},"Concepts"),(0,c.kt)("p",null,"In this section we will discuss the general concepts that are used inside the\naries-javascript ecosystem. These concepts will help you understand the basics\non a high level."),(0,c.kt)(i.Z,{mdxType:"DocCardList"}))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/862058fd.3ae6be20.js b/assets/js/862058fd.3ae6be20.js deleted file mode 100644 index eafa9140..00000000 --- a/assets/js/862058fd.3ae6be20.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8709],{3905:(e,t,a)=>{a.d(t,{Zo:()=>u,kt:()=>h});var i=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,i)}return a}function r(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var l=i.createContext({}),d=function(e){var t=i.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):r(r({},t),e)),a},u=function(e){var t=d(e.components);return i.createElement(l.Provider,{value:t},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},c=i.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=d(a),c=n,h=p["".concat(l,".").concat(c)]||p[c]||m[c]||o;return a?i.createElement(h,r(r({ref:t},u),{},{components:a})):i.createElement(h,r({ref:t},u))}));function h(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,r=new Array(o);r[0]=c;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:n,r[1]=s;for(var d=2;d{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var i=a(7462),n=(a(7294),a(3905));const o={},r="Mediation",s={unversionedId:"tutorials/mediation",id:"version-0.4/tutorials/mediation",title:"Mediation",description:"This section assumes that you have:",source:"@site/versioned_docs/version-0.4/tutorials/mediation.md",sourceDirName:"tutorials",slug:"/tutorials/mediation",permalink:"/guides/tutorials/mediation",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Issue a credential",permalink:"/guides/tutorials/issue-a-credential"},next:{title:"Using PostgreSQL as Database for Indy SDK in Node.js",permalink:"/guides/tutorials/indy-sdk-postgres-database-nodejs/"}},l={},d=[{value:"What is a mediator, and Why should I use one?",id:"what-is-a-mediator-and-why-should-i-use-one",level:3},{value:"1. Mediator setup",id:"1-mediator-setup",level:3},{value:"2. Recipient (Alice) setup",id:"2-recipient-alice-setup",level:3},{value:"3. Message exchange",id:"3-message-exchange",level:3},{value:"Useful resources",id:"useful-resources",level:3}],u={toc:d},p="wrapper";function m(e){let{components:t,...a}=e;return(0,n.kt)(p,(0,i.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"mediation"},"Mediation"),(0,n.kt)("blockquote",null,(0,n.kt)("p",{parentName:"blockquote"},"This section assumes that you have:"),(0,n.kt)("ol",{parentName:"blockquote"},(0,n.kt)("li",{parentName:"ol"},"Set up a ",(0,n.kt)("a",{parentName:"li",href:"../getting-started/installation"},"valid environment")," for development"),(0,n.kt)("li",{parentName:"ol"},"Basic knowledge of the required fields in the ",(0,n.kt)("a",{parentName:"li",href:"./agent-config"},"agent\nconfig"))),(0,n.kt)("p",{parentName:"blockquote"},"The agent setup varies depending on your target environment, React Native or Node.js.",(0,n.kt)("br",{parentName:"p"}),"\n","This tutorial assumes a Node.js environment for all agents (Alice, Bob, Meditator).")),(0,n.kt)("p",null,"This tutorial shows how to set up a mediator, how to configure an agent to use a mediator, and how agents exchange messages with a mediator in place.\nConcepts are explained in isolation:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"/guides/tutorials/mediation#1-mediator-setup"},"First"),", it is shown how to set up a mediator."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"/guides/tutorials/mediation#2-recipient-alice-setup"},"Second"),", it is demonstrated how to use a mediator."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"/guides/tutorials/mediation#3-message-exchange"},"Third"),", the message exchange between agents with a mediator in place is explained.")),(0,n.kt)("h3",{id:"what-is-a-mediator-and-why-should-i-use-one"},"What is a mediator, and Why should I use one?"),(0,n.kt)("p",null,"A mediator is just a special type of agent."),(0,n.kt)("admonition",{type:"info"},(0,n.kt)("p",{parentName:"admonition"},"\"When we describe agent-to-agent communication, it is convenient to think of an interaction only in terms of Alice and Bob and their agents. We say things like: \"Alice's agent sends a message to Bob's agent\" -- or perhaps \"Alice's edge agent sends a message to Bob's cloud agent, which forwards it to Bob's edge agent\"."),(0,n.kt)("p",{parentName:"admonition"},"Such statements adopt a useful level of abstraction--one that's highly recommended for most discussions. However, they make a number of simplifications. By modeling the roles of mediators and relays in routing, we can support routes that use multiple transports, routes that are not fully known (or knowable) to the sender, routes that pass through mix networks, and other advanced and powerful concepts.\"",(0,n.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0046-mediators-and-relays/README.md#aries-rfc-0046-mediators-and-relays"},"Aries RFC 0046: Mediators and Relays"))),(0,n.kt)("p",null,'A practical example where the use of mediators is beneficial can be found in a mobile environment. A mobile agent, aka. your mobile wallet, receives messages from other agents. Technically, sending HTTP messages to a mobile agent is impossible because the agent does not have a public IP. As you have probably seen in previous examples, a workaround for this scenario is to use ngrok. Another option is to use a mediator. When an agent is configured to use a mediator, messages to that agent are routed through the mediator and from there to its destination. Thus, a mobile agent can use a "public" mediator to receive messages on its behalf and poll them from time to time.'),(0,n.kt)("p",null,"This is just one example of how a mediator can be used. Further resources about mediators can be found ",(0,n.kt)("a",{parentName:"p",href:"/guides/tutorials/mediation#useful-resources"},"here"),"."),(0,n.kt)("admonition",{type:"tip"},(0,n.kt)("p",{parentName:"admonition"},"With mediators, WebSockets come in handy. In a production environment, it is recommendable to register a ",(0,n.kt)("inlineCode",{parentName:"p"},"WsInboundTransport()")," for Alice and a ",(0,n.kt)("inlineCode",{parentName:"p"},"WsOutboundTransport()")," for the mediator. These WebSocket transports allow the mediator to push messages to Alice instead of having Alice pull messages from the mediator repeatedly.")),(0,n.kt)("h3",{id:"1-mediator-setup"},"1. Mediator setup"),(0,n.kt)("p",null,"The first part shows how to set up a mediator agent. Generally, there are two ways to do that: deploying it from scratch or using a third-party mediator. This section focuses on the former approach, setting up the mediator from scratch."),(0,n.kt)("p",null,"The mediator is set up on port 3001 and creates an Out-of-Band invitation that allows multiple other agents to connect to the mediator. Configuring an agent as a mediator demands utilizing the ",(0,n.kt)("inlineCode",{parentName:"p"},"MediatorModule"),". In this example, the ",(0,n.kt)("inlineCode",{parentName:"p"},"autoAcceptMediationRequests")," flag is set to true to accept mediation requests automatically."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers mediator-setup.ts section-1",showLineNumbers:!0,"mediator-setup.ts":!0,"section-1":!0},"")),(0,n.kt)("h3",{id:"2-recipient-alice-setup"},"2. Recipient (Alice) setup"),(0,n.kt)("p",null,"The second part shows how to use a mediator. Becoming a recipient of a mediator requires using the ",(0,n.kt)("inlineCode",{parentName:"p"},"MediationRecipientModule"),". The setup is the same whether you use your own or a third-party mediator."),(0,n.kt)("p",null,"The easiest way to set everything up is by configuring the ",(0,n.kt)("inlineCode",{parentName:"p"},"MediationRecipientModule")," to connect to the mediator on agent startup. This can be done by constructing the module with the ",(0,n.kt)("inlineCode",{parentName:"p"},"mediatorInvitationUrl"),". You can get the mediatorInvitationUrl either from ",(0,n.kt)("a",{parentName:"p",href:"/guides/tutorials/mediation#1-mediator-setup"},"part one")," by running a mediator yourself or from a public mediator such as the Animo-mediator. The following snippet uses the latter approach."),(0,n.kt)("p",null,"The ",(0,n.kt)("inlineCode",{parentName:"p"},"ConnectionsModule")," used in this snippet serves the sole purpose of automatically accepting connections and thus simplifying setup."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers mediation-recipient.ts section-1",showLineNumbers:!0,"mediation-recipient.ts":!0,"section-1":!0},"")),(0,n.kt)("admonition",{type:"info"},(0,n.kt)("p",{parentName:"admonition"},"In case you are using a third-party mediator and cannot create an invitationUrl, it is common practice for mediators to provide an endpoint from which the invitationUrl can be fetched.")),(0,n.kt)("h3",{id:"3-message-exchange"},"3. Message exchange"),(0,n.kt)("p",null,"This section explains the message exchange between agents when a mediator is in place. The process is illustrated using the diagram below. Parts ",(0,n.kt)("a",{parentName:"p",href:"/guides/tutorials/mediation#1-mediator-setup"},"one")," and ",(0,n.kt)("a",{parentName:"p",href:"/guides/tutorials/mediation#2-recipient-alice-setup"},"two")," of this tutorial showed how to set up and use a mediator. If the ",(0,n.kt)("inlineCode",{parentName:"p"},"mediatorInvitationUrl")," is specified when constructing the ",(0,n.kt)("inlineCode",{parentName:"p"},"MediationRecipientModule")," (as in ",(0,n.kt)("a",{parentName:"p",href:"/guides/tutorials/mediation#2-recipient-alice-setup"},"Part two"),"), the mediation request and grant ",(0,n.kt)("em",{parentName:"p"},"(1-2)")," between Alice and the mediator will be performed automatically when Alice's agent is started."),(0,n.kt)("p",null,"If Alice establishes a connection with another fictional agent, say, Bob's agent, who is not using any mediators ",(0,n.kt)("em",{parentName:"p"},"(3-6)"),". (Connection establishment is no different when a mediator is involved). Then, messages from Alice to Bob ",(0,n.kt)("em",{parentName:"p"},"(7)")," are routed directly to Bob, while messages from Bob to Alice ",(0,n.kt)("em",{parentName:"p"},"(8-9)")," are routed through the intermediary."),(0,n.kt)("mermaid",{value:"sequenceDiagram\n autonumber\n participant Alice\n participant Mediator\n participant Bob\n Note over Mediator: Start\n Note over Alice: Start\n Alice->>Mediator: Request Mediation\n Mediator->>Alice: Grant Mediation\n Note over Bob: Start\n Alice->>Alice: CreateInvitation\n Alice --\x3e Bob: (Send Invitation to Bob)\n Bob->>Bob: RecieveInvitation\n Alice->>Bob: WaitForConnection\n Alice->>Bob: SendMessage Alice->Bob\n Bob->>Mediator: SendMessage Bob->Alice (Mediator)\n Mediator->>Alice: ForwardMessage Bob->Alice (Mediator)"}),(0,n.kt)("h3",{id:"useful-resources"},"Useful resources"),(0,n.kt)("p",null,"For more information about mediator refer to:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0211-route-coordination"},"Aries Mediator Coordination Protocol")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://aries-mediator.animo.id/#/"},"Hyperledger Aries Mediator Agent")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0046-mediators-and-relays/README.md#aries-rfc-0046-mediators-and-relays"},"Aries RFC 0046: Mediators and Relays"))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/862058fd.5345e424.js b/assets/js/862058fd.5345e424.js new file mode 100644 index 00000000..f362528d --- /dev/null +++ b/assets/js/862058fd.5345e424.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8709],{3905:(e,t,a)=>{a.d(t,{Zo:()=>u,kt:()=>h});var i=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,i)}return a}function r(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var l=i.createContext({}),d=function(e){var t=i.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):r(r({},t),e)),a},u=function(e){var t=d(e.components);return i.createElement(l.Provider,{value:t},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},c=i.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=d(a),c=n,h=p["".concat(l,".").concat(c)]||p[c]||m[c]||o;return a?i.createElement(h,r(r({ref:t},u),{},{components:a})):i.createElement(h,r({ref:t},u))}));function h(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,r=new Array(o);r[0]=c;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:n,r[1]=s;for(var d=2;d{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var i=a(7462),n=(a(7294),a(3905));const o={},r="Mediation",s={unversionedId:"tutorials/mediation",id:"version-0.4/tutorials/mediation",title:"Mediation",description:"This section assumes that you have:",source:"@site/versioned_docs/version-0.4/tutorials/mediation.md",sourceDirName:"tutorials",slug:"/tutorials/mediation",permalink:"/guides/0.4/tutorials/mediation",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Issue a credential",permalink:"/guides/0.4/tutorials/issue-a-credential"},next:{title:"Using PostgreSQL as Database for Indy SDK in Node.js",permalink:"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/"}},l={},d=[{value:"What is a mediator, and Why should I use one?",id:"what-is-a-mediator-and-why-should-i-use-one",level:3},{value:"1. Mediator setup",id:"1-mediator-setup",level:3},{value:"2. Recipient (Alice) setup",id:"2-recipient-alice-setup",level:3},{value:"3. Message exchange",id:"3-message-exchange",level:3},{value:"Useful resources",id:"useful-resources",level:3}],u={toc:d},p="wrapper";function m(e){let{components:t,...a}=e;return(0,n.kt)(p,(0,i.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"mediation"},"Mediation"),(0,n.kt)("blockquote",null,(0,n.kt)("p",{parentName:"blockquote"},"This section assumes that you have:"),(0,n.kt)("ol",{parentName:"blockquote"},(0,n.kt)("li",{parentName:"ol"},"Set up a ",(0,n.kt)("a",{parentName:"li",href:"../getting-started/installation"},"valid environment")," for development"),(0,n.kt)("li",{parentName:"ol"},"Basic knowledge of the required fields in the ",(0,n.kt)("a",{parentName:"li",href:"./agent-config"},"agent\nconfig"))),(0,n.kt)("p",{parentName:"blockquote"},"The agent setup varies depending on your target environment, React Native or Node.js.",(0,n.kt)("br",{parentName:"p"}),"\n","This tutorial assumes a Node.js environment for all agents (Alice, Bob, Meditator).")),(0,n.kt)("p",null,"This tutorial shows how to set up a mediator, how to configure an agent to use a mediator, and how agents exchange messages with a mediator in place.\nConcepts are explained in isolation:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"/guides/0.4/tutorials/mediation#1-mediator-setup"},"First"),", it is shown how to set up a mediator."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"/guides/0.4/tutorials/mediation#2-recipient-alice-setup"},"Second"),", it is demonstrated how to use a mediator."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"/guides/0.4/tutorials/mediation#3-message-exchange"},"Third"),", the message exchange between agents with a mediator in place is explained.")),(0,n.kt)("h3",{id:"what-is-a-mediator-and-why-should-i-use-one"},"What is a mediator, and Why should I use one?"),(0,n.kt)("p",null,"A mediator is just a special type of agent."),(0,n.kt)("admonition",{type:"info"},(0,n.kt)("p",{parentName:"admonition"},"\"When we describe agent-to-agent communication, it is convenient to think of an interaction only in terms of Alice and Bob and their agents. We say things like: \"Alice's agent sends a message to Bob's agent\" -- or perhaps \"Alice's edge agent sends a message to Bob's cloud agent, which forwards it to Bob's edge agent\"."),(0,n.kt)("p",{parentName:"admonition"},"Such statements adopt a useful level of abstraction--one that's highly recommended for most discussions. However, they make a number of simplifications. By modeling the roles of mediators and relays in routing, we can support routes that use multiple transports, routes that are not fully known (or knowable) to the sender, routes that pass through mix networks, and other advanced and powerful concepts.\"",(0,n.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0046-mediators-and-relays/README.md#aries-rfc-0046-mediators-and-relays"},"Aries RFC 0046: Mediators and Relays"))),(0,n.kt)("p",null,'A practical example where the use of mediators is beneficial can be found in a mobile environment. A mobile agent, aka. your mobile wallet, receives messages from other agents. Technically, sending HTTP messages to a mobile agent is impossible because the agent does not have a public IP. As you have probably seen in previous examples, a workaround for this scenario is to use ngrok. Another option is to use a mediator. When an agent is configured to use a mediator, messages to that agent are routed through the mediator and from there to its destination. Thus, a mobile agent can use a "public" mediator to receive messages on its behalf and poll them from time to time.'),(0,n.kt)("p",null,"This is just one example of how a mediator can be used. Further resources about mediators can be found ",(0,n.kt)("a",{parentName:"p",href:"/guides/0.4/tutorials/mediation#useful-resources"},"here"),"."),(0,n.kt)("admonition",{type:"tip"},(0,n.kt)("p",{parentName:"admonition"},"With mediators, WebSockets come in handy. In a production environment, it is recommendable to register a ",(0,n.kt)("inlineCode",{parentName:"p"},"WsInboundTransport()")," for Alice and a ",(0,n.kt)("inlineCode",{parentName:"p"},"WsOutboundTransport()")," for the mediator. These WebSocket transports allow the mediator to push messages to Alice instead of having Alice pull messages from the mediator repeatedly.")),(0,n.kt)("h3",{id:"1-mediator-setup"},"1. Mediator setup"),(0,n.kt)("p",null,"The first part shows how to set up a mediator agent. Generally, there are two ways to do that: deploying it from scratch or using a third-party mediator. This section focuses on the former approach, setting up the mediator from scratch."),(0,n.kt)("p",null,"The mediator is set up on port 3001 and creates an Out-of-Band invitation that allows multiple other agents to connect to the mediator. Configuring an agent as a mediator demands utilizing the ",(0,n.kt)("inlineCode",{parentName:"p"},"MediatorModule"),". In this example, the ",(0,n.kt)("inlineCode",{parentName:"p"},"autoAcceptMediationRequests")," flag is set to true to accept mediation requests automatically."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers mediator-setup.ts section-1",showLineNumbers:!0,"mediator-setup.ts":!0,"section-1":!0},"")),(0,n.kt)("h3",{id:"2-recipient-alice-setup"},"2. Recipient (Alice) setup"),(0,n.kt)("p",null,"The second part shows how to use a mediator. Becoming a recipient of a mediator requires using the ",(0,n.kt)("inlineCode",{parentName:"p"},"MediationRecipientModule"),". The setup is the same whether you use your own or a third-party mediator."),(0,n.kt)("p",null,"The easiest way to set everything up is by configuring the ",(0,n.kt)("inlineCode",{parentName:"p"},"MediationRecipientModule")," to connect to the mediator on agent startup. This can be done by constructing the module with the ",(0,n.kt)("inlineCode",{parentName:"p"},"mediatorInvitationUrl"),". You can get the mediatorInvitationUrl either from ",(0,n.kt)("a",{parentName:"p",href:"/guides/0.4/tutorials/mediation#1-mediator-setup"},"part one")," by running a mediator yourself or from a public mediator such as the Animo-mediator. The following snippet uses the latter approach."),(0,n.kt)("p",null,"The ",(0,n.kt)("inlineCode",{parentName:"p"},"ConnectionsModule")," used in this snippet serves the sole purpose of automatically accepting connections and thus simplifying setup."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers mediation-recipient.ts section-1",showLineNumbers:!0,"mediation-recipient.ts":!0,"section-1":!0},"")),(0,n.kt)("admonition",{type:"info"},(0,n.kt)("p",{parentName:"admonition"},"In case you are using a third-party mediator and cannot create an invitationUrl, it is common practice for mediators to provide an endpoint from which the invitationUrl can be fetched.")),(0,n.kt)("h3",{id:"3-message-exchange"},"3. Message exchange"),(0,n.kt)("p",null,"This section explains the message exchange between agents when a mediator is in place. The process is illustrated using the diagram below. Parts ",(0,n.kt)("a",{parentName:"p",href:"/guides/0.4/tutorials/mediation#1-mediator-setup"},"one")," and ",(0,n.kt)("a",{parentName:"p",href:"/guides/0.4/tutorials/mediation#2-recipient-alice-setup"},"two")," of this tutorial showed how to set up and use a mediator. If the ",(0,n.kt)("inlineCode",{parentName:"p"},"mediatorInvitationUrl")," is specified when constructing the ",(0,n.kt)("inlineCode",{parentName:"p"},"MediationRecipientModule")," (as in ",(0,n.kt)("a",{parentName:"p",href:"/guides/0.4/tutorials/mediation#2-recipient-alice-setup"},"Part two"),"), the mediation request and grant ",(0,n.kt)("em",{parentName:"p"},"(1-2)")," between Alice and the mediator will be performed automatically when Alice's agent is started."),(0,n.kt)("p",null,"If Alice establishes a connection with another fictional agent, say, Bob's agent, who is not using any mediators ",(0,n.kt)("em",{parentName:"p"},"(3-6)"),". (Connection establishment is no different when a mediator is involved). Then, messages from Alice to Bob ",(0,n.kt)("em",{parentName:"p"},"(7)")," are routed directly to Bob, while messages from Bob to Alice ",(0,n.kt)("em",{parentName:"p"},"(8-9)")," are routed through the intermediary."),(0,n.kt)("mermaid",{value:"sequenceDiagram\n autonumber\n participant Alice\n participant Mediator\n participant Bob\n Note over Mediator: Start\n Note over Alice: Start\n Alice->>Mediator: Request Mediation\n Mediator->>Alice: Grant Mediation\n Note over Bob: Start\n Alice->>Alice: CreateInvitation\n Alice --\x3e Bob: (Send Invitation to Bob)\n Bob->>Bob: RecieveInvitation\n Alice->>Bob: WaitForConnection\n Alice->>Bob: SendMessage Alice->Bob\n Bob->>Mediator: SendMessage Bob->Alice (Mediator)\n Mediator->>Alice: ForwardMessage Bob->Alice (Mediator)"}),(0,n.kt)("h3",{id:"useful-resources"},"Useful resources"),(0,n.kt)("p",null,"For more information about mediator refer to:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0211-route-coordination"},"Aries Mediator Coordination Protocol")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://aries-mediator.animo.id/#/"},"Hyperledger Aries Mediator Agent")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0046-mediators-and-relays/README.md#aries-rfc-0046-mediators-and-relays"},"Aries RFC 0046: Mediators and Relays"))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8b37bb4b.270284d2.js b/assets/js/8b37bb4b.270284d2.js new file mode 100644 index 00000000..015b3f55 --- /dev/null +++ b/assets/js/8b37bb4b.270284d2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4565],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>h});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),d=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=d(e.components);return a.createElement(l.Provider,{value:t},e.children)},u="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=d(n),m=r,h=u["".concat(l,".").concat(m)]||u[m]||c[m]||i;return n?a.createElement(h,o(o({ref:t},p),{},{components:n})):a.createElement(h,o({ref:t},p))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:r,o[1]=s;for(var d=2;d{n.d(t,{Z:()=>o});var a=n(7294),r=n(6010);const i={tabItem:"tabItem_Ymn6"};function o(e){let{children:t,hidden:n,className:o}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(i.tabItem,o),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>N});var a=n(7462),r=n(7294),i=n(6010),o=n(2466),s=n(6550),l=n(1980),d=n(7392),p=n(12);function u(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function c(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??u(n);return function(e){const t=(0,d.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const a=(0,s.k6)(),i=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,l._X)(i),(0,r.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(a.location.search);t.set(i,e),a.replace({...a.location,search:t.toString()})}),[i,a])]}function g(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,i=c(e),[o,s]=(0,r.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(!m({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:i}))),[l,d]=h({queryString:n,groupId:a}),[u,g]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,i]=(0,p.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:a}),f=(()=>{const e=l??u;return m({value:e,tabValues:i})?e:null})();(0,r.useLayoutEffect)((()=>{f&&s(f)}),[f]);return{selectedValue:o,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);s(e),d(e),g(e)}),[d,g,i]),tabValues:i}}var f=n(2389);const y={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:n,selectedValue:s,selectValue:l,tabValues:d}=e;const p=[],{blockElementScrollPositionUntilNextRender:u}=(0,o.o5)(),c=e=>{const t=e.currentTarget,n=p.indexOf(t),a=d[n].value;a!==s&&(u(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const n=p.indexOf(e.currentTarget)+1;t=p[n]??p[0];break}case"ArrowLeft":{const n=p.indexOf(e.currentTarget)-1;t=p[n]??p[p.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},d.map((e=>{let{value:t,label:n,attributes:o}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>p.push(e),onKeyDown:m,onClick:c},o,{className:(0,i.Z)("tabs__item",y.tabItem,o?.className,{"tabs__item--active":s===t})}),n??t)})))}function v(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function b(e){const t=g(e);return r.createElement("div",{className:(0,i.Z)("tabs-container",y.tabList)},r.createElement(k,(0,a.Z)({},e,t)),r.createElement(v,(0,a.Z)({},e,t)))}function N(e){const t=(0,f.Z)();return r.createElement(b,(0,a.Z)({key:String(t)},e))}},3624:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>d,toc:()=>u});var a=n(7462),r=(n(7294),n(3905)),i=n(4866),o=n(5162);const s={},l="Indy VDR",d={unversionedId:"getting-started/set-up/indy-vdr",id:"version-0.4/getting-started/set-up/indy-vdr",title:"Indy VDR",description:"Hyperledger Indy VDR, Verifiable Data Registry, can be used to connect to one or more Indy Node ledger pools given sets of genesis transactions. Methods are provided to construct ledger requests and send them to the validators, collecting the results and ensuring that there is a consensus between the nodes. In the context of Aries Framework JavaScript, we mainly leverage it to register, and resolve, schemas, credential definitions and DIDs.",source:"@site/versioned_docs/version-0.4/getting-started/set-up/indy-vdr.md",sourceDirName:"getting-started/set-up",slug:"/getting-started/set-up/indy-vdr",permalink:"/guides/0.4/getting-started/set-up/indy-vdr",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"AnonCreds RS",permalink:"/guides/0.4/getting-started/set-up/anoncreds-rs"},next:{title:"cheqd",permalink:"/guides/0.4/getting-started/set-up/cheqd/"}},p={},u=[{value:"Installing Indy VDR",id:"installing-indy-vdr",level:3},{value:"Adding Indy VDR to the agent",id:"adding-indy-vdr-to-the-agent",level:3},{value:"Configuration",id:"configuration",level:3},{value:"indyVdr",id:"indyvdr",level:4},{value:"networks",id:"networks",level:4},{value:"indyNamespace",id:"indynamespace",level:5},{value:"isProduction",id:"isproduction",level:5},{value:"genesisTransactions",id:"genesistransactions",level:5},{value:"connectOnStartup",id:"connectonstartup",level:5},{value:"transactionAuthorAgreement",id:"transactionauthoragreement",level:5},{value:"transactionAuthorAgreement.version",id:"transactionauthoragreementversion",level:5},{value:"transactionAuthorAgreement.acceptanceMechanism",id:"transactionauthoragreementacceptancemechanism",level:5},{value:"Supported Node.JS versions for Indy VDR",id:"supported-nodejs-versions-for-indy-vdr",level:3}],c={toc:u},m="wrapper";function h(e){let{components:t,...n}=e;return(0,r.kt)(m,(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"indy-vdr"},"Indy VDR"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-vdr"},"Hyperledger Indy VDR"),", Verifiable Data Registry, can be used to connect to one or more Indy Node ledger pools given sets of genesis transactions. Methods are provided to construct ledger requests and send them to the validators, collecting the results and ensuring that there is a consensus between the nodes. In the context of Aries Framework JavaScript, we mainly leverage it to register, and resolve, schemas, credential definitions and DIDs."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Support for Indy VDR in Aries Framework JavaScript is currently experimental. We recommend new projects to use Indy VDR from the start, and also to migrate existing projects to Indy VDR, from the indy-sdk. However, projects may experience some issues. If you encounter any issues, please ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript/issues/new"},"open an issue"),"."),(0,r.kt)("p",{parentName:"admonition"},"Currently, there are few limitations to using Indy VDR."),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},"When running in Node.JS, only Node.JS 18 is supported for now. See ",(0,r.kt)("a",{parentName:"li",href:"#supported-nodejs-versions-for-indy-vdr"},"Supported Node.JS versions for Indy VDR")),(0,r.kt)("li",{parentName:"ul"},"Install scripts rely on bash command substitution to get the proper binaries for each system architecture and platform. Therefore, if you are under Windows, you must configure ",(0,r.kt)("inlineCode",{parentName:"li"},"npm")," or ",(0,r.kt)("inlineCode",{parentName:"li"},"yarn")," to use a bash-compliant shell (e.g. ",(0,r.kt)("inlineCode",{parentName:"li"},'npm config set script-shell "C:\\\\Program Files\\\\git\\\\bin\\\\bash.exe"'),")"))),(0,r.kt)("h3",{id:"installing-indy-vdr"},"Installing Indy VDR"),(0,r.kt)("p",null,"When using Aries Framework JavaScript with Indy VDR, there are a few extra dependencies that need to be installed. We need to install the ",(0,r.kt)("inlineCode",{parentName:"p"},"@hyperledger/indy-vdr"),", which contains all the functionality to register objects on an Hyperledger Indy VDR. Secondly, we need to add native bindings for the specific platform ",(0,r.kt)("inlineCode",{parentName:"p"},"@hyperledger/indy-vdr-"),". Currently there are bindings for Node.JS, as ",(0,r.kt)("inlineCode",{parentName:"p"},"@hyperledger/indy-vdr-nodejs"),", and React Native as ",(0,r.kt)("inlineCode",{parentName:"p"},"@hyperlegder/indy-vdr-react-native"),"."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @aries-framework/indy-vdr@^0.4.0 @hyperledger/indy-vdr-nodejs@^0.1.0\n"))),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @aries-framework/indy-vdr@^0.4.0 @hyperledger/indy-vdr-react-native@^0.1.0\n")))),(0,r.kt)("h3",{id:"adding-indy-vdr-to-the-agent"},"Adding Indy VDR to the agent"),(0,r.kt)("p",null,"After installing the dependencies, we can register the Indy VDR module on the agent."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-indy-vdr.ts section-1",showLineNumbers:!0,"set-up-indy-vdr.ts":!0,"section-1":!0},""))),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-indy-vdr-rn.ts section-1",showLineNumbers:!0,"set-up-indy-vdr-rn.ts":!0,"section-1":!0},"")))),(0,r.kt)("h3",{id:"configuration"},"Configuration"),(0,r.kt)("p",null,"As you can see below, the Indy VDR module takes the native bindings and a list of networks. This list of networks will be used to resolve and register objects on."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"typescript showLineNumbers set-up-indy-vdr-config.ts section-1",typescript:!0,showLineNumbers:!0,"set-up-indy-vdr-config.ts":!0,"section-1":!0},"")),(0,r.kt)("h4",{id:"indyvdr"},"indyVdr"),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Type"),": ",(0,r.kt)("inlineCode",{parentName:"p"},"IndyVdr")),(0,r.kt)("p",null,"the ",(0,r.kt)("inlineCode",{parentName:"p"},"indyVdr")," key takes a class that implements all the native bindings for Indy VDR. This can be imoprted from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@hyperledger/indy-vdr-nodejs")," package or the ",(0,r.kt)("inlineCode",{parentName:"p"},"@hyperledger/indy-vdr-react-native")," package."),(0,r.kt)("h4",{id:"networks"},"networks"),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Type"),": ",(0,r.kt)("inlineCode",{parentName:"p"},"IndyVdrPoolConfig[]")),(0,r.kt)("p",null,"An array of indy networks to connect to. The list can contain the following object and it must ",(0,r.kt)("a",{parentName:"p",href:"#indyledgersgenesistransactions"},(0,r.kt)("inlineCode",{parentName:"a"},"genesisTransactions")),"."),(0,r.kt)("h5",{id:"indynamespace"},"indyNamespace"),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Type"),": ",(0,r.kt)("inlineCode",{parentName:"p"},"string")),(0,r.kt)("p",null,"The Indy namespace aka the name identifying the name of the network connecting to. See also ",(0,r.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/indy-did-method/#indy-did-method-identifiers"},"indy did method identifiers")),(0,r.kt)("h5",{id:"isproduction"},(0,r.kt)("inlineCode",{parentName:"h5"},"isProduction")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Type"),": ",(0,r.kt)("inlineCode",{parentName:"p"},"boolean")),(0,r.kt)("p",null,"Whether the ledger is a production ledger. This is used for detecting which ledger to use in case of unqualified identifiers as production ledgers have priority."),(0,r.kt)("h5",{id:"genesistransactions"},(0,r.kt)("inlineCode",{parentName:"h5"},"genesisTransactions")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Type"),": ",(0,r.kt)("inlineCode",{parentName:"p"},"string")),(0,r.kt)("p",null,"Stringified JSON object of the transaction."),(0,r.kt)("h5",{id:"connectonstartup"},(0,r.kt)("inlineCode",{parentName:"h5"},"connectOnStartup")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Type"),": ",(0,r.kt)("inlineCode",{parentName:"p"},"boolean")),(0,r.kt)("p",null,"Whether to connect to the ledger on startup. Defaults to ",(0,r.kt)("inlineCode",{parentName:"p"},"false"),"."),(0,r.kt)("h5",{id:"transactionauthoragreement"},(0,r.kt)("inlineCode",{parentName:"h5"},"transactionAuthorAgreement")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Type"),": ",(0,r.kt)("inlineCode",{parentName:"p"},"TransactionAuthorAgreement")),(0,r.kt)("p",null,"JSON representation specifying the version and acceptance mechanism. The version is the unique version of the transaction author agreement acceptance mechanism list (AML). The acceptance mechanism refers to the acceptance mechanism label of the item in the AML. For more details you may consult the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-node/blob/master/docs/source/transactions.md#transaction_author_agreement_aml"},"indy-node docs on AML")),(0,r.kt)("h5",{id:"transactionauthoragreementversion"},(0,r.kt)("inlineCode",{parentName:"h5"},"transactionAuthorAgreement.version")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Type"),": ",(0,r.kt)("inlineCode",{parentName:"p"},"string")),(0,r.kt)("p",null,"The version of the AML acceptance mechanism. This is a string representation of a version number e.g. '1' or '1.4'"),(0,r.kt)("h5",{id:"transactionauthoragreementacceptancemechanism"},(0,r.kt)("inlineCode",{parentName:"h5"},"transactionAuthorAgreement.acceptanceMechanism")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Type"),": ",(0,r.kt)("inlineCode",{parentName:"p"},"string")),(0,r.kt)("p",null,"The acceptance mechanism to choose. This ",(0,r.kt)("em",{parentName:"p"},"must")," be ",(0,r.kt)("em",{parentName:"p"},"one")," of the available labels of the acceptance mechanisms key-value pairs in the AML e.g. 'EULA'."),(0,r.kt)("h3",{id:"supported-nodejs-versions-for-indy-vdr"},"Supported Node.JS versions for Indy VDR"),(0,r.kt)("p",null,"Due to an issue in ",(0,r.kt)("inlineCode",{parentName:"p"},"ref-napi")," (which is used in the Node.JS bindings for Indy VDR), performance for Indy VDR in Node.JS is not as expected. A patched version for ",(0,r.kt)("inlineCode",{parentName:"p"},"ref-napi")," has been published that fixes this issue, but this only works in Node.JS 18+."),(0,r.kt)("p",null,"To use Indy VDR in Node.JS, make sure you're using Node.JS 18 and patch the ",(0,r.kt)("inlineCode",{parentName:"p"},"ref-napi")," package to point towards ",(0,r.kt)("inlineCode",{parentName:"p"},"@2060.io/ref-napi")," in your ",(0,r.kt)("inlineCode",{parentName:"p"},"package.json"),":"),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"NPM",value:"tab1",mdxType:"TabItem"},(0,r.kt)("p",null,"Using ",(0,r.kt)("a",{parentName:"p",href:"https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides"},"NPM ",(0,r.kt)("inlineCode",{parentName:"a"},"overrides"))," we can point the ",(0,r.kt)("inlineCode",{parentName:"p"},"ref-napi")," package to ",(0,r.kt)("inlineCode",{parentName:"p"},"@2060.io/ref-napi"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "overrides": {\n "ref-napi": "npm:@2060.io/ref-napi"\n }\n}\n'))),(0,r.kt)(o.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,r.kt)("p",null,"Using ",(0,r.kt)("a",{parentName:"p",href:"https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/"},"Yarn ",(0,r.kt)("inlineCode",{parentName:"a"},"resolutions"))," we can point the ",(0,r.kt)("inlineCode",{parentName:"p"},"ref-napi")," package to ",(0,r.kt)("inlineCode",{parentName:"p"},"@2060.io/ref-napi"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "resolutions": {\n "ref-napi": "npm:@2060.io/ref-napi"\n }\n}\n')))),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"See the following issues for more information on the performance bottleneck"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-askar/issues/76"},"https://github.com/hyperledger/aries-askar/issues/76")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/node-ffi-napi/ref-napi/issues/72"},"https://github.com/node-ffi-napi/ref-napi/issues/72")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/node-ffi-napi/ref-napi/pull/73"},"https://github.com/node-ffi-napi/ref-napi/pull/73")))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8b37bb4b.78c46236.js b/assets/js/8b37bb4b.78c46236.js deleted file mode 100644 index 1ea8be1d..00000000 --- a/assets/js/8b37bb4b.78c46236.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4565],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>h});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),d=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=d(e.components);return a.createElement(l.Provider,{value:t},e.children)},u="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=d(n),m=r,h=u["".concat(l,".").concat(m)]||u[m]||c[m]||i;return n?a.createElement(h,o(o({ref:t},p),{},{components:n})):a.createElement(h,o({ref:t},p))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:r,o[1]=s;for(var d=2;d{n.d(t,{Z:()=>o});var a=n(7294),r=n(6010);const i={tabItem:"tabItem_Ymn6"};function o(e){let{children:t,hidden:n,className:o}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(i.tabItem,o),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>N});var a=n(7462),r=n(7294),i=n(6010),o=n(2466),s=n(6550),l=n(1980),d=n(7392),p=n(12);function u(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function c(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??u(n);return function(e){const t=(0,d.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const a=(0,s.k6)(),i=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,l._X)(i),(0,r.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(a.location.search);t.set(i,e),a.replace({...a.location,search:t.toString()})}),[i,a])]}function g(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,i=c(e),[o,s]=(0,r.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(!m({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:i}))),[l,d]=h({queryString:n,groupId:a}),[u,g]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,i]=(0,p.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:a}),f=(()=>{const e=l??u;return m({value:e,tabValues:i})?e:null})();(0,r.useLayoutEffect)((()=>{f&&s(f)}),[f]);return{selectedValue:o,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);s(e),d(e),g(e)}),[d,g,i]),tabValues:i}}var f=n(2389);const y={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:n,selectedValue:s,selectValue:l,tabValues:d}=e;const p=[],{blockElementScrollPositionUntilNextRender:u}=(0,o.o5)(),c=e=>{const t=e.currentTarget,n=p.indexOf(t),a=d[n].value;a!==s&&(u(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const n=p.indexOf(e.currentTarget)+1;t=p[n]??p[0];break}case"ArrowLeft":{const n=p.indexOf(e.currentTarget)-1;t=p[n]??p[p.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},d.map((e=>{let{value:t,label:n,attributes:o}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>p.push(e),onKeyDown:m,onClick:c},o,{className:(0,i.Z)("tabs__item",y.tabItem,o?.className,{"tabs__item--active":s===t})}),n??t)})))}function v(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function b(e){const t=g(e);return r.createElement("div",{className:(0,i.Z)("tabs-container",y.tabList)},r.createElement(k,(0,a.Z)({},e,t)),r.createElement(v,(0,a.Z)({},e,t)))}function N(e){const t=(0,f.Z)();return r.createElement(b,(0,a.Z)({key:String(t)},e))}},3624:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>d,toc:()=>u});var a=n(7462),r=(n(7294),n(3905)),i=n(4866),o=n(5162);const s={},l="Indy VDR",d={unversionedId:"getting-started/set-up/indy-vdr",id:"version-0.4/getting-started/set-up/indy-vdr",title:"Indy VDR",description:"Hyperledger Indy VDR, Verifiable Data Registry, can be used to connect to one or more Indy Node ledger pools given sets of genesis transactions. Methods are provided to construct ledger requests and send them to the validators, collecting the results and ensuring that there is a consensus between the nodes. In the context of Aries Framework JavaScript, we mainly leverage it to register, and resolve, schemas, credential definitions and DIDs.",source:"@site/versioned_docs/version-0.4/getting-started/set-up/indy-vdr.md",sourceDirName:"getting-started/set-up",slug:"/getting-started/set-up/indy-vdr",permalink:"/guides/getting-started/set-up/indy-vdr",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"AnonCreds RS",permalink:"/guides/getting-started/set-up/anoncreds-rs"},next:{title:"cheqd",permalink:"/guides/getting-started/set-up/cheqd/"}},p={},u=[{value:"Installing Indy VDR",id:"installing-indy-vdr",level:3},{value:"Adding Indy VDR to the agent",id:"adding-indy-vdr-to-the-agent",level:3},{value:"Configuration",id:"configuration",level:3},{value:"indyVdr",id:"indyvdr",level:4},{value:"networks",id:"networks",level:4},{value:"indyNamespace",id:"indynamespace",level:5},{value:"isProduction",id:"isproduction",level:5},{value:"genesisTransactions",id:"genesistransactions",level:5},{value:"connectOnStartup",id:"connectonstartup",level:5},{value:"transactionAuthorAgreement",id:"transactionauthoragreement",level:5},{value:"transactionAuthorAgreement.version",id:"transactionauthoragreementversion",level:5},{value:"transactionAuthorAgreement.acceptanceMechanism",id:"transactionauthoragreementacceptancemechanism",level:5},{value:"Supported Node.JS versions for Indy VDR",id:"supported-nodejs-versions-for-indy-vdr",level:3}],c={toc:u},m="wrapper";function h(e){let{components:t,...n}=e;return(0,r.kt)(m,(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"indy-vdr"},"Indy VDR"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-vdr"},"Hyperledger Indy VDR"),", Verifiable Data Registry, can be used to connect to one or more Indy Node ledger pools given sets of genesis transactions. Methods are provided to construct ledger requests and send them to the validators, collecting the results and ensuring that there is a consensus between the nodes. In the context of Aries Framework JavaScript, we mainly leverage it to register, and resolve, schemas, credential definitions and DIDs."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Support for Indy VDR in Aries Framework JavaScript is currently experimental. We recommend new projects to use Indy VDR from the start, and also to migrate existing projects to Indy VDR, from the indy-sdk. However, projects may experience some issues. If you encounter any issues, please ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript/issues/new"},"open an issue"),"."),(0,r.kt)("p",{parentName:"admonition"},"Currently, there are few limitations to using Indy VDR."),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},"When running in Node.JS, only Node.JS 18 is supported for now. See ",(0,r.kt)("a",{parentName:"li",href:"#supported-nodejs-versions-for-indy-vdr"},"Supported Node.JS versions for Indy VDR")),(0,r.kt)("li",{parentName:"ul"},"Install scripts rely on bash command substitution to get the proper binaries for each system architecture and platform. Therefore, if you are under Windows, you must configure ",(0,r.kt)("inlineCode",{parentName:"li"},"npm")," or ",(0,r.kt)("inlineCode",{parentName:"li"},"yarn")," to use a bash-compliant shell (e.g. ",(0,r.kt)("inlineCode",{parentName:"li"},'npm config set script-shell "C:\\\\Program Files\\\\git\\\\bin\\\\bash.exe"'),")"))),(0,r.kt)("h3",{id:"installing-indy-vdr"},"Installing Indy VDR"),(0,r.kt)("p",null,"When using Aries Framework JavaScript with Indy VDR, there are a few extra dependencies that need to be installed. We need to install the ",(0,r.kt)("inlineCode",{parentName:"p"},"@hyperledger/indy-vdr"),", which contains all the functionality to register objects on an Hyperledger Indy VDR. Secondly, we need to add native bindings for the specific platform ",(0,r.kt)("inlineCode",{parentName:"p"},"@hyperledger/indy-vdr-"),". Currently there are bindings for Node.JS, as ",(0,r.kt)("inlineCode",{parentName:"p"},"@hyperledger/indy-vdr-nodejs"),", and React Native as ",(0,r.kt)("inlineCode",{parentName:"p"},"@hyperlegder/indy-vdr-react-native"),"."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @aries-framework/indy-vdr@^0.4.0 @hyperledger/indy-vdr-nodejs@^0.1.0\n"))),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @aries-framework/indy-vdr@^0.4.0 @hyperledger/indy-vdr-react-native@^0.1.0\n")))),(0,r.kt)("h3",{id:"adding-indy-vdr-to-the-agent"},"Adding Indy VDR to the agent"),(0,r.kt)("p",null,"After installing the dependencies, we can register the Indy VDR module on the agent."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-indy-vdr.ts section-1",showLineNumbers:!0,"set-up-indy-vdr.ts":!0,"section-1":!0},""))),(0,r.kt)(o.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-indy-vdr-rn.ts section-1",showLineNumbers:!0,"set-up-indy-vdr-rn.ts":!0,"section-1":!0},"")))),(0,r.kt)("h3",{id:"configuration"},"Configuration"),(0,r.kt)("p",null,"As you can see below, the Indy VDR module takes the native bindings and a list of networks. This list of networks will be used to resolve and register objects on."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"typescript showLineNumbers set-up-indy-vdr-config.ts section-1",typescript:!0,showLineNumbers:!0,"set-up-indy-vdr-config.ts":!0,"section-1":!0},"")),(0,r.kt)("h4",{id:"indyvdr"},"indyVdr"),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Type"),": ",(0,r.kt)("inlineCode",{parentName:"p"},"IndyVdr")),(0,r.kt)("p",null,"the ",(0,r.kt)("inlineCode",{parentName:"p"},"indyVdr")," key takes a class that implements all the native bindings for Indy VDR. This can be imoprted from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@hyperledger/indy-vdr-nodejs")," package or the ",(0,r.kt)("inlineCode",{parentName:"p"},"@hyperledger/indy-vdr-react-native")," package."),(0,r.kt)("h4",{id:"networks"},"networks"),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Type"),": ",(0,r.kt)("inlineCode",{parentName:"p"},"IndyVdrPoolConfig[]")),(0,r.kt)("p",null,"An array of indy networks to connect to. The list can contain the following object and it must ",(0,r.kt)("a",{parentName:"p",href:"#indyledgersgenesistransactions"},(0,r.kt)("inlineCode",{parentName:"a"},"genesisTransactions")),"."),(0,r.kt)("h5",{id:"indynamespace"},"indyNamespace"),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Type"),": ",(0,r.kt)("inlineCode",{parentName:"p"},"string")),(0,r.kt)("p",null,"The Indy namespace aka the name identifying the name of the network connecting to. See also ",(0,r.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/indy-did-method/#indy-did-method-identifiers"},"indy did method identifiers")),(0,r.kt)("h5",{id:"isproduction"},(0,r.kt)("inlineCode",{parentName:"h5"},"isProduction")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Type"),": ",(0,r.kt)("inlineCode",{parentName:"p"},"boolean")),(0,r.kt)("p",null,"Whether the ledger is a production ledger. This is used for detecting which ledger to use in case of unqualified identifiers as production ledgers have priority."),(0,r.kt)("h5",{id:"genesistransactions"},(0,r.kt)("inlineCode",{parentName:"h5"},"genesisTransactions")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Type"),": ",(0,r.kt)("inlineCode",{parentName:"p"},"string")),(0,r.kt)("p",null,"Stringified JSON object of the transaction."),(0,r.kt)("h5",{id:"connectonstartup"},(0,r.kt)("inlineCode",{parentName:"h5"},"connectOnStartup")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Type"),": ",(0,r.kt)("inlineCode",{parentName:"p"},"boolean")),(0,r.kt)("p",null,"Whether to connect to the ledger on startup. Defaults to ",(0,r.kt)("inlineCode",{parentName:"p"},"false"),"."),(0,r.kt)("h5",{id:"transactionauthoragreement"},(0,r.kt)("inlineCode",{parentName:"h5"},"transactionAuthorAgreement")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Type"),": ",(0,r.kt)("inlineCode",{parentName:"p"},"TransactionAuthorAgreement")),(0,r.kt)("p",null,"JSON representation specifying the version and acceptance mechanism. The version is the unique version of the transaction author agreement acceptance mechanism list (AML). The acceptance mechanism refers to the acceptance mechanism label of the item in the AML. For more details you may consult the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-node/blob/master/docs/source/transactions.md#transaction_author_agreement_aml"},"indy-node docs on AML")),(0,r.kt)("h5",{id:"transactionauthoragreementversion"},(0,r.kt)("inlineCode",{parentName:"h5"},"transactionAuthorAgreement.version")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Type"),": ",(0,r.kt)("inlineCode",{parentName:"p"},"string")),(0,r.kt)("p",null,"The version of the AML acceptance mechanism. This is a string representation of a version number e.g. '1' or '1.4'"),(0,r.kt)("h5",{id:"transactionauthoragreementacceptancemechanism"},(0,r.kt)("inlineCode",{parentName:"h5"},"transactionAuthorAgreement.acceptanceMechanism")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Type"),": ",(0,r.kt)("inlineCode",{parentName:"p"},"string")),(0,r.kt)("p",null,"The acceptance mechanism to choose. This ",(0,r.kt)("em",{parentName:"p"},"must")," be ",(0,r.kt)("em",{parentName:"p"},"one")," of the available labels of the acceptance mechanisms key-value pairs in the AML e.g. 'EULA'."),(0,r.kt)("h3",{id:"supported-nodejs-versions-for-indy-vdr"},"Supported Node.JS versions for Indy VDR"),(0,r.kt)("p",null,"Due to an issue in ",(0,r.kt)("inlineCode",{parentName:"p"},"ref-napi")," (which is used in the Node.JS bindings for Indy VDR), performance for Indy VDR in Node.JS is not as expected. A patched version for ",(0,r.kt)("inlineCode",{parentName:"p"},"ref-napi")," has been published that fixes this issue, but this only works in Node.JS 18+."),(0,r.kt)("p",null,"To use Indy VDR in Node.JS, make sure you're using Node.JS 18 and patch the ",(0,r.kt)("inlineCode",{parentName:"p"},"ref-napi")," package to point towards ",(0,r.kt)("inlineCode",{parentName:"p"},"@2060.io/ref-napi")," in your ",(0,r.kt)("inlineCode",{parentName:"p"},"package.json"),":"),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"NPM",value:"tab1",mdxType:"TabItem"},(0,r.kt)("p",null,"Using ",(0,r.kt)("a",{parentName:"p",href:"https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides"},"NPM ",(0,r.kt)("inlineCode",{parentName:"a"},"overrides"))," we can point the ",(0,r.kt)("inlineCode",{parentName:"p"},"ref-napi")," package to ",(0,r.kt)("inlineCode",{parentName:"p"},"@2060.io/ref-napi"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "overrides": {\n "ref-napi": "npm:@2060.io/ref-napi"\n }\n}\n'))),(0,r.kt)(o.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,r.kt)("p",null,"Using ",(0,r.kt)("a",{parentName:"p",href:"https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/"},"Yarn ",(0,r.kt)("inlineCode",{parentName:"a"},"resolutions"))," we can point the ",(0,r.kt)("inlineCode",{parentName:"p"},"ref-napi")," package to ",(0,r.kt)("inlineCode",{parentName:"p"},"@2060.io/ref-napi"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "resolutions": {\n "ref-napi": "npm:@2060.io/ref-napi"\n }\n}\n')))),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"See the following issues for more information on the performance bottleneck"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-askar/issues/76"},"https://github.com/hyperledger/aries-askar/issues/76")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/node-ffi-napi/ref-napi/issues/72"},"https://github.com/node-ffi-napi/ref-napi/issues/72")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/node-ffi-napi/ref-napi/pull/73"},"https://github.com/node-ffi-napi/ref-napi/pull/73")))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8b5bb00b.74a71399.js b/assets/js/8b5bb00b.74a71399.js deleted file mode 100644 index a187545d..00000000 --- a/assets/js/8b5bb00b.74a71399.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8417],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=a.createContext({}),d=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=d(e.components);return a.createElement(s.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),p=d(n),m=o,h=p["".concat(s,".").concat(m)]||p[m]||u[m]||i;return n?a.createElement(h,r(r({ref:t},c),{},{components:n})):a.createElement(h,r({ref:t},c))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:o,r[1]=l;for(var d=2;d{n.d(t,{Z:()=>r});var a=n(7294),o=n(6010);const i={tabItem:"tabItem_Ymn6"};function r(e){let{children:t,hidden:n,className:r}=e;return a.createElement("div",{role:"tabpanel",className:(0,o.Z)(i.tabItem,r),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),o=n(7294),i=n(6010),r=n(2466),l=n(6550),s=n(1980),d=n(7392),c=n(12);function p(e){return function(e){return o.Children.map(e,(e=>{if((0,o.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:o}}=e;return{value:t,label:n,attributes:a,default:o}}))}function u(e){const{values:t,children:n}=e;return(0,o.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,d.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const a=(0,l.k6)(),i=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._X)(i),(0,o.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(a.location.search);t.set(i,e),a.replace({...a.location,search:t.toString()})}),[i,a])]}function g(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,i=u(e),[r,l]=(0,o.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(!m({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:i}))),[s,d]=h({queryString:n,groupId:a}),[p,g]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,i]=(0,c.Nk)(n);return[a,(0,o.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:a}),f=(()=>{const e=s??p;return m({value:e,tabValues:i})?e:null})();(0,o.useLayoutEffect)((()=>{f&&l(f)}),[f]);return{selectedValue:r,selectValue:(0,o.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);l(e),d(e),g(e)}),[d,g,i]),tabValues:i}}var f=n(2389);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:n,selectedValue:l,selectValue:s,tabValues:d}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,r.o5)(),u=e=>{const t=e.currentTarget,n=c.indexOf(t),a=d[n].value;a!==l&&(p(t),s(a))},m=e=>{let t=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return o.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},d.map((e=>{let{value:t,label:n,attributes:r}=e;return o.createElement("li",(0,a.Z)({role:"tab",tabIndex:l===t?0:-1,"aria-selected":l===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:u},r,{className:(0,i.Z)("tabs__item",v.tabItem,r?.className,{"tabs__item--active":l===t})}),n??t)})))}function b(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,o.cloneElement)(e,{className:"margin-top--md"}):null}return o.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,o.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function y(e){const t=g(e);return o.createElement("div",{className:(0,i.Z)("tabs-container",v.tabList)},o.createElement(k,(0,a.Z)({},e,t)),o.createElement(b,(0,a.Z)({},e,t)))}function w(e){const t=(0,f.Z)();return o.createElement(y,(0,a.Z)({key:String(t)},e))}},8610:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>l,metadata:()=>d,toc:()=>p});var a=n(7462),o=(n(7294),n(3905)),i=n(4866),r=n(5162);const l={},s="Migrating from AFJ 0.1.0 to 0.2.x",d={unversionedId:"updating/versions/0.1-to-0.2",id:"version-0.4/updating/versions/0.1-to-0.2",title:"Migrating from AFJ 0.1.0 to 0.2.x",description:"This document describes everything you need to know for updating AFJ 0.1.0 to 0.2.x. If you're not aware of how updating in AFJ works make sure to first read the guide on Updating AFJ.",source:"@site/versioned_docs/version-0.4/updating/versions/0.1-to-0.2.md",sourceDirName:"updating/versions",slug:"/updating/versions/0.1-to-0.2",permalink:"/guides/updating/versions/0.1-to-0.2",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Migrating from an Indy SDK Wallet to Aries Askar",permalink:"/guides/updating/update-indy-sdk-to-askar"},next:{title:"Migrating from AFJ 0.2.x to 0.3.x",permalink:"/guides/updating/versions/0.2-to-0.3"}},c={},p=[{value:"React Native",id:"react-native",level:4},{value:"Node",id:"node",level:4},{value:"Breaking Code Changes",id:"breaking-code-changes",level:2},{value:"Credentials Module",id:"credentials-module",level:3},{value:"Module API Updates",id:"module-api-updates",level:4},{value:"0.1.0",id:"010",level:5},{value:"0.2.x",id:"02x",level:5},{value:"Data from Received Messages only Stored in Record after Accepting",id:"data-from-received-messages-only-stored-in-record-after-accepting",level:4},{value:"0.1.0",id:"010-1",level:5},{value:"0.2.x",id:"02x-1",level:5},{value:"Messages Extracted from Credential Record",id:"messages-extracted-from-credential-record",level:4},{value:"0.1.0",id:"010-2",level:5},{value:"0.2.x",id:"02x-2",level:5},{value:"Connections Module",id:"connections-module",level:3},{value:"Creating a Legacy Invitation",id:"creating-a-legacy-invitation",level:4},{value:"0.1.0",id:"010-3",level:5},{value:"0.2.x",id:"02x-3",level:5},{value:"Receiving a Legacy Invitation",id:"receiving-a-legacy-invitation",level:4},{value:"0.1.0",id:"010-4",level:5},{value:"0.2.x",id:"02x-4",level:5},{value:"Updating to use DidExchangeState",id:"updating-to-use-didexchangestate",level:4},{value:"Updating Custom Messages to the New Message Type Objects",id:"updating-custom-messages-to-the-new-message-type-objects",level:3},{value:"0.1.0",id:"010-5",level:4},{value:"0.2.x",id:"02x-5",level:4},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:2},{value:"Credential Metadata",id:"credential-metadata",level:3},{value:"0.1.0",id:"010-6",level:4},{value:"0.2.x",id:"02x-6",level:4},{value:"Migrate Credential Record Properties",id:"migrate-credential-record-properties",level:3},{value:"0.1.0",id:"010-7",level:4},{value:"0.2.x",id:"02x-7",level:4},{value:"Mediation Record Role",id:"mediation-record-role",level:3},{value:"Extracting Did Documents to Did Repository",id:"extracting-did-documents-to-did-repository",level:3},{value:"0.1.0",id:"010-8",level:4},{value:"0.2.x",id:"02x-8",level:4},{value:"Migrating to the Out of Band Record",id:"migrating-to-the-out-of-band-record",level:3},{value:"0.1.0",id:"010-9",level:4},{value:"0.2.x",id:"02x-9",level:4},{value:"Unifying Connection States and Roles",id:"unifying-connection-states-and-roles",level:3},{value:"0.1.0",id:"010-10",level:4},{value:"0.2.0",id:"020",level:4}],u={toc:p},m="wrapper";function h(e){let{components:t,...n}=e;return(0,o.kt)(m,(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"migrating-from-afj-010-to-02x"},"Migrating from AFJ 0.1.0 to 0.2.x"),(0,o.kt)("p",null,"This document describes everything you need to know for updating AFJ 0.1.0 to 0.2.x. If you're not aware of how updating in AFJ works make sure to first read the guide on ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.5/updating/"},"Updating AFJ"),"."),(0,o.kt)("p",null,"First of all, update you dependencies to the 0.2.x versions. This will also update the needed peer depedencnies. ",(0,o.kt)("strong",{parentName:"p"},"Extension packages are not updated with this command"),". You need to update these manually, and make sure they're up to date with the latest version of AFJ."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"React Native",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/react-native@^0.2.0 @aries-framework/core@^0.2.0 indy-sdk-react-native@^0.2.0\n\n# or NPM\nnpn install @aries-framework/react-native@^0.2.0 @aries-framework/core@^0.2.0 indy-sdk-react-native@^0.2.0\n"))),(0,o.kt)(r.Z,{label:"Node",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/node@^0.2.0 @aries-framework/core@^0.2.0\n\n# or NPM\nnpm install @aries-framework/node@^0.2.0 @aries-framework/core@^0.2.0\n")))),(0,o.kt)("h2",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,o.kt)("p",null,"This section will list all breaking changes made to the public API of AFJ between version 0.1.0 and 0.2.0."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here (e.g. see ",(0,o.kt)("a",{parentName:"p",href:"#updating-custom-messages-to-the-new-message-type-objects"},"Updating Custom Messages to the New Message Type Objects"),"), but it is possible some breaking changes are not documented here (feel free to open PRs).")),(0,o.kt)("h3",{id:"credentials-module"},"Credentials Module"),(0,o.kt)("h4",{id:"module-api-updates"},"Module API Updates"),(0,o.kt)("p",null,"With the addition of the issue credential v2 protocol and the preparation for multiple attachment formats (to be added in a later release), we've made some big changes to the credentials module API. Most changes are related to structure, so updating your code to the new API should be straightforward."),(0,o.kt)("p",null,"Basically for all methods in the credential module you should take the following steps to update your code:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Move all function parameters into a single object. All module methods now take a single object that contain all properties."),(0,o.kt)("li",{parentName:"ol"},"For methods that initiate a protocol (starting from offer, proposal), you should pass ",(0,o.kt)("inlineCode",{parentName:"li"},"protocolVersion: 'v1'")," to indicate we should use the v1 protocol. (v2 is also supported, but this focuses on the breaking changes, not the new features)."),(0,o.kt)("li",{parentName:"ol"},"All indy specific attributes (e.g. credentialDefinitionId) should be passed in the ",(0,o.kt)("inlineCode",{parentName:"li"},"credentialFormats.indy")," object."),(0,o.kt)("li",{parentName:"ol"},"The preview should now be passed as only the preview attributes (the the full preview) and provided in the ",(0,o.kt)("inlineCode",{parentName:"li"},"credentialFormats.indy")," object.")),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.credentials.offerCredential('connectionId', {\n autoAcceptCredential: AutoAcceptCredential.Always,\n comment: 'hello',\n\n credentialDefinitionId: 'credentialDefinitionId',\n preview: new CredentialPreview({\n attributes: [new CredentialPreviewAttribute({ name: 'key', value: 'value' })],\n }),\n})\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.credentials.offerCredential({\n connectionId: 'connectionId',\n protocolVersion: 'v1',\n\n autoAcceptCredential: AutoAcceptCredential.Always,\n comment: 'hello',\n\n credentialFormats: {\n indy: {\n credentialDefinitionId: 'credentialDefinitionId',\n attributes: [{ name: 'key', value: 'value' }],\n },\n },\n})\n")))),(0,o.kt)("h4",{id:"data-from-received-messages-only-stored-in-record-after-accepting"},"Data from Received Messages only Stored in Record after Accepting"),(0,o.kt)("p",null,"Previously when we received a message from another connection we would store the relevant data from the exchange in the credential record. The values we would store were the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialDefinitionId")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"schemaId")," in the credential metadata, and the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialAttributes")," field."),(0,o.kt)("p",null,"Starting with AFJ 0.2.0 the values are not stored in the credential record until after the message content has been accepted (in the case of an offer this means after sending the request message). This is to avoid ambiguity of the values in the credential record. If I have sent a proposal and then receive an offer, should the credential record contain the values from the proposal or the values from the offer? The first one reflects our view on what the data should be, the second one reflects the latest data."),(0,o.kt)("p",null,"We decided to make the record properties always hold our view of what the data should be, and only update it after accepting the contents of a received message (either using auto accept, or by calling the ",(0,o.kt)("inlineCode",{parentName:"p"},"acceptXXX")," methods on the credential module)."),(0,o.kt)("p",null,"This is an important change and requires some updates to how you extract the relevant data from the offer (or other messages such the proposal). We've added a new ",(0,o.kt)("inlineCode",{parentName:"p"},"getFormatData")," method on the credentials module that allows you to retrieve the attributes and format data for all messages in an exchange. One of the advantages of this approach is that we don't have to store all relevant data in the credential record anymore, which helps when adding new formats that don't match with the attributes used for indy credentials. In addition, the return value for this method is the same whether v1 or v2 of the protocol is used. This means your code should only care about the credential format (indy in this case) and doesn't have to worry about the protocol version."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"agent.events.on(\n CredentialEventTypes.CredentialStateChanged,\n ({ payload: { credentialRecord } }) => {\n const indyCredentialMetadata = credentialRecord.metadata.get(CredentialMetadataKeys.IndyCredential)\n\n // Get credential definition id, schema id and attributes from offer\n const credentialDefinitionId = indyCredentialMetadata?.credentialDefinitionId\n const schemaId = indyCredentialMetadata?.schemaId\n const attributes = credentialRecord.credentialAttributes\n }\n)\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"agent.events.on(\n CredentialEventTypes.CredentialStateChanged,\n async ({ payload: { credentialRecord } }) => {\n const formatData = await agent.credentials.getFormatData(credentialRecord.id)\n\n // Get credential definition id, schema id and attributes from offer\n const credentialDefinitionId = formatData.offer?.indy?.cred_def_id\n const schemaId = formatData.offer?.indy?.schema_id\n const attributes = formatData.offerAttributes\n }\n)\n")),(0,o.kt)("p",null,"The return value of the ",(0,o.kt)("inlineCode",{parentName:"p"},"getFormatData")," method is fully typed an directly returns the format data as encoded in the attachment. It also returns the ",(0,o.kt)("inlineCode",{parentName:"p"},"proposalAttributes")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"offerAttributes")," values which contain the attributes for the indy credential. This is not part of the attachment data itself, but can be seen as the format data for the credential."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"{\n proposalAttributes: [{ name: 'key', value: 'value' mimeType: 'text/plain' }],\n proposal: {\n indy: { } // indy proposal as described in RFC 0592\n },\n offerAttributes: [{ name: 'key', value: 'value' mimeType: 'text/plain' }],\n offer: {\n indy: { } // indy offer as described in RFC 0592\n },\n request: {\n indy: { } // indy request as described in RFC 0592\n }\n credential: {\n indy: { } // indy credential as described in RFC 0592\n }\n}\n")))),(0,o.kt)("h4",{id:"messages-extracted-from-credential-record"},"Messages Extracted from Credential Record"),(0,o.kt)("p",null,"The DIDComm messages that were previously stored on the credential record, have been extracted to separate DIDComm message records. This makes it easier to work with multiple versions of the protocol internally, and keeps the credential exchange record agnostic of the protocol version. Instead of accessing the messages through the ",(0,o.kt)("inlineCode",{parentName:"p"},"proposalMessage"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"offerMessage"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"requestMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialMessage")," parameters, we now expose dedicated methods on the credentials module to retrieve the message."),(0,o.kt)("p",null,"With the addition of the v2 messages, all v1 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," while v2 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V2")," (",(0,o.kt)("inlineCode",{parentName:"p"},"V1ProposeCredentialMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"V2ProposeCredentialMessage"),"). If you were using these messages classes throughout your codebase, update them to use the ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," prefix."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const credentialRecord = await agent.credentials.getById('credentialRecordId')\n\nconst proposalMessage = credentialRecord.proposalMessage\nconst offerMessage = credentialRecord.offerMessage\nconst requestMessage = credentialRecord.requestMessage\nconst credentialMessage = credentialRecord.credentialMessage\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const credentialRecord = await agent.credentials.getById('credentialRecordId')\n\nconst proposalMessage = await agent.credentials.findProposalMessage('credentialRecordId')\nconst offerMessage = await agent.credentials.findOfferMessage('credentialRecordId')\nconst requestMessage = await agent.credentials.findRequestMessage('credentialRecordId')\nconst credentialMessage = await agent.credentials.findCredentialMessage('credentialRecordId')\n")),(0,o.kt)("p",null,"Because AFJ now also supports the issue credential v2 protocol, the return type of this protocol has been changed to ",(0,o.kt)("inlineCode",{parentName:"p"},"V1XXXMessage | V2XXXMessage | null"),". Take this into account when working with the messages."),(0,o.kt)("p",null,"You can check if a message is a specific version by using the ",(0,o.kt)("inlineCode",{parentName:"p"},"instanceof")," operator:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"if (proposalMessage instanceof V1ProposeCredentialMessage) {\n // do something\n}\n")),(0,o.kt)("p",null,"Shared properties (e.g. the proposal messages for v1 and v2 both have the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialPreview")," property) can be accessed without doing an instance check."))),(0,o.kt)("h3",{id:"connections-module"},"Connections Module"),(0,o.kt)("p",null,"Version 0.2.0 added support for the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md"},"Out of Band protocol")," with support for the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0023-did-exchange"},"DID Exchange protocol"),". Internally AFJ now uses out of band invitations for all connections, even if you're connecting using the old invitations from the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0160-connection-protocol"},"Connection protocol"),"."),(0,o.kt)("h4",{id:"creating-a-legacy-invitation"},"Creating a Legacy Invitation"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"createInvitation")," method on the connections module has been moved to the out of band module and renamed to ",(0,o.kt)("inlineCode",{parentName:"p"},"createLegacyInvitation"),". The method is not planned to be removed in the near future, the legacy merely indicates this will create an RFC 0160 connection invitation. Internally AFJ creates an out of band invitation and transforms it into a legacy invitation. If you want to create an out of band invitation instead, you should use ",(0,o.kt)("inlineCode",{parentName:"p"},"oob.createInvitation"),"."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { connectionRecord, invitation } = await agent.connections.createInvitation({\n /* config */\n})\n\nconst invitationUrl = invitation.toUrl({ domain: 'https://example.com' })\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { outOfBandRecord, invitation } = await agent.oob.createLegacyInvitation({\n /* config */\n})\n\nconst invitationUrl = invitation.toUrl({ domain: 'https://example.com' })\n")),(0,o.kt)("p",null,"Important thing to note here is that the ",(0,o.kt)("inlineCode",{parentName:"p"},"oob.createLegacyInvitation")," does not return a connection record, but rather an out of band record. Because out of band also supports connection-less scenarios, a connection record is not created until a connection request is received (or sent in the case of the invitee role)."),(0,o.kt)("p",null,"You can listen for connection state change events that are associated with a specific out of band id. This allows you to link a connection to an invitation you created."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"// Listen for connection state changed events associated with the out of band record\nagent.events.on(ConnectionEventTypes.ConnectionStateChanged, (event) => {\n if (event.payload.connectionRecord.outOfBandId === outOfBandRecord.id) {\n console.log(`Connection state changed for connection with out of band id ${outOfBandRecord.id}`)\n }\n})\n")),(0,o.kt)("p",null,"It is also possible to retrieve all connection records associated with an out of band invitation. Because of multi use invitations, there could be multiple connection records associated with a single out of band invitation. Instead of having a separate connection record that will always stay in the invited state, the out of band record will now handle the multi use capabilities of an invitation."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"// Retrieve all connections associated with an out of band id\nconst connections = await agent.connections.findAllByOutOfBandId(outOfBandRecord.id)\n")))),(0,o.kt)("h4",{id:"receiving-a-legacy-invitation"},"Receiving a Legacy Invitation"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"receiveInvitation")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"receiveInvitationFromUrl")," methods on the connections module have also been moved to the out of band module. Both methods support the new out of band invitations and the legacy RFC 0160 connection invitations. Internally AFJ converts the old invitations to out of band invitations."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const invitationUrl = 'https://example.com?c_i=eyXXX'\n\n// Receive invitation directly from url\nconst connectionRecord = await agent.connections.receiveInvitationFromUrl(invitationUrl, {\n /* config */\n})\n\n// Parse invitation and receive invitation\nconst parsedInvitation = await ConnectionInvitationMessage.fromUrl(invitationUrl)\nconst connectionRecord = await agent.connections.receiveInvitation(parsedInvitation, {\n /* config */\n})\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const invitationUrl = 'https://example.com?c_i=eyXXX'\n\n// Receive invitation directly from url\nconst { outOfBandRecord, connectionRecord } = await agent.oob.receiveInvitationFromUrl(invitationUrl, {\n /* config */\n})\n\n// Parse invitation and receive invitation\nconst parsedInvitation = await agent.oob.parseInvitation(invitationUrl)\nconst secondConnectionRecord = await agent.oob.receiveInvitation(parsedInvitation, {\n /* config */\n})\n")),(0,o.kt)("p",null,"The new receive invitation methods on the out of band module won't always return a connection record anymore. The out of band invitation may not contain any handshake protocols. In the case of receiving a connection invitation you will always receive a connection record though, as you can't use it for connection-less invitations."))),(0,o.kt)("h4",{id:"updating-to-use-didexchangestate"},"Updating to use ",(0,o.kt)("inlineCode",{parentName:"h4"},"DidExchangeState")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," that was previously used for the state of the ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionRecord")," has been changed to use the ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," for both connections made using the RFC 0160 Connection Protocol, as well as the RFC 0023 DID Exchange Protocol."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," has the following values:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.Start"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.InvitationSent"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.InvitationReceived"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.RequestSent"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.RequestReceived"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.ResponseSent"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.ResponseReceived"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.Abandoned"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.Completed"))),(0,o.kt)("p",null,"If you still need to access the old ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," you can do so by accessing the computed ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionRecord.rfc0160State")," property. This will return the old ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," value."),(0,o.kt)("h3",{id:"updating-custom-messages-to-the-new-message-type-objects"},"Updating Custom Messages to the New Message Type Objects"),(0,o.kt)("p",null,"Although this isn't a breaking change to the public API of the framework, it is something that you will need to take into account when creating custom modules. Starting from AFJ 0.2.0 we now support handling messages with different minor versions (e.g. receive a message with ",(0,o.kt)("inlineCode",{parentName:"p"},"@type")," version 1.1 while we only support 1.0). With this change messages must now declare the message type as an ",(0,o.kt)("inlineCode",{parentName:"p"},"ParsedMessageType")," object. We've added an ",(0,o.kt)("inlineCode",{parentName:"p"},"parseMessageType")," util method that can help with this."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { AgentMessage } from '@aries-framework/core'\nimport { Equals } from 'class-validator'\n\nclass MyMessage extends AgentMessage {\n @Equals(MyMessage.type)\n public readonly type = MyMessage.type\n public static readonly type = 'https://didcomm.org/my-protocol/1.0/my-type'\n}\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { AgentMessage, IsValidMessageType, parseMessageType } from '@aries-framework/core'\nimport { Equals } from 'class-validator'\n\nclass MyMessage extends AgentMessage {\n // use IsValidMessageType instead of Equals\n @IsValidMessageType(MyMessage.type)\n // append .messageTypeUri to get the actual URI when instantiating a message\n public readonly type = MyMessage.type.messageTypeUri\n // use parseMessageType to get the message type object from a type. You can declare the object yourself, but this is the recommended way\n public static readonly type = parseMessageType('https://didcomm.org/my-protocol/1.0/my-type')\n}\n")))),(0,o.kt)("h2",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,o.kt)("p",null,"The 0.2.0 release is heavy on breaking changes to the storage format. This is not what we intend to do with every release. But as there's not that many people yet using the framework in production, and there were a lot of changes needed to keep the API straightforward, we decided to bundle a lot of breaking changes in this one release."),(0,o.kt)("p",null,"Below all breaking storage changes are explained in as much detail as possible. The update assistant provides all tools to migrate without a hassle, but it is important to know what has changed. All examples only show the keys that have changed, unrelated keys in records have been omitted."),(0,o.kt)("p",null,"See the ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.5/updating/update-assistant"},"Update Assistant")," documentation for a guide on how to use the update assistant."),(0,o.kt)("p",null,"The following config can be provided to the update assistant to migrate from 0.1.0 to 0.2.0:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "v0_1ToV0_2": {\n "mediationRoleUpdateStrategy": ""\n }\n}\n')),(0,o.kt)("h3",{id:"credential-metadata"},"Credential Metadata"),(0,o.kt)("p",null,"The credential record had a custom ",(0,o.kt)("inlineCode",{parentName:"p"},"metadata")," property in pre-0.1.0 storage that contained the ",(0,o.kt)("inlineCode",{parentName:"p"},"requestMetadata"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"schemaId")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialDefinition")," properties. Later a generic metadata API was added that only allows objects to be stored. Therefore the properties were moved into a different structure."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "requestMetadata": ,\n "schemaId": "",\n "credentialDefinitionId": ""\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "_internal/indyRequest": ,\n "_internal/indyCredential": {\n "schemaId": "",\n "credentialDefinitionId": ""\n }\n}\n')),(0,o.kt)("p",null,"Accessing the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialDefinitionId")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"schemaId")," properties will now be done by retrieving the ",(0,o.kt)("inlineCode",{parentName:"p"},"CredentialMetadataKeys.IndyCredential")," metadata key."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const indyCredential = credentialRecord.metadata.get(CredentialMetadataKeys.IndyCredential)\n\n// both properties are optional\nindyCredential?.credentialDefinitionId\nindyCredential?.schemaId\n")))),(0,o.kt)("h3",{id:"migrate-credential-record-properties"},"Migrate Credential Record Properties"),(0,o.kt)("p",null,"In 0.2.0 the v1 DIDComm messages have been moved out of the credential record into separate records using the DidCommMessageRepository. The migration scripts extracts all messages (proposalMessage, offerMessage, requestMessage, credentialMessage) and moves them into the DidCommMessageRepository."),(0,o.kt)("p",null,"With the addition of support for different protocol versions the credential record now stores the protocol version. With the addition of issue credential v2 support, other credential formats than indy can be used, and multiple credentials can be issued at once. To account for this the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialId")," has been replaced by the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentials")," array. This is an array of objects containing the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialRecordId")," and the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialRecordType"),". For all current credentials the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialRecordType")," will always be ",(0,o.kt)("inlineCode",{parentName:"p"},"indy"),"."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "credentialId": "09e46da9-a575-4909-b016-040e96c3c539",\n "proposalMessage": { ... },\n "offerMessage": { ... },\n "requestMessage": { ... },\n "credentialMessage": { ... },\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "protocolVersion": "v1",\n "credentials": [\n {\n "credentialRecordId": "09e46da9-a575-4909-b016-040e96c3c539",\n "credentialRecordType": "indy"\n }\n ]\n}\n')))),(0,o.kt)("h3",{id:"mediation-record-role"},"Mediation Record Role"),(0,o.kt)("p",null,"The role in the mediation record was always being set to ",(0,o.kt)("inlineCode",{parentName:"p"},"MediationRole.Mediator")," for both mediators and recipients. This didn't cause any issues, but would return the wrong role for recipients."),(0,o.kt)("p",null,"In 0.2 a check is added to make sure the role of a mediation record matches with actions (e.g. a recipient can't grant mediation), which means it will throw an error if the role is not set correctly."),(0,o.kt)("p",null,"Because it's not always possible detect whether the role should actually be mediator or recipient, a number of configuration options are provided on how the role should be updated using the ",(0,o.kt)("inlineCode",{parentName:"p"},"v0_1ToV0_2.mediationRoleUpdateStrategy")," option:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"allMediator"),": The role is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Mediator")," for both mediators and recipients"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"allRecipient"),": The role is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Recipient")," for both mediators and recipients"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"recipientIfEndpoint")," (",(0,o.kt)("strong",{parentName:"li"},"default"),"): The role is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Recipient")," if their is an ",(0,o.kt)("inlineCode",{parentName:"li"},"endpoint")," configured on the record. The endpoint is not set when running as a mediator. There is one case where this could be problematic when the role should be recipient, if the mediation grant hasn't actually occurred (meaning the endpoint is not set). This is probably the best approach\notherwise it is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Mediator")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"doNotChange"),": The role is not changed")),(0,o.kt)("p",null,"Most agents only act as either the role of mediator or recipient, in which case the ",(0,o.kt)("inlineCode",{parentName:"p"},"allMediator")," or ",(0,o.kt)("inlineCode",{parentName:"p"},"allRecipient")," configuration is the most appropriate. If your agent acts as both a recipient and mediator, the ",(0,o.kt)("inlineCode",{parentName:"p"},"recipientIfEndpoint")," configuration is the most appropriate. The ",(0,o.kt)("inlineCode",{parentName:"p"},"doNotChange")," options is not recommended and can lead to errors if the role is not set correctly."),(0,o.kt)("h3",{id:"extracting-did-documents-to-did-repository"},"Extracting Did Documents to Did Repository"),(0,o.kt)("p",null,"The connection record previously stored both did documents from a connection in the connection record itself. Version 0.2.0 added a generic did storage that can be used for numerous usages, one of which is the storage of did documents for connection records."),(0,o.kt)("p",null,"The migration script extracts the did documents from the ",(0,o.kt)("inlineCode",{parentName:"p"},"didDoc")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"theirDidDoc")," properties from the connection record, updates them to did documents compliant with the did core spec, and stores them in the did repository. By doing so it also updates the unqualified dids in the ",(0,o.kt)("inlineCode",{parentName:"p"},"did")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"theirDid")," fields generated by the indy-sdk to fully qualified ",(0,o.kt)("inlineCode",{parentName:"p"},"did:peer")," dids compliant with the ",(0,o.kt)("a",{parentName:"p",href:"https://identity.foundation/peer-did-method-spec/"},"Peer DID Method Specification"),"."),(0,o.kt)("p",null,"To account for the fact that the mechanism to migrate legacy did document to peer did documents is not defined yet, the legacy did and did document are stored in the did record metadata. This will be deleted later if we can be certain the did doc conversion to a ",(0,o.kt)("inlineCode",{parentName:"p"},"did:peer")," did document is correct."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "did": "BBPoJqRKatdcfLEAFL7exC",\n "theirDid": "UppcJ5APts7ot5WX25943F",\n "verkey": "GAb4NUvpBcHVCvtP45vTVa5Bp74vFg3iXzdp1Gbd68Wf",\n "didDoc": ,\n "theirDidDoc": ,\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "did": "did:peer:1zQmXUaPPhPCbUVZ3hGYmQmGxWTwyDfhqESXCpMFhKaF9Y2A",\n "theirDid": "did:peer:1zQmZMygzYqNwU6Uhmewx5Xepf2VLp5S4HLSwwgf2aiKZuwa"\n}\n')))),(0,o.kt)("h3",{id:"migrating-to-the-out-of-band-record"},"Migrating to the Out of Band Record"),(0,o.kt)("p",null,"With the addition of the out of band protocol, invitations are now stored in the ",(0,o.kt)("inlineCode",{parentName:"p"},"OutOfBandRecord"),". In addition a new field ",(0,o.kt)("inlineCode",{parentName:"p"},"invitationDid")," is added to the connection record that is generated based on the invitation service or did. This allows to reuse existing connections."),(0,o.kt)("p",null,"The migration script extracts the invitation and other relevant data into a separate ",(0,o.kt)("inlineCode",{parentName:"p"},"OutOfBandRecord"),". By doing so it converts the old connection protocol invitation into the new Out of band invitation message. Based on the service or did of the invitation, the ",(0,o.kt)("inlineCode",{parentName:"p"},"invitationDid")," is populated."),(0,o.kt)("p",null,"Previously when creating a multi use invitation, a connection record would be created with the ",(0,o.kt)("inlineCode",{parentName:"p"},"multiUseInvitation")," set to true. The connection record would always be in state ",(0,o.kt)("inlineCode",{parentName:"p"},"invited"),". If a request for the multi use invitation came in, a new connection record would be created. With the addition of the out of band module, no connection records are created until a request is received. So for multi use invitation this means that the connection record with multiUseInvitation=true will be deleted, and instead all connections created using that out of band invitation will contain the ",(0,o.kt)("inlineCode",{parentName:"p"},"outOfBandId")," of the multi use invitation."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "invitation": {\n "@type": "https://didcomm.org/connections/1.0/invitation",\n "@id": "04a2c382-999e-4de9-a1d2-9dec0b2fa5e4",\n "recipientKeys": ["E6D1m3eERqCueX4ZgMCY14B4NceAr6XP2HyVqt55gDhu"],\n "serviceEndpoint": "https://example.com",\n "label": "test"\n },\n "multiUseInvitation": "false"\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "invitationDid": "did:peer:2.Ez6MksYU4MHtfmNhNm1uGMvANr9j4CBv2FymjiJtRgA36bSVH.SeyJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbSJ9",\n "outOfBandId": "04a2c382-999e-4de9-a1d2-9dec0b2fa5e4"\n}\n')))),(0,o.kt)("h3",{id:"unifying-connection-states-and-roles"},"Unifying Connection States and Roles"),(0,o.kt)("p",null,"With the addition of the did exchange protocol there are now two states and roles related to the connection record; for the did exchange protocol and for the connection protocol. To keep it easy to work with the connection record, all state and role values are updated to those of the ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeRole")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," enums."),(0,o.kt)("p",null,"The migration script transforms all connection record state and role values to their respective values of the ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeRole")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," enums. For convenience a getter\nproperty ",(0,o.kt)("inlineCode",{parentName:"p"},"rfc0160ConnectionState")," is added to the connection record which returns the ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," value."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "state": "invited",\n "role": "inviter"\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.0",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "state": "invitation-sent",\n "role": "responder"\n}\n')))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8b5bb00b.d378dc12.js b/assets/js/8b5bb00b.d378dc12.js new file mode 100644 index 00000000..c48a1373 --- /dev/null +++ b/assets/js/8b5bb00b.d378dc12.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8417],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=a.createContext({}),d=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=d(e.components);return a.createElement(s.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),p=d(n),m=o,h=p["".concat(s,".").concat(m)]||p[m]||u[m]||i;return n?a.createElement(h,r(r({ref:t},c),{},{components:n})):a.createElement(h,r({ref:t},c))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:o,r[1]=l;for(var d=2;d{n.d(t,{Z:()=>r});var a=n(7294),o=n(6010);const i={tabItem:"tabItem_Ymn6"};function r(e){let{children:t,hidden:n,className:r}=e;return a.createElement("div",{role:"tabpanel",className:(0,o.Z)(i.tabItem,r),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),o=n(7294),i=n(6010),r=n(2466),l=n(6550),s=n(1980),d=n(7392),c=n(12);function p(e){return function(e){return o.Children.map(e,(e=>{if((0,o.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:o}}=e;return{value:t,label:n,attributes:a,default:o}}))}function u(e){const{values:t,children:n}=e;return(0,o.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,d.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const a=(0,l.k6)(),i=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._X)(i),(0,o.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(a.location.search);t.set(i,e),a.replace({...a.location,search:t.toString()})}),[i,a])]}function g(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,i=u(e),[r,l]=(0,o.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(!m({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:i}))),[s,d]=h({queryString:n,groupId:a}),[p,g]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,i]=(0,c.Nk)(n);return[a,(0,o.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:a}),f=(()=>{const e=s??p;return m({value:e,tabValues:i})?e:null})();(0,o.useLayoutEffect)((()=>{f&&l(f)}),[f]);return{selectedValue:r,selectValue:(0,o.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);l(e),d(e),g(e)}),[d,g,i]),tabValues:i}}var f=n(2389);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:n,selectedValue:l,selectValue:s,tabValues:d}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,r.o5)(),u=e=>{const t=e.currentTarget,n=c.indexOf(t),a=d[n].value;a!==l&&(p(t),s(a))},m=e=>{let t=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return o.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},d.map((e=>{let{value:t,label:n,attributes:r}=e;return o.createElement("li",(0,a.Z)({role:"tab",tabIndex:l===t?0:-1,"aria-selected":l===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:u},r,{className:(0,i.Z)("tabs__item",v.tabItem,r?.className,{"tabs__item--active":l===t})}),n??t)})))}function b(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,o.cloneElement)(e,{className:"margin-top--md"}):null}return o.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,o.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function y(e){const t=g(e);return o.createElement("div",{className:(0,i.Z)("tabs-container",v.tabList)},o.createElement(k,(0,a.Z)({},e,t)),o.createElement(b,(0,a.Z)({},e,t)))}function w(e){const t=(0,f.Z)();return o.createElement(y,(0,a.Z)({key:String(t)},e))}},8610:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>l,metadata:()=>d,toc:()=>p});var a=n(7462),o=(n(7294),n(3905)),i=n(4866),r=n(5162);const l={},s="Migrating from AFJ 0.1.0 to 0.2.x",d={unversionedId:"updating/versions/0.1-to-0.2",id:"version-0.4/updating/versions/0.1-to-0.2",title:"Migrating from AFJ 0.1.0 to 0.2.x",description:"This document describes everything you need to know for updating AFJ 0.1.0 to 0.2.x. If you're not aware of how updating in AFJ works make sure to first read the guide on Updating AFJ.",source:"@site/versioned_docs/version-0.4/updating/versions/0.1-to-0.2.md",sourceDirName:"updating/versions",slug:"/updating/versions/0.1-to-0.2",permalink:"/guides/0.4/updating/versions/0.1-to-0.2",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Migrating from an Indy SDK Wallet to Aries Askar",permalink:"/guides/0.4/updating/update-indy-sdk-to-askar"},next:{title:"Migrating from AFJ 0.2.x to 0.3.x",permalink:"/guides/0.4/updating/versions/0.2-to-0.3"}},c={},p=[{value:"React Native",id:"react-native",level:4},{value:"Node",id:"node",level:4},{value:"Breaking Code Changes",id:"breaking-code-changes",level:2},{value:"Credentials Module",id:"credentials-module",level:3},{value:"Module API Updates",id:"module-api-updates",level:4},{value:"0.1.0",id:"010",level:5},{value:"0.2.x",id:"02x",level:5},{value:"Data from Received Messages only Stored in Record after Accepting",id:"data-from-received-messages-only-stored-in-record-after-accepting",level:4},{value:"0.1.0",id:"010-1",level:5},{value:"0.2.x",id:"02x-1",level:5},{value:"Messages Extracted from Credential Record",id:"messages-extracted-from-credential-record",level:4},{value:"0.1.0",id:"010-2",level:5},{value:"0.2.x",id:"02x-2",level:5},{value:"Connections Module",id:"connections-module",level:3},{value:"Creating a Legacy Invitation",id:"creating-a-legacy-invitation",level:4},{value:"0.1.0",id:"010-3",level:5},{value:"0.2.x",id:"02x-3",level:5},{value:"Receiving a Legacy Invitation",id:"receiving-a-legacy-invitation",level:4},{value:"0.1.0",id:"010-4",level:5},{value:"0.2.x",id:"02x-4",level:5},{value:"Updating to use DidExchangeState",id:"updating-to-use-didexchangestate",level:4},{value:"Updating Custom Messages to the New Message Type Objects",id:"updating-custom-messages-to-the-new-message-type-objects",level:3},{value:"0.1.0",id:"010-5",level:4},{value:"0.2.x",id:"02x-5",level:4},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:2},{value:"Credential Metadata",id:"credential-metadata",level:3},{value:"0.1.0",id:"010-6",level:4},{value:"0.2.x",id:"02x-6",level:4},{value:"Migrate Credential Record Properties",id:"migrate-credential-record-properties",level:3},{value:"0.1.0",id:"010-7",level:4},{value:"0.2.x",id:"02x-7",level:4},{value:"Mediation Record Role",id:"mediation-record-role",level:3},{value:"Extracting Did Documents to Did Repository",id:"extracting-did-documents-to-did-repository",level:3},{value:"0.1.0",id:"010-8",level:4},{value:"0.2.x",id:"02x-8",level:4},{value:"Migrating to the Out of Band Record",id:"migrating-to-the-out-of-band-record",level:3},{value:"0.1.0",id:"010-9",level:4},{value:"0.2.x",id:"02x-9",level:4},{value:"Unifying Connection States and Roles",id:"unifying-connection-states-and-roles",level:3},{value:"0.1.0",id:"010-10",level:4},{value:"0.2.0",id:"020",level:4}],u={toc:p},m="wrapper";function h(e){let{components:t,...n}=e;return(0,o.kt)(m,(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"migrating-from-afj-010-to-02x"},"Migrating from AFJ 0.1.0 to 0.2.x"),(0,o.kt)("p",null,"This document describes everything you need to know for updating AFJ 0.1.0 to 0.2.x. If you're not aware of how updating in AFJ works make sure to first read the guide on ",(0,o.kt)("a",{parentName:"p",href:"/guides/updating/"},"Updating AFJ"),"."),(0,o.kt)("p",null,"First of all, update you dependencies to the 0.2.x versions. This will also update the needed peer depedencnies. ",(0,o.kt)("strong",{parentName:"p"},"Extension packages are not updated with this command"),". You need to update these manually, and make sure they're up to date with the latest version of AFJ."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"React Native",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/react-native@^0.2.0 @aries-framework/core@^0.2.0 indy-sdk-react-native@^0.2.0\n\n# or NPM\nnpn install @aries-framework/react-native@^0.2.0 @aries-framework/core@^0.2.0 indy-sdk-react-native@^0.2.0\n"))),(0,o.kt)(r.Z,{label:"Node",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/node@^0.2.0 @aries-framework/core@^0.2.0\n\n# or NPM\nnpm install @aries-framework/node@^0.2.0 @aries-framework/core@^0.2.0\n")))),(0,o.kt)("h2",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,o.kt)("p",null,"This section will list all breaking changes made to the public API of AFJ between version 0.1.0 and 0.2.0."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here (e.g. see ",(0,o.kt)("a",{parentName:"p",href:"#updating-custom-messages-to-the-new-message-type-objects"},"Updating Custom Messages to the New Message Type Objects"),"), but it is possible some breaking changes are not documented here (feel free to open PRs).")),(0,o.kt)("h3",{id:"credentials-module"},"Credentials Module"),(0,o.kt)("h4",{id:"module-api-updates"},"Module API Updates"),(0,o.kt)("p",null,"With the addition of the issue credential v2 protocol and the preparation for multiple attachment formats (to be added in a later release), we've made some big changes to the credentials module API. Most changes are related to structure, so updating your code to the new API should be straightforward."),(0,o.kt)("p",null,"Basically for all methods in the credential module you should take the following steps to update your code:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Move all function parameters into a single object. All module methods now take a single object that contain all properties."),(0,o.kt)("li",{parentName:"ol"},"For methods that initiate a protocol (starting from offer, proposal), you should pass ",(0,o.kt)("inlineCode",{parentName:"li"},"protocolVersion: 'v1'")," to indicate we should use the v1 protocol. (v2 is also supported, but this focuses on the breaking changes, not the new features)."),(0,o.kt)("li",{parentName:"ol"},"All indy specific attributes (e.g. credentialDefinitionId) should be passed in the ",(0,o.kt)("inlineCode",{parentName:"li"},"credentialFormats.indy")," object."),(0,o.kt)("li",{parentName:"ol"},"The preview should now be passed as only the preview attributes (the the full preview) and provided in the ",(0,o.kt)("inlineCode",{parentName:"li"},"credentialFormats.indy")," object.")),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.credentials.offerCredential('connectionId', {\n autoAcceptCredential: AutoAcceptCredential.Always,\n comment: 'hello',\n\n credentialDefinitionId: 'credentialDefinitionId',\n preview: new CredentialPreview({\n attributes: [new CredentialPreviewAttribute({ name: 'key', value: 'value' })],\n }),\n})\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.credentials.offerCredential({\n connectionId: 'connectionId',\n protocolVersion: 'v1',\n\n autoAcceptCredential: AutoAcceptCredential.Always,\n comment: 'hello',\n\n credentialFormats: {\n indy: {\n credentialDefinitionId: 'credentialDefinitionId',\n attributes: [{ name: 'key', value: 'value' }],\n },\n },\n})\n")))),(0,o.kt)("h4",{id:"data-from-received-messages-only-stored-in-record-after-accepting"},"Data from Received Messages only Stored in Record after Accepting"),(0,o.kt)("p",null,"Previously when we received a message from another connection we would store the relevant data from the exchange in the credential record. The values we would store were the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialDefinitionId")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"schemaId")," in the credential metadata, and the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialAttributes")," field."),(0,o.kt)("p",null,"Starting with AFJ 0.2.0 the values are not stored in the credential record until after the message content has been accepted (in the case of an offer this means after sending the request message). This is to avoid ambiguity of the values in the credential record. If I have sent a proposal and then receive an offer, should the credential record contain the values from the proposal or the values from the offer? The first one reflects our view on what the data should be, the second one reflects the latest data."),(0,o.kt)("p",null,"We decided to make the record properties always hold our view of what the data should be, and only update it after accepting the contents of a received message (either using auto accept, or by calling the ",(0,o.kt)("inlineCode",{parentName:"p"},"acceptXXX")," methods on the credential module)."),(0,o.kt)("p",null,"This is an important change and requires some updates to how you extract the relevant data from the offer (or other messages such the proposal). We've added a new ",(0,o.kt)("inlineCode",{parentName:"p"},"getFormatData")," method on the credentials module that allows you to retrieve the attributes and format data for all messages in an exchange. One of the advantages of this approach is that we don't have to store all relevant data in the credential record anymore, which helps when adding new formats that don't match with the attributes used for indy credentials. In addition, the return value for this method is the same whether v1 or v2 of the protocol is used. This means your code should only care about the credential format (indy in this case) and doesn't have to worry about the protocol version."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"agent.events.on(\n CredentialEventTypes.CredentialStateChanged,\n ({ payload: { credentialRecord } }) => {\n const indyCredentialMetadata = credentialRecord.metadata.get(CredentialMetadataKeys.IndyCredential)\n\n // Get credential definition id, schema id and attributes from offer\n const credentialDefinitionId = indyCredentialMetadata?.credentialDefinitionId\n const schemaId = indyCredentialMetadata?.schemaId\n const attributes = credentialRecord.credentialAttributes\n }\n)\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"agent.events.on(\n CredentialEventTypes.CredentialStateChanged,\n async ({ payload: { credentialRecord } }) => {\n const formatData = await agent.credentials.getFormatData(credentialRecord.id)\n\n // Get credential definition id, schema id and attributes from offer\n const credentialDefinitionId = formatData.offer?.indy?.cred_def_id\n const schemaId = formatData.offer?.indy?.schema_id\n const attributes = formatData.offerAttributes\n }\n)\n")),(0,o.kt)("p",null,"The return value of the ",(0,o.kt)("inlineCode",{parentName:"p"},"getFormatData")," method is fully typed an directly returns the format data as encoded in the attachment. It also returns the ",(0,o.kt)("inlineCode",{parentName:"p"},"proposalAttributes")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"offerAttributes")," values which contain the attributes for the indy credential. This is not part of the attachment data itself, but can be seen as the format data for the credential."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"{\n proposalAttributes: [{ name: 'key', value: 'value' mimeType: 'text/plain' }],\n proposal: {\n indy: { } // indy proposal as described in RFC 0592\n },\n offerAttributes: [{ name: 'key', value: 'value' mimeType: 'text/plain' }],\n offer: {\n indy: { } // indy offer as described in RFC 0592\n },\n request: {\n indy: { } // indy request as described in RFC 0592\n }\n credential: {\n indy: { } // indy credential as described in RFC 0592\n }\n}\n")))),(0,o.kt)("h4",{id:"messages-extracted-from-credential-record"},"Messages Extracted from Credential Record"),(0,o.kt)("p",null,"The DIDComm messages that were previously stored on the credential record, have been extracted to separate DIDComm message records. This makes it easier to work with multiple versions of the protocol internally, and keeps the credential exchange record agnostic of the protocol version. Instead of accessing the messages through the ",(0,o.kt)("inlineCode",{parentName:"p"},"proposalMessage"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"offerMessage"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"requestMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialMessage")," parameters, we now expose dedicated methods on the credentials module to retrieve the message."),(0,o.kt)("p",null,"With the addition of the v2 messages, all v1 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," while v2 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V2")," (",(0,o.kt)("inlineCode",{parentName:"p"},"V1ProposeCredentialMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"V2ProposeCredentialMessage"),"). If you were using these messages classes throughout your codebase, update them to use the ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," prefix."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const credentialRecord = await agent.credentials.getById('credentialRecordId')\n\nconst proposalMessage = credentialRecord.proposalMessage\nconst offerMessage = credentialRecord.offerMessage\nconst requestMessage = credentialRecord.requestMessage\nconst credentialMessage = credentialRecord.credentialMessage\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const credentialRecord = await agent.credentials.getById('credentialRecordId')\n\nconst proposalMessage = await agent.credentials.findProposalMessage('credentialRecordId')\nconst offerMessage = await agent.credentials.findOfferMessage('credentialRecordId')\nconst requestMessage = await agent.credentials.findRequestMessage('credentialRecordId')\nconst credentialMessage = await agent.credentials.findCredentialMessage('credentialRecordId')\n")),(0,o.kt)("p",null,"Because AFJ now also supports the issue credential v2 protocol, the return type of this protocol has been changed to ",(0,o.kt)("inlineCode",{parentName:"p"},"V1XXXMessage | V2XXXMessage | null"),". Take this into account when working with the messages."),(0,o.kt)("p",null,"You can check if a message is a specific version by using the ",(0,o.kt)("inlineCode",{parentName:"p"},"instanceof")," operator:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"if (proposalMessage instanceof V1ProposeCredentialMessage) {\n // do something\n}\n")),(0,o.kt)("p",null,"Shared properties (e.g. the proposal messages for v1 and v2 both have the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialPreview")," property) can be accessed without doing an instance check."))),(0,o.kt)("h3",{id:"connections-module"},"Connections Module"),(0,o.kt)("p",null,"Version 0.2.0 added support for the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md"},"Out of Band protocol")," with support for the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0023-did-exchange"},"DID Exchange protocol"),". Internally AFJ now uses out of band invitations for all connections, even if you're connecting using the old invitations from the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0160-connection-protocol"},"Connection protocol"),"."),(0,o.kt)("h4",{id:"creating-a-legacy-invitation"},"Creating a Legacy Invitation"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"createInvitation")," method on the connections module has been moved to the out of band module and renamed to ",(0,o.kt)("inlineCode",{parentName:"p"},"createLegacyInvitation"),". The method is not planned to be removed in the near future, the legacy merely indicates this will create an RFC 0160 connection invitation. Internally AFJ creates an out of band invitation and transforms it into a legacy invitation. If you want to create an out of band invitation instead, you should use ",(0,o.kt)("inlineCode",{parentName:"p"},"oob.createInvitation"),"."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { connectionRecord, invitation } = await agent.connections.createInvitation({\n /* config */\n})\n\nconst invitationUrl = invitation.toUrl({ domain: 'https://example.com' })\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { outOfBandRecord, invitation } = await agent.oob.createLegacyInvitation({\n /* config */\n})\n\nconst invitationUrl = invitation.toUrl({ domain: 'https://example.com' })\n")),(0,o.kt)("p",null,"Important thing to note here is that the ",(0,o.kt)("inlineCode",{parentName:"p"},"oob.createLegacyInvitation")," does not return a connection record, but rather an out of band record. Because out of band also supports connection-less scenarios, a connection record is not created until a connection request is received (or sent in the case of the invitee role)."),(0,o.kt)("p",null,"You can listen for connection state change events that are associated with a specific out of band id. This allows you to link a connection to an invitation you created."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"// Listen for connection state changed events associated with the out of band record\nagent.events.on(ConnectionEventTypes.ConnectionStateChanged, (event) => {\n if (event.payload.connectionRecord.outOfBandId === outOfBandRecord.id) {\n console.log(`Connection state changed for connection with out of band id ${outOfBandRecord.id}`)\n }\n})\n")),(0,o.kt)("p",null,"It is also possible to retrieve all connection records associated with an out of band invitation. Because of multi use invitations, there could be multiple connection records associated with a single out of band invitation. Instead of having a separate connection record that will always stay in the invited state, the out of band record will now handle the multi use capabilities of an invitation."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"// Retrieve all connections associated with an out of band id\nconst connections = await agent.connections.findAllByOutOfBandId(outOfBandRecord.id)\n")))),(0,o.kt)("h4",{id:"receiving-a-legacy-invitation"},"Receiving a Legacy Invitation"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"receiveInvitation")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"receiveInvitationFromUrl")," methods on the connections module have also been moved to the out of band module. Both methods support the new out of band invitations and the legacy RFC 0160 connection invitations. Internally AFJ converts the old invitations to out of band invitations."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const invitationUrl = 'https://example.com?c_i=eyXXX'\n\n// Receive invitation directly from url\nconst connectionRecord = await agent.connections.receiveInvitationFromUrl(invitationUrl, {\n /* config */\n})\n\n// Parse invitation and receive invitation\nconst parsedInvitation = await ConnectionInvitationMessage.fromUrl(invitationUrl)\nconst connectionRecord = await agent.connections.receiveInvitation(parsedInvitation, {\n /* config */\n})\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const invitationUrl = 'https://example.com?c_i=eyXXX'\n\n// Receive invitation directly from url\nconst { outOfBandRecord, connectionRecord } = await agent.oob.receiveInvitationFromUrl(invitationUrl, {\n /* config */\n})\n\n// Parse invitation and receive invitation\nconst parsedInvitation = await agent.oob.parseInvitation(invitationUrl)\nconst secondConnectionRecord = await agent.oob.receiveInvitation(parsedInvitation, {\n /* config */\n})\n")),(0,o.kt)("p",null,"The new receive invitation methods on the out of band module won't always return a connection record anymore. The out of band invitation may not contain any handshake protocols. In the case of receiving a connection invitation you will always receive a connection record though, as you can't use it for connection-less invitations."))),(0,o.kt)("h4",{id:"updating-to-use-didexchangestate"},"Updating to use ",(0,o.kt)("inlineCode",{parentName:"h4"},"DidExchangeState")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," that was previously used for the state of the ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionRecord")," has been changed to use the ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," for both connections made using the RFC 0160 Connection Protocol, as well as the RFC 0023 DID Exchange Protocol."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," has the following values:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.Start"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.InvitationSent"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.InvitationReceived"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.RequestSent"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.RequestReceived"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.ResponseSent"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.ResponseReceived"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.Abandoned"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.Completed"))),(0,o.kt)("p",null,"If you still need to access the old ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," you can do so by accessing the computed ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionRecord.rfc0160State")," property. This will return the old ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," value."),(0,o.kt)("h3",{id:"updating-custom-messages-to-the-new-message-type-objects"},"Updating Custom Messages to the New Message Type Objects"),(0,o.kt)("p",null,"Although this isn't a breaking change to the public API of the framework, it is something that you will need to take into account when creating custom modules. Starting from AFJ 0.2.0 we now support handling messages with different minor versions (e.g. receive a message with ",(0,o.kt)("inlineCode",{parentName:"p"},"@type")," version 1.1 while we only support 1.0). With this change messages must now declare the message type as an ",(0,o.kt)("inlineCode",{parentName:"p"},"ParsedMessageType")," object. We've added an ",(0,o.kt)("inlineCode",{parentName:"p"},"parseMessageType")," util method that can help with this."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { AgentMessage } from '@aries-framework/core'\nimport { Equals } from 'class-validator'\n\nclass MyMessage extends AgentMessage {\n @Equals(MyMessage.type)\n public readonly type = MyMessage.type\n public static readonly type = 'https://didcomm.org/my-protocol/1.0/my-type'\n}\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { AgentMessage, IsValidMessageType, parseMessageType } from '@aries-framework/core'\nimport { Equals } from 'class-validator'\n\nclass MyMessage extends AgentMessage {\n // use IsValidMessageType instead of Equals\n @IsValidMessageType(MyMessage.type)\n // append .messageTypeUri to get the actual URI when instantiating a message\n public readonly type = MyMessage.type.messageTypeUri\n // use parseMessageType to get the message type object from a type. You can declare the object yourself, but this is the recommended way\n public static readonly type = parseMessageType('https://didcomm.org/my-protocol/1.0/my-type')\n}\n")))),(0,o.kt)("h2",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,o.kt)("p",null,"The 0.2.0 release is heavy on breaking changes to the storage format. This is not what we intend to do with every release. But as there's not that many people yet using the framework in production, and there were a lot of changes needed to keep the API straightforward, we decided to bundle a lot of breaking changes in this one release."),(0,o.kt)("p",null,"Below all breaking storage changes are explained in as much detail as possible. The update assistant provides all tools to migrate without a hassle, but it is important to know what has changed. All examples only show the keys that have changed, unrelated keys in records have been omitted."),(0,o.kt)("p",null,"See the ",(0,o.kt)("a",{parentName:"p",href:"/guides/updating/update-assistant"},"Update Assistant")," documentation for a guide on how to use the update assistant."),(0,o.kt)("p",null,"The following config can be provided to the update assistant to migrate from 0.1.0 to 0.2.0:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "v0_1ToV0_2": {\n "mediationRoleUpdateStrategy": ""\n }\n}\n')),(0,o.kt)("h3",{id:"credential-metadata"},"Credential Metadata"),(0,o.kt)("p",null,"The credential record had a custom ",(0,o.kt)("inlineCode",{parentName:"p"},"metadata")," property in pre-0.1.0 storage that contained the ",(0,o.kt)("inlineCode",{parentName:"p"},"requestMetadata"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"schemaId")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialDefinition")," properties. Later a generic metadata API was added that only allows objects to be stored. Therefore the properties were moved into a different structure."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "requestMetadata": ,\n "schemaId": "",\n "credentialDefinitionId": ""\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "_internal/indyRequest": ,\n "_internal/indyCredential": {\n "schemaId": "",\n "credentialDefinitionId": ""\n }\n}\n')),(0,o.kt)("p",null,"Accessing the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialDefinitionId")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"schemaId")," properties will now be done by retrieving the ",(0,o.kt)("inlineCode",{parentName:"p"},"CredentialMetadataKeys.IndyCredential")," metadata key."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const indyCredential = credentialRecord.metadata.get(CredentialMetadataKeys.IndyCredential)\n\n// both properties are optional\nindyCredential?.credentialDefinitionId\nindyCredential?.schemaId\n")))),(0,o.kt)("h3",{id:"migrate-credential-record-properties"},"Migrate Credential Record Properties"),(0,o.kt)("p",null,"In 0.2.0 the v1 DIDComm messages have been moved out of the credential record into separate records using the DidCommMessageRepository. The migration scripts extracts all messages (proposalMessage, offerMessage, requestMessage, credentialMessage) and moves them into the DidCommMessageRepository."),(0,o.kt)("p",null,"With the addition of support for different protocol versions the credential record now stores the protocol version. With the addition of issue credential v2 support, other credential formats than indy can be used, and multiple credentials can be issued at once. To account for this the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialId")," has been replaced by the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentials")," array. This is an array of objects containing the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialRecordId")," and the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialRecordType"),". For all current credentials the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialRecordType")," will always be ",(0,o.kt)("inlineCode",{parentName:"p"},"indy"),"."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "credentialId": "09e46da9-a575-4909-b016-040e96c3c539",\n "proposalMessage": { ... },\n "offerMessage": { ... },\n "requestMessage": { ... },\n "credentialMessage": { ... },\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "protocolVersion": "v1",\n "credentials": [\n {\n "credentialRecordId": "09e46da9-a575-4909-b016-040e96c3c539",\n "credentialRecordType": "indy"\n }\n ]\n}\n')))),(0,o.kt)("h3",{id:"mediation-record-role"},"Mediation Record Role"),(0,o.kt)("p",null,"The role in the mediation record was always being set to ",(0,o.kt)("inlineCode",{parentName:"p"},"MediationRole.Mediator")," for both mediators and recipients. This didn't cause any issues, but would return the wrong role for recipients."),(0,o.kt)("p",null,"In 0.2 a check is added to make sure the role of a mediation record matches with actions (e.g. a recipient can't grant mediation), which means it will throw an error if the role is not set correctly."),(0,o.kt)("p",null,"Because it's not always possible detect whether the role should actually be mediator or recipient, a number of configuration options are provided on how the role should be updated using the ",(0,o.kt)("inlineCode",{parentName:"p"},"v0_1ToV0_2.mediationRoleUpdateStrategy")," option:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"allMediator"),": The role is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Mediator")," for both mediators and recipients"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"allRecipient"),": The role is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Recipient")," for both mediators and recipients"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"recipientIfEndpoint")," (",(0,o.kt)("strong",{parentName:"li"},"default"),"): The role is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Recipient")," if their is an ",(0,o.kt)("inlineCode",{parentName:"li"},"endpoint")," configured on the record. The endpoint is not set when running as a mediator. There is one case where this could be problematic when the role should be recipient, if the mediation grant hasn't actually occurred (meaning the endpoint is not set). This is probably the best approach\notherwise it is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Mediator")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"doNotChange"),": The role is not changed")),(0,o.kt)("p",null,"Most agents only act as either the role of mediator or recipient, in which case the ",(0,o.kt)("inlineCode",{parentName:"p"},"allMediator")," or ",(0,o.kt)("inlineCode",{parentName:"p"},"allRecipient")," configuration is the most appropriate. If your agent acts as both a recipient and mediator, the ",(0,o.kt)("inlineCode",{parentName:"p"},"recipientIfEndpoint")," configuration is the most appropriate. The ",(0,o.kt)("inlineCode",{parentName:"p"},"doNotChange")," options is not recommended and can lead to errors if the role is not set correctly."),(0,o.kt)("h3",{id:"extracting-did-documents-to-did-repository"},"Extracting Did Documents to Did Repository"),(0,o.kt)("p",null,"The connection record previously stored both did documents from a connection in the connection record itself. Version 0.2.0 added a generic did storage that can be used for numerous usages, one of which is the storage of did documents for connection records."),(0,o.kt)("p",null,"The migration script extracts the did documents from the ",(0,o.kt)("inlineCode",{parentName:"p"},"didDoc")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"theirDidDoc")," properties from the connection record, updates them to did documents compliant with the did core spec, and stores them in the did repository. By doing so it also updates the unqualified dids in the ",(0,o.kt)("inlineCode",{parentName:"p"},"did")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"theirDid")," fields generated by the indy-sdk to fully qualified ",(0,o.kt)("inlineCode",{parentName:"p"},"did:peer")," dids compliant with the ",(0,o.kt)("a",{parentName:"p",href:"https://identity.foundation/peer-did-method-spec/"},"Peer DID Method Specification"),"."),(0,o.kt)("p",null,"To account for the fact that the mechanism to migrate legacy did document to peer did documents is not defined yet, the legacy did and did document are stored in the did record metadata. This will be deleted later if we can be certain the did doc conversion to a ",(0,o.kt)("inlineCode",{parentName:"p"},"did:peer")," did document is correct."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "did": "BBPoJqRKatdcfLEAFL7exC",\n "theirDid": "UppcJ5APts7ot5WX25943F",\n "verkey": "GAb4NUvpBcHVCvtP45vTVa5Bp74vFg3iXzdp1Gbd68Wf",\n "didDoc": ,\n "theirDidDoc": ,\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "did": "did:peer:1zQmXUaPPhPCbUVZ3hGYmQmGxWTwyDfhqESXCpMFhKaF9Y2A",\n "theirDid": "did:peer:1zQmZMygzYqNwU6Uhmewx5Xepf2VLp5S4HLSwwgf2aiKZuwa"\n}\n')))),(0,o.kt)("h3",{id:"migrating-to-the-out-of-band-record"},"Migrating to the Out of Band Record"),(0,o.kt)("p",null,"With the addition of the out of band protocol, invitations are now stored in the ",(0,o.kt)("inlineCode",{parentName:"p"},"OutOfBandRecord"),". In addition a new field ",(0,o.kt)("inlineCode",{parentName:"p"},"invitationDid")," is added to the connection record that is generated based on the invitation service or did. This allows to reuse existing connections."),(0,o.kt)("p",null,"The migration script extracts the invitation and other relevant data into a separate ",(0,o.kt)("inlineCode",{parentName:"p"},"OutOfBandRecord"),". By doing so it converts the old connection protocol invitation into the new Out of band invitation message. Based on the service or did of the invitation, the ",(0,o.kt)("inlineCode",{parentName:"p"},"invitationDid")," is populated."),(0,o.kt)("p",null,"Previously when creating a multi use invitation, a connection record would be created with the ",(0,o.kt)("inlineCode",{parentName:"p"},"multiUseInvitation")," set to true. The connection record would always be in state ",(0,o.kt)("inlineCode",{parentName:"p"},"invited"),". If a request for the multi use invitation came in, a new connection record would be created. With the addition of the out of band module, no connection records are created until a request is received. So for multi use invitation this means that the connection record with multiUseInvitation=true will be deleted, and instead all connections created using that out of band invitation will contain the ",(0,o.kt)("inlineCode",{parentName:"p"},"outOfBandId")," of the multi use invitation."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "invitation": {\n "@type": "https://didcomm.org/connections/1.0/invitation",\n "@id": "04a2c382-999e-4de9-a1d2-9dec0b2fa5e4",\n "recipientKeys": ["E6D1m3eERqCueX4ZgMCY14B4NceAr6XP2HyVqt55gDhu"],\n "serviceEndpoint": "https://example.com",\n "label": "test"\n },\n "multiUseInvitation": "false"\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "invitationDid": "did:peer:2.Ez6MksYU4MHtfmNhNm1uGMvANr9j4CBv2FymjiJtRgA36bSVH.SeyJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbSJ9",\n "outOfBandId": "04a2c382-999e-4de9-a1d2-9dec0b2fa5e4"\n}\n')))),(0,o.kt)("h3",{id:"unifying-connection-states-and-roles"},"Unifying Connection States and Roles"),(0,o.kt)("p",null,"With the addition of the did exchange protocol there are now two states and roles related to the connection record; for the did exchange protocol and for the connection protocol. To keep it easy to work with the connection record, all state and role values are updated to those of the ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeRole")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," enums."),(0,o.kt)("p",null,"The migration script transforms all connection record state and role values to their respective values of the ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeRole")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," enums. For convenience a getter\nproperty ",(0,o.kt)("inlineCode",{parentName:"p"},"rfc0160ConnectionState")," is added to the connection record which returns the ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," value."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "state": "invited",\n "role": "inviter"\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.0",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "state": "invitation-sent",\n "role": "responder"\n}\n')))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/92188087.180b9f4a.js b/assets/js/92188087.180b9f4a.js new file mode 100644 index 00000000..4ed278c0 --- /dev/null +++ b/assets/js/92188087.180b9f4a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[537],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(n),m=o,f=u["".concat(l,".").concat(m)]||u[m]||d[m]||a;return n?r.createElement(f,i(i({ref:t},c),{},{components:n})):r.createElement(f,i({ref:t},c))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const a={},i="REST API",s={unversionedId:"extensions/rest",id:"extensions/rest",title:"REST API",description:"The Credo REST API provides simple RESTful endpoints for Credo methods, to allow you stand up an agent for communication over the internet instantly. You simply provide your agent configuration. The REST endpoints allow you to interact with your agent over HTTP and WebSockets.",source:"@site/guides/extensions/rest.md",sourceDirName:"extensions",slug:"/extensions/rest",permalink:"/guides/extensions/rest",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Extensions",permalink:"/guides/extensions/"},next:{title:"React Hooks",permalink:"/guides/extensions/react-hooks"}},l={},p=[{value:"Quick Setup",id:"quick-setup",level:2},{value:"Directly on computer",id:"directly-on-computer",level:3},{value:"Configuration",id:"configuration",level:3}],c={toc:p},u="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"rest-api"},"REST API"),(0,o.kt)("p",null,"The Credo REST API provides simple RESTful endpoints for Credo methods, to allow you stand up an agent for communication over the internet instantly. You simply provide your agent configuration. The REST endpoints allow you to interact with your agent over HTTP and WebSockets."),(0,o.kt)("p",null,"The Credo REST API is the most convenient way for self-sovereign identity (SSI) developers to interact with SSI agents."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"\u2b50 ",(0,o.kt)("strong",{parentName:"li"},"Endpoints")," to create connections, issue credentials, and request proofs."),(0,o.kt)("li",{parentName:"ul"},"\ud83d\udcbb ",(0,o.kt)("strong",{parentName:"li"},"CLI")," that makes it super easy to start an instance of the REST API."),(0,o.kt)("li",{parentName:"ul"},"\ud83c\udf10 ",(0,o.kt)("strong",{parentName:"li"},"Interoperable")," with all major Aries implementations.")),(0,o.kt)("admonition",{type:"danger"},(0,o.kt)("p",{parentName:"admonition"},"The ",(0,o.kt)("inlineCode",{parentName:"p"},"@credo-ts/rest")," package has not been updated to work with the latest version (",(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"0.4.x")),") of ",(0,o.kt)("inlineCode",{parentName:"p"},"@credo-ts/core"),". The documentation in this section is for version ",(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"0.9.x"))," of the ",(0,o.kt)("inlineCode",{parentName:"p"},"@credo-ts/rest")," package, that works with ",(0,o.kt)("inlineCode",{parentName:"p"},"@credo-ts/core")," version ",(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"0.2.x")),". Extension packages (such as REST API) are versioned separately from the core packages.")),(0,o.kt)("h2",{id:"quick-setup"},"Quick Setup"),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"This guide assumes you have followed the install guides for the framework (See ",(0,o.kt)("a",{parentName:"p",href:"../../getting-started/index.md"},"Getting Started")," section) for your platform and a valid ",(0,o.kt)("a",{parentName:"p",href:"https://nodejs.org"},"Node.js")," project setup.")),(0,o.kt)("p",null,"Using the CLI is the easiest way to get started with REST API."),(0,o.kt)("p",null,"You can do this directly on your machine."),(0,o.kt)("h3",{id:"directly-on-computer"},"Directly on computer"),(0,o.kt)("p",null,"After installing and confirming that Libindy is installed, simply run:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},'npx -p @credo-ts/rest credo-rest start \\\n --label "Credo Rest" \\\n --wallet-id "walletId" \\\n --wallet-key "walletKey" \\\n --endpoint http://localhost:5000 \\\n --admin-port 3000 \\\n --outbound-transport http \\\n --inbound-transport http 5000\n')),(0,o.kt)("p",null,"The REST API provides an OpenAPI schema that can easily be viewed using the SwaggerUI that is provided with the server. The endpoint documentation can be viewed at the ",(0,o.kt)("inlineCode",{parentName:"p"},"/docs")," endpoint (e.g. ",(0,o.kt)("a",{parentName:"p",href:"http://localhost:3000/docs"},"http://localhost:3000/docs"),")."),(0,o.kt)("h3",{id:"configuration"},"Configuration"),(0,o.kt)("p",null,"To find out all available configuration options from the CLI, you can run the CLI command with ",(0,o.kt)("inlineCode",{parentName:"p"},"--help"),". This will print a full list of all available options."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"npx -p @credo-ts/rest afj-rest start --help\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/92188087.fe2e4f83.js b/assets/js/92188087.fe2e4f83.js deleted file mode 100644 index a3aa4030..00000000 --- a/assets/js/92188087.fe2e4f83.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[537],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(n),m=o,f=u["".concat(l,".").concat(m)]||u[m]||d[m]||a;return n?r.createElement(f,i(i({ref:t},c),{},{components:n})):r.createElement(f,i({ref:t},c))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const a={},i="REST API",s={unversionedId:"extensions/rest",id:"extensions/rest",title:"REST API",description:"The Credo REST API provides simple RESTful endpoints for Credo methods, to allow you stand up an agent for communication over the internet instantly. You simply provide your agent configuration. The REST endpoints allow you to interact with your agent over HTTP and WebSockets.",source:"@site/guides/extensions/rest.md",sourceDirName:"extensions",slug:"/extensions/rest",permalink:"/guides/0.5/extensions/rest",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Extensions",permalink:"/guides/0.5/extensions/"},next:{title:"React Hooks",permalink:"/guides/0.5/extensions/react-hooks"}},l={},p=[{value:"Quick Setup",id:"quick-setup",level:2},{value:"Directly on computer",id:"directly-on-computer",level:3},{value:"Configuration",id:"configuration",level:3}],c={toc:p},u="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"rest-api"},"REST API"),(0,o.kt)("p",null,"The Credo REST API provides simple RESTful endpoints for Credo methods, to allow you stand up an agent for communication over the internet instantly. You simply provide your agent configuration. The REST endpoints allow you to interact with your agent over HTTP and WebSockets."),(0,o.kt)("p",null,"The Credo REST API is the most convenient way for self-sovereign identity (SSI) developers to interact with SSI agents."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"\u2b50 ",(0,o.kt)("strong",{parentName:"li"},"Endpoints")," to create connections, issue credentials, and request proofs."),(0,o.kt)("li",{parentName:"ul"},"\ud83d\udcbb ",(0,o.kt)("strong",{parentName:"li"},"CLI")," that makes it super easy to start an instance of the REST API."),(0,o.kt)("li",{parentName:"ul"},"\ud83c\udf10 ",(0,o.kt)("strong",{parentName:"li"},"Interoperable")," with all major Aries implementations.")),(0,o.kt)("admonition",{type:"danger"},(0,o.kt)("p",{parentName:"admonition"},"The ",(0,o.kt)("inlineCode",{parentName:"p"},"@credo-ts/rest")," package has not been updated to work with the latest version (",(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"0.4.x")),") of ",(0,o.kt)("inlineCode",{parentName:"p"},"@credo-ts/core"),". The documentation in this section is for version ",(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"0.9.x"))," of the ",(0,o.kt)("inlineCode",{parentName:"p"},"@credo-ts/rest")," package, that works with ",(0,o.kt)("inlineCode",{parentName:"p"},"@credo-ts/core")," version ",(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"0.2.x")),". Extension packages (such as REST API) are versioned separately from the core packages.")),(0,o.kt)("h2",{id:"quick-setup"},"Quick Setup"),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"This guide assumes you have followed the install guides for the framework (See ",(0,o.kt)("a",{parentName:"p",href:"../../getting-started/index.md"},"Getting Started")," section) for your platform and a valid ",(0,o.kt)("a",{parentName:"p",href:"https://nodejs.org"},"Node.js")," project setup.")),(0,o.kt)("p",null,"Using the CLI is the easiest way to get started with REST API."),(0,o.kt)("p",null,"You can do this directly on your machine."),(0,o.kt)("h3",{id:"directly-on-computer"},"Directly on computer"),(0,o.kt)("p",null,"After installing and confirming that Libindy is installed, simply run:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},'npx -p @credo-ts/rest credo-rest start \\\n --label "Credo Rest" \\\n --wallet-id "walletId" \\\n --wallet-key "walletKey" \\\n --endpoint http://localhost:5000 \\\n --admin-port 3000 \\\n --outbound-transport http \\\n --inbound-transport http 5000\n')),(0,o.kt)("p",null,"The REST API provides an OpenAPI schema that can easily be viewed using the SwaggerUI that is provided with the server. The endpoint documentation can be viewed at the ",(0,o.kt)("inlineCode",{parentName:"p"},"/docs")," endpoint (e.g. ",(0,o.kt)("a",{parentName:"p",href:"http://localhost:3000/docs"},"http://localhost:3000/docs"),")."),(0,o.kt)("h3",{id:"configuration"},"Configuration"),(0,o.kt)("p",null,"To find out all available configuration options from the CLI, you can run the CLI command with ",(0,o.kt)("inlineCode",{parentName:"p"},"--help"),". This will print a full list of all available options."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"npx -p @credo-ts/rest afj-rest start --help\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.678d7a53.js b/assets/js/935f2afb.678d7a53.js deleted file mode 100644 index d849bcd5..00000000 --- a/assets/js/935f2afb.678d7a53.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"v0.5.x","banner":"unreleased","badge":true,"noIndex":false,"className":"docs-version-current","isLast":false,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Intro","href":"/guides/0.5/","docId":"index"},{"type":"category","label":"Getting started","items":[{"type":"link","label":"Prerequisites","href":"/guides/0.5/getting-started/prerequisites","docId":"getting-started/prerequisites"},{"type":"category","label":"Agent Setup","items":[{"type":"link","label":"Aries Askar","href":"/guides/0.5/getting-started/set-up/aries-askar","docId":"getting-started/set-up/aries-askar"},{"type":"link","label":"AnonCreds","href":"/guides/0.5/getting-started/set-up/anoncreds","docId":"getting-started/set-up/anoncreds"},{"type":"link","label":"Indy VDR","href":"/guides/0.5/getting-started/set-up/indy-vdr","docId":"getting-started/set-up/indy-vdr"},{"type":"link","label":"cheqd","href":"/guides/0.5/getting-started/set-up/cheqd/","docId":"getting-started/set-up/cheqd/index"}],"collapsed":true,"collapsible":true,"href":"/guides/0.5/getting-started/set-up/"}],"collapsed":true,"collapsible":true,"href":"/guides/0.5/getting-started/"},{"type":"category","label":"Concepts","items":[{"type":"link","label":"Agents","href":"/guides/0.5/concepts/agents","docId":"concepts/agents"},{"type":"link","label":"DIDs and DIDComm","href":"/guides/0.5/concepts/did-and-didcomm","docId":"concepts/did-and-didcomm"},{"type":"link","label":"Platform and Environment","href":"/guides/0.5/concepts/platform-and-environment","docId":"concepts/platform-and-environment"}],"collapsed":true,"collapsible":true,"href":"/guides/0.5/concepts/"},{"type":"category","label":"Features","items":[{"type":"link","label":"Hyperledger Aries and Aries Interop Profile","href":"/guides/0.5/features/aries","docId":"features/aries"},{"type":"link","label":"OpenID for Verifiable Credentials","href":"/guides/0.5/features/openid4vc","docId":"features/openid4vc"},{"type":"link","label":"Decentralized Identifiers","href":"/guides/0.5/features/dids","docId":"features/dids"},{"type":"link","label":"Verifiable Credentials","href":"/guides/0.5/features/credentials","docId":"features/credentials"}],"collapsed":true,"collapsible":true,"href":"/guides/0.5/features/"},{"type":"category","label":"Tutorials","items":[{"type":"category","label":"Agent Config","items":[{"type":"link","label":"Logging","href":"/guides/0.5/tutorials/agent-config/logging","docId":"tutorials/agent-config/logging"}],"collapsed":true,"collapsible":true,"href":"/guides/0.5/tutorials/agent-config/"},{"type":"link","label":"Create a connection","href":"/guides/0.5/tutorials/create-a-connection","docId":"tutorials/create-a-connection"},{"type":"link","label":"Cheqd Did Module","href":"/guides/0.5/tutorials/cheqd/","docId":"tutorials/cheqd/index"},{"type":"link","label":"Registering a schema and credential definition on an AnonCreds Registry","href":"/guides/0.5/tutorials/registering-schema-and-credential-definition","docId":"tutorials/registering-schema-and-credential-definition"},{"type":"link","label":"Issue a credential","href":"/guides/0.5/tutorials/issue-a-credential","docId":"tutorials/issue-a-credential"},{"type":"link","label":"Mediation","href":"/guides/0.5/tutorials/mediation","docId":"tutorials/mediation"}],"collapsed":true,"collapsible":true,"href":"/guides/0.5/tutorials/"},{"type":"category","label":"Updating","items":[{"type":"link","label":"Update Assistant","href":"/guides/0.5/updating/update-assistant","docId":"updating/update-assistant"},{"type":"link","label":"Migrating from an Indy SDK Wallet to Aries Askar","href":"/guides/0.5/updating/update-indy-sdk-to-askar","docId":"updating/update-indy-sdk-to-askar"},{"type":"link","label":"Migrating from Credo 0.1.0 to 0.2.x","href":"/guides/0.5/updating/versions/0.1-to-0.2","docId":"updating/versions/0.1-to-0.2"},{"type":"link","label":"Migrating from Credo 0.2.x to 0.3.x","href":"/guides/0.5/updating/versions/0.2-to-0.3","docId":"updating/versions/0.2-to-0.3"},{"type":"link","label":"Migrating from Credo 0.3.x to 0.4.x","href":"/guides/0.5/updating/versions/0.3-to-0.4","docId":"updating/versions/0.3-to-0.4"}],"collapsed":true,"collapsible":true,"href":"/guides/0.5/updating/"},{"type":"link","label":"The Credo Ecosystem","href":"/guides/0.5/ecosystem/","docId":"ecosystem/index"},{"type":"category","label":"Extensions","items":[{"type":"link","label":"REST API","href":"/guides/0.5/extensions/rest","docId":"extensions/rest"},{"type":"link","label":"React Hooks","href":"/guides/0.5/extensions/react-hooks","docId":"extensions/react-hooks"},{"type":"link","label":"Redux Store","href":"/guides/0.5/extensions/redux-store","docId":"extensions/redux-store"},{"type":"link","label":"Push Notifications","href":"/guides/0.5/extensions/push-notifications","docId":"extensions/push-notifications"}],"collapsed":true,"collapsible":true,"href":"/guides/0.5/extensions/"}]},"docs":{"concepts/agents":{"id":"concepts/agents","title":"Agents","description":"When working with any Credo implementation, you will interact with an Credo","sidebar":"tutorialSidebar"},"concepts/did-and-didcomm":{"id":"concepts/did-and-didcomm","title":"DIDs and DIDComm","description":"DIDs","sidebar":"tutorialSidebar"},"concepts/index":{"id":"concepts/index","title":"Concepts","description":"In this section we will discuss the general concepts that are used inside the","sidebar":"tutorialSidebar"},"concepts/platform-and-environment":{"id":"concepts/platform-and-environment","title":"Platform and Environment","description":"Credo is developed to support a Node.JS and React Native environment. With this it is entirely possible to build an entire SSI ecosystem with Credo. This would use Node.JS as an issuer as a verifier, and uses React Native as a holder.","sidebar":"tutorialSidebar"},"ecosystem/index":{"id":"ecosystem/index","title":"The Credo Ecosystem","description":"The Credo ecosystem includes various components that are spread across multiple repositories. In this section we\'ll go over what these components are and how the relate to one another.","sidebar":"tutorialSidebar"},"extensions/index":{"id":"extensions/index","title":"Extensions","description":"Credo Extensions is an extensions repository to Credo. It hosts libraries built on top of Credo that don\'t necessarily belong to the core of the project.","sidebar":"tutorialSidebar"},"extensions/push-notifications":{"id":"extensions/push-notifications","title":"Push Notifications","description":"The Push Notifications plugin package provides a way for you to register your APNs and Firebase push notification token at an agent, allowing you to use push notifications directly from Credo.","sidebar":"tutorialSidebar"},"extensions/react-hooks":{"id":"extensions/react-hooks","title":"React Hooks","description":"The React Hooks package exposes useful React hooks that allow you to easily interact with Credo from a React client application.","sidebar":"tutorialSidebar"},"extensions/redux-store":{"id":"extensions/redux-store","title":"Redux Store","description":"The Redux Store is an implementation of state management that can be used to build React & React Native SSI clients using Credo.","sidebar":"tutorialSidebar"},"extensions/rest":{"id":"extensions/rest","title":"REST API","description":"The Credo REST API provides simple RESTful endpoints for Credo methods, to allow you stand up an agent for communication over the internet instantly. You simply provide your agent configuration. The REST endpoints allow you to interact with your agent over HTTP and WebSockets.","sidebar":"tutorialSidebar"},"features/aries":{"id":"features/aries","title":"Hyperledger Aries and Aries Interop Profile","description":"Initially, Credo was built as an Hyperledger Aries framework, focusing on implementing the Aries RFCs and supporting the Aries Interop Profile.","sidebar":"tutorialSidebar"},"features/credentials":{"id":"features/credentials","title":"Verifiable Credentials","description":"One of the main features of Credo is the issuance and verification of Verifiable Credentials.","sidebar":"tutorialSidebar"},"features/dids":{"id":"features/dids","title":"Decentralized Identifiers","description":"Decentralized identifiers are a core components of Credo, and used everywhere in the framework.","sidebar":"tutorialSidebar"},"features/index":{"id":"features/index","title":"Supported Features","description":"This section tries to list all the standards and features that are supported by Credo.","sidebar":"tutorialSidebar"},"features/openid4vc":{"id":"features/openid4vc","title":"OpenID for Verifiable Credentials","description":"Since Credo 0.4, support was added to receive credentials using OpenID for Verifiable Credential Issuance, and since 0.5 support was added for all the other OpenID for Verifiable Credential flows.","sidebar":"tutorialSidebar"},"getting-started/index":{"id":"getting-started/index","title":"Getting started","description":"In this section we will go over everything you need to get started on a technical level. First there are some general prerequisites for Node.JS and React Native. Credo works for creating both server-side applications (commonly but not always for creating issuer and verifier agents) and mobile applications (commonly holder agents).","sidebar":"tutorialSidebar"},"getting-started/prerequisites":{"id":"getting-started/prerequisites","title":"Prerequisites","description":"To work with Credo we need to install some dependencies and set-up our Node.JS environment. Even when creating a mobile app in React Native, we need Node.JS installed. We will go over the specific installation process for each platform. Go ahead and pick your system of choice to get started!","sidebar":"tutorialSidebar"},"getting-started/set-up/anoncreds":{"id":"getting-started/set-up/anoncreds","title":"AnonCreds","description":"The AnonCreds module provides functionality for issuing and verifying AnonCreds credentials in Credo. The AnonCreds implementation is based on AnonCreds RS, a direct implementation of the AnonCreds V1.0 specification that provides functionality like; creating a schema object, creating a credential definition object, creating a credential, verifying a proof presentation and much more.","sidebar":"tutorialSidebar"},"getting-started/set-up/aries-askar":{"id":"getting-started/set-up/aries-askar","title":"Aries Askar","description":"Aries Askar provides secure, encrypted storage and cryptographic support for encrypting, decrypting, signing and verifying data. It also provides both the Wallet and StorageService implementations for the agent.","sidebar":"tutorialSidebar"},"getting-started/set-up/cheqd/index":{"id":"getting-started/set-up/cheqd/index","title":"cheqd","description":"cheqd is a blockchain network, built in the Cosmos ecosystem for Self-Sovereign Identity (SSI). The cheqd Network leverages the cheqd DID method and enables DID-Linked Resources to be written to the network, associated with a DID and controlled using the verification methods in the DID Document.","sidebar":"tutorialSidebar"},"getting-started/set-up/index":{"id":"getting-started/set-up/index","title":"Agent Setup","description":"This guide assumes you have followed the Prerequisites, and you have a valid","sidebar":"tutorialSidebar"},"getting-started/set-up/indy-vdr":{"id":"getting-started/set-up/indy-vdr","title":"Indy VDR","description":"Hyperledger Indy VDR, Verifiable Data Registry, can be used to connect to one or more Indy Node ledger pools given sets of genesis transactions. Methods are provided to construct ledger requests and send them to the validators, collecting the results and ensuring that there is a consensus between the nodes. In the context of Credo, we mainly leverage it to register, and resolve, schemas, credential definitions and DIDs.","sidebar":"tutorialSidebar"},"index":{"id":"index","title":"Intro","description":"Welcome, to the Credo community!","sidebar":"tutorialSidebar"},"tutorials/agent-config/index":{"id":"tutorials/agent-config/index","title":"Agent Config","description":"The Credo agent is very extensible. These are all the configuration options with a short description:","sidebar":"tutorialSidebar"},"tutorials/agent-config/logging":{"id":"tutorials/agent-config/logging","title":"Logging","description":"Using the Default ConsoleLogger","sidebar":"tutorialSidebar"},"tutorials/cheqd/index":{"id":"tutorials/cheqd/index","title":"Cheqd Did Module","description":"In this tutorial we will see how to use the cheqd modules in detail","sidebar":"tutorialSidebar"},"tutorials/create-a-connection":{"id":"tutorials/create-a-connection","title":"Create a connection","description":"In this tutorial we will create a connection as Acme Corp with Bob. We will","sidebar":"tutorialSidebar"},"tutorials/index":{"id":"tutorials/index","title":"Tutorials","description":"In this section we will explain some features that everyone will use. This","sidebar":"tutorialSidebar"},"tutorials/issue-a-credential":{"id":"tutorials/issue-a-credential","title":"Issue a credential","description":"In this tutorial we will issue a credential from the Issuer to a Holder. We will start with setting up both their agents with the minimal configuration required to follow this tutorial. It is assumed that there is a connection between the Issuer and the Holder and the Issuer also has a registered schema and credential definition. After initializing the Issuer will send a credential to the holder, and will then accept this credential and automatically store it in their wallet.","sidebar":"tutorialSidebar"},"tutorials/mediation":{"id":"tutorials/mediation","title":"Mediation","description":"This section assumes that you have:","sidebar":"tutorialSidebar"},"tutorials/registering-schema-and-credential-definition":{"id":"tutorials/registering-schema-and-credential-definition","title":"Registering a schema and credential definition on an AnonCreds Registry","description":"In this tutorial we will register a schema and credential definition on an AnonCredsRegistry e.g. Hyperledger Indy ledger indy-vdr, cheqd.","sidebar":"tutorialSidebar"},"updating/index":{"id":"updating/index","title":"Updating Credo","description":"This section will cover everything you need to know about updating Credo to a newer version.","sidebar":"tutorialSidebar"},"updating/update-assistant":{"id":"updating/update-assistant","title":"Update Assistant","description":"The Update Assistant helps you update the storage objects from Credo to newer versions. This documents describes the different ways you can leverage the Update Assistant from fully managed to more manual approaches.","sidebar":"tutorialSidebar"},"updating/update-indy-sdk-to-askar":{"id":"updating/update-indy-sdk-to-askar","title":"Migrating from an Indy SDK Wallet to Aries Askar","description":"This documentation explains the process of migrating your Indy SDK wallet to Aries Askar.","sidebar":"tutorialSidebar"},"updating/versions/0.1-to-0.2":{"id":"updating/versions/0.1-to-0.2","title":"Migrating from Credo 0.1.0 to 0.2.x","description":"This document describes everything you need to know for updating Credo 0.1.0 to 0.2.x. If you\'re not aware of how updating in Credo works make sure to first read the guide on Updating Credo.","sidebar":"tutorialSidebar"},"updating/versions/0.2-to-0.3":{"id":"updating/versions/0.2-to-0.3","title":"Migrating from Credo 0.2.x to 0.3.x","description":"This document describes everything you need to know for updating Credo 0.2.x to 0.3.x. If you\'re not aware of how updating in Credo works make sure to first read the guide on Updating Credo.","sidebar":"tutorialSidebar"},"updating/versions/0.3-to-0.4":{"id":"updating/versions/0.3-to-0.4","title":"Migrating from Credo 0.3.x to 0.4.x","description":"This document describes everything you need to know for updating Credo 0.3.x to 0.4.x. If you\'re not aware of how updating in Credo works make sure to first read the guide on Updating Credo.","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.dd5a756e.js b/assets/js/935f2afb.dd5a756e.js new file mode 100644 index 00000000..53fc2c98 --- /dev/null +++ b/assets/js/935f2afb.dd5a756e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"v0.5.x","banner":null,"badge":true,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Intro","href":"/guides/","docId":"index"},{"type":"category","label":"Getting started","items":[{"type":"link","label":"Prerequisites","href":"/guides/getting-started/prerequisites","docId":"getting-started/prerequisites"},{"type":"category","label":"Agent Setup","items":[{"type":"link","label":"Aries Askar","href":"/guides/getting-started/set-up/aries-askar","docId":"getting-started/set-up/aries-askar"},{"type":"link","label":"AnonCreds","href":"/guides/getting-started/set-up/anoncreds","docId":"getting-started/set-up/anoncreds"},{"type":"link","label":"Indy VDR","href":"/guides/getting-started/set-up/indy-vdr","docId":"getting-started/set-up/indy-vdr"},{"type":"link","label":"cheqd","href":"/guides/getting-started/set-up/cheqd/","docId":"getting-started/set-up/cheqd/index"}],"collapsed":true,"collapsible":true,"href":"/guides/getting-started/set-up/"}],"collapsed":true,"collapsible":true,"href":"/guides/getting-started/"},{"type":"category","label":"Concepts","items":[{"type":"link","label":"Agents","href":"/guides/concepts/agents","docId":"concepts/agents"},{"type":"link","label":"DIDs and DIDComm","href":"/guides/concepts/did-and-didcomm","docId":"concepts/did-and-didcomm"},{"type":"link","label":"Platform and Environment","href":"/guides/concepts/platform-and-environment","docId":"concepts/platform-and-environment"}],"collapsed":true,"collapsible":true,"href":"/guides/concepts/"},{"type":"category","label":"Features","items":[{"type":"link","label":"Hyperledger Aries and Aries Interop Profile","href":"/guides/features/aries","docId":"features/aries"},{"type":"link","label":"OpenID for Verifiable Credentials","href":"/guides/features/openid4vc","docId":"features/openid4vc"},{"type":"link","label":"Decentralized Identifiers","href":"/guides/features/dids","docId":"features/dids"},{"type":"link","label":"Verifiable Credentials","href":"/guides/features/credentials","docId":"features/credentials"}],"collapsed":true,"collapsible":true,"href":"/guides/features/"},{"type":"category","label":"Tutorials","items":[{"type":"category","label":"Agent Config","items":[{"type":"link","label":"Logging","href":"/guides/tutorials/agent-config/logging","docId":"tutorials/agent-config/logging"}],"collapsed":true,"collapsible":true,"href":"/guides/tutorials/agent-config/"},{"type":"link","label":"Create a connection","href":"/guides/tutorials/create-a-connection","docId":"tutorials/create-a-connection"},{"type":"link","label":"Cheqd Did Module","href":"/guides/tutorials/cheqd/","docId":"tutorials/cheqd/index"},{"type":"link","label":"Registering a schema and credential definition on an AnonCreds Registry","href":"/guides/tutorials/registering-schema-and-credential-definition","docId":"tutorials/registering-schema-and-credential-definition"},{"type":"link","label":"Issue a credential","href":"/guides/tutorials/issue-a-credential","docId":"tutorials/issue-a-credential"},{"type":"link","label":"Mediation","href":"/guides/tutorials/mediation","docId":"tutorials/mediation"}],"collapsed":true,"collapsible":true,"href":"/guides/tutorials/"},{"type":"category","label":"Updating","items":[{"type":"link","label":"Update Assistant","href":"/guides/updating/update-assistant","docId":"updating/update-assistant"},{"type":"link","label":"Migrating from an Indy SDK Wallet to Aries Askar","href":"/guides/updating/update-indy-sdk-to-askar","docId":"updating/update-indy-sdk-to-askar"},{"type":"link","label":"Migrating from Credo 0.1.0 to 0.2.x","href":"/guides/updating/versions/0.1-to-0.2","docId":"updating/versions/0.1-to-0.2"},{"type":"link","label":"Migrating from Credo 0.2.x to 0.3.x","href":"/guides/updating/versions/0.2-to-0.3","docId":"updating/versions/0.2-to-0.3"},{"type":"link","label":"Migrating from Credo 0.3.x to 0.4.x","href":"/guides/updating/versions/0.3-to-0.4","docId":"updating/versions/0.3-to-0.4"}],"collapsed":true,"collapsible":true,"href":"/guides/updating/"},{"type":"link","label":"The Credo Ecosystem","href":"/guides/ecosystem/","docId":"ecosystem/index"},{"type":"category","label":"Extensions","items":[{"type":"link","label":"REST API","href":"/guides/extensions/rest","docId":"extensions/rest"},{"type":"link","label":"React Hooks","href":"/guides/extensions/react-hooks","docId":"extensions/react-hooks"},{"type":"link","label":"Redux Store","href":"/guides/extensions/redux-store","docId":"extensions/redux-store"},{"type":"link","label":"Push Notifications","href":"/guides/extensions/push-notifications","docId":"extensions/push-notifications"}],"collapsed":true,"collapsible":true,"href":"/guides/extensions/"}]},"docs":{"concepts/agents":{"id":"concepts/agents","title":"Agents","description":"When working with any Credo implementation, you will interact with an Credo","sidebar":"tutorialSidebar"},"concepts/did-and-didcomm":{"id":"concepts/did-and-didcomm","title":"DIDs and DIDComm","description":"DIDs","sidebar":"tutorialSidebar"},"concepts/index":{"id":"concepts/index","title":"Concepts","description":"In this section we will discuss the general concepts that are used inside the","sidebar":"tutorialSidebar"},"concepts/platform-and-environment":{"id":"concepts/platform-and-environment","title":"Platform and Environment","description":"Credo is developed to support a Node.JS and React Native environment. With this it is entirely possible to build an entire SSI ecosystem with Credo. This would use Node.JS as an issuer as a verifier, and uses React Native as a holder.","sidebar":"tutorialSidebar"},"ecosystem/index":{"id":"ecosystem/index","title":"The Credo Ecosystem","description":"The Credo ecosystem includes various components that are spread across multiple repositories. In this section we\'ll go over what these components are and how the relate to one another.","sidebar":"tutorialSidebar"},"extensions/index":{"id":"extensions/index","title":"Extensions","description":"Credo Extensions is an extensions repository to Credo. It hosts libraries built on top of Credo that don\'t necessarily belong to the core of the project.","sidebar":"tutorialSidebar"},"extensions/push-notifications":{"id":"extensions/push-notifications","title":"Push Notifications","description":"The Push Notifications plugin package provides a way for you to register your APNs and Firebase push notification token at an agent, allowing you to use push notifications directly from Credo.","sidebar":"tutorialSidebar"},"extensions/react-hooks":{"id":"extensions/react-hooks","title":"React Hooks","description":"The React Hooks package exposes useful React hooks that allow you to easily interact with Credo from a React client application.","sidebar":"tutorialSidebar"},"extensions/redux-store":{"id":"extensions/redux-store","title":"Redux Store","description":"The Redux Store is an implementation of state management that can be used to build React & React Native SSI clients using Credo.","sidebar":"tutorialSidebar"},"extensions/rest":{"id":"extensions/rest","title":"REST API","description":"The Credo REST API provides simple RESTful endpoints for Credo methods, to allow you stand up an agent for communication over the internet instantly. You simply provide your agent configuration. The REST endpoints allow you to interact with your agent over HTTP and WebSockets.","sidebar":"tutorialSidebar"},"features/aries":{"id":"features/aries","title":"Hyperledger Aries and Aries Interop Profile","description":"Initially, Credo was built as an Hyperledger Aries framework, focusing on implementing the Aries RFCs and supporting the Aries Interop Profile.","sidebar":"tutorialSidebar"},"features/credentials":{"id":"features/credentials","title":"Verifiable Credentials","description":"One of the main features of Credo is the issuance and verification of Verifiable Credentials.","sidebar":"tutorialSidebar"},"features/dids":{"id":"features/dids","title":"Decentralized Identifiers","description":"Decentralized identifiers are a core components of Credo, and used everywhere in the framework.","sidebar":"tutorialSidebar"},"features/index":{"id":"features/index","title":"Supported Features","description":"This section tries to list all the standards and features that are supported by Credo.","sidebar":"tutorialSidebar"},"features/openid4vc":{"id":"features/openid4vc","title":"OpenID for Verifiable Credentials","description":"Since Credo 0.4, support was added to receive credentials using OpenID for Verifiable Credential Issuance, and since 0.5 support was added for all the other OpenID for Verifiable Credential flows.","sidebar":"tutorialSidebar"},"getting-started/index":{"id":"getting-started/index","title":"Getting started","description":"In this section we will go over everything you need to get started on a technical level. First there are some general prerequisites for Node.JS and React Native. Credo works for creating both server-side applications (commonly but not always for creating issuer and verifier agents) and mobile applications (commonly holder agents).","sidebar":"tutorialSidebar"},"getting-started/prerequisites":{"id":"getting-started/prerequisites","title":"Prerequisites","description":"To work with Credo we need to install some dependencies and set-up our Node.JS environment. Even when creating a mobile app in React Native, we need Node.JS installed. We will go over the specific installation process for each platform. Go ahead and pick your system of choice to get started!","sidebar":"tutorialSidebar"},"getting-started/set-up/anoncreds":{"id":"getting-started/set-up/anoncreds","title":"AnonCreds","description":"The AnonCreds module provides functionality for issuing and verifying AnonCreds credentials in Credo. The AnonCreds implementation is based on AnonCreds RS, a direct implementation of the AnonCreds V1.0 specification that provides functionality like; creating a schema object, creating a credential definition object, creating a credential, verifying a proof presentation and much more.","sidebar":"tutorialSidebar"},"getting-started/set-up/aries-askar":{"id":"getting-started/set-up/aries-askar","title":"Aries Askar","description":"Aries Askar provides secure, encrypted storage and cryptographic support for encrypting, decrypting, signing and verifying data. It also provides both the Wallet and StorageService implementations for the agent.","sidebar":"tutorialSidebar"},"getting-started/set-up/cheqd/index":{"id":"getting-started/set-up/cheqd/index","title":"cheqd","description":"cheqd is a blockchain network, built in the Cosmos ecosystem for Self-Sovereign Identity (SSI). The cheqd Network leverages the cheqd DID method and enables DID-Linked Resources to be written to the network, associated with a DID and controlled using the verification methods in the DID Document.","sidebar":"tutorialSidebar"},"getting-started/set-up/index":{"id":"getting-started/set-up/index","title":"Agent Setup","description":"This guide assumes you have followed the Prerequisites, and you have a valid","sidebar":"tutorialSidebar"},"getting-started/set-up/indy-vdr":{"id":"getting-started/set-up/indy-vdr","title":"Indy VDR","description":"Hyperledger Indy VDR, Verifiable Data Registry, can be used to connect to one or more Indy Node ledger pools given sets of genesis transactions. Methods are provided to construct ledger requests and send them to the validators, collecting the results and ensuring that there is a consensus between the nodes. In the context of Credo, we mainly leverage it to register, and resolve, schemas, credential definitions and DIDs.","sidebar":"tutorialSidebar"},"index":{"id":"index","title":"Intro","description":"Welcome, to the Credo community!","sidebar":"tutorialSidebar"},"tutorials/agent-config/index":{"id":"tutorials/agent-config/index","title":"Agent Config","description":"The Credo agent is very extensible. These are all the configuration options with a short description:","sidebar":"tutorialSidebar"},"tutorials/agent-config/logging":{"id":"tutorials/agent-config/logging","title":"Logging","description":"Using the Default ConsoleLogger","sidebar":"tutorialSidebar"},"tutorials/cheqd/index":{"id":"tutorials/cheqd/index","title":"Cheqd Did Module","description":"In this tutorial we will see how to use the cheqd modules in detail","sidebar":"tutorialSidebar"},"tutorials/create-a-connection":{"id":"tutorials/create-a-connection","title":"Create a connection","description":"In this tutorial we will create a connection as Acme Corp with Bob. We will","sidebar":"tutorialSidebar"},"tutorials/index":{"id":"tutorials/index","title":"Tutorials","description":"In this section we will explain some features that everyone will use. This","sidebar":"tutorialSidebar"},"tutorials/issue-a-credential":{"id":"tutorials/issue-a-credential","title":"Issue a credential","description":"In this tutorial we will issue a credential from the Issuer to a Holder. We will start with setting up both their agents with the minimal configuration required to follow this tutorial. It is assumed that there is a connection between the Issuer and the Holder and the Issuer also has a registered schema and credential definition. After initializing the Issuer will send a credential to the holder, and will then accept this credential and automatically store it in their wallet.","sidebar":"tutorialSidebar"},"tutorials/mediation":{"id":"tutorials/mediation","title":"Mediation","description":"This section assumes that you have:","sidebar":"tutorialSidebar"},"tutorials/registering-schema-and-credential-definition":{"id":"tutorials/registering-schema-and-credential-definition","title":"Registering a schema and credential definition on an AnonCreds Registry","description":"In this tutorial we will register a schema and credential definition on an AnonCredsRegistry e.g. Hyperledger Indy ledger indy-vdr, cheqd.","sidebar":"tutorialSidebar"},"updating/index":{"id":"updating/index","title":"Updating Credo","description":"This section will cover everything you need to know about updating Credo to a newer version.","sidebar":"tutorialSidebar"},"updating/update-assistant":{"id":"updating/update-assistant","title":"Update Assistant","description":"The Update Assistant helps you update the storage objects from Credo to newer versions. This documents describes the different ways you can leverage the Update Assistant from fully managed to more manual approaches.","sidebar":"tutorialSidebar"},"updating/update-indy-sdk-to-askar":{"id":"updating/update-indy-sdk-to-askar","title":"Migrating from an Indy SDK Wallet to Aries Askar","description":"This documentation explains the process of migrating your Indy SDK wallet to Aries Askar.","sidebar":"tutorialSidebar"},"updating/versions/0.1-to-0.2":{"id":"updating/versions/0.1-to-0.2","title":"Migrating from Credo 0.1.0 to 0.2.x","description":"This document describes everything you need to know for updating Credo 0.1.0 to 0.2.x. If you\'re not aware of how updating in Credo works make sure to first read the guide on Updating Credo.","sidebar":"tutorialSidebar"},"updating/versions/0.2-to-0.3":{"id":"updating/versions/0.2-to-0.3","title":"Migrating from Credo 0.2.x to 0.3.x","description":"This document describes everything you need to know for updating Credo 0.2.x to 0.3.x. If you\'re not aware of how updating in Credo works make sure to first read the guide on Updating Credo.","sidebar":"tutorialSidebar"},"updating/versions/0.3-to-0.4":{"id":"updating/versions/0.3-to-0.4","title":"Migrating from Credo 0.3.x to 0.4.x","description":"This document describes everything you need to know for updating Credo 0.3.x to 0.4.x. If you\'re not aware of how updating in Credo works make sure to first read the guide on Updating Credo.","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/assets/js/95261082.e337adff.js b/assets/js/95261082.f9fc1fe2.js similarity index 70% rename from assets/js/95261082.e337adff.js rename to assets/js/95261082.f9fc1fe2.js index f5d4fc24..ecd1fcbf 100644 --- a/assets/js/95261082.e337adff.js +++ b/assets/js/95261082.f9fc1fe2.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[2086],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var u=a.createContext({}),l=function(e){var t=a.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=l(e.components);return a.createElement(u.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},f=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,u=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(n),f=r,m=d["".concat(u,".").concat(f)]||d[f]||p[f]||o;return n?a.createElement(m,i(i({ref:t},c),{},{components:n})):a.createElement(m,i({ref:t},c))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=f;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s[d]="string"==typeof e?e:r,i[1]=s;for(var l=2;l{n.d(t,{Z:()=>i});var a=n(7294),r=n(6010);const o={tabItem:"tabItem_Ymn6"};function i(e){let{children:t,hidden:n,className:i}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(o.tabItem,i),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),r=n(7294),o=n(6010),i=n(2466),s=n(6550),u=n(1980),l=n(7392),c=n(12);function d(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function p(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??d(n);return function(e){const t=(0,l.l)(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 f(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function m(e){let{queryString:t=!1,groupId:n}=e;const a=(0,s.k6)(),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,u._X)(o),(0,r.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(a.location.search);t.set(o,e),a.replace({...a.location,search:t.toString()})}),[o,a])]}function h(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,o=p(e),[i,s]=(0,r.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(!f({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}))),[u,l]=m({queryString:n,groupId:a}),[d,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,o]=(0,c.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:a}),b=(()=>{const e=u??d;return f({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{b&&s(b)}),[b]);return{selectedValue:i,selectValue:(0,r.useCallback)((e=>{if(!f({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);s(e),l(e),h(e)}),[l,h,o]),tabValues:o}}var b=n(2389);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function v(e){let{className:t,block:n,selectedValue:s,selectValue:u,tabValues:l}=e;const c=[],{blockElementScrollPositionUntilNextRender:d}=(0,i.o5)(),p=e=>{const t=e.currentTarget,n=c.indexOf(t),a=l[n].value;a!==s&&(d(t),u(a))},f=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},l.map((e=>{let{value:t,label:n,attributes:i}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>c.push(e),onKeyDown:f,onClick:p},i,{className:(0,o.Z)("tabs__item",g.tabItem,i?.className,{"tabs__item--active":s===t})}),n??t)})))}function y(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function k(e){const t=h(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",g.tabList)},r.createElement(v,(0,a.Z)({},e,t)),r.createElement(y,(0,a.Z)({},e,t)))}function w(e){const t=(0,b.Z)();return r.createElement(k,(0,a.Z)({key:String(t)},e))}},3418:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>u,default:()=>m,frontMatter:()=>s,metadata:()=>l,toc:()=>d});var a=n(7462),r=(n(7294),n(3905)),o=n(4866),i=n(5162);const s={},u="Push Notifications",l={unversionedId:"extensions/push-notifications",id:"extensions/push-notifications",title:"Push Notifications",description:"The Push Notifications plugin package provides a way for you to register your APNs and Firebase push notification token at an agent, allowing you to use push notifications directly from Credo.",source:"@site/guides/extensions/push-notifications.md",sourceDirName:"extensions",slug:"/extensions/push-notifications",permalink:"/guides/0.5/extensions/push-notifications",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Redux Store",permalink:"/guides/0.5/extensions/redux-store"}},c={},d=[{value:"Installation",id:"installation",level:2},{value:"npm",id:"npm",level:2},{value:"Yarn",id:"yarn",level:2},{value:"Usage",id:"usage",level:2}],p={toc:d},f="wrapper";function m(e){let{components:t,...n}=e;return(0,r.kt)(f,(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"push-notifications"},"Push Notifications"),(0,r.kt)("p",null,"The Push Notifications plugin package provides a way for you to register your APNs and Firebase push notification token at an agent, allowing you to use push notifications directly from Credo."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"This document is for version ",(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"0.5.x"))," of the ",(0,r.kt)("inlineCode",{parentName:"p"},"@credo-ts/push-notifications")," package, that works with ",(0,r.kt)("inlineCode",{parentName:"p"},"@credo-ts/core")," version ",(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"0.4.x")),". Extension packages (such as Push Notifications) are versioned separately from the core packages.")),(0,r.kt)("h2",{id:"installation"},"Installation"),(0,r.kt)("p",null,"To add the Push Notifications plugin package to your existing project simply run:"),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(i.Z,{label:"npm",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"npm i @credo-ts/push-notifications\n"))),(0,r.kt)(i.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @credo-ts/push-notifications\n"))),(0,r.kt)(i.Z,{label:"Usage",value:"tab3",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { PushNotificationsApnsModule, PushNotificationsFcmModule } from '@credo-ts/push-notifications'\nimport { } from '@credo-ts/core'\n\nconst agent = new Agent({\n /** agent config... */,\n // Register the modules\n modules: {\n pushNotificationsApns: new PushNotificationsApnsModule(),\n pushNotificationsFcm: new PushNotificationsFcmModule(),\n },\n }\n})\n\nawait agent.initialize()\n\n/* -- iOS -- */\n\n// To send apns device info to another agent you have to acquire the device token and send it.\nawait agent.modules.pushNotificationsApns.sendDeviceInfo(\n 'a-valid-connection-id'\n { deviceToken: '123' },\n)\n\n// To get the device info and the used service back from the other agent\nawait agent.modules.pushNotificationsApns.getDeviceInfo('a-valid-connection')\n\n/* -- fcm / Android -- */\n\n// To send fcm, primarily Android, device info to another agent you have to acquire the device token and send it.\nawait agent.modules.pushNotificationsFcm.sendDeviceInfo(\n 'a-valid-connection-id'\n { deviceToken: '123' },\n)\n\n// To get the device info and the used service back from the other agent\nawait agent.modules.pushNotificationsFcm.getDeviceInfo('a-valid-connection')\n\n")))))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[2086],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var u=a.createContext({}),l=function(e){var t=a.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=l(e.components);return a.createElement(u.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},f=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,u=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(n),f=r,m=d["".concat(u,".").concat(f)]||d[f]||p[f]||o;return n?a.createElement(m,i(i({ref:t},c),{},{components:n})):a.createElement(m,i({ref:t},c))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=f;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s[d]="string"==typeof e?e:r,i[1]=s;for(var l=2;l{n.d(t,{Z:()=>i});var a=n(7294),r=n(6010);const o={tabItem:"tabItem_Ymn6"};function i(e){let{children:t,hidden:n,className:i}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(o.tabItem,i),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),r=n(7294),o=n(6010),i=n(2466),s=n(6550),u=n(1980),l=n(7392),c=n(12);function d(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function p(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??d(n);return function(e){const t=(0,l.l)(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 f(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function m(e){let{queryString:t=!1,groupId:n}=e;const a=(0,s.k6)(),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,u._X)(o),(0,r.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(a.location.search);t.set(o,e),a.replace({...a.location,search:t.toString()})}),[o,a])]}function h(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,o=p(e),[i,s]=(0,r.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(!f({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}))),[u,l]=m({queryString:n,groupId:a}),[d,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,o]=(0,c.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:a}),b=(()=>{const e=u??d;return f({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{b&&s(b)}),[b]);return{selectedValue:i,selectValue:(0,r.useCallback)((e=>{if(!f({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);s(e),l(e),h(e)}),[l,h,o]),tabValues:o}}var b=n(2389);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function v(e){let{className:t,block:n,selectedValue:s,selectValue:u,tabValues:l}=e;const c=[],{blockElementScrollPositionUntilNextRender:d}=(0,i.o5)(),p=e=>{const t=e.currentTarget,n=c.indexOf(t),a=l[n].value;a!==s&&(d(t),u(a))},f=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},l.map((e=>{let{value:t,label:n,attributes:i}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>c.push(e),onKeyDown:f,onClick:p},i,{className:(0,o.Z)("tabs__item",g.tabItem,i?.className,{"tabs__item--active":s===t})}),n??t)})))}function y(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function k(e){const t=h(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",g.tabList)},r.createElement(v,(0,a.Z)({},e,t)),r.createElement(y,(0,a.Z)({},e,t)))}function w(e){const t=(0,b.Z)();return r.createElement(k,(0,a.Z)({key:String(t)},e))}},3418:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>u,default:()=>m,frontMatter:()=>s,metadata:()=>l,toc:()=>d});var a=n(7462),r=(n(7294),n(3905)),o=n(4866),i=n(5162);const s={},u="Push Notifications",l={unversionedId:"extensions/push-notifications",id:"extensions/push-notifications",title:"Push Notifications",description:"The Push Notifications plugin package provides a way for you to register your APNs and Firebase push notification token at an agent, allowing you to use push notifications directly from Credo.",source:"@site/guides/extensions/push-notifications.md",sourceDirName:"extensions",slug:"/extensions/push-notifications",permalink:"/guides/extensions/push-notifications",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Redux Store",permalink:"/guides/extensions/redux-store"}},c={},d=[{value:"Installation",id:"installation",level:2},{value:"npm",id:"npm",level:2},{value:"Yarn",id:"yarn",level:2},{value:"Usage",id:"usage",level:2}],p={toc:d},f="wrapper";function m(e){let{components:t,...n}=e;return(0,r.kt)(f,(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"push-notifications"},"Push Notifications"),(0,r.kt)("p",null,"The Push Notifications plugin package provides a way for you to register your APNs and Firebase push notification token at an agent, allowing you to use push notifications directly from Credo."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"This document is for version ",(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"0.5.x"))," of the ",(0,r.kt)("inlineCode",{parentName:"p"},"@credo-ts/push-notifications")," package, that works with ",(0,r.kt)("inlineCode",{parentName:"p"},"@credo-ts/core")," version ",(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"0.4.x")),". Extension packages (such as Push Notifications) are versioned separately from the core packages.")),(0,r.kt)("h2",{id:"installation"},"Installation"),(0,r.kt)("p",null,"To add the Push Notifications plugin package to your existing project simply run:"),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(i.Z,{label:"npm",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"npm i @credo-ts/push-notifications\n"))),(0,r.kt)(i.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @credo-ts/push-notifications\n"))),(0,r.kt)(i.Z,{label:"Usage",value:"tab3",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { PushNotificationsApnsModule, PushNotificationsFcmModule } from '@credo-ts/push-notifications'\nimport { } from '@credo-ts/core'\n\nconst agent = new Agent({\n /** agent config... */,\n // Register the modules\n modules: {\n pushNotificationsApns: new PushNotificationsApnsModule(),\n pushNotificationsFcm: new PushNotificationsFcmModule(),\n },\n }\n})\n\nawait agent.initialize()\n\n/* -- iOS -- */\n\n// To send apns device info to another agent you have to acquire the device token and send it.\nawait agent.modules.pushNotificationsApns.sendDeviceInfo(\n 'a-valid-connection-id'\n { deviceToken: '123' },\n)\n\n// To get the device info and the used service back from the other agent\nawait agent.modules.pushNotificationsApns.getDeviceInfo('a-valid-connection')\n\n/* -- fcm / Android -- */\n\n// To send fcm, primarily Android, device info to another agent you have to acquire the device token and send it.\nawait agent.modules.pushNotificationsFcm.sendDeviceInfo(\n 'a-valid-connection-id'\n { deviceToken: '123' },\n)\n\n// To get the device info and the used service back from the other agent\nawait agent.modules.pushNotificationsFcm.getDeviceInfo('a-valid-connection')\n\n")))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/996925d9.7c209dbd.js b/assets/js/996925d9.e46877ef.js similarity index 62% rename from assets/js/996925d9.7c209dbd.js rename to assets/js/996925d9.e46877ef.js index ba476278..e0547994 100644 --- a/assets/js/996925d9.7c209dbd.js +++ b/assets/js/996925d9.e46877ef.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[3901],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),u=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=u(e.components);return r.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),p=u(n),m=a,f=p["".concat(s,".").concat(m)]||p[m]||d[m]||o;return n?r.createElement(f,l(l({ref:t},c),{},{components:n})):r.createElement(f,l({ref:t},c))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=m;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[p]="string"==typeof e?e:a,l[1]=i;for(var u=2;u{n.d(t,{Z:()=>l});var r=n(7294),a=n(6010);const o={tabItem:"tabItem_Ymn6"};function l(e){let{children:t,hidden:n,className:l}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(o.tabItem,l),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var r=n(7462),a=n(7294),o=n(6010),l=n(2466),i=n(6550),s=n(1980),u=n(7392),c=n(12);function p(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function d(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,u.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:n}=e;const r=(0,i.k6)(),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._X)(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 h(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,o=d(e),[l,i]=(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(!m({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 r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:o}))),[s,u]=f({queryString:n,groupId:r}),[p,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,o]=(0,c.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:r}),b=(()=>{const e=s??p;return m({value:e,tabValues:o})?e:null})();(0,a.useLayoutEffect)((()=>{b&&i(b)}),[b]);return{selectedValue:l,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);i(e),u(e),h(e)}),[u,h,o]),tabValues:o}}var b=n(2389);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function g(e){let{className:t,block:n,selectedValue:i,selectValue:s,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,l.o5)(),d=e=>{const t=e.currentTarget,n=c.indexOf(t),r=u[n].value;r!==i&&(p(t),s(r))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},u.map((e=>{let{value:t,label:n,attributes:l}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},l,{className:(0,o.Z)("tabs__item",v.tabItem,l?.className,{"tabs__item--active":i===t})}),n??t)})))}function k(e){let{lazy:t,children:n,selectedValue:r}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function y(e){const t=h(e);return a.createElement("div",{className:(0,o.Z)("tabs-container",v.tabList)},a.createElement(g,(0,r.Z)({},e,t)),a.createElement(k,(0,r.Z)({},e,t)))}function w(e){const t=(0,b.Z)();return a.createElement(y,(0,r.Z)({key:String(t)},e))}},1089:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>f,frontMatter:()=>i,metadata:()=>u,toc:()=>p});var r=n(7462),a=(n(7294),n(3905)),o=n(4866),l=n(5162);const i={},s="Prerequisites",u={unversionedId:"getting-started/prerequisites",id:"getting-started/prerequisites",title:"Prerequisites",description:"To work with Credo we need to install some dependencies and set-up our Node.JS environment. Even when creating a mobile app in React Native, we need Node.JS installed. We will go over the specific installation process for each platform. Go ahead and pick your system of choice to get started!",source:"@site/guides/getting-started/prerequisites.md",sourceDirName:"getting-started",slug:"/getting-started/prerequisites",permalink:"/guides/0.5/getting-started/prerequisites",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Getting started",permalink:"/guides/0.5/getting-started/"},next:{title:"Agent Setup",permalink:"/guides/0.5/getting-started/set-up/"}},c={},p=[{value:"Node.JS",id:"nodejs",level:3},{value:"Windows",id:"windows",level:4},{value:"macOS",id:"macos",level:4},{value:"Linux",id:"linux",level:4},{value:"Arch Linux",id:"arch-linux",level:5},{value:"Debian",id:"debian",level:5},{value:"Red Hat",id:"red-hat",level:5},{value:"NPM",id:"npm",level:3},{value:"Yarn",id:"yarn",level:3},{value:"Project Setup",id:"project-setup",level:3}],d={toc:p},m="wrapper";function f(e){let{components:t,...n}=e;return(0,a.kt)(m,(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"prerequisites"},"Prerequisites"),(0,a.kt)("p",null,"To work with ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts"},"Credo")," we need to install some dependencies and set-up our Node.JS environment. Even when creating a mobile app in React Native, we need Node.JS installed. We will go over the specific installation process for each platform. Go ahead and pick your system of choice to get started!"),(0,a.kt)("p",null,"The specific items that we set-up:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://nodejs.org"},"Node.JS")," - v16 or v18"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://classic.yarnpkg.com/lang/en/docs/install"},"yarn")," or ",(0,a.kt)("a",{parentName:"li",href:"https://www.npmjs.com/"},"npm")),(0,a.kt)("li",{parentName:"ul"},"Node.JS or React Native project.")),(0,a.kt)("h3",{id:"nodejs"},"Node.JS"),(0,a.kt)("p",null,"NodeJS is the most popular JavaScript runtime environment excluding browsers. It can run on your desktop or even a server."),(0,a.kt)(o.Z,{mdxType:"Tabs"},(0,a.kt)(l.Z,{label:"Windows",value:"tab1",mdxType:"TabItem"},(0,a.kt)("p",null,"You can download it from the ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.org/en/download/"},"Node.JS Website"))),(0,a.kt)(l.Z,{label:"macOS",value:"tab2",mdxType:"TabItem"},(0,a.kt)("p",null,"Make sure you have ",(0,a.kt)("a",{parentName:"p",href:"https://brew.sh/"},"Homebrew")," installed. If not you can install it with the following command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n')),(0,a.kt)("p",null,"Then install Node.JS with the following command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"brew install nodejs\n")),(0,a.kt)("p",null,"Alternatively, you can download it from the ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.org/en/download/"},"Node.JS Website"))),(0,a.kt)(l.Z,{label:"Linux",value:"tab3",mdxType:"TabItem"},(0,a.kt)("p",null,"Either follow one of the specific steps for installing Node.JS on linux below, or you can download it directly from the ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.org/en/download/"},"Node.JS Website")),(0,a.kt)("h5",{id:"arch-linux"},"Arch Linux"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"pacman -S nodejs npm\n")),(0,a.kt)("h5",{id:"debian"},"Debian"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"curl -fsSL https://deb.nodesource.com/setup_18.x | bash -\napt-get install -y nodejs\n")),(0,a.kt)("h5",{id:"red-hat"},"Red Hat"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"curl -sL https://rpm.nodesource.com/setup_18.x | bash -\nyum install nodejs\n")))),(0,a.kt)("h3",{id:"npm"},"NPM"),(0,a.kt)("p",null,"The Node Package Manager comes pre-bundled with the NodeJS installation from above."),(0,a.kt)("h3",{id:"yarn"},"Yarn"),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"Only required when not using npm")),(0,a.kt)("p",null,"For every platform, the installation of yarn is the same."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"npm install --global yarn\n")),(0,a.kt)("h3",{id:"project-setup"},"Project Setup"),(0,a.kt)("p",null,"Finally, you need to make sure you have a project set-up using Node.JS or React Native. If you're not familiar with setting up a project, we suggest following the ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.dev/en/learn/"},"Introduction to Node.JS")," or ",(0,a.kt)("a",{parentName:"p",href:"https://reactnative.dev/docs/environment-setup"},"React Native Quickstart")," guides."))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[3901],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),u=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=u(e.components);return r.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),p=u(n),m=a,f=p["".concat(s,".").concat(m)]||p[m]||d[m]||o;return n?r.createElement(f,l(l({ref:t},c),{},{components:n})):r.createElement(f,l({ref:t},c))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=m;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[p]="string"==typeof e?e:a,l[1]=i;for(var u=2;u{n.d(t,{Z:()=>l});var r=n(7294),a=n(6010);const o={tabItem:"tabItem_Ymn6"};function l(e){let{children:t,hidden:n,className:l}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(o.tabItem,l),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var r=n(7462),a=n(7294),o=n(6010),l=n(2466),i=n(6550),s=n(1980),u=n(7392),c=n(12);function p(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function d(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,u.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:n}=e;const r=(0,i.k6)(),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._X)(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 h(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,o=d(e),[l,i]=(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(!m({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 r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:o}))),[s,u]=f({queryString:n,groupId:r}),[p,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,o]=(0,c.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:r}),b=(()=>{const e=s??p;return m({value:e,tabValues:o})?e:null})();(0,a.useLayoutEffect)((()=>{b&&i(b)}),[b]);return{selectedValue:l,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);i(e),u(e),h(e)}),[u,h,o]),tabValues:o}}var b=n(2389);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function g(e){let{className:t,block:n,selectedValue:i,selectValue:s,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,l.o5)(),d=e=>{const t=e.currentTarget,n=c.indexOf(t),r=u[n].value;r!==i&&(p(t),s(r))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},u.map((e=>{let{value:t,label:n,attributes:l}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},l,{className:(0,o.Z)("tabs__item",v.tabItem,l?.className,{"tabs__item--active":i===t})}),n??t)})))}function k(e){let{lazy:t,children:n,selectedValue:r}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function y(e){const t=h(e);return a.createElement("div",{className:(0,o.Z)("tabs-container",v.tabList)},a.createElement(g,(0,r.Z)({},e,t)),a.createElement(k,(0,r.Z)({},e,t)))}function w(e){const t=(0,b.Z)();return a.createElement(y,(0,r.Z)({key:String(t)},e))}},1089:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>f,frontMatter:()=>i,metadata:()=>u,toc:()=>p});var r=n(7462),a=(n(7294),n(3905)),o=n(4866),l=n(5162);const i={},s="Prerequisites",u={unversionedId:"getting-started/prerequisites",id:"getting-started/prerequisites",title:"Prerequisites",description:"To work with Credo we need to install some dependencies and set-up our Node.JS environment. Even when creating a mobile app in React Native, we need Node.JS installed. We will go over the specific installation process for each platform. Go ahead and pick your system of choice to get started!",source:"@site/guides/getting-started/prerequisites.md",sourceDirName:"getting-started",slug:"/getting-started/prerequisites",permalink:"/guides/getting-started/prerequisites",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Getting started",permalink:"/guides/getting-started/"},next:{title:"Agent Setup",permalink:"/guides/getting-started/set-up/"}},c={},p=[{value:"Node.JS",id:"nodejs",level:3},{value:"Windows",id:"windows",level:4},{value:"macOS",id:"macos",level:4},{value:"Linux",id:"linux",level:4},{value:"Arch Linux",id:"arch-linux",level:5},{value:"Debian",id:"debian",level:5},{value:"Red Hat",id:"red-hat",level:5},{value:"NPM",id:"npm",level:3},{value:"Yarn",id:"yarn",level:3},{value:"Project Setup",id:"project-setup",level:3}],d={toc:p},m="wrapper";function f(e){let{components:t,...n}=e;return(0,a.kt)(m,(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"prerequisites"},"Prerequisites"),(0,a.kt)("p",null,"To work with ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts"},"Credo")," we need to install some dependencies and set-up our Node.JS environment. Even when creating a mobile app in React Native, we need Node.JS installed. We will go over the specific installation process for each platform. Go ahead and pick your system of choice to get started!"),(0,a.kt)("p",null,"The specific items that we set-up:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://nodejs.org"},"Node.JS")," - v16 or v18"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://classic.yarnpkg.com/lang/en/docs/install"},"yarn")," or ",(0,a.kt)("a",{parentName:"li",href:"https://www.npmjs.com/"},"npm")),(0,a.kt)("li",{parentName:"ul"},"Node.JS or React Native project.")),(0,a.kt)("h3",{id:"nodejs"},"Node.JS"),(0,a.kt)("p",null,"NodeJS is the most popular JavaScript runtime environment excluding browsers. It can run on your desktop or even a server."),(0,a.kt)(o.Z,{mdxType:"Tabs"},(0,a.kt)(l.Z,{label:"Windows",value:"tab1",mdxType:"TabItem"},(0,a.kt)("p",null,"You can download it from the ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.org/en/download/"},"Node.JS Website"))),(0,a.kt)(l.Z,{label:"macOS",value:"tab2",mdxType:"TabItem"},(0,a.kt)("p",null,"Make sure you have ",(0,a.kt)("a",{parentName:"p",href:"https://brew.sh/"},"Homebrew")," installed. If not you can install it with the following command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n')),(0,a.kt)("p",null,"Then install Node.JS with the following command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"brew install nodejs\n")),(0,a.kt)("p",null,"Alternatively, you can download it from the ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.org/en/download/"},"Node.JS Website"))),(0,a.kt)(l.Z,{label:"Linux",value:"tab3",mdxType:"TabItem"},(0,a.kt)("p",null,"Either follow one of the specific steps for installing Node.JS on linux below, or you can download it directly from the ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.org/en/download/"},"Node.JS Website")),(0,a.kt)("h5",{id:"arch-linux"},"Arch Linux"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"pacman -S nodejs npm\n")),(0,a.kt)("h5",{id:"debian"},"Debian"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"curl -fsSL https://deb.nodesource.com/setup_18.x | bash -\napt-get install -y nodejs\n")),(0,a.kt)("h5",{id:"red-hat"},"Red Hat"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"curl -sL https://rpm.nodesource.com/setup_18.x | bash -\nyum install nodejs\n")))),(0,a.kt)("h3",{id:"npm"},"NPM"),(0,a.kt)("p",null,"The Node Package Manager comes pre-bundled with the NodeJS installation from above."),(0,a.kt)("h3",{id:"yarn"},"Yarn"),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"Only required when not using npm")),(0,a.kt)("p",null,"For every platform, the installation of yarn is the same."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"npm install --global yarn\n")),(0,a.kt)("h3",{id:"project-setup"},"Project Setup"),(0,a.kt)("p",null,"Finally, you need to make sure you have a project set-up using Node.JS or React Native. If you're not familiar with setting up a project, we suggest following the ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.dev/en/learn/"},"Introduction to Node.JS")," or ",(0,a.kt)("a",{parentName:"p",href:"https://reactnative.dev/docs/environment-setup"},"React Native Quickstart")," guides."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/997e3d85.30121511.js b/assets/js/997e3d85.88d9aeeb.js similarity index 57% rename from assets/js/997e3d85.30121511.js rename to assets/js/997e3d85.88d9aeeb.js index be941638..6d2414ed 100644 --- a/assets/js/997e3d85.30121511.js +++ b/assets/js/997e3d85.88d9aeeb.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[2680],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=l(r),u=a,f=m["".concat(c,".").concat(u)]||m[u]||d[u]||i;return r?n.createElement(f,o(o({ref:t},p),{},{components:r})):n.createElement(f,o({ref:t},p))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=u;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[m]="string"==typeof e?e:a,o[1]=s;for(var l=2;l{r.d(t,{Z:()=>h});var n=r(7294),a=r(6010),i=r(3438),o=r(9960),s=r(3919),c=r(5999);const l={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function p(e){let{href:t,children:r}=e;return n.createElement(o.Z,{href:t,className:(0,a.Z)("card padding--lg",l.cardContainer)},r)}function m(e){let{href:t,icon:r,title:i,description:o}=e;return n.createElement(p,{href:t},n.createElement("h2",{className:(0,a.Z)("text--truncate",l.cardTitle),title:i},r," ",i),o&&n.createElement("p",{className:(0,a.Z)("text--truncate",l.cardDescription),title:o},o))}function d(e){let{item:t}=e;const r=(0,i.Wl)(t);return r?n.createElement(m,{href:r,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,c.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function u(e){let{item:t}=e;const r=(0,s.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",a=(0,i.xz)(t.docId??void 0);return n.createElement(m,{href:t.href,icon:r,title:t.label,description:a?.description})}function f(e){let{item:t}=e;switch(t.type){case"link":return n.createElement(u,{item:t});case"category":return n.createElement(d,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function k(e){let{className:t}=e;const r=(0,i.jA)();return n.createElement(h,{items:r.items,className:t})}function h(e){const{items:t,className:r}=e;if(!t)return n.createElement(k,e);const o=(0,i.MN)(t);return n.createElement("section",{className:(0,a.Z)("row",r)},o.map(((e,t)=>n.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},n.createElement(f,{item:e})))))}},3583:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var n=r(7462),a=(r(7294),r(3905)),i=r(2991);const o={},s="Extensions",c={unversionedId:"extensions/index",id:"version-0.4/extensions/index",title:"Extensions",description:"Aries Framework JavaScript Extensions is an extensions repository to Aries Framework JavaScript (AFJ). It hosts libraries built on top of Aries Framework JavaScript that don't necessarily belong to the core of the project.",source:"@site/versioned_docs/version-0.4/extensions/index.md",sourceDirName:"extensions",slug:"/extensions/",permalink:"/guides/extensions/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"The Aries JavaScript Ecosystem",permalink:"/guides/ecosystem/"},next:{title:"REST API",permalink:"/guides/extensions/rest"}},l={},p=[],m={toc:p},d="wrapper";function u(e){let{components:t,...r}=e;return(0,a.kt)(d,(0,n.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"extensions"},"Extensions"),(0,a.kt)("p",null,"Aries Framework JavaScript Extensions is an extensions repository to Aries Framework JavaScript (AFJ). It hosts libraries built on top of Aries Framework JavaScript that don't necessarily belong to the core of the project."),(0,a.kt)("p",null,"Currently, there are four packages in the extension repository. Example extension libraries include React Hooks for AFJ and a REST API wrapper."),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Package"),(0,a.kt)("th",{parentName:"tr",align:null},"Version"),(0,a.kt)("th",{parentName:"tr",align:null},"Description"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"https://www.npmjs.com/package/@aries-framework/redux-store"},(0,a.kt)("inlineCode",{parentName:"a"},"@aries-framework/redux-store"))),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("img",{parentName:"td",src:"https://img.shields.io/npm/v/@aries-framework/redux-store",alt:"@aries-framework/redux-store version"})),(0,a.kt)("td",{parentName:"tr",align:null},"Redux toolkit wrapper around Aries Framework JavaScript")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"https://www.npmjs.com/package/@aries-framework/rest"},(0,a.kt)("inlineCode",{parentName:"a"},"@aries-framework/rest"))),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("img",{parentName:"td",src:"https://img.shields.io/npm/v/@aries-framework/rest",alt:"@aries-framework/rest version"})),(0,a.kt)("td",{parentName:"tr",align:null},"Rest endpoint wrapper for using your agent over HTTP")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"https://www.npmjs.com/package/@aries-framework/react-hooks"},(0,a.kt)("inlineCode",{parentName:"a"},"@aries-framework/react-hooks"))),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("img",{parentName:"td",src:"https://img.shields.io/npm/v/@aries-framework/react-hooks",alt:"@aries-framework/react-hooks version"})),(0,a.kt)("td",{parentName:"tr",align:null},"React Hooks for data handling and agent interaction")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"https://www.npmjs.com/package/@aries-framework/push-notifications"},(0,a.kt)("inlineCode",{parentName:"a"},"@aries-framework/push-notifications"))),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("img",{parentName:"td",src:"https://img.shields.io/npm/v/@aries-framework/push-notifications",alt:"@aries-framework/push-notifications version"})),(0,a.kt)("td",{parentName:"tr",align:null},"Push notification plugin for Aries Framework JavaScript")))),(0,a.kt)(i.Z,{mdxType:"DocCardList"}))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[2680],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=l(r),u=a,f=m["".concat(c,".").concat(u)]||m[u]||d[u]||i;return r?n.createElement(f,o(o({ref:t},p),{},{components:r})):n.createElement(f,o({ref:t},p))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=u;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[m]="string"==typeof e?e:a,o[1]=s;for(var l=2;l{r.d(t,{Z:()=>h});var n=r(7294),a=r(6010),i=r(3438),o=r(9960),s=r(3919),c=r(5999);const l={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function p(e){let{href:t,children:r}=e;return n.createElement(o.Z,{href:t,className:(0,a.Z)("card padding--lg",l.cardContainer)},r)}function m(e){let{href:t,icon:r,title:i,description:o}=e;return n.createElement(p,{href:t},n.createElement("h2",{className:(0,a.Z)("text--truncate",l.cardTitle),title:i},r," ",i),o&&n.createElement("p",{className:(0,a.Z)("text--truncate",l.cardDescription),title:o},o))}function d(e){let{item:t}=e;const r=(0,i.Wl)(t);return r?n.createElement(m,{href:r,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,c.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function u(e){let{item:t}=e;const r=(0,s.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",a=(0,i.xz)(t.docId??void 0);return n.createElement(m,{href:t.href,icon:r,title:t.label,description:a?.description})}function f(e){let{item:t}=e;switch(t.type){case"link":return n.createElement(u,{item:t});case"category":return n.createElement(d,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function k(e){let{className:t}=e;const r=(0,i.jA)();return n.createElement(h,{items:r.items,className:t})}function h(e){const{items:t,className:r}=e;if(!t)return n.createElement(k,e);const o=(0,i.MN)(t);return n.createElement("section",{className:(0,a.Z)("row",r)},o.map(((e,t)=>n.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},n.createElement(f,{item:e})))))}},3583:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var n=r(7462),a=(r(7294),r(3905)),i=r(2991);const o={},s="Extensions",c={unversionedId:"extensions/index",id:"version-0.4/extensions/index",title:"Extensions",description:"Aries Framework JavaScript Extensions is an extensions repository to Aries Framework JavaScript (AFJ). It hosts libraries built on top of Aries Framework JavaScript that don't necessarily belong to the core of the project.",source:"@site/versioned_docs/version-0.4/extensions/index.md",sourceDirName:"extensions",slug:"/extensions/",permalink:"/guides/0.4/extensions/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"The Aries JavaScript Ecosystem",permalink:"/guides/0.4/ecosystem/"},next:{title:"REST API",permalink:"/guides/0.4/extensions/rest"}},l={},p=[],m={toc:p},d="wrapper";function u(e){let{components:t,...r}=e;return(0,a.kt)(d,(0,n.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"extensions"},"Extensions"),(0,a.kt)("p",null,"Aries Framework JavaScript Extensions is an extensions repository to Aries Framework JavaScript (AFJ). It hosts libraries built on top of Aries Framework JavaScript that don't necessarily belong to the core of the project."),(0,a.kt)("p",null,"Currently, there are four packages in the extension repository. Example extension libraries include React Hooks for AFJ and a REST API wrapper."),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Package"),(0,a.kt)("th",{parentName:"tr",align:null},"Version"),(0,a.kt)("th",{parentName:"tr",align:null},"Description"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"https://www.npmjs.com/package/@aries-framework/redux-store"},(0,a.kt)("inlineCode",{parentName:"a"},"@aries-framework/redux-store"))),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("img",{parentName:"td",src:"https://img.shields.io/npm/v/@aries-framework/redux-store",alt:"@aries-framework/redux-store version"})),(0,a.kt)("td",{parentName:"tr",align:null},"Redux toolkit wrapper around Aries Framework JavaScript")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"https://www.npmjs.com/package/@aries-framework/rest"},(0,a.kt)("inlineCode",{parentName:"a"},"@aries-framework/rest"))),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("img",{parentName:"td",src:"https://img.shields.io/npm/v/@aries-framework/rest",alt:"@aries-framework/rest version"})),(0,a.kt)("td",{parentName:"tr",align:null},"Rest endpoint wrapper for using your agent over HTTP")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"https://www.npmjs.com/package/@aries-framework/react-hooks"},(0,a.kt)("inlineCode",{parentName:"a"},"@aries-framework/react-hooks"))),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("img",{parentName:"td",src:"https://img.shields.io/npm/v/@aries-framework/react-hooks",alt:"@aries-framework/react-hooks version"})),(0,a.kt)("td",{parentName:"tr",align:null},"React Hooks for data handling and agent interaction")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"https://www.npmjs.com/package/@aries-framework/push-notifications"},(0,a.kt)("inlineCode",{parentName:"a"},"@aries-framework/push-notifications"))),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("img",{parentName:"td",src:"https://img.shields.io/npm/v/@aries-framework/push-notifications",alt:"@aries-framework/push-notifications version"})),(0,a.kt)("td",{parentName:"tr",align:null},"Push notification plugin for Aries Framework JavaScript")))),(0,a.kt)(i.Z,{mdxType:"DocCardList"}))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9edc454f.78b0e51d.js b/assets/js/9edc454f.8a7c38fd.js similarity index 59% rename from assets/js/9edc454f.78b0e51d.js rename to assets/js/9edc454f.8a7c38fd.js index e6f772f5..e623ad63 100644 --- a/assets/js/9edc454f.78b0e51d.js +++ b/assets/js/9edc454f.8a7c38fd.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7854],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var d=r.createContext({}),p=function(e){var t=r.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(d.Provider,{value:t},e.children)},u="mdxType",l={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,d=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(n),f=o,h=u["".concat(d,".").concat(f)]||u[f]||l[f]||i;return n?r.createElement(h,a(a({ref:t},c),{},{components:n})):r.createElement(h,a({ref:t},c))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=f;var s={};for(var d in t)hasOwnProperty.call(t,d)&&(s[d]=t[d]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>l,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const i={},a="React Native",s={unversionedId:"getting-started/set-up/indy-sdk/react-native",id:"version-0.4/getting-started/set-up/indy-sdk/react-native",title:"React Native",description:"The setup of Indy SDK for React Native is rather different than Node.JS. We do not have to install dependencies on the host-platform, but for the build target. For React Native this would be the Indy SDK for Android & iOS. This guide covers both the Android and iOS setup, as in most React Native projects you will need both.",source:"@site/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/react-native.md",sourceDirName:"getting-started/set-up/indy-sdk",slug:"/getting-started/set-up/indy-sdk/react-native",permalink:"/guides/getting-started/set-up/indy-sdk/react-native",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"macOS (ARM)",permalink:"/guides/getting-started/set-up/indy-sdk/macos-arm"},next:{title:"AnonCreds RS",permalink:"/guides/getting-started/set-up/anoncreds-rs"}},d={},p=[{value:"Expo",id:"expo",level:2},{value:"Without Expo",id:"without-expo",level:2}],c={toc:p},u="wrapper";function l(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"react-native"},"React Native"),(0,o.kt)("p",null,"The setup of Indy SDK for React Native is rather different than Node.JS. We do not have to install dependencies on the host-platform, but for the build target. For React Native this would be the Indy SDK for Android & iOS. This guide covers both the Android and iOS setup, as in most React Native projects you will need both."),(0,o.kt)("h2",{id:"expo"},"Expo"),(0,o.kt)("p",null,"If you're using ",(0,o.kt)("a",{parentName:"p",href:"https://expo.dev"},"Expo"),", the recommended way to install the Indy SDK is by using the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/animo/indy-sdk-expo-plugin"},"Indy SDK Expo Plugin"),". This will correclty set-up your project with the Indy SDK using an ",(0,o.kt)("a",{parentName:"p",href:"https://docs.expo.dev/guides/config-plugins/"},"Expo Config Plugin")," for both iOS and Android."),(0,o.kt)("p",null,"Refer to the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/animo/indy-sdk-expo-plugin"},"Indy SDK Expo Plugin")," repository for installation instructions."),(0,o.kt)("h2",{id:"without-expo"},"Without Expo"),(0,o.kt)("p",null,"When not using Expo, you will need to set-up the Indy SDK for both Android and iOS using the ",(0,o.kt)("inlineCode",{parentName:"p"},"indy-sdk-react-native")," package directly. Refer to the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk-react-native"},"Indy SDK React Native")," repository for installation instructions."))}l.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7854],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var d=r.createContext({}),p=function(e){var t=r.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(d.Provider,{value:t},e.children)},u="mdxType",l={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,d=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(n),f=o,h=u["".concat(d,".").concat(f)]||u[f]||l[f]||i;return n?r.createElement(h,a(a({ref:t},c),{},{components:n})):r.createElement(h,a({ref:t},c))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=f;var s={};for(var d in t)hasOwnProperty.call(t,d)&&(s[d]=t[d]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>l,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const i={},a="React Native",s={unversionedId:"getting-started/set-up/indy-sdk/react-native",id:"version-0.4/getting-started/set-up/indy-sdk/react-native",title:"React Native",description:"The setup of Indy SDK for React Native is rather different than Node.JS. We do not have to install dependencies on the host-platform, but for the build target. For React Native this would be the Indy SDK for Android & iOS. This guide covers both the Android and iOS setup, as in most React Native projects you will need both.",source:"@site/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/react-native.md",sourceDirName:"getting-started/set-up/indy-sdk",slug:"/getting-started/set-up/indy-sdk/react-native",permalink:"/guides/0.4/getting-started/set-up/indy-sdk/react-native",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"macOS (ARM)",permalink:"/guides/0.4/getting-started/set-up/indy-sdk/macos-arm"},next:{title:"AnonCreds RS",permalink:"/guides/0.4/getting-started/set-up/anoncreds-rs"}},d={},p=[{value:"Expo",id:"expo",level:2},{value:"Without Expo",id:"without-expo",level:2}],c={toc:p},u="wrapper";function l(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"react-native"},"React Native"),(0,o.kt)("p",null,"The setup of Indy SDK for React Native is rather different than Node.JS. We do not have to install dependencies on the host-platform, but for the build target. For React Native this would be the Indy SDK for Android & iOS. This guide covers both the Android and iOS setup, as in most React Native projects you will need both."),(0,o.kt)("h2",{id:"expo"},"Expo"),(0,o.kt)("p",null,"If you're using ",(0,o.kt)("a",{parentName:"p",href:"https://expo.dev"},"Expo"),", the recommended way to install the Indy SDK is by using the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/animo/indy-sdk-expo-plugin"},"Indy SDK Expo Plugin"),". This will correclty set-up your project with the Indy SDK using an ",(0,o.kt)("a",{parentName:"p",href:"https://docs.expo.dev/guides/config-plugins/"},"Expo Config Plugin")," for both iOS and Android."),(0,o.kt)("p",null,"Refer to the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/animo/indy-sdk-expo-plugin"},"Indy SDK Expo Plugin")," repository for installation instructions."),(0,o.kt)("h2",{id:"without-expo"},"Without Expo"),(0,o.kt)("p",null,"When not using Expo, you will need to set-up the Indy SDK for both Android and iOS using the ",(0,o.kt)("inlineCode",{parentName:"p"},"indy-sdk-react-native")," package directly. Refer to the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk-react-native"},"Indy SDK React Native")," repository for installation instructions."))}l.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a1dc5557.64bae966.js b/assets/js/a1dc5557.d28877e4.js similarity index 58% rename from assets/js/a1dc5557.64bae966.js rename to assets/js/a1dc5557.d28877e4.js index 823faae9..792dc567 100644 --- a/assets/js/a1dc5557.64bae966.js +++ b/assets/js/a1dc5557.d28877e4.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8230],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>f});var s=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);t&&(s=s.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,s)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(s=0;s=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=s.createContext({}),u=function(e){var t=s.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},d=function(e){var t=u(e.components);return s.createElement(l.Provider,{value:t},e.children)},p="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return s.createElement(s.Fragment,{},t)}},g=s.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),p=u(n),g=r,f=p["".concat(l,".").concat(g)]||p[g]||c[g]||o;return n?s.createElement(f,a(a({ref:t},d),{},{components:n})):s.createElement(f,a({ref:t},d))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,a=new Array(o);a[0]=g;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[p]="string"==typeof e?e:r,a[1]=i;for(var u=2;u{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>u});var s=n(7462),r=(n(7294),n(3905));const o={},a="Using PostgreSQL as Database for Indy SDK in Node.js",i={unversionedId:"tutorials/indy-sdk-postgres-database-nodejs/index",id:"version-0.4/tutorials/indy-sdk-postgres-database-nodejs/index",title:"Using PostgreSQL as Database for Indy SDK in Node.js",description:"By default the Indy SDK will use an SQLite database for storage. In mobile environments this is sufficient and allows us to keep storage local to the device, but in server environments we oftentimes want a more scalable storage solution. By leveraging the PostgreSQL plugin for Indy SDK we can use PostgreSQL as a storage solution instead of SQLite.",source:"@site/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/index.md",sourceDirName:"tutorials/indy-sdk-postgres-database-nodejs",slug:"/tutorials/indy-sdk-postgres-database-nodejs/",permalink:"/guides/tutorials/indy-sdk-postgres-database-nodejs/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Mediation",permalink:"/guides/tutorials/mediation"},next:{title:"Postgres Setup for Linux",permalink:"/guides/tutorials/indy-sdk-postgres-database-nodejs/linux"}},l={},u=[{value:"Installation of the Postgres Plugin",id:"installation-of-the-postgres-plugin",level:2},{value:"Using the Postgres Plugin in AFJ",id:"using-the-postgres-plugin-in-afj",level:2}],d={toc:u},p="wrapper";function c(e){let{components:t,...n}=e;return(0,r.kt)(p,(0,s.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"using-postgresql-as-database-for-indy-sdk-in-nodejs"},"Using PostgreSQL as Database for Indy SDK in Node.js"),(0,r.kt)("p",null,"By default the Indy SDK will use an SQLite database for storage. In mobile environments this is sufficient and allows us to keep storage local to the device, but in server environments we oftentimes want a more scalable storage solution. By leveraging the PostgreSQL plugin for Indy SDK we can use PostgreSQL as a storage solution instead of SQLite."),(0,r.kt)("p",null,"This document describes the installation process of the Postgres plugin for IndySDK and how you need to configure AFJ to use it."),(0,r.kt)("h2",{id:"installation-of-the-postgres-plugin"},"Installation of the Postgres Plugin"),(0,r.kt)("p",null,"For installation of the Postgres plugin, please refer to the platform specific guides:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/guides/tutorials/indy-sdk-postgres-database-nodejs/macos"},"macOS")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/guides/tutorials/indy-sdk-postgres-database-nodejs/linux"},"Linux")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/guides/tutorials/indy-sdk-postgres-database-nodejs/windows"},"Windows"))),(0,r.kt)("h2",{id:"using-the-postgres-plugin-in-afj"},"Using the Postgres Plugin in AFJ"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-indy-sdk-postgres.ts section-1",showLineNumbers:!0,"set-up-indy-sdk-postgres.ts":!0,"section-1":!0},"")))}c.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8230],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>f});var s=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);t&&(s=s.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,s)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(s=0;s=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=s.createContext({}),u=function(e){var t=s.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},d=function(e){var t=u(e.components);return s.createElement(l.Provider,{value:t},e.children)},p="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return s.createElement(s.Fragment,{},t)}},g=s.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),p=u(n),g=r,f=p["".concat(l,".").concat(g)]||p[g]||c[g]||o;return n?s.createElement(f,a(a({ref:t},d),{},{components:n})):s.createElement(f,a({ref:t},d))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,a=new Array(o);a[0]=g;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[p]="string"==typeof e?e:r,a[1]=i;for(var u=2;u{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>u});var s=n(7462),r=(n(7294),n(3905));const o={},a="Using PostgreSQL as Database for Indy SDK in Node.js",i={unversionedId:"tutorials/indy-sdk-postgres-database-nodejs/index",id:"version-0.4/tutorials/indy-sdk-postgres-database-nodejs/index",title:"Using PostgreSQL as Database for Indy SDK in Node.js",description:"By default the Indy SDK will use an SQLite database for storage. In mobile environments this is sufficient and allows us to keep storage local to the device, but in server environments we oftentimes want a more scalable storage solution. By leveraging the PostgreSQL plugin for Indy SDK we can use PostgreSQL as a storage solution instead of SQLite.",source:"@site/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/index.md",sourceDirName:"tutorials/indy-sdk-postgres-database-nodejs",slug:"/tutorials/indy-sdk-postgres-database-nodejs/",permalink:"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Mediation",permalink:"/guides/0.4/tutorials/mediation"},next:{title:"Postgres Setup for Linux",permalink:"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/linux"}},l={},u=[{value:"Installation of the Postgres Plugin",id:"installation-of-the-postgres-plugin",level:2},{value:"Using the Postgres Plugin in AFJ",id:"using-the-postgres-plugin-in-afj",level:2}],d={toc:u},p="wrapper";function c(e){let{components:t,...n}=e;return(0,r.kt)(p,(0,s.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"using-postgresql-as-database-for-indy-sdk-in-nodejs"},"Using PostgreSQL as Database for Indy SDK in Node.js"),(0,r.kt)("p",null,"By default the Indy SDK will use an SQLite database for storage. In mobile environments this is sufficient and allows us to keep storage local to the device, but in server environments we oftentimes want a more scalable storage solution. By leveraging the PostgreSQL plugin for Indy SDK we can use PostgreSQL as a storage solution instead of SQLite."),(0,r.kt)("p",null,"This document describes the installation process of the Postgres plugin for IndySDK and how you need to configure AFJ to use it."),(0,r.kt)("h2",{id:"installation-of-the-postgres-plugin"},"Installation of the Postgres Plugin"),(0,r.kt)("p",null,"For installation of the Postgres plugin, please refer to the platform specific guides:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/macos"},"macOS")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/linux"},"Linux")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/windows"},"Windows"))),(0,r.kt)("h2",{id:"using-the-postgres-plugin-in-afj"},"Using the Postgres Plugin in AFJ"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-indy-sdk-postgres.ts section-1",showLineNumbers:!0,"set-up-indy-sdk-postgres.ts":!0,"section-1":!0},"")))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a2a3716e.67147bbd.js b/assets/js/a2a3716e.e6ed1b19.js similarity index 85% rename from assets/js/a2a3716e.67147bbd.js rename to assets/js/a2a3716e.e6ed1b19.js index 16d6008f..bd847046 100644 --- a/assets/js/a2a3716e.67147bbd.js +++ b/assets/js/a2a3716e.e6ed1b19.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[644],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var l=n.createContext({}),s=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},u=function(e){var t=s(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,a=e.originalType,l=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),p=s(r),m=i,f=p["".concat(l,".").concat(m)]||p[m]||d[m]||a;return r?n.createElement(f,o(o({ref:t},u),{},{components:r})):n.createElement(f,o({ref:t},u))}));function f(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=r.length,o=new Array(a);o[0]=m;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[p]="string"==typeof e?e:i,o[1]=c;for(var s=2;s{r.d(t,{Z:()=>g});var n=r(7294),i=r(6010),a=r(3438),o=r(9960),c=r(3919),l=r(5999);const s={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function u(e){let{href:t,children:r}=e;return n.createElement(o.Z,{href:t,className:(0,i.Z)("card padding--lg",s.cardContainer)},r)}function p(e){let{href:t,icon:r,title:a,description:o}=e;return n.createElement(u,{href:t},n.createElement("h2",{className:(0,i.Z)("text--truncate",s.cardTitle),title:a},r," ",a),o&&n.createElement("p",{className:(0,i.Z)("text--truncate",s.cardDescription),title:o},o))}function d(e){let{item:t}=e;const r=(0,a.Wl)(t);return r?n.createElement(p,{href:r,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,l.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function m(e){let{item:t}=e;const r=(0,c.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",i=(0,a.xz)(t.docId??void 0);return n.createElement(p,{href:t.href,icon:r,title:t.label,description:i?.description})}function f(e){let{item:t}=e;switch(t.type){case"link":return n.createElement(m,{item:t});case"category":return n.createElement(d,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function y(e){let{className:t}=e;const r=(0,a.jA)();return n.createElement(g,{items:r.items,className:t})}function g(e){const{items:t,className:r}=e;if(!t)return n.createElement(y,e);const o=(0,a.MN)(t);return n.createElement("section",{className:(0,i.Z)("row",r)},o.map(((e,t)=>n.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},n.createElement(f,{item:e})))))}},4789:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>m,frontMatter:()=>o,metadata:()=>l,toc:()=>u});var n=r(7462),i=(r(7294),r(3905)),a=r(2991);const o={},c="Tutorials",l={unversionedId:"tutorials/index",id:"tutorials/index",title:"Tutorials",description:"In this section we will explain some features that everyone will use. This",source:"@site/guides/tutorials/index.md",sourceDirName:"tutorials",slug:"/tutorials/",permalink:"/guides/0.5/tutorials/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Verifiable Credentials",permalink:"/guides/0.5/features/credentials"},next:{title:"Agent Config",permalink:"/guides/0.5/tutorials/agent-config/"}},s={},u=[],p={toc:u},d="wrapper";function m(e){let{components:t,...r}=e;return(0,i.kt)(d,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"tutorials"},"Tutorials"),(0,i.kt)("p",null,"In this section we will explain some features that everyone will use. This\nincludes setting up your Aries agent, creating a connection between Aries\nagents, issuing a credential and verifying a proof."),(0,i.kt)(a.Z,{mdxType:"DocCardList"}))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[644],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var l=n.createContext({}),s=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},u=function(e){var t=s(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,a=e.originalType,l=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),p=s(r),m=i,f=p["".concat(l,".").concat(m)]||p[m]||d[m]||a;return r?n.createElement(f,o(o({ref:t},u),{},{components:r})):n.createElement(f,o({ref:t},u))}));function f(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=r.length,o=new Array(a);o[0]=m;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[p]="string"==typeof e?e:i,o[1]=c;for(var s=2;s{r.d(t,{Z:()=>g});var n=r(7294),i=r(6010),a=r(3438),o=r(9960),c=r(3919),l=r(5999);const s={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function u(e){let{href:t,children:r}=e;return n.createElement(o.Z,{href:t,className:(0,i.Z)("card padding--lg",s.cardContainer)},r)}function p(e){let{href:t,icon:r,title:a,description:o}=e;return n.createElement(u,{href:t},n.createElement("h2",{className:(0,i.Z)("text--truncate",s.cardTitle),title:a},r," ",a),o&&n.createElement("p",{className:(0,i.Z)("text--truncate",s.cardDescription),title:o},o))}function d(e){let{item:t}=e;const r=(0,a.Wl)(t);return r?n.createElement(p,{href:r,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,l.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function m(e){let{item:t}=e;const r=(0,c.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",i=(0,a.xz)(t.docId??void 0);return n.createElement(p,{href:t.href,icon:r,title:t.label,description:i?.description})}function f(e){let{item:t}=e;switch(t.type){case"link":return n.createElement(m,{item:t});case"category":return n.createElement(d,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function y(e){let{className:t}=e;const r=(0,a.jA)();return n.createElement(g,{items:r.items,className:t})}function g(e){const{items:t,className:r}=e;if(!t)return n.createElement(y,e);const o=(0,a.MN)(t);return n.createElement("section",{className:(0,i.Z)("row",r)},o.map(((e,t)=>n.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},n.createElement(f,{item:e})))))}},4789:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>m,frontMatter:()=>o,metadata:()=>l,toc:()=>u});var n=r(7462),i=(r(7294),r(3905)),a=r(2991);const o={},c="Tutorials",l={unversionedId:"tutorials/index",id:"tutorials/index",title:"Tutorials",description:"In this section we will explain some features that everyone will use. This",source:"@site/guides/tutorials/index.md",sourceDirName:"tutorials",slug:"/tutorials/",permalink:"/guides/tutorials/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Verifiable Credentials",permalink:"/guides/features/credentials"},next:{title:"Agent Config",permalink:"/guides/tutorials/agent-config/"}},s={},u=[],p={toc:u},d="wrapper";function m(e){let{components:t,...r}=e;return(0,i.kt)(d,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"tutorials"},"Tutorials"),(0,i.kt)("p",null,"In this section we will explain some features that everyone will use. This\nincludes setting up your Aries agent, creating a connection between Aries\nagents, issuing a credential and verifying a proof."),(0,i.kt)(a.Z,{mdxType:"DocCardList"}))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a690f229.8817a567.js b/assets/js/a690f229.8817a567.js new file mode 100644 index 00000000..23c0925f --- /dev/null +++ b/assets/js/a690f229.8817a567.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[9841],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>h});var n=a(7294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var l=n.createContext({}),u=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},p=function(e){var t=u(e.components);return n.createElement(l.Provider,{value:t},e.children)},d="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),d=u(a),c=i,h=d["".concat(l,".").concat(c)]||d[c]||g[c]||r;return a?n.createElement(h,s(s({ref:t},p),{},{components:a})):n.createElement(h,s({ref:t},p))}));function h(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=a.length,s=new Array(r);s[0]=c;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[d]="string"==typeof e?e:i,s[1]=o;for(var u=2;u{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>g,frontMatter:()=>r,metadata:()=>o,toc:()=>u});var n=a(7462),i=(a(7294),a(3905));const r={},s="Update Assistant",o={unversionedId:"updating/update-assistant",id:"version-0.4/updating/update-assistant",title:"Update Assistant",description:"The Update Assistant helps you update the storage objects from AFJ to newer versions. This documents describes the different ways you can leverage the Update Assistant from fully managed to more manual approaches.",source:"@site/versioned_docs/version-0.4/updating/update-assistant.md",sourceDirName:"updating",slug:"/updating/update-assistant",permalink:"/guides/0.4/updating/update-assistant",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Updating AFJ",permalink:"/guides/0.4/updating/"},next:{title:"Migrating from an Indy SDK Wallet to Aries Askar",permalink:"/guides/0.4/updating/update-indy-sdk-to-askar"}},l={},u=[{value:"Update Strategies",id:"update-strategies",level:2},{value:"Manually instantiating the update assistant on agent startup",id:"manually-instantiating-the-update-assistant-on-agent-startup",level:3},{value:"Storing the agent storage version outside of the agent storage",id:"storing-the-agent-storage-version-outside-of-the-agent-storage",level:3},{value:"Automatically update on agent startup",id:"automatically-update-on-agent-startup",level:3},{value:"Backups",id:"backups",level:2}],p={toc:u},d="wrapper";function g(e){let{components:t,...a}=e;return(0,i.kt)(d,(0,n.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"update-assistant"},"Update Assistant"),(0,i.kt)("p",null,"The Update Assistant helps you update the storage objects from AFJ to newer versions. This documents describes the different ways you can leverage the Update Assistant from fully managed to more manual approaches."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#update-strategies"},"Update Strategies"),(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#manually-instantiating-the-update-assistant-on-agent-startup"},"Manually instantiating the update assistant on agent startup")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#storing-the-agent-storage-version-outside-of-the-agent-storage"},"Storing the agent storage version outside of the agent storage")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#automatically-update-on-agent-startup"},"Automatically update on agent startup")))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#backups"},"Backups"))),(0,i.kt)("h2",{id:"update-strategies"},"Update Strategies"),(0,i.kt)("p",null,"There are three options on how to leverage the update assistant on agent startup:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Manually instantiating the update assistant on agent startup"),(0,i.kt)("li",{parentName:"ol"},"Storing the agent storage version outside of the agent storage"),(0,i.kt)("li",{parentName:"ol"},"Automatically update on agent startup")),(0,i.kt)("h3",{id:"manually-instantiating-the-update-assistant-on-agent-startup"},"Manually instantiating the update assistant on agent startup"),(0,i.kt)("p",null,"When the version of the storage is stored inside the agent storage, it means we need to check if the agent needs to be updated on every agent startup. We'll initialize the update assistant and check whether the storage is up to date. The advantage of this approach is that you don't have to store anything yourself, and have full control over the workflow."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts"},"import { UpdateAssistant, Agent } from '@aries-framework/core'\n\n// or @aries-framework/node\nimport { agentDependencies } from '@aries-framework/react-native'\n\n// First create the agent\nconst agent = new Agent({\n config,\n dependencies: agentDependencies,\n})\n\n// Then initialize the update assistant with the update config\nconst updateAssistant = new UpdateAssistant(agent, {\n v0_1ToV0_2: {\n mediationRoleUpdateStrategy: 'allMediator',\n },\n})\n\n// Initialize the update assistant so we can read the current storage version\n// from the wallet. If you manually initialize the wallet you should do this _before_\n// calling initialize on the update assistant\n// await agent.wallet.initialize(walletConfig)\nawait updateAssistant.initialize()\n\n// Check if the agent is up to date, if not call update\nif (!(await updateAssistant.isUpToDate())) {\n await updateAssistant.update()\n}\n\n// Once finished initialize the agent. You should do this on every launch of the agent\nawait agent.initialize()\n")),(0,i.kt)("h3",{id:"storing-the-agent-storage-version-outside-of-the-agent-storage"},"Storing the agent storage version outside of the agent storage"),(0,i.kt)("p",null,"When the version of the storage is stored outside of the agent storage, you don't have to initialize the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," on every agent agent startup. You can just check if the storage version is up to date and instantiate the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," if not. The advantage of this approach is that you don't have to instantiate the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," on every agent startup, but this does mean that you have to store the storage version yourself."),(0,i.kt)("p",null,"When a wallet has been exported and later imported you don't always have the latest version available. If this is the case you can always rely on Method 1 or 2 for updating the wallet, and storing the version yourself afterwards. You can also get the current version by calling ",(0,i.kt)("inlineCode",{parentName:"p"},"await updateAssistant.getCurrentAgentStorageVersion()"),". Do note the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," needs to be initialized before calling this method."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts"},"import { UpdateAssistant, Agent } from '@aries-framework/core'\n\n// or @aries-framework/node\nimport { agentDependencies } from '@aries-framework/react-native'\n\n// The storage version will normally be stored in e.g. persistent storage on a mobile device\nlet currentStorageVersion: VersionString = '0.1'\n\n// First create the agent\nconst agent = new Agent({\n config,\n dependencies: agentDependencies,\n})\n\n// We only initialize the update assistant if our stored version is not equal\n// to the frameworkStorageVersion of the UpdateAssistant. The advantage of this\n// is that we don't have to initialize the UpdateAssistant to retrieve the current\n// storage version.\nif (currentStorageVersion !== UpdateAssistant.frameworkStorageVersion) {\n const updateAssistant = new UpdateAssistant(agent, {\n v0_1ToV0_2: {\n mediationRoleUpdateStrategy: 'recipientIfEndpoint',\n },\n })\n\n // Same as with the previous strategy, if you normally call agent.wallet.initialize() manually\n // you need to call this before calling updateAssistant.initialize()\n await updateAssistant.initialize()\n\n await updateAssistant.update()\n\n // Store the version so we can leverage it during the next agent startup and don't have\n // to initialize the update assistant again until a new version is released\n currentStorageVersion = UpdateAssistant.frameworkStorageVersion\n}\n\n// Once finished initialize the agent. You should do this on every launch of the agent\nawait agent.initialize()\n")),(0,i.kt)("h3",{id:"automatically-update-on-agent-startup"},"Automatically update on agent startup"),(0,i.kt)("p",null,"This is by far the easiest way to update the agent, but has the least amount of flexibility and is not configurable. This means you will have to use the default update options to update the agent storage. You can find the default update config in the respective version migration guides (e.g. in ",(0,i.kt)("a",{parentName:"p",href:"/guides/updating/versions/0.1-to-0.2"},"0.1-to-0.2"),")."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts"},"import { UpdateAssistant, Agent } from '@aries-framework/core'\n\n// or @aries-framework/node\nimport { agentDependencies } from '@aries-framework/react-native'\n\n// First create the agent, setting the autoUpdateStorageOnStartup option to true\nconst agent = new Agent({\n config: {\n ...config,\n autoUpdateStorageOnStartup: true,\n },\n dependencies: agentDependencies,\n})\n\n// Then we call initialize, which under the hood will call the update assistant if the storage is not update to date.\nawait agent.initialize()\n")),(0,i.kt)("h2",{id:"backups"},"Backups"),(0,i.kt)("p",null,"Before starting the update, the update assistant will automatically create a backup of the wallet. If the migration succeeds the backup won't be used. If the backup fails, another backup will be made of the migrated wallet, after which the backup will be restored."),(0,i.kt)("p",null,"The backups can be found at the following locations. The ",(0,i.kt)("inlineCode",{parentName:"p"},"backupIdentifier")," is generated at the start of the update process and generated based on the current timestamp."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Backup path: ",(0,i.kt)("inlineCode",{parentName:"li"},"${agent.config.fileSystem.basePath}/afj/migration/backup/${backupIdentifier}")),(0,i.kt)("li",{parentName:"ul"},"Migration backup: ",(0,i.kt)("inlineCode",{parentName:"li"},"${agent.config.fileSystem.basePath}/afj/migration/backup/${backupIdentifier}-error"))),(0,i.kt)("blockquote",null,(0,i.kt)("p",{parentName:"blockquote"},"In the future the backup assistant will make a number of improvements to the recovery process. Namely:"),(0,i.kt)("ul",{parentName:"blockquote"},(0,i.kt)("li",{parentName:"ul"},"Do not throw an error if the update fails, but rather return an object that contains the status, and include the backup paths and backup identifiers."))))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a690f229.9ee705e9.js b/assets/js/a690f229.9ee705e9.js deleted file mode 100644 index 7f236033..00000000 --- a/assets/js/a690f229.9ee705e9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[9841],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>h});var n=a(7294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var l=n.createContext({}),u=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},p=function(e){var t=u(e.components);return n.createElement(l.Provider,{value:t},e.children)},d="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),d=u(a),c=i,h=d["".concat(l,".").concat(c)]||d[c]||g[c]||r;return a?n.createElement(h,s(s({ref:t},p),{},{components:a})):n.createElement(h,s({ref:t},p))}));function h(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=a.length,s=new Array(r);s[0]=c;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[d]="string"==typeof e?e:i,s[1]=o;for(var u=2;u{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>g,frontMatter:()=>r,metadata:()=>o,toc:()=>u});var n=a(7462),i=(a(7294),a(3905));const r={},s="Update Assistant",o={unversionedId:"updating/update-assistant",id:"version-0.4/updating/update-assistant",title:"Update Assistant",description:"The Update Assistant helps you update the storage objects from AFJ to newer versions. This documents describes the different ways you can leverage the Update Assistant from fully managed to more manual approaches.",source:"@site/versioned_docs/version-0.4/updating/update-assistant.md",sourceDirName:"updating",slug:"/updating/update-assistant",permalink:"/guides/updating/update-assistant",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Updating AFJ",permalink:"/guides/updating/"},next:{title:"Migrating from an Indy SDK Wallet to Aries Askar",permalink:"/guides/updating/update-indy-sdk-to-askar"}},l={},u=[{value:"Update Strategies",id:"update-strategies",level:2},{value:"Manually instantiating the update assistant on agent startup",id:"manually-instantiating-the-update-assistant-on-agent-startup",level:3},{value:"Storing the agent storage version outside of the agent storage",id:"storing-the-agent-storage-version-outside-of-the-agent-storage",level:3},{value:"Automatically update on agent startup",id:"automatically-update-on-agent-startup",level:3},{value:"Backups",id:"backups",level:2}],p={toc:u},d="wrapper";function g(e){let{components:t,...a}=e;return(0,i.kt)(d,(0,n.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"update-assistant"},"Update Assistant"),(0,i.kt)("p",null,"The Update Assistant helps you update the storage objects from AFJ to newer versions. This documents describes the different ways you can leverage the Update Assistant from fully managed to more manual approaches."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#update-strategies"},"Update Strategies"),(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#manually-instantiating-the-update-assistant-on-agent-startup"},"Manually instantiating the update assistant on agent startup")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#storing-the-agent-storage-version-outside-of-the-agent-storage"},"Storing the agent storage version outside of the agent storage")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#automatically-update-on-agent-startup"},"Automatically update on agent startup")))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#backups"},"Backups"))),(0,i.kt)("h2",{id:"update-strategies"},"Update Strategies"),(0,i.kt)("p",null,"There are three options on how to leverage the update assistant on agent startup:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Manually instantiating the update assistant on agent startup"),(0,i.kt)("li",{parentName:"ol"},"Storing the agent storage version outside of the agent storage"),(0,i.kt)("li",{parentName:"ol"},"Automatically update on agent startup")),(0,i.kt)("h3",{id:"manually-instantiating-the-update-assistant-on-agent-startup"},"Manually instantiating the update assistant on agent startup"),(0,i.kt)("p",null,"When the version of the storage is stored inside the agent storage, it means we need to check if the agent needs to be updated on every agent startup. We'll initialize the update assistant and check whether the storage is up to date. The advantage of this approach is that you don't have to store anything yourself, and have full control over the workflow."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts"},"import { UpdateAssistant, Agent } from '@aries-framework/core'\n\n// or @aries-framework/node\nimport { agentDependencies } from '@aries-framework/react-native'\n\n// First create the agent\nconst agent = new Agent({\n config,\n dependencies: agentDependencies,\n})\n\n// Then initialize the update assistant with the update config\nconst updateAssistant = new UpdateAssistant(agent, {\n v0_1ToV0_2: {\n mediationRoleUpdateStrategy: 'allMediator',\n },\n})\n\n// Initialize the update assistant so we can read the current storage version\n// from the wallet. If you manually initialize the wallet you should do this _before_\n// calling initialize on the update assistant\n// await agent.wallet.initialize(walletConfig)\nawait updateAssistant.initialize()\n\n// Check if the agent is up to date, if not call update\nif (!(await updateAssistant.isUpToDate())) {\n await updateAssistant.update()\n}\n\n// Once finished initialize the agent. You should do this on every launch of the agent\nawait agent.initialize()\n")),(0,i.kt)("h3",{id:"storing-the-agent-storage-version-outside-of-the-agent-storage"},"Storing the agent storage version outside of the agent storage"),(0,i.kt)("p",null,"When the version of the storage is stored outside of the agent storage, you don't have to initialize the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," on every agent agent startup. You can just check if the storage version is up to date and instantiate the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," if not. The advantage of this approach is that you don't have to instantiate the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," on every agent startup, but this does mean that you have to store the storage version yourself."),(0,i.kt)("p",null,"When a wallet has been exported and later imported you don't always have the latest version available. If this is the case you can always rely on Method 1 or 2 for updating the wallet, and storing the version yourself afterwards. You can also get the current version by calling ",(0,i.kt)("inlineCode",{parentName:"p"},"await updateAssistant.getCurrentAgentStorageVersion()"),". Do note the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," needs to be initialized before calling this method."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts"},"import { UpdateAssistant, Agent } from '@aries-framework/core'\n\n// or @aries-framework/node\nimport { agentDependencies } from '@aries-framework/react-native'\n\n// The storage version will normally be stored in e.g. persistent storage on a mobile device\nlet currentStorageVersion: VersionString = '0.1'\n\n// First create the agent\nconst agent = new Agent({\n config,\n dependencies: agentDependencies,\n})\n\n// We only initialize the update assistant if our stored version is not equal\n// to the frameworkStorageVersion of the UpdateAssistant. The advantage of this\n// is that we don't have to initialize the UpdateAssistant to retrieve the current\n// storage version.\nif (currentStorageVersion !== UpdateAssistant.frameworkStorageVersion) {\n const updateAssistant = new UpdateAssistant(agent, {\n v0_1ToV0_2: {\n mediationRoleUpdateStrategy: 'recipientIfEndpoint',\n },\n })\n\n // Same as with the previous strategy, if you normally call agent.wallet.initialize() manually\n // you need to call this before calling updateAssistant.initialize()\n await updateAssistant.initialize()\n\n await updateAssistant.update()\n\n // Store the version so we can leverage it during the next agent startup and don't have\n // to initialize the update assistant again until a new version is released\n currentStorageVersion = UpdateAssistant.frameworkStorageVersion\n}\n\n// Once finished initialize the agent. You should do this on every launch of the agent\nawait agent.initialize()\n")),(0,i.kt)("h3",{id:"automatically-update-on-agent-startup"},"Automatically update on agent startup"),(0,i.kt)("p",null,"This is by far the easiest way to update the agent, but has the least amount of flexibility and is not configurable. This means you will have to use the default update options to update the agent storage. You can find the default update config in the respective version migration guides (e.g. in ",(0,i.kt)("a",{parentName:"p",href:"/guides/0.5/updating/versions/0.1-to-0.2"},"0.1-to-0.2"),")."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts"},"import { UpdateAssistant, Agent } from '@aries-framework/core'\n\n// or @aries-framework/node\nimport { agentDependencies } from '@aries-framework/react-native'\n\n// First create the agent, setting the autoUpdateStorageOnStartup option to true\nconst agent = new Agent({\n config: {\n ...config,\n autoUpdateStorageOnStartup: true,\n },\n dependencies: agentDependencies,\n})\n\n// Then we call initialize, which under the hood will call the update assistant if the storage is not update to date.\nawait agent.initialize()\n")),(0,i.kt)("h2",{id:"backups"},"Backups"),(0,i.kt)("p",null,"Before starting the update, the update assistant will automatically create a backup of the wallet. If the migration succeeds the backup won't be used. If the backup fails, another backup will be made of the migrated wallet, after which the backup will be restored."),(0,i.kt)("p",null,"The backups can be found at the following locations. The ",(0,i.kt)("inlineCode",{parentName:"p"},"backupIdentifier")," is generated at the start of the update process and generated based on the current timestamp."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Backup path: ",(0,i.kt)("inlineCode",{parentName:"li"},"${agent.config.fileSystem.basePath}/afj/migration/backup/${backupIdentifier}")),(0,i.kt)("li",{parentName:"ul"},"Migration backup: ",(0,i.kt)("inlineCode",{parentName:"li"},"${agent.config.fileSystem.basePath}/afj/migration/backup/${backupIdentifier}-error"))),(0,i.kt)("blockquote",null,(0,i.kt)("p",{parentName:"blockquote"},"In the future the backup assistant will make a number of improvements to the recovery process. Namely:"),(0,i.kt)("ul",{parentName:"blockquote"},(0,i.kt)("li",{parentName:"ul"},"Do not throw an error if the update fails, but rather return an object that contains the status, and include the backup paths and backup identifiers."))))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a69e7b9a.cd4652af.js b/assets/js/a69e7b9a.c70f81eb.js similarity index 77% rename from assets/js/a69e7b9a.cd4652af.js rename to assets/js/a69e7b9a.c70f81eb.js index 0856fa82..378c9683 100644 --- a/assets/js/a69e7b9a.cd4652af.js +++ b/assets/js/a69e7b9a.c70f81eb.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4365],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var u=n.createContext({}),i=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=i(e.components);return n.createElement(u.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,u=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=i(r),m=a,f=d["".concat(u,".").concat(m)]||d[m]||p[m]||o;return r?n.createElement(f,l(l({ref:t},c),{},{components:r})):n.createElement(f,l({ref:t},c))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=m;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s[d]="string"==typeof e?e:a,l[1]=s;for(var i=2;i{r.d(t,{Z:()=>l});var n=r(7294),a=r(6010);const o={tabItem:"tabItem_Ymn6"};function l(e){let{children:t,hidden:r,className:l}=e;return n.createElement("div",{role:"tabpanel",className:(0,a.Z)(o.tabItem,l),hidden:r},t)}},4866:(e,t,r)=>{r.d(t,{Z:()=>x});var n=r(7462),a=r(7294),o=r(6010),l=r(2466),s=r(6550),u=r(1980),i=r(7392),c=r(12);function d(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:r,attributes:n,default:a}}=e;return{value:t,label:r,attributes:n,default:a}}))}function p(e){const{values:t,children:r}=e;return(0,a.useMemo)((()=>{const e=t??d(r);return function(e){const t=(0,i.l)(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,r])}function m(e){let{value:t,tabValues:r}=e;return r.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:r}=e;const n=(0,s.k6)(),o=function(e){let{queryString:t=!1,groupId:r}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!r)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 r??null}({queryString:t,groupId:r});return[(0,u._X)(o),(0,a.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(n.location.search);t.set(o,e),n.replace({...n.location,search:t.toString()})}),[o,n])]}function b(e){const{defaultValue:t,queryString:r=!1,groupId:n}=e,o=p(e),[l,s]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:r}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=r.find((e=>e.default))??r[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:o}))),[u,i]=f({queryString:r,groupId:n}),[d,b]=function(e){let{groupId:t}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,o]=(0,c.Nk)(r);return[n,(0,a.useCallback)((e=>{r&&o.set(e)}),[r,o])]}({groupId:n}),h=(()=>{const e=u??d;return m({value:e,tabValues:o})?e:null})();(0,a.useLayoutEffect)((()=>{h&&s(h)}),[h]);return{selectedValue:l,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);s(e),i(e),b(e)}),[i,b,o]),tabValues:o}}var h=r(2389);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function v(e){let{className:t,block:r,selectedValue:s,selectValue:u,tabValues:i}=e;const c=[],{blockElementScrollPositionUntilNextRender:d}=(0,l.o5)(),p=e=>{const t=e.currentTarget,r=c.indexOf(t),n=i[r].value;n!==s&&(d(t),u(n))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const r=c.indexOf(e.currentTarget)+1;t=c[r]??c[0];break}case"ArrowLeft":{const r=c.indexOf(e.currentTarget)-1;t=c[r]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":r},t)},i.map((e=>{let{value:t,label:r,attributes:l}=e;return a.createElement("li",(0,n.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:p},l,{className:(0,o.Z)("tabs__item",g.tabItem,l?.className,{"tabs__item--active":s===t})}),r??t)})))}function y(e){let{lazy:t,children:r,selectedValue:n}=e;if(r=Array.isArray(r)?r:[r],t){const e=r.find((e=>e.props.value===n));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},r.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==n}))))}function k(e){const t=b(e);return a.createElement("div",{className:(0,o.Z)("tabs-container",g.tabList)},a.createElement(v,(0,n.Z)({},e,t)),a.createElement(y,(0,n.Z)({},e,t)))}function x(e){const t=(0,h.Z)();return a.createElement(k,(0,n.Z)({key:String(t)},e))}},6935:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>u,default:()=>f,frontMatter:()=>s,metadata:()=>i,toc:()=>d});var n=r(7462),a=(r(7294),r(3905)),o=r(4866),l=r(5162);const s={},u="Redux Store",i={unversionedId:"extensions/redux-store",id:"extensions/redux-store",title:"Redux Store",description:"The Redux Store is an implementation of state management that can be used to build React & React Native SSI clients using Credo.",source:"@site/guides/extensions/redux-store.md",sourceDirName:"extensions",slug:"/extensions/redux-store",permalink:"/guides/0.5/extensions/redux-store",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"React Hooks",permalink:"/guides/0.5/extensions/react-hooks"},next:{title:"Push Notifications",permalink:"/guides/0.5/extensions/push-notifications"}},c={},d=[{value:"Installation",id:"installation",level:2},{value:"npm",id:"npm",level:2},{value:"Yarn",id:"yarn",level:2}],p={toc:d},m="wrapper";function f(e){let{components:t,...r}=e;return(0,a.kt)(m,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"redux-store"},"Redux Store"),(0,a.kt)("p",null,"The Redux Store is an implementation of state management that can be used to build React & React Native SSI clients using Credo."),(0,a.kt)("p",null,"The Redux Store allows you to integrate state management for the most important parts of using Credo in a client application (mediation, connections, credentials and proofs), allowing you to sync UI state with the state of the agent as it interacts with other agents through the framework."),(0,a.kt)("admonition",{type:"note"},(0,a.kt)("p",{parentName:"admonition"},"This document is for version ",(0,a.kt)("strong",{parentName:"p"},(0,a.kt)("inlineCode",{parentName:"strong"},"0.4.x"))," of the ",(0,a.kt)("inlineCode",{parentName:"p"},"@credo-ts/redux-store")," package, that works with ",(0,a.kt)("inlineCode",{parentName:"p"},"@credo-ts/core")," version ",(0,a.kt)("strong",{parentName:"p"},(0,a.kt)("inlineCode",{parentName:"strong"},"0.4.x")),". Extension packages (such as Redux Store) are versioned separately from the core packages.")),(0,a.kt)("h2",{id:"installation"},"Installation"),(0,a.kt)("p",null,"To add the Redux Store package to your existing project simply run:"),(0,a.kt)(o.Z,{mdxType:"Tabs"},(0,a.kt)(l.Z,{label:"npm",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"npm i @credo-ts/redux-store\n"))),(0,a.kt)(l.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @credo-ts/redux-store\n")))))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4365],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var u=n.createContext({}),i=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=i(e.components);return n.createElement(u.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,u=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=i(r),m=a,f=d["".concat(u,".").concat(m)]||d[m]||p[m]||o;return r?n.createElement(f,l(l({ref:t},c),{},{components:r})):n.createElement(f,l({ref:t},c))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=m;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s[d]="string"==typeof e?e:a,l[1]=s;for(var i=2;i{r.d(t,{Z:()=>l});var n=r(7294),a=r(6010);const o={tabItem:"tabItem_Ymn6"};function l(e){let{children:t,hidden:r,className:l}=e;return n.createElement("div",{role:"tabpanel",className:(0,a.Z)(o.tabItem,l),hidden:r},t)}},4866:(e,t,r)=>{r.d(t,{Z:()=>x});var n=r(7462),a=r(7294),o=r(6010),l=r(2466),s=r(6550),u=r(1980),i=r(7392),c=r(12);function d(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:r,attributes:n,default:a}}=e;return{value:t,label:r,attributes:n,default:a}}))}function p(e){const{values:t,children:r}=e;return(0,a.useMemo)((()=>{const e=t??d(r);return function(e){const t=(0,i.l)(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,r])}function m(e){let{value:t,tabValues:r}=e;return r.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:r}=e;const n=(0,s.k6)(),o=function(e){let{queryString:t=!1,groupId:r}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!r)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 r??null}({queryString:t,groupId:r});return[(0,u._X)(o),(0,a.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(n.location.search);t.set(o,e),n.replace({...n.location,search:t.toString()})}),[o,n])]}function b(e){const{defaultValue:t,queryString:r=!1,groupId:n}=e,o=p(e),[l,s]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:r}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=r.find((e=>e.default))??r[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:o}))),[u,i]=f({queryString:r,groupId:n}),[d,b]=function(e){let{groupId:t}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,o]=(0,c.Nk)(r);return[n,(0,a.useCallback)((e=>{r&&o.set(e)}),[r,o])]}({groupId:n}),h=(()=>{const e=u??d;return m({value:e,tabValues:o})?e:null})();(0,a.useLayoutEffect)((()=>{h&&s(h)}),[h]);return{selectedValue:l,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);s(e),i(e),b(e)}),[i,b,o]),tabValues:o}}var h=r(2389);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function v(e){let{className:t,block:r,selectedValue:s,selectValue:u,tabValues:i}=e;const c=[],{blockElementScrollPositionUntilNextRender:d}=(0,l.o5)(),p=e=>{const t=e.currentTarget,r=c.indexOf(t),n=i[r].value;n!==s&&(d(t),u(n))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const r=c.indexOf(e.currentTarget)+1;t=c[r]??c[0];break}case"ArrowLeft":{const r=c.indexOf(e.currentTarget)-1;t=c[r]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":r},t)},i.map((e=>{let{value:t,label:r,attributes:l}=e;return a.createElement("li",(0,n.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:p},l,{className:(0,o.Z)("tabs__item",g.tabItem,l?.className,{"tabs__item--active":s===t})}),r??t)})))}function y(e){let{lazy:t,children:r,selectedValue:n}=e;if(r=Array.isArray(r)?r:[r],t){const e=r.find((e=>e.props.value===n));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},r.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==n}))))}function k(e){const t=b(e);return a.createElement("div",{className:(0,o.Z)("tabs-container",g.tabList)},a.createElement(v,(0,n.Z)({},e,t)),a.createElement(y,(0,n.Z)({},e,t)))}function x(e){const t=(0,h.Z)();return a.createElement(k,(0,n.Z)({key:String(t)},e))}},6935:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>u,default:()=>f,frontMatter:()=>s,metadata:()=>i,toc:()=>d});var n=r(7462),a=(r(7294),r(3905)),o=r(4866),l=r(5162);const s={},u="Redux Store",i={unversionedId:"extensions/redux-store",id:"extensions/redux-store",title:"Redux Store",description:"The Redux Store is an implementation of state management that can be used to build React & React Native SSI clients using Credo.",source:"@site/guides/extensions/redux-store.md",sourceDirName:"extensions",slug:"/extensions/redux-store",permalink:"/guides/extensions/redux-store",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"React Hooks",permalink:"/guides/extensions/react-hooks"},next:{title:"Push Notifications",permalink:"/guides/extensions/push-notifications"}},c={},d=[{value:"Installation",id:"installation",level:2},{value:"npm",id:"npm",level:2},{value:"Yarn",id:"yarn",level:2}],p={toc:d},m="wrapper";function f(e){let{components:t,...r}=e;return(0,a.kt)(m,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"redux-store"},"Redux Store"),(0,a.kt)("p",null,"The Redux Store is an implementation of state management that can be used to build React & React Native SSI clients using Credo."),(0,a.kt)("p",null,"The Redux Store allows you to integrate state management for the most important parts of using Credo in a client application (mediation, connections, credentials and proofs), allowing you to sync UI state with the state of the agent as it interacts with other agents through the framework."),(0,a.kt)("admonition",{type:"note"},(0,a.kt)("p",{parentName:"admonition"},"This document is for version ",(0,a.kt)("strong",{parentName:"p"},(0,a.kt)("inlineCode",{parentName:"strong"},"0.4.x"))," of the ",(0,a.kt)("inlineCode",{parentName:"p"},"@credo-ts/redux-store")," package, that works with ",(0,a.kt)("inlineCode",{parentName:"p"},"@credo-ts/core")," version ",(0,a.kt)("strong",{parentName:"p"},(0,a.kt)("inlineCode",{parentName:"strong"},"0.4.x")),". Extension packages (such as Redux Store) are versioned separately from the core packages.")),(0,a.kt)("h2",{id:"installation"},"Installation"),(0,a.kt)("p",null,"To add the Redux Store package to your existing project simply run:"),(0,a.kt)(o.Z,{mdxType:"Tabs"},(0,a.kt)(l.Z,{label:"npm",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"npm i @credo-ts/redux-store\n"))),(0,a.kt)(l.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @credo-ts/redux-store\n")))))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6e4808e6.8649b62c.js b/assets/js/b1d5f389.11b3c5e0.js similarity index 59% rename from assets/js/6e4808e6.8649b62c.js rename to assets/js/b1d5f389.11b3c5e0.js index 30110558..558f302a 100644 --- a/assets/js/6e4808e6.8649b62c.js +++ b/assets/js/b1d5f389.11b3c5e0.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[1271],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),u=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=u(e.components);return a.createElement(i.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),p=u(n),m=r,f=p["".concat(i,".").concat(m)]||p[m]||d[m]||o;return n?a.createElement(f,s(s({ref:t},c),{},{components:n})):a.createElement(f,s({ref:t},c))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,s=new Array(o);s[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l[p]="string"==typeof e?e:r,s[1]=l;for(var u=2;u{n.d(t,{Z:()=>s});var a=n(7294),r=n(6010);const o={tabItem:"tabItem_Ymn6"};function s(e){let{children:t,hidden:n,className:s}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(o.tabItem,s),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),r=n(7294),o=n(6010),s=n(2466),l=n(6550),i=n(1980),u=n(7392),c=n(12);function p(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function d(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,u.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:n}=e;const a=(0,l.k6)(),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,i._X)(o),(0,r.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(a.location.search);t.set(o,e),a.replace({...a.location,search:t.toString()})}),[o,a])]}function h(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,o=d(e),[s,l]=(0,r.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(!m({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}))),[i,u]=f({queryString:n,groupId:a}),[p,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,o]=(0,c.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:a}),g=(()=>{const e=i??p;return m({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{g&&l(g)}),[g]);return{selectedValue:s,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);l(e),u(e),h(e)}),[u,h,o]),tabValues:o}}var g=n(2389);const k={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){let{className:t,block:n,selectedValue:l,selectValue:i,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,s.o5)(),d=e=>{const t=e.currentTarget,n=c.indexOf(t),a=u[n].value;a!==l&&(p(t),i(a))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},u.map((e=>{let{value:t,label:n,attributes:s}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:l===t?0:-1,"aria-selected":l===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},s,{className:(0,o.Z)("tabs__item",k.tabItem,s?.className,{"tabs__item--active":l===t})}),n??t)})))}function b(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function v(e){const t=h(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",k.tabList)},r.createElement(y,(0,a.Z)({},e,t)),r.createElement(b,(0,a.Z)({},e,t)))}function w(e){const t=(0,g.Z)();return r.createElement(v,(0,a.Z)({key:String(t)},e))}},1752:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>f,frontMatter:()=>l,metadata:()=>u,toc:()=>p});var a=n(7462),r=(n(7294),n(3905)),o=n(4866),s=n(5162);const l={},i="React Hooks",u={unversionedId:"extensions/react-hooks",id:"extensions/react-hooks",title:"React Hooks",description:"The React Hooks package exposes useful React hooks that allow you to easily interact with Credo from a React client application.",source:"@site/guides/extensions/react-hooks.md",sourceDirName:"extensions",slug:"/extensions/react-hooks",permalink:"/guides/0.5/extensions/react-hooks",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"REST API",permalink:"/guides/0.5/extensions/rest"},next:{title:"Redux Store",permalink:"/guides/0.5/extensions/redux-store"}},c={},p=[{value:"Installation",id:"installation",level:2},{value:"npm",id:"npm",level:2},{value:"Yarn",id:"yarn",level:2},{value:"Usage",id:"usage",level:2}],d={toc:p},m="wrapper";function f(e){let{components:t,...n}=e;return(0,r.kt)(m,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"react-hooks"},"React Hooks"),(0,r.kt)("p",null,"The React Hooks package exposes useful React hooks that allow you to easily interact with Credo from a React client application."),(0,r.kt)("p",null,"These hooks provide a simple way to query agent data in a client application, allowing you to focus on the user interface."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"This document is for version ",(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"0.5.x"))," of the ",(0,r.kt)("inlineCode",{parentName:"p"},"@credo-ts/react-hooks")," package, that works with ",(0,r.kt)("inlineCode",{parentName:"p"},"@credo-ts/core")," version ",(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"0.4.x")),". Extension packages (such as React Hooks) are versioned separately from the core packages.")),(0,r.kt)("h2",{id:"installation"},"Installation"),(0,r.kt)("p",null,"To add the React Hooks package to your existing project simply run:"),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{label:"npm",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"npm i @credo-ts/react-hooks@^0.5\n"))),(0,r.kt)(s.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @credo-ts/react-hooks@^0.5\n")))),(0,r.kt)("h2",{id:"usage"},"Usage"),(0,r.kt)("p",null,"This package exposes useful React hooks that allow you to easily interact with Credo."),(0,r.kt)("p",null,"Everything exported from Hooks:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import AgentProvider, {\n useAgent,\n useConnections,\n useConnectionById,\n useCredentials,\n useCredentialById,\n useCredentialByState,\n useProofs,\n useProofById,\n useProofByState,\n} from '@credo-ts/react-hooks'\n")),(0,r.kt)("p",null,"First step is to wrap your entire app in our ",(0,r.kt)("inlineCode",{parentName:"p"},""),". The provider takes an initialized agent. The base of your app should look something like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-tsx"},"import AgentProvider from '@credo-ts/react-hooks'\n\nconst App = () => {\n const [agent, setAgent] = useState(undefined)\n\n const initializeAgent = async () => {\n const appAgent = new Agent({\n /* agent options */\n })\n await appAgent.initialize()\n setAgent(appAgent)\n }\n\n useEffect(() => {\n initializeAgent()\n }, [])\n\n if (!agent) return \n\n return /* Your app here */\n}\n")),(0,r.kt)("p",null,"And that's it! Your app should be set up to receive all the necessary data your app will need! Now let's see how we actually get that data to our components."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"useAgent")," hook returns ",(0,r.kt)("inlineCode",{parentName:"p"},"{ agent, loading }")," so anytime you need access to any of the methods tied to the agent, you can ",(0,r.kt)("inlineCode",{parentName:"p"},"useAgent()")," anywhere."),(0,r.kt)("p",null,"The following is an example of how you could use the ",(0,r.kt)("inlineCode",{parentName:"p"},"useConnections")," hook to render a full list of all a user's connections."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { useConnections } from '@credo-ts/react-hooks'\n\nconst MyConnectionsComponent = () => {\n // all base hooks return an array of objects and a loading boolean\n const { connections, loading } = useConnections()\n\n return } />\n}\n")),(0,r.kt)("p",null,"The three base hooks: ",(0,r.kt)("inlineCode",{parentName:"p"},"useConnections"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"useCredentials"),", and ",(0,r.kt)("inlineCode",{parentName:"p"},"useProofs")," work just like the above! Just call the hook, destructure the data, and pass it through!"),(0,r.kt)("p",null,"Each base hook has a ",(0,r.kt)("inlineCode",{parentName:"p"},"ById")," version that returns a singular record. For example if I wanted only a specific connectionRecord, I'd do this."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"const connection = useConnectionById(id)\n")),(0,r.kt)("p",null,"More commonly, you'll want to get a filtered list of records based off of their state. Well, Hooray! We have a ",(0,r.kt)("inlineCode",{parentName:"p"},"ByState")," version as well. For example, you can do this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"const credentials = useCredentialByState(CredentialState.OfferReceived)\n")))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[9843],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),u=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=u(e.components);return a.createElement(i.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),p=u(n),m=r,f=p["".concat(i,".").concat(m)]||p[m]||d[m]||o;return n?a.createElement(f,s(s({ref:t},c),{},{components:n})):a.createElement(f,s({ref:t},c))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,s=new Array(o);s[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l[p]="string"==typeof e?e:r,s[1]=l;for(var u=2;u{n.d(t,{Z:()=>s});var a=n(7294),r=n(6010);const o={tabItem:"tabItem_Ymn6"};function s(e){let{children:t,hidden:n,className:s}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(o.tabItem,s),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),r=n(7294),o=n(6010),s=n(2466),l=n(6550),i=n(1980),u=n(7392),c=n(12);function p(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function d(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,u.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:n}=e;const a=(0,l.k6)(),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,i._X)(o),(0,r.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(a.location.search);t.set(o,e),a.replace({...a.location,search:t.toString()})}),[o,a])]}function h(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,o=d(e),[s,l]=(0,r.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(!m({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}))),[i,u]=f({queryString:n,groupId:a}),[p,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,o]=(0,c.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:a}),k=(()=>{const e=i??p;return m({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{k&&l(k)}),[k]);return{selectedValue:s,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);l(e),u(e),h(e)}),[u,h,o]),tabValues:o}}var k=n(2389);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){let{className:t,block:n,selectedValue:l,selectValue:i,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,s.o5)(),d=e=>{const t=e.currentTarget,n=c.indexOf(t),a=u[n].value;a!==l&&(p(t),i(a))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},u.map((e=>{let{value:t,label:n,attributes:s}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:l===t?0:-1,"aria-selected":l===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},s,{className:(0,o.Z)("tabs__item",g.tabItem,s?.className,{"tabs__item--active":l===t})}),n??t)})))}function b(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function v(e){const t=h(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",g.tabList)},r.createElement(y,(0,a.Z)({},e,t)),r.createElement(b,(0,a.Z)({},e,t)))}function w(e){const t=(0,k.Z)();return r.createElement(v,(0,a.Z)({key:String(t)},e))}},6457:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>f,frontMatter:()=>l,metadata:()=>u,toc:()=>p});var a=n(7462),r=(n(7294),n(3905)),o=n(4866),s=n(5162);const l={},i="React Hooks",u={unversionedId:"extensions/react-hooks",id:"version-0.4/extensions/react-hooks",title:"React Hooks",description:"The React Hooks package exposes useful React hooks that allow you to easily interact with AFJ from a React client application.",source:"@site/versioned_docs/version-0.4/extensions/react-hooks.md",sourceDirName:"extensions",slug:"/extensions/react-hooks",permalink:"/guides/0.4/extensions/react-hooks",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"REST API",permalink:"/guides/0.4/extensions/rest"},next:{title:"Redux Store",permalink:"/guides/0.4/extensions/redux-store"}},c={},p=[{value:"Installation",id:"installation",level:2},{value:"npm",id:"npm",level:2},{value:"Yarn",id:"yarn",level:2},{value:"Usage",id:"usage",level:2}],d={toc:p},m="wrapper";function f(e){let{components:t,...n}=e;return(0,r.kt)(m,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"react-hooks"},"React Hooks"),(0,r.kt)("p",null,"The React Hooks package exposes useful React hooks that allow you to easily interact with AFJ from a React client application."),(0,r.kt)("p",null,"These hooks provide a simple way to query agent data in a client application, allowing you to focus on the user interface."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"This document is for version ",(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"0.5.x"))," of the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/react-hooks")," package, that works with ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/core")," version ",(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"0.4.x")),". Extension packages (such as React Hooks) are versioned separately from the core packages.")),(0,r.kt)("h2",{id:"installation"},"Installation"),(0,r.kt)("p",null,"To add the React Hooks package to your existing project simply run:"),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{label:"npm",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"npm i @aries-framework/react-hooks@^0.5\n"))),(0,r.kt)(s.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/react-hooks@^0.5\n")))),(0,r.kt)("h2",{id:"usage"},"Usage"),(0,r.kt)("p",null,"This package exposes useful React hooks that allow you to easily interact with AFJ."),(0,r.kt)("p",null,"Everything exported from Hooks:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import AgentProvider, {\n useAgent,\n useConnections,\n useConnectionById,\n useCredentials,\n useCredentialById,\n useCredentialByState,\n useProofs,\n useProofById,\n useProofByState,\n} from '@aries-framework/react-hooks'\n")),(0,r.kt)("p",null,"First step is to wrap your entire app in our ",(0,r.kt)("inlineCode",{parentName:"p"},""),". The provider takes an initialized agent. The base of your app should look something like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-tsx"},"import AgentProvider from '@aries-framework/react-hooks'\n\nconst App = () => {\n const [agent, setAgent] = useState(undefined)\n\n const initializeAgent = async () => {\n const appAgent = new Agent({\n /* agent options */\n })\n await appAgent.initialize()\n setAgent(appAgent)\n }\n\n useEffect(() => {\n initializeAgent()\n }, [])\n\n if (!agent) return \n\n return /* Your app here */\n}\n")),(0,r.kt)("p",null,"And that's it! Your app should be set up to receive all the necessary data your app will need! Now let's see how we actually get that data to our components."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"useAgent")," hook returns ",(0,r.kt)("inlineCode",{parentName:"p"},"{ agent, loading }")," so anytime you need access to any of the methods tied to the agent, you can ",(0,r.kt)("inlineCode",{parentName:"p"},"useAgent()")," anywhere."),(0,r.kt)("p",null,"The following is an example of how you could use the ",(0,r.kt)("inlineCode",{parentName:"p"},"useConnections")," hook to render a full list of all a user's connections."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { useConnections } from '@aries-framework/react-hooks'\n\nconst MyConnectionsComponent = () => {\n // all base hooks return an array of objects and a loading boolean\n const { connections, loading } = useConnections()\n\n return } />\n}\n")),(0,r.kt)("p",null,"The three base hooks: ",(0,r.kt)("inlineCode",{parentName:"p"},"useConnections"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"useCredentials"),", and ",(0,r.kt)("inlineCode",{parentName:"p"},"useProofs")," work just like the above! Just call the hook, destructure the data, and pass it through!"),(0,r.kt)("p",null,"Each base hook has a ",(0,r.kt)("inlineCode",{parentName:"p"},"ById")," version that returns a singular record. For example if I wanted only a specific connectionRecord, I'd do this."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"const connection = useConnectionById(id)\n")),(0,r.kt)("p",null,"More commonly, you'll want to get a filtered list of records based off of their state. Well, Hooray! We have a ",(0,r.kt)("inlineCode",{parentName:"p"},"ByState")," version as well. For example, you can do this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"const credentials = useCredentialByState(CredentialState.OfferReceived)\n")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/bcace162.51139a8f.js b/assets/js/bcace162.8ae0a365.js similarity index 69% rename from assets/js/bcace162.51139a8f.js rename to assets/js/bcace162.8ae0a365.js index 5b92591d..e6ffa034 100644 --- a/assets/js/bcace162.51139a8f.js +++ b/assets/js/bcace162.8ae0a365.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[752],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var u=a.createContext({}),l=function(e){var t=a.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=l(e.components);return a.createElement(u.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},f=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,u=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=l(n),f=r,m=p["".concat(u,".").concat(f)]||p[f]||d[f]||o;return n?a.createElement(m,i(i({ref:t},c),{},{components:n})):a.createElement(m,i({ref:t},c))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=f;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var l=2;l{n.d(t,{Z:()=>i});var a=n(7294),r=n(6010);const o={tabItem:"tabItem_Ymn6"};function i(e){let{children:t,hidden:n,className:i}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(o.tabItem,i),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),r=n(7294),o=n(6010),i=n(2466),s=n(6550),u=n(1980),l=n(7392),c=n(12);function p(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function d(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,l.l)(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 f(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function m(e){let{queryString:t=!1,groupId:n}=e;const a=(0,s.k6)(),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,u._X)(o),(0,r.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(a.location.search);t.set(o,e),a.replace({...a.location,search:t.toString()})}),[o,a])]}function h(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,o=d(e),[i,s]=(0,r.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(!f({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}))),[u,l]=m({queryString:n,groupId:a}),[p,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,o]=(0,c.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:a}),v=(()=>{const e=u??p;return f({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{v&&s(v)}),[v]);return{selectedValue:i,selectValue:(0,r.useCallback)((e=>{if(!f({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);s(e),l(e),h(e)}),[l,h,o]),tabValues:o}}var v=n(2389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function g(e){let{className:t,block:n,selectedValue:s,selectValue:u,tabValues:l}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,i.o5)(),d=e=>{const t=e.currentTarget,n=c.indexOf(t),a=l[n].value;a!==s&&(p(t),u(a))},f=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},l.map((e=>{let{value:t,label:n,attributes:i}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>c.push(e),onKeyDown:f,onClick:d},i,{className:(0,o.Z)("tabs__item",b.tabItem,i?.className,{"tabs__item--active":s===t})}),n??t)})))}function y(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function k(e){const t=h(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",b.tabList)},r.createElement(g,(0,a.Z)({},e,t)),r.createElement(y,(0,a.Z)({},e,t)))}function w(e){const t=(0,v.Z)();return r.createElement(k,(0,a.Z)({key:String(t)},e))}},8150:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>u,default:()=>m,frontMatter:()=>s,metadata:()=>l,toc:()=>p});var a=n(7462),r=(n(7294),n(3905)),o=n(4866),i=n(5162);const s={},u="Push Notifications",l={unversionedId:"extensions/push-notifications",id:"version-0.4/extensions/push-notifications",title:"Push Notifications",description:"The Push Notifications plugin package provides a way for you to register your APNs and Firebase push notification token at an agent, allowing you to use push notifications directly from AFJ.",source:"@site/versioned_docs/version-0.4/extensions/push-notifications.md",sourceDirName:"extensions",slug:"/extensions/push-notifications",permalink:"/guides/extensions/push-notifications",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Redux Store",permalink:"/guides/extensions/redux-store"}},c={},p=[{value:"Installation",id:"installation",level:2},{value:"npm",id:"npm",level:2},{value:"Yarn",id:"yarn",level:2},{value:"Usage",id:"usage",level:2}],d={toc:p},f="wrapper";function m(e){let{components:t,...n}=e;return(0,r.kt)(f,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"push-notifications"},"Push Notifications"),(0,r.kt)("p",null,"The Push Notifications plugin package provides a way for you to register your APNs and Firebase push notification token at an agent, allowing you to use push notifications directly from AFJ."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"This document is for version ",(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"0.5.x"))," of the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/push-notifications")," package, that works with ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/core")," version ",(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"0.4.x")),". Extension packages (such as Push Notifications) are versioned separately from the core packages.")),(0,r.kt)("h2",{id:"installation"},"Installation"),(0,r.kt)("p",null,"To add the Push Notifications plugin package to your existing project simply run:"),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(i.Z,{label:"npm",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"npm i @aries-framework/push-notifications\n"))),(0,r.kt)(i.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/push-notifications\n"))),(0,r.kt)(i.Z,{label:"Usage",value:"tab3",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { PushNotificationsApnsModule, PushNotificationsFcmModule } from '@aries-framework/push-notifications'\nimport { } from '@aries-framework/core'\n\nconst agent = new Agent({\n /** agent config... */,\n // Register the modules\n modules: {\n pushNotificationsApns: new PushNotificationsApnsModule(),\n pushNotificationsFcm: new PushNotificationsFcmModule(),\n },\n }\n})\n\nawait agent.initialize()\n\n/* -- iOS -- */\n\n// To send apns device info to another agent you have to acquire the device token and send it.\nawait agent.modules.pushNotificationsApns.sendDeviceInfo(\n 'a-valid-connection-id'\n { deviceToken: '123' },\n)\n\n// To get the device info and the used service back from the other agent\nawait agent.modules.pushNotificationsApns.getDeviceInfo('a-valid-connection')\n\n/* -- fcm / Android -- */\n\n// To send fcm, primarily Android, device info to another agent you have to acquire the device token and send it.\nawait agent.modules.pushNotificationsFcm.sendDeviceInfo(\n 'a-valid-connection-id'\n { deviceToken: '123' },\n)\n\n// To get the device info and the used service back from the other agent\nawait agent.modules.pushNotificationsFcm.getDeviceInfo('a-valid-connection')\n\n")))))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[752],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var u=a.createContext({}),l=function(e){var t=a.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=l(e.components);return a.createElement(u.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},f=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,u=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=l(n),f=r,m=p["".concat(u,".").concat(f)]||p[f]||d[f]||o;return n?a.createElement(m,i(i({ref:t},c),{},{components:n})):a.createElement(m,i({ref:t},c))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=f;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var l=2;l{n.d(t,{Z:()=>i});var a=n(7294),r=n(6010);const o={tabItem:"tabItem_Ymn6"};function i(e){let{children:t,hidden:n,className:i}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(o.tabItem,i),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),r=n(7294),o=n(6010),i=n(2466),s=n(6550),u=n(1980),l=n(7392),c=n(12);function p(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function d(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,l.l)(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 f(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function m(e){let{queryString:t=!1,groupId:n}=e;const a=(0,s.k6)(),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,u._X)(o),(0,r.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(a.location.search);t.set(o,e),a.replace({...a.location,search:t.toString()})}),[o,a])]}function h(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,o=d(e),[i,s]=(0,r.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(!f({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}))),[u,l]=m({queryString:n,groupId:a}),[p,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,o]=(0,c.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:a}),v=(()=>{const e=u??p;return f({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{v&&s(v)}),[v]);return{selectedValue:i,selectValue:(0,r.useCallback)((e=>{if(!f({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);s(e),l(e),h(e)}),[l,h,o]),tabValues:o}}var v=n(2389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function g(e){let{className:t,block:n,selectedValue:s,selectValue:u,tabValues:l}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,i.o5)(),d=e=>{const t=e.currentTarget,n=c.indexOf(t),a=l[n].value;a!==s&&(p(t),u(a))},f=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},l.map((e=>{let{value:t,label:n,attributes:i}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>c.push(e),onKeyDown:f,onClick:d},i,{className:(0,o.Z)("tabs__item",b.tabItem,i?.className,{"tabs__item--active":s===t})}),n??t)})))}function y(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function k(e){const t=h(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",b.tabList)},r.createElement(g,(0,a.Z)({},e,t)),r.createElement(y,(0,a.Z)({},e,t)))}function w(e){const t=(0,v.Z)();return r.createElement(k,(0,a.Z)({key:String(t)},e))}},8150:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>u,default:()=>m,frontMatter:()=>s,metadata:()=>l,toc:()=>p});var a=n(7462),r=(n(7294),n(3905)),o=n(4866),i=n(5162);const s={},u="Push Notifications",l={unversionedId:"extensions/push-notifications",id:"version-0.4/extensions/push-notifications",title:"Push Notifications",description:"The Push Notifications plugin package provides a way for you to register your APNs and Firebase push notification token at an agent, allowing you to use push notifications directly from AFJ.",source:"@site/versioned_docs/version-0.4/extensions/push-notifications.md",sourceDirName:"extensions",slug:"/extensions/push-notifications",permalink:"/guides/0.4/extensions/push-notifications",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Redux Store",permalink:"/guides/0.4/extensions/redux-store"}},c={},p=[{value:"Installation",id:"installation",level:2},{value:"npm",id:"npm",level:2},{value:"Yarn",id:"yarn",level:2},{value:"Usage",id:"usage",level:2}],d={toc:p},f="wrapper";function m(e){let{components:t,...n}=e;return(0,r.kt)(f,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"push-notifications"},"Push Notifications"),(0,r.kt)("p",null,"The Push Notifications plugin package provides a way for you to register your APNs and Firebase push notification token at an agent, allowing you to use push notifications directly from AFJ."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"This document is for version ",(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"0.5.x"))," of the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/push-notifications")," package, that works with ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/core")," version ",(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"0.4.x")),". Extension packages (such as Push Notifications) are versioned separately from the core packages.")),(0,r.kt)("h2",{id:"installation"},"Installation"),(0,r.kt)("p",null,"To add the Push Notifications plugin package to your existing project simply run:"),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(i.Z,{label:"npm",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"npm i @aries-framework/push-notifications\n"))),(0,r.kt)(i.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/push-notifications\n"))),(0,r.kt)(i.Z,{label:"Usage",value:"tab3",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { PushNotificationsApnsModule, PushNotificationsFcmModule } from '@aries-framework/push-notifications'\nimport { } from '@aries-framework/core'\n\nconst agent = new Agent({\n /** agent config... */,\n // Register the modules\n modules: {\n pushNotificationsApns: new PushNotificationsApnsModule(),\n pushNotificationsFcm: new PushNotificationsFcmModule(),\n },\n }\n})\n\nawait agent.initialize()\n\n/* -- iOS -- */\n\n// To send apns device info to another agent you have to acquire the device token and send it.\nawait agent.modules.pushNotificationsApns.sendDeviceInfo(\n 'a-valid-connection-id'\n { deviceToken: '123' },\n)\n\n// To get the device info and the used service back from the other agent\nawait agent.modules.pushNotificationsApns.getDeviceInfo('a-valid-connection')\n\n/* -- fcm / Android -- */\n\n// To send fcm, primarily Android, device info to another agent you have to acquire the device token and send it.\nawait agent.modules.pushNotificationsFcm.sendDeviceInfo(\n 'a-valid-connection-id'\n { deviceToken: '123' },\n)\n\n// To get the device info and the used service back from the other agent\nawait agent.modules.pushNotificationsFcm.getDeviceInfo('a-valid-connection')\n\n")))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/bd5be9ae.2f888633.js b/assets/js/bd5be9ae.2f888633.js deleted file mode 100644 index 379865f3..00000000 --- a/assets/js/bd5be9ae.2f888633.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[1993],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),u=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=u(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=u(n),m=r,h=d["".concat(l,".").concat(m)]||d[m]||p[m]||i;return n?a.createElement(h,o(o({ref:t},c),{},{components:n})):a.createElement(h,o({ref:t},c))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:r,o[1]=s;for(var u=2;u{n.d(t,{Z:()=>o});var a=n(7294),r=n(6010);const i={tabItem:"tabItem_Ymn6"};function o(e){let{children:t,hidden:n,className:o}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(i.tabItem,o),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>N});var a=n(7462),r=n(7294),i=n(6010),o=n(2466),s=n(6550),l=n(1980),u=n(7392),c=n(12);function d(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function p(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??d(n);return function(e){const t=(0,u.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const a=(0,s.k6)(),i=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,l._X)(i),(0,r.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(a.location.search);t.set(i,e),a.replace({...a.location,search:t.toString()})}),[i,a])]}function f(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,i=p(e),[o,s]=(0,r.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(!m({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:i}))),[l,u]=h({queryString:n,groupId:a}),[d,f]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,i]=(0,c.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:a}),g=(()=>{const e=l??d;return m({value:e,tabValues:i})?e:null})();(0,r.useLayoutEffect)((()=>{g&&s(g)}),[g]);return{selectedValue:o,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);s(e),u(e),f(e)}),[u,f,i]),tabValues:i}}var g=n(2389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:n,selectedValue:s,selectValue:l,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:d}=(0,o.o5)(),p=e=>{const t=e.currentTarget,n=c.indexOf(t),a=u[n].value;a!==s&&(d(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},u.map((e=>{let{value:t,label:n,attributes:o}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:p},o,{className:(0,i.Z)("tabs__item",b.tabItem,o?.className,{"tabs__item--active":s===t})}),n??t)})))}function v(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function y(e){const t=f(e);return r.createElement("div",{className:(0,i.Z)("tabs-container",b.tabList)},r.createElement(k,(0,a.Z)({},e,t)),r.createElement(v,(0,a.Z)({},e,t)))}function N(e){const t=(0,g.Z)();return r.createElement(y,(0,a.Z)({key:String(t)},e))}},2347:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>u,toc:()=>d});var a=n(7462),r=(n(7294),n(3905)),i=n(4866),o=n(5162);const s={},l="Issue a credential",u={unversionedId:"tutorials/issue-a-credential",id:"tutorials/issue-a-credential",title:"Issue a credential",description:"In this tutorial we will issue a credential from the Issuer to a Holder. We will start with setting up both their agents with the minimal configuration required to follow this tutorial. It is assumed that there is a connection between the Issuer and the Holder and the Issuer also has a registered schema and credential definition. After initializing the Issuer will send a credential to the holder, and will then accept this credential and automatically store it in their wallet.",source:"@site/guides/tutorials/issue-a-credential.md",sourceDirName:"tutorials",slug:"/tutorials/issue-a-credential",permalink:"/guides/0.5/tutorials/issue-a-credential",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Registering a schema and credential definition on an AnonCreds Registry",permalink:"/guides/0.5/tutorials/registering-schema-and-credential-definition"},next:{title:"Mediation",permalink:"/guides/0.5/tutorials/mediation"}},c={},d=[{value:"1. Setting up the agents",id:"1-setting-up-the-agents",level:3},{value:"Issuer",id:"issuer",level:4},{value:"Holder",id:"holder",level:4},{value:"3. Listening for incoming credentials",id:"3-listening-for-incoming-credentials",level:3},{value:"4. Issuing a credential",id:"4-issuing-a-credential",level:3},{value:"Useful resources",id:"useful-resources",level:3}],p={toc:d},m="wrapper";function h(e){let{components:t,...n}=e;return(0,r.kt)(m,(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"issue-a-credential"},"Issue a credential"),(0,r.kt)("p",null,"In this tutorial we will issue a credential from the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," to a ",(0,r.kt)("em",{parentName:"p"},"Holder"),". We will start with setting up both their agents with the minimal configuration required to follow this tutorial. It is assumed that there is a connection between the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," and the ",(0,r.kt)("em",{parentName:"p"},"Holder")," and the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," also has a registered schema and credential definition. After initializing the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," will send a credential to the ",(0,r.kt)("em",{parentName:"p"},"holder"),", and will then accept this credential and automatically store it in their wallet."),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Using ",(0,r.kt)("a",{parentName:"em",href:"https://anoncreds-wg.github.io/anoncreds-spec/"},"AnonCreds")," and the ",(0,r.kt)("a",{parentName:"em",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0453-issue-credential-v2/README.md"},"Issue Credential V2 Protocol")," or the ",(0,r.kt)("a",{parentName:"em",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0036-issue-credential/README.md"},"Issue Credential V1 Protocol"),".")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This section assumes that"),(0,r.kt)("ol",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ol"},"You have ",(0,r.kt)("a",{parentName:"li",href:"../getting-started"},"set-up your develoment environment"),"."),(0,r.kt)("li",{parentName:"ol"},"You have basic knowledge of the required fields in the ",(0,r.kt)("a",{parentName:"li",href:"./agent-config"},"Agent Config")),(0,r.kt)("li",{parentName:"ol"},"You have completed the ",(0,r.kt)("a",{parentName:"li",href:"./create-a-connection"},"Create a Connection tutorial")),(0,r.kt)("li",{parentName:"ol"},"You have a registered schema and credential definition. This can be done by following the ",(0,r.kt)("a",{parentName:"li",href:"./registering-schema-and-credential-definition"},"Registering on a AnonCreds Registry")))),(0,r.kt)("h3",{id:"1-setting-up-the-agents"},"1. Setting up the agents"),(0,r.kt)("p",null,"First for both agents we must setup and initialize an agent to work with. Depending on your target, ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/react-native"},"React Native")," or ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/react-native"},"Node.js"),", it might vary."),(0,r.kt)("p",null,"In this tutorial the ",(0,r.kt)("em",{parentName:"p"},"Holder")," will be in a ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/nodejs"},"Node.js environment")," and the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," also in a ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/nodejs"},"Node.js environment"),"."),(0,r.kt)("h4",{id:"issuer"},"Issuer"),(0,r.kt)("p",null,"For the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," the setup is commonly not the same as the ",(0,r.kt)("em",{parentName:"p"},"Holder"),". In the example they both live in a server environment, meaning they do not need a mediator. More commonly, the ",(0,r.kt)("em",{parentName:"p"},"Holder")," is in a mobile environment where a mediator is required for receiving DIDComm messages."),(0,r.kt)("p",null,"It is also very important for the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," to have a public DID, for the binding with a credential definition, amongst other things. For this demo we will use ",(0,r.kt)("a",{parentName:"p",href:"http://test.bcovrin.vonx.io"},"BCovrin Test"),". If you want to follow this tutorial, you have to register a public DID ",(0,r.kt)("a",{parentName:"p",href:"http://test.bcovrin.vonx.io"},"here")," via the Wallet seed field (this must be the same as the seed inside the config under the key ",(0,r.kt)("a",{parentName:"p",href:"./agent-config#publicdidseed"},(0,r.kt)("inlineCode",{parentName:"a"},"publicDidSeed")),")."),(0,r.kt)("p",null,"In order to reach the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," we have to add a list of ",(0,r.kt)("a",{parentName:"p",href:"./agent-config#endpoints"},(0,r.kt)("inlineCode",{parentName:"a"},"endpoints"))," of the agent that exposes the ",(0,r.kt)("inlineCode",{parentName:"p"},"inboundTransport")," to the public. In the example below we add an ",(0,r.kt)("inlineCode",{parentName:"p"},"inboundTransport")," and use port ",(0,r.kt)("inlineCode",{parentName:"p"},"3002"),". For development purposes it is recommended to use a tunneling service for this, like ",(0,r.kt)("a",{parentName:"p",href:"https://ngrok.com"},"Ngrok"),". Ngrok will allow you to reach your locally exposed endpoint from the public. If a tunneling service is used, make sure to use the ",(0,r.kt)("inlineCode",{parentName:"p"},"HTTPS")," variant as mobile environments, by default, do not accept ",(0,r.kt)("inlineCode",{parentName:"p"},"HTTP")," anymore."),(0,r.kt)("p",null,"To install ",(0,r.kt)("a",{parentName:"p",href:"https://ngrok.com"},"Ngrok")," and expose the port to the public the following commands can be used:"),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"yarn",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"yarn global add ngrok\n\nngrok http \n"))),(0,r.kt)(o.Z,{label:"npm",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"npm install --global ngrok\n\nngrok http \n")))),(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers issue-a-credential.ts section-1",showLineNumbers:!0,"issue-a-credential.ts":!0,"section-1":!0},""))),(0,r.kt)("h4",{id:"holder"},"Holder"),(0,r.kt)("p",null,"For the ",(0,r.kt)("em",{parentName:"p"},"Holder")," we need to setup a basic agent with a wallet, mediator, outbound transport and a ledger."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"If you want to follow this tutorial in a mobile environment:"),(0,r.kt)("ol",{parentName:"blockquote"},(0,r.kt)("li",{parentName:"ol"},"Use the ",(0,r.kt)("inlineCode",{parentName:"li"},"agentDependencies")," from ",(0,r.kt)("inlineCode",{parentName:"li"},"@credo-ts/react-native")),(0,r.kt)("li",{parentName:"ol"},"It is very important to note that mobile agents do not support HTTP by default. It is recommended to do everything over HTTPS, but for development HTTP can be enabled for ",(0,r.kt)("a",{parentName:"li",href:"https://stackoverflow.com/questions/30731785/how-do-i-load-an-http-url-with-app-transport-security-enabled-in-ios-9"},"iOS")," and ",(0,r.kt)("a",{parentName:"li",href:"https://stackoverflow.com/questions/51902629/how-to-allow-all-network-connection-types-http-and-https-in-android-9-pie"},"Android"),"."))),(0,r.kt)("admonition",{type:"holder"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers issue-a-credential.ts section-2",showLineNumbers:!0,"issue-a-credential.ts":!0,"section-2":!0},""))),(0,r.kt)("h3",{id:"3-listening-for-incoming-credentials"},"3. Listening for incoming credentials"),(0,r.kt)("p",null,"When we want to accept a credential, we have to listen to incoming credentials and handle accordingly. In this example we do not have any user interaction, but is likely that your application would have a user-interface which would display the credential. When receiving a credential offer you can get the values from ",(0,r.kt)("inlineCode",{parentName:"p"},"credentialExchangeRecord.credentialAttributes"),"."),(0,r.kt)("admonition",{type:"holder"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers issue-a-credential.ts section-3",showLineNumbers:!0,"issue-a-credential.ts":!0,"section-3":!0},""))),(0,r.kt)("h3",{id:"4-issuing-a-credential"},"4. Issuing a credential"),(0,r.kt)("p",null,"Now that everything is setup on both sides, the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," can now offer a credential to the ",(0,r.kt)("em",{parentName:"p"},"Holder"),"."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"In this example we do not instantiate a connection and assume that there is one. Please refer to this guide ",(0,r.kt)("a",{parentName:"p",href:"./create-a-connection"},"Create a connection")," to get a connection and connectionId.")),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Indy",value:"tab1",mdxType:"TabItem"},(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers issue-a-credential.ts section-4",showLineNumbers:!0,"issue-a-credential.ts":!0,"section-4":!0},"")))),(0,r.kt)(o.Z,{label:"AnonCreds",value:"tab2",mdxType:"TabItem"},(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers issue-a-credential.ts section-5",showLineNumbers:!0,"issue-a-credential.ts":!0,"section-5":!0},""))))),(0,r.kt)("h3",{id:"useful-resources"},"Useful resources"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://anoncreds-wg.github.io/anoncreds-spec/"},"AnonCreds")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0036-issue-credential/README.md"},"Issue Credential V1 Protocol")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0453-issue-credential-v2/README.md"},"Issue Credential V2 Protocol"))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/bd5be9ae.ab302442.js b/assets/js/bd5be9ae.ab302442.js new file mode 100644 index 00000000..98efd083 --- /dev/null +++ b/assets/js/bd5be9ae.ab302442.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[1993],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),u=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=u(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=u(n),m=r,h=d["".concat(l,".").concat(m)]||d[m]||p[m]||i;return n?a.createElement(h,o(o({ref:t},c),{},{components:n})):a.createElement(h,o({ref:t},c))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:r,o[1]=s;for(var u=2;u{n.d(t,{Z:()=>o});var a=n(7294),r=n(6010);const i={tabItem:"tabItem_Ymn6"};function o(e){let{children:t,hidden:n,className:o}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(i.tabItem,o),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>N});var a=n(7462),r=n(7294),i=n(6010),o=n(2466),s=n(6550),l=n(1980),u=n(7392),c=n(12);function d(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function p(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??d(n);return function(e){const t=(0,u.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const a=(0,s.k6)(),i=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,l._X)(i),(0,r.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(a.location.search);t.set(i,e),a.replace({...a.location,search:t.toString()})}),[i,a])]}function f(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,i=p(e),[o,s]=(0,r.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(!m({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:i}))),[l,u]=h({queryString:n,groupId:a}),[d,f]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,i]=(0,c.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:a}),g=(()=>{const e=l??d;return m({value:e,tabValues:i})?e:null})();(0,r.useLayoutEffect)((()=>{g&&s(g)}),[g]);return{selectedValue:o,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);s(e),u(e),f(e)}),[u,f,i]),tabValues:i}}var g=n(2389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:n,selectedValue:s,selectValue:l,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:d}=(0,o.o5)(),p=e=>{const t=e.currentTarget,n=c.indexOf(t),a=u[n].value;a!==s&&(d(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},u.map((e=>{let{value:t,label:n,attributes:o}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:p},o,{className:(0,i.Z)("tabs__item",b.tabItem,o?.className,{"tabs__item--active":s===t})}),n??t)})))}function v(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function y(e){const t=f(e);return r.createElement("div",{className:(0,i.Z)("tabs-container",b.tabList)},r.createElement(k,(0,a.Z)({},e,t)),r.createElement(v,(0,a.Z)({},e,t)))}function N(e){const t=(0,g.Z)();return r.createElement(y,(0,a.Z)({key:String(t)},e))}},2347:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>u,toc:()=>d});var a=n(7462),r=(n(7294),n(3905)),i=n(4866),o=n(5162);const s={},l="Issue a credential",u={unversionedId:"tutorials/issue-a-credential",id:"tutorials/issue-a-credential",title:"Issue a credential",description:"In this tutorial we will issue a credential from the Issuer to a Holder. We will start with setting up both their agents with the minimal configuration required to follow this tutorial. It is assumed that there is a connection between the Issuer and the Holder and the Issuer also has a registered schema and credential definition. After initializing the Issuer will send a credential to the holder, and will then accept this credential and automatically store it in their wallet.",source:"@site/guides/tutorials/issue-a-credential.md",sourceDirName:"tutorials",slug:"/tutorials/issue-a-credential",permalink:"/guides/tutorials/issue-a-credential",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Registering a schema and credential definition on an AnonCreds Registry",permalink:"/guides/tutorials/registering-schema-and-credential-definition"},next:{title:"Mediation",permalink:"/guides/tutorials/mediation"}},c={},d=[{value:"1. Setting up the agents",id:"1-setting-up-the-agents",level:3},{value:"Issuer",id:"issuer",level:4},{value:"Holder",id:"holder",level:4},{value:"3. Listening for incoming credentials",id:"3-listening-for-incoming-credentials",level:3},{value:"4. Issuing a credential",id:"4-issuing-a-credential",level:3},{value:"Useful resources",id:"useful-resources",level:3}],p={toc:d},m="wrapper";function h(e){let{components:t,...n}=e;return(0,r.kt)(m,(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"issue-a-credential"},"Issue a credential"),(0,r.kt)("p",null,"In this tutorial we will issue a credential from the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," to a ",(0,r.kt)("em",{parentName:"p"},"Holder"),". We will start with setting up both their agents with the minimal configuration required to follow this tutorial. It is assumed that there is a connection between the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," and the ",(0,r.kt)("em",{parentName:"p"},"Holder")," and the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," also has a registered schema and credential definition. After initializing the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," will send a credential to the ",(0,r.kt)("em",{parentName:"p"},"holder"),", and will then accept this credential and automatically store it in their wallet."),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"Using ",(0,r.kt)("a",{parentName:"em",href:"https://anoncreds-wg.github.io/anoncreds-spec/"},"AnonCreds")," and the ",(0,r.kt)("a",{parentName:"em",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0453-issue-credential-v2/README.md"},"Issue Credential V2 Protocol")," or the ",(0,r.kt)("a",{parentName:"em",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0036-issue-credential/README.md"},"Issue Credential V1 Protocol"),".")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This section assumes that"),(0,r.kt)("ol",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ol"},"You have ",(0,r.kt)("a",{parentName:"li",href:"../getting-started"},"set-up your develoment environment"),"."),(0,r.kt)("li",{parentName:"ol"},"You have basic knowledge of the required fields in the ",(0,r.kt)("a",{parentName:"li",href:"./agent-config"},"Agent Config")),(0,r.kt)("li",{parentName:"ol"},"You have completed the ",(0,r.kt)("a",{parentName:"li",href:"./create-a-connection"},"Create a Connection tutorial")),(0,r.kt)("li",{parentName:"ol"},"You have a registered schema and credential definition. This can be done by following the ",(0,r.kt)("a",{parentName:"li",href:"./registering-schema-and-credential-definition"},"Registering on a AnonCreds Registry")))),(0,r.kt)("h3",{id:"1-setting-up-the-agents"},"1. Setting up the agents"),(0,r.kt)("p",null,"First for both agents we must setup and initialize an agent to work with. Depending on your target, ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/react-native"},"React Native")," or ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/react-native"},"Node.js"),", it might vary."),(0,r.kt)("p",null,"In this tutorial the ",(0,r.kt)("em",{parentName:"p"},"Holder")," will be in a ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/nodejs"},"Node.js environment")," and the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," also in a ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/nodejs"},"Node.js environment"),"."),(0,r.kt)("h4",{id:"issuer"},"Issuer"),(0,r.kt)("p",null,"For the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," the setup is commonly not the same as the ",(0,r.kt)("em",{parentName:"p"},"Holder"),". In the example they both live in a server environment, meaning they do not need a mediator. More commonly, the ",(0,r.kt)("em",{parentName:"p"},"Holder")," is in a mobile environment where a mediator is required for receiving DIDComm messages."),(0,r.kt)("p",null,"It is also very important for the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," to have a public DID, for the binding with a credential definition, amongst other things. For this demo we will use ",(0,r.kt)("a",{parentName:"p",href:"http://test.bcovrin.vonx.io"},"BCovrin Test"),". If you want to follow this tutorial, you have to register a public DID ",(0,r.kt)("a",{parentName:"p",href:"http://test.bcovrin.vonx.io"},"here")," via the Wallet seed field (this must be the same as the seed inside the config under the key ",(0,r.kt)("a",{parentName:"p",href:"./agent-config#publicdidseed"},(0,r.kt)("inlineCode",{parentName:"a"},"publicDidSeed")),")."),(0,r.kt)("p",null,"In order to reach the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," we have to add a list of ",(0,r.kt)("a",{parentName:"p",href:"./agent-config#endpoints"},(0,r.kt)("inlineCode",{parentName:"a"},"endpoints"))," of the agent that exposes the ",(0,r.kt)("inlineCode",{parentName:"p"},"inboundTransport")," to the public. In the example below we add an ",(0,r.kt)("inlineCode",{parentName:"p"},"inboundTransport")," and use port ",(0,r.kt)("inlineCode",{parentName:"p"},"3002"),". For development purposes it is recommended to use a tunneling service for this, like ",(0,r.kt)("a",{parentName:"p",href:"https://ngrok.com"},"Ngrok"),". Ngrok will allow you to reach your locally exposed endpoint from the public. If a tunneling service is used, make sure to use the ",(0,r.kt)("inlineCode",{parentName:"p"},"HTTPS")," variant as mobile environments, by default, do not accept ",(0,r.kt)("inlineCode",{parentName:"p"},"HTTP")," anymore."),(0,r.kt)("p",null,"To install ",(0,r.kt)("a",{parentName:"p",href:"https://ngrok.com"},"Ngrok")," and expose the port to the public the following commands can be used:"),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"yarn",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"yarn global add ngrok\n\nngrok http \n"))),(0,r.kt)(o.Z,{label:"npm",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"npm install --global ngrok\n\nngrok http \n")))),(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers issue-a-credential.ts section-1",showLineNumbers:!0,"issue-a-credential.ts":!0,"section-1":!0},""))),(0,r.kt)("h4",{id:"holder"},"Holder"),(0,r.kt)("p",null,"For the ",(0,r.kt)("em",{parentName:"p"},"Holder")," we need to setup a basic agent with a wallet, mediator, outbound transport and a ledger."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"If you want to follow this tutorial in a mobile environment:"),(0,r.kt)("ol",{parentName:"blockquote"},(0,r.kt)("li",{parentName:"ol"},"Use the ",(0,r.kt)("inlineCode",{parentName:"li"},"agentDependencies")," from ",(0,r.kt)("inlineCode",{parentName:"li"},"@credo-ts/react-native")),(0,r.kt)("li",{parentName:"ol"},"It is very important to note that mobile agents do not support HTTP by default. It is recommended to do everything over HTTPS, but for development HTTP can be enabled for ",(0,r.kt)("a",{parentName:"li",href:"https://stackoverflow.com/questions/30731785/how-do-i-load-an-http-url-with-app-transport-security-enabled-in-ios-9"},"iOS")," and ",(0,r.kt)("a",{parentName:"li",href:"https://stackoverflow.com/questions/51902629/how-to-allow-all-network-connection-types-http-and-https-in-android-9-pie"},"Android"),"."))),(0,r.kt)("admonition",{type:"holder"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers issue-a-credential.ts section-2",showLineNumbers:!0,"issue-a-credential.ts":!0,"section-2":!0},""))),(0,r.kt)("h3",{id:"3-listening-for-incoming-credentials"},"3. Listening for incoming credentials"),(0,r.kt)("p",null,"When we want to accept a credential, we have to listen to incoming credentials and handle accordingly. In this example we do not have any user interaction, but is likely that your application would have a user-interface which would display the credential. When receiving a credential offer you can get the values from ",(0,r.kt)("inlineCode",{parentName:"p"},"credentialExchangeRecord.credentialAttributes"),"."),(0,r.kt)("admonition",{type:"holder"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers issue-a-credential.ts section-3",showLineNumbers:!0,"issue-a-credential.ts":!0,"section-3":!0},""))),(0,r.kt)("h3",{id:"4-issuing-a-credential"},"4. Issuing a credential"),(0,r.kt)("p",null,"Now that everything is setup on both sides, the ",(0,r.kt)("em",{parentName:"p"},"Issuer")," can now offer a credential to the ",(0,r.kt)("em",{parentName:"p"},"Holder"),"."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"In this example we do not instantiate a connection and assume that there is one. Please refer to this guide ",(0,r.kt)("a",{parentName:"p",href:"./create-a-connection"},"Create a connection")," to get a connection and connectionId.")),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"Indy",value:"tab1",mdxType:"TabItem"},(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers issue-a-credential.ts section-4",showLineNumbers:!0,"issue-a-credential.ts":!0,"section-4":!0},"")))),(0,r.kt)(o.Z,{label:"AnonCreds",value:"tab2",mdxType:"TabItem"},(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers issue-a-credential.ts section-5",showLineNumbers:!0,"issue-a-credential.ts":!0,"section-5":!0},""))))),(0,r.kt)("h3",{id:"useful-resources"},"Useful resources"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://anoncreds-wg.github.io/anoncreds-spec/"},"AnonCreds")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0036-issue-credential/README.md"},"Issue Credential V1 Protocol")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0453-issue-credential-v2/README.md"},"Issue Credential V2 Protocol"))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c5cd793e.f7c6a4c8.js b/assets/js/c5cd793e.f7c6a4c8.js deleted file mode 100644 index e7b821f0..00000000 --- a/assets/js/c5cd793e.f7c6a4c8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8925],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>g});var i=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function s(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var d=i.createContext({}),l=function(e){var t=i.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=l(e.components);return i.createElement(d.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},m=i.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,d=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),p=l(n),m=r,g=p["".concat(d,".").concat(m)]||p[m]||u[m]||a;return n?i.createElement(g,s(s({ref:t},c),{},{components:n})):i.createElement(g,s({ref:t},c))}));function g(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,s=new Array(a);s[0]=m;var o={};for(var d in t)hasOwnProperty.call(t,d)&&(o[d]=t[d]);o.originalType=e,o[p]="string"==typeof e?e:r,s[1]=o;for(var l=2;l{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>o,toc:()=>l});var i=n(7462),r=(n(7294),n(3905));const a={},s="Registering a schema and credential definition on an AnonCreds Registry",o={unversionedId:"tutorials/registering-schema-and-credential-definition",id:"version-0.4/tutorials/registering-schema-and-credential-definition",title:"Registering a schema and credential definition on an AnonCreds Registry",description:"In this tutorial we will register a schema and credential definition on an AnonCredsRegistry e.g. Hyperledger Indy ledger indy-vdr, cheqd.",source:"@site/versioned_docs/version-0.4/tutorials/registering-schema-and-credential-definition.md",sourceDirName:"tutorials",slug:"/tutorials/registering-schema-and-credential-definition",permalink:"/guides/tutorials/registering-schema-and-credential-definition",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Cheqd Did Module",permalink:"/guides/tutorials/cheqd/"},next:{title:"Issue a credential",permalink:"/guides/tutorials/issue-a-credential"}},d={},l=[{value:"1. Setting up the agent",id:"1-setting-up-the-agent",level:3},{value:"2. Importing a DID (optional)",id:"2-importing-a-did-optional",level:3},{value:"3. Registering a schema",id:"3-registering-a-schema",level:3},{value:"3. Registering a credential definition",id:"3-registering-a-credential-definition",level:3},{value:"Using it",id:"using-it",level:3},{value:"Useful Resources",id:"useful-resources",level:3}],c={toc:l},p="wrapper";function u(e){let{components:t,...n}=e;return(0,r.kt)(p,(0,i.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"registering-a-schema-and-credential-definition-on-an-anoncreds-registry"},"Registering a schema and credential definition on an AnonCreds Registry"),(0,r.kt)("p",null,"In this tutorial we will register a schema and credential definition on an AnonCredsRegistry e.g. Hyperledger Indy ledger ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-vdr"},"indy-vdr"),", ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript/packages/cheqd"},"cheqd"),"."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This section assumes that"),(0,r.kt)("ol",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ol"},"You have ",(0,r.kt)("a",{parentName:"li",href:"../getting-started"},"set-up your development environment"),"."),(0,r.kt)("li",{parentName:"ol"},"You have basic knowledge of the required fields in the ",(0,r.kt)("a",{parentName:"li",href:"./agent-config"},"Agent Config")))),(0,r.kt)("h3",{id:"1-setting-up-the-agent"},"1. Setting up the agent"),(0,r.kt)("p",null,"First, an agent must be setup with a wallet and an indy-vdr or cheqd module. For these code examples, we will use a Node.js environment."),(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers register-schema-and-cred-def.ts section-1",showLineNumbers:!0,"register-schema-and-cred-def.ts":!0,"section-1":!0},""))),(0,r.kt)("h3",{id:"2-importing-a-did-optional"},"2. Importing a DID (optional)"),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"There are many ledgers which can be used to register DIDs on for development."),(0,r.kt)("h4",{parentName:"admonition",id:"indy-vdr"},"Indy VDR"),(0,r.kt)("p",{parentName:"admonition"},"We recommend ",(0,r.kt)("a",{parentName:"p",href:"http://test.bcovrin.vonx.io/"},"bcovrin test net"),". This network allows very easily to register a DID from a seed which can then be used as the ",(0,r.kt)("inlineCode",{parentName:"p"},"privateKey")," in the snippet below. The seed is used as the private key for legacy compatibility with the Hyperledger Indy-SDK. The ",(0,r.kt)("a",{parentName:"p",href:"http://test.bcovrin.vonx.io/genesis"},"genesis transactions")," can also be retrieved for easy integration."),(0,r.kt)("h4",{parentName:"admonition",id:"cheqd"},"Cheqd"),(0,r.kt)("p",{parentName:"admonition"},"Follow the ",(0,r.kt)("a",{parentName:"p",href:"/guides/getting-started/set-up/cheqd/"},"cheqd setup")," and ",(0,r.kt)("a",{parentName:"p",href:"/guides/tutorials/cheqd/"},"cheqd DID module")," to setup the network and create a DID. Cheqd supports a mainnet for production and a testnet for development purposes.")),(0,r.kt)("p",null,"In order to register a schema and credential definition, a DID must be added to the agent first. This can be done by calling ",(0,r.kt)("inlineCode",{parentName:"p"},"agent.dids.create()"),", but this does require an endorser DID to be present as the ",(0,r.kt)("inlineCode",{parentName:"p"},"submitterDid"),". For this tutorial a DID will already be registered on the ledger, but it will be imported, with the associated private key, to be used later when registering the schema and credential definition."),(0,r.kt)("p",null,"This section can be omitted if your agent already has a DID in its wallet."),(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers register-schema-and-cred-def.ts section-2",showLineNumbers:!0,"register-schema-and-cred-def.ts":!0,"section-2":!0},""))),(0,r.kt)("h3",{id:"3-registering-a-schema"},"3. Registering a schema"),(0,r.kt)("p",null,"When you have a registered DID on a network and in your wallet, you can register a schema. Registering a schema requires four fields: ",(0,r.kt)("inlineCode",{parentName:"p"},"issuerId"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"name"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"version")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"attrNames"),". It is important to note that the ",(0,r.kt)("inlineCode",{parentName:"p"},"issuerId")," must be the same as a DID in your wallet."),(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers register-schema-and-cred-def.ts section-3",showLineNumbers:!0,"register-schema-and-cred-def.ts":!0,"section-3":!0},""))),(0,r.kt)("h3",{id:"3-registering-a-credential-definition"},"3. Registering a credential definition"),(0,r.kt)("p",null,"After registering a schema, a credential definition can be registered based on the schema. The credential definition, amongst more things, binds the schema to a specific issuer. Schemas can be reused between issuers, but a credential definition is specific to an issuer. In a credential definition revocation can also be specified. This section will not go in-depth about revocation."),(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers register-schema-and-cred-def.ts section-4",showLineNumbers:!0,"register-schema-and-cred-def.ts":!0,"section-4":!0},""))),(0,r.kt)("h3",{id:"using-it"},"Using it"),(0,r.kt)("p",null,"After everything is registered on a AnonCredsRegistry, we can use it to issue credentials. The next tutorial is all about issuing an AnonCreds credential with this setup."),(0,r.kt)("h3",{id:"useful-resources"},"Useful Resources"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://docs.cheqd.io/identity/guides/anoncreds"},"Cheqd AnonCreds Specification"))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c5cd793e.f960b53b.js b/assets/js/c5cd793e.f960b53b.js new file mode 100644 index 00000000..e2d2a5f8 --- /dev/null +++ b/assets/js/c5cd793e.f960b53b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8925],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>g});var i=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function s(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var d=i.createContext({}),l=function(e){var t=i.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=l(e.components);return i.createElement(d.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},m=i.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,d=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),p=l(n),m=r,g=p["".concat(d,".").concat(m)]||p[m]||u[m]||a;return n?i.createElement(g,s(s({ref:t},c),{},{components:n})):i.createElement(g,s({ref:t},c))}));function g(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,s=new Array(a);s[0]=m;var o={};for(var d in t)hasOwnProperty.call(t,d)&&(o[d]=t[d]);o.originalType=e,o[p]="string"==typeof e?e:r,s[1]=o;for(var l=2;l{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>o,toc:()=>l});var i=n(7462),r=(n(7294),n(3905));const a={},s="Registering a schema and credential definition on an AnonCreds Registry",o={unversionedId:"tutorials/registering-schema-and-credential-definition",id:"version-0.4/tutorials/registering-schema-and-credential-definition",title:"Registering a schema and credential definition on an AnonCreds Registry",description:"In this tutorial we will register a schema and credential definition on an AnonCredsRegistry e.g. Hyperledger Indy ledger indy-vdr, cheqd.",source:"@site/versioned_docs/version-0.4/tutorials/registering-schema-and-credential-definition.md",sourceDirName:"tutorials",slug:"/tutorials/registering-schema-and-credential-definition",permalink:"/guides/0.4/tutorials/registering-schema-and-credential-definition",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Cheqd Did Module",permalink:"/guides/0.4/tutorials/cheqd/"},next:{title:"Issue a credential",permalink:"/guides/0.4/tutorials/issue-a-credential"}},d={},l=[{value:"1. Setting up the agent",id:"1-setting-up-the-agent",level:3},{value:"2. Importing a DID (optional)",id:"2-importing-a-did-optional",level:3},{value:"3. Registering a schema",id:"3-registering-a-schema",level:3},{value:"3. Registering a credential definition",id:"3-registering-a-credential-definition",level:3},{value:"Using it",id:"using-it",level:3},{value:"Useful Resources",id:"useful-resources",level:3}],c={toc:l},p="wrapper";function u(e){let{components:t,...n}=e;return(0,r.kt)(p,(0,i.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"registering-a-schema-and-credential-definition-on-an-anoncreds-registry"},"Registering a schema and credential definition on an AnonCreds Registry"),(0,r.kt)("p",null,"In this tutorial we will register a schema and credential definition on an AnonCredsRegistry e.g. Hyperledger Indy ledger ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-vdr"},"indy-vdr"),", ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript/packages/cheqd"},"cheqd"),"."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This section assumes that"),(0,r.kt)("ol",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ol"},"You have ",(0,r.kt)("a",{parentName:"li",href:"../getting-started"},"set-up your development environment"),"."),(0,r.kt)("li",{parentName:"ol"},"You have basic knowledge of the required fields in the ",(0,r.kt)("a",{parentName:"li",href:"./agent-config"},"Agent Config")))),(0,r.kt)("h3",{id:"1-setting-up-the-agent"},"1. Setting up the agent"),(0,r.kt)("p",null,"First, an agent must be setup with a wallet and an indy-vdr or cheqd module. For these code examples, we will use a Node.js environment."),(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers register-schema-and-cred-def.ts section-1",showLineNumbers:!0,"register-schema-and-cred-def.ts":!0,"section-1":!0},""))),(0,r.kt)("h3",{id:"2-importing-a-did-optional"},"2. Importing a DID (optional)"),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"There are many ledgers which can be used to register DIDs on for development."),(0,r.kt)("h4",{parentName:"admonition",id:"indy-vdr"},"Indy VDR"),(0,r.kt)("p",{parentName:"admonition"},"We recommend ",(0,r.kt)("a",{parentName:"p",href:"http://test.bcovrin.vonx.io/"},"bcovrin test net"),". This network allows very easily to register a DID from a seed which can then be used as the ",(0,r.kt)("inlineCode",{parentName:"p"},"privateKey")," in the snippet below. The seed is used as the private key for legacy compatibility with the Hyperledger Indy-SDK. The ",(0,r.kt)("a",{parentName:"p",href:"http://test.bcovrin.vonx.io/genesis"},"genesis transactions")," can also be retrieved for easy integration."),(0,r.kt)("h4",{parentName:"admonition",id:"cheqd"},"Cheqd"),(0,r.kt)("p",{parentName:"admonition"},"Follow the ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.4/getting-started/set-up/cheqd/"},"cheqd setup")," and ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.4/tutorials/cheqd/"},"cheqd DID module")," to setup the network and create a DID. Cheqd supports a mainnet for production and a testnet for development purposes.")),(0,r.kt)("p",null,"In order to register a schema and credential definition, a DID must be added to the agent first. This can be done by calling ",(0,r.kt)("inlineCode",{parentName:"p"},"agent.dids.create()"),", but this does require an endorser DID to be present as the ",(0,r.kt)("inlineCode",{parentName:"p"},"submitterDid"),". For this tutorial a DID will already be registered on the ledger, but it will be imported, with the associated private key, to be used later when registering the schema and credential definition."),(0,r.kt)("p",null,"This section can be omitted if your agent already has a DID in its wallet."),(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers register-schema-and-cred-def.ts section-2",showLineNumbers:!0,"register-schema-and-cred-def.ts":!0,"section-2":!0},""))),(0,r.kt)("h3",{id:"3-registering-a-schema"},"3. Registering a schema"),(0,r.kt)("p",null,"When you have a registered DID on a network and in your wallet, you can register a schema. Registering a schema requires four fields: ",(0,r.kt)("inlineCode",{parentName:"p"},"issuerId"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"name"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"version")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"attrNames"),". It is important to note that the ",(0,r.kt)("inlineCode",{parentName:"p"},"issuerId")," must be the same as a DID in your wallet."),(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers register-schema-and-cred-def.ts section-3",showLineNumbers:!0,"register-schema-and-cred-def.ts":!0,"section-3":!0},""))),(0,r.kt)("h3",{id:"3-registering-a-credential-definition"},"3. Registering a credential definition"),(0,r.kt)("p",null,"After registering a schema, a credential definition can be registered based on the schema. The credential definition, amongst more things, binds the schema to a specific issuer. Schemas can be reused between issuers, but a credential definition is specific to an issuer. In a credential definition revocation can also be specified. This section will not go in-depth about revocation."),(0,r.kt)("admonition",{type:"issuer"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers register-schema-and-cred-def.ts section-4",showLineNumbers:!0,"register-schema-and-cred-def.ts":!0,"section-4":!0},""))),(0,r.kt)("h3",{id:"using-it"},"Using it"),(0,r.kt)("p",null,"After everything is registered on a AnonCredsRegistry, we can use it to issue credentials. The next tutorial is all about issuing an AnonCreds credential with this setup."),(0,r.kt)("h3",{id:"useful-resources"},"Useful Resources"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://docs.cheqd.io/identity/guides/anoncreds"},"Cheqd AnonCreds Specification"))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c970593d.c8e661ef.js b/assets/js/c970593d.ed1d6eb1.js similarity index 93% rename from assets/js/c970593d.c8e661ef.js rename to assets/js/c970593d.ed1d6eb1.js index c2739e74..963d5307 100644 --- a/assets/js/c970593d.c8e661ef.js +++ b/assets/js/c970593d.ed1d6eb1.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[703],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>h});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},d=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,c=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=l(n),g=a,h=p["".concat(c,".").concat(g)]||p[g]||u[g]||i;return n?r.createElement(h,o(o({ref:t},d),{},{components:n})):r.createElement(h,o({ref:t},d))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=g;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:a,o[1]=s;for(var l=2;l{n.d(t,{Z:()=>f});var r=n(7294),a=n(6010),i=n(3438),o=n(9960),s=n(3919),c=n(5999);const l={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function d(e){let{href:t,children:n}=e;return r.createElement(o.Z,{href:t,className:(0,a.Z)("card padding--lg",l.cardContainer)},n)}function p(e){let{href:t,icon:n,title:i,description:o}=e;return r.createElement(d,{href:t},r.createElement("h2",{className:(0,a.Z)("text--truncate",l.cardTitle),title:i},n," ",i),o&&r.createElement("p",{className:(0,a.Z)("text--truncate",l.cardDescription),title:o},o))}function u(e){let{item:t}=e;const n=(0,i.Wl)(t);return n?r.createElement(p,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,c.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function g(e){let{item:t}=e;const n=(0,s.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",a=(0,i.xz)(t.docId??void 0);return r.createElement(p,{href:t.href,icon:n,title:t.label,description:a?.description})}function h(e){let{item:t}=e;switch(t.type){case"link":return r.createElement(g,{item:t});case"category":return r.createElement(u,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function m(e){let{className:t}=e;const n=(0,i.jA)();return r.createElement(f,{items:n.items,className:t})}function f(e){const{items:t,className:n}=e;if(!t)return r.createElement(m,e);const o=(0,i.MN)(t);return r.createElement("section",{className:(0,a.Z)("row",n)},o.map(((e,t)=>r.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},r.createElement(h,{item:e})))))}},4933:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>g,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var r=n(7462),a=(n(7294),n(3905)),i=n(2991);const o={},s="Updating AFJ",c={unversionedId:"updating/index",id:"version-0.3/updating/index",title:"Updating AFJ",description:"This section will cover everything you need to know about updating Aries Framework JavaScript to a newer version.",source:"@site/versioned_docs/version-0.3/updating/index.md",sourceDirName:"updating",slug:"/updating/",permalink:"/guides/0.3/updating/",draft:!1,tags:[],version:"0.3",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Postgres Setup for windows",permalink:"/guides/0.3/tutorials/postgres-database-nodejs/windows"},next:{title:"Update Assistant",permalink:"/guides/0.3/updating/update-assistant"}},l={},d=[{value:"Versioning",id:"versioning",level:2},{value:"Types of breaking changes",id:"types-of-breaking-changes",level:2},{value:"Breaking Code Changes",id:"breaking-code-changes",level:3},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:3},{value:"Migration Guides",id:"migration-guides",level:2}],p={toc:d},u="wrapper";function g(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"updating-afj"},"Updating AFJ"),(0,a.kt)("p",null,"This section will cover everything you need to know about updating Aries Framework JavaScript to a newer version."),(0,a.kt)(i.Z,{mdxType:"DocCardList"}),(0,a.kt)("h2",{id:"versioning"},"Versioning"),(0,a.kt)("p",null,"Aries Framework JavaScript follows ",(0,a.kt)("a",{parentName:"p",href:"https://semver.org/"},"semantic versioning"),". This means that major version changes (",(0,a.kt)("strong",{parentName:"p"},"1"),".0.0) are considered breaking changes. When features are added this is a minor version change (0.",(0,a.kt)("strong",{parentName:"p"},"1"),".0). For bug fixes the patch version change is used (0.0.",(0,a.kt)("strong",{parentName:"p"},"1"),")."),(0,a.kt)("p",null,"While AFJ is still in pre-1.0.0 version, the version change types are shifted to the right. This means a major version change is now a minor change (0.",(0,a.kt)("strong",{parentName:"p"},"1"),".0) and a minor change is now a patch change (0.0.",(0,a.kt)("strong",{parentName:"p"},"1"),"). This is done to keep the version below 1.0.0, indicating the framework is still in early development and users can expect more breaking changes that when the version has already reached 1.0.0."),(0,a.kt)("p",null,"This means if the second number in the version (0.",(0,a.kt)("strong",{parentName:"p"},"1"),".0) changes, you need to be careful with updating and always consult this page for update instructions. If only the third number changes (0.0.",(0,a.kt)("strong",{parentName:"p"},"1"),"), you can update without any issues."),(0,a.kt)("h2",{id:"types-of-breaking-changes"},"Types of breaking changes"),(0,a.kt)("p",null,"Updates to AFJ bring new features and improvements to the framework. To better adapt the framework to new features we sometimes make breaking changes that will improve how AFJ works. There's two parts to updates with breaking changes:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Breaking code changes"),(0,a.kt)("li",{parentName:"ol"},"Breaking storage changes")),(0,a.kt)("h3",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,a.kt)("p",null,"Breaking changes to code means changes to how you interact with AFJ. This includes methods being renamed, moved to another module or extended to better integrate with new features. We'll try to cover all breaking changes in migration guides, so you know exactly what is needed to update to a new version and keep the same functionality."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"If you encounter any breaking changes that aren't mentioned in the migration docs, please open an issue in the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-javascript-docs/issues"},"Aries JavaScript Docs")," repository, or directly create a PR describing the change.")),(0,a.kt)("h3",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,a.kt)("p",null,"Breaking changes to storage are a bit more complex to deal with. While breaking changes to code only require you to update your code once, breaking changes to storage needs to be updated for every agent instance. Luckily, we've made the migration as easy as possible for you using the ",(0,a.kt)("a",{parentName:"p",href:"/guides/0.3/updating/update-assistant"},"Update Assistant"),". The Update Assistant will update all storage objects to the storage model that is expected by the newest version. If a version made changes to the storage, this will be explicitly mentioned in the migration guide. See the ",(0,a.kt)("a",{parentName:"p",href:"/guides/0.5/updating/update-assistant"},"Update Assistant")," documentation for detailed instructions on how to use the update assistant."),(0,a.kt)("h2",{id:"migration-guides"},"Migration Guides"),(0,a.kt)("p",null,"Currently the following migration guides are available:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/0.3/updating/versions/0.1-to-0.2"},"Migrating from AFJ 0.1.0 to 0.2.x")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/0.3/updating/versions/0.2-to-0.3"},"Migrating from AFJ 0.2.x to 0.3.x"))))}g.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[703],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>h});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},d=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,c=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=l(n),g=a,h=p["".concat(c,".").concat(g)]||p[g]||u[g]||i;return n?r.createElement(h,o(o({ref:t},d),{},{components:n})):r.createElement(h,o({ref:t},d))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=g;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:a,o[1]=s;for(var l=2;l{n.d(t,{Z:()=>f});var r=n(7294),a=n(6010),i=n(3438),o=n(9960),s=n(3919),c=n(5999);const l={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function d(e){let{href:t,children:n}=e;return r.createElement(o.Z,{href:t,className:(0,a.Z)("card padding--lg",l.cardContainer)},n)}function p(e){let{href:t,icon:n,title:i,description:o}=e;return r.createElement(d,{href:t},r.createElement("h2",{className:(0,a.Z)("text--truncate",l.cardTitle),title:i},n," ",i),o&&r.createElement("p",{className:(0,a.Z)("text--truncate",l.cardDescription),title:o},o))}function u(e){let{item:t}=e;const n=(0,i.Wl)(t);return n?r.createElement(p,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,c.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function g(e){let{item:t}=e;const n=(0,s.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",a=(0,i.xz)(t.docId??void 0);return r.createElement(p,{href:t.href,icon:n,title:t.label,description:a?.description})}function h(e){let{item:t}=e;switch(t.type){case"link":return r.createElement(g,{item:t});case"category":return r.createElement(u,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function m(e){let{className:t}=e;const n=(0,i.jA)();return r.createElement(f,{items:n.items,className:t})}function f(e){const{items:t,className:n}=e;if(!t)return r.createElement(m,e);const o=(0,i.MN)(t);return r.createElement("section",{className:(0,a.Z)("row",n)},o.map(((e,t)=>r.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},r.createElement(h,{item:e})))))}},4933:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>g,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var r=n(7462),a=(n(7294),n(3905)),i=n(2991);const o={},s="Updating AFJ",c={unversionedId:"updating/index",id:"version-0.3/updating/index",title:"Updating AFJ",description:"This section will cover everything you need to know about updating Aries Framework JavaScript to a newer version.",source:"@site/versioned_docs/version-0.3/updating/index.md",sourceDirName:"updating",slug:"/updating/",permalink:"/guides/0.3/updating/",draft:!1,tags:[],version:"0.3",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Postgres Setup for windows",permalink:"/guides/0.3/tutorials/postgres-database-nodejs/windows"},next:{title:"Update Assistant",permalink:"/guides/0.3/updating/update-assistant"}},l={},d=[{value:"Versioning",id:"versioning",level:2},{value:"Types of breaking changes",id:"types-of-breaking-changes",level:2},{value:"Breaking Code Changes",id:"breaking-code-changes",level:3},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:3},{value:"Migration Guides",id:"migration-guides",level:2}],p={toc:d},u="wrapper";function g(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"updating-afj"},"Updating AFJ"),(0,a.kt)("p",null,"This section will cover everything you need to know about updating Aries Framework JavaScript to a newer version."),(0,a.kt)(i.Z,{mdxType:"DocCardList"}),(0,a.kt)("h2",{id:"versioning"},"Versioning"),(0,a.kt)("p",null,"Aries Framework JavaScript follows ",(0,a.kt)("a",{parentName:"p",href:"https://semver.org/"},"semantic versioning"),". This means that major version changes (",(0,a.kt)("strong",{parentName:"p"},"1"),".0.0) are considered breaking changes. When features are added this is a minor version change (0.",(0,a.kt)("strong",{parentName:"p"},"1"),".0). For bug fixes the patch version change is used (0.0.",(0,a.kt)("strong",{parentName:"p"},"1"),")."),(0,a.kt)("p",null,"While AFJ is still in pre-1.0.0 version, the version change types are shifted to the right. This means a major version change is now a minor change (0.",(0,a.kt)("strong",{parentName:"p"},"1"),".0) and a minor change is now a patch change (0.0.",(0,a.kt)("strong",{parentName:"p"},"1"),"). This is done to keep the version below 1.0.0, indicating the framework is still in early development and users can expect more breaking changes that when the version has already reached 1.0.0."),(0,a.kt)("p",null,"This means if the second number in the version (0.",(0,a.kt)("strong",{parentName:"p"},"1"),".0) changes, you need to be careful with updating and always consult this page for update instructions. If only the third number changes (0.0.",(0,a.kt)("strong",{parentName:"p"},"1"),"), you can update without any issues."),(0,a.kt)("h2",{id:"types-of-breaking-changes"},"Types of breaking changes"),(0,a.kt)("p",null,"Updates to AFJ bring new features and improvements to the framework. To better adapt the framework to new features we sometimes make breaking changes that will improve how AFJ works. There's two parts to updates with breaking changes:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Breaking code changes"),(0,a.kt)("li",{parentName:"ol"},"Breaking storage changes")),(0,a.kt)("h3",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,a.kt)("p",null,"Breaking changes to code means changes to how you interact with AFJ. This includes methods being renamed, moved to another module or extended to better integrate with new features. We'll try to cover all breaking changes in migration guides, so you know exactly what is needed to update to a new version and keep the same functionality."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"If you encounter any breaking changes that aren't mentioned in the migration docs, please open an issue in the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-javascript-docs/issues"},"Aries JavaScript Docs")," repository, or directly create a PR describing the change.")),(0,a.kt)("h3",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,a.kt)("p",null,"Breaking changes to storage are a bit more complex to deal with. While breaking changes to code only require you to update your code once, breaking changes to storage needs to be updated for every agent instance. Luckily, we've made the migration as easy as possible for you using the ",(0,a.kt)("a",{parentName:"p",href:"/guides/0.3/updating/update-assistant"},"Update Assistant"),". The Update Assistant will update all storage objects to the storage model that is expected by the newest version. If a version made changes to the storage, this will be explicitly mentioned in the migration guide. See the ",(0,a.kt)("a",{parentName:"p",href:"/guides/updating/update-assistant"},"Update Assistant")," documentation for detailed instructions on how to use the update assistant."),(0,a.kt)("h2",{id:"migration-guides"},"Migration Guides"),(0,a.kt)("p",null,"Currently the following migration guides are available:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/0.3/updating/versions/0.1-to-0.2"},"Migrating from AFJ 0.1.0 to 0.2.x")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"/guides/0.3/updating/versions/0.2-to-0.3"},"Migrating from AFJ 0.2.x to 0.3.x"))))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ca99fa15.14f0d88b.js b/assets/js/ca99fa15.14f0d88b.js deleted file mode 100644 index ca513fba..00000000 --- a/assets/js/ca99fa15.14f0d88b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[3080],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),d=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=d(e.components);return r.createElement(c.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),m=d(n),p=o,f=m["".concat(c,".").concat(p)]||m[p]||u[p]||i;return n?r.createElement(f,a(a({ref:t},l),{},{components:n})):r.createElement(f,a({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=p;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[m]="string"==typeof e?e:o,a[1]=s;for(var d=2;d{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>d});var r=n(7462),o=(n(7294),n(3905));const i={},a="DIDs and DIDComm",s={unversionedId:"concepts/did-and-didcomm",id:"concepts/did-and-didcomm",title:"DIDs and DIDComm",description:"DIDs",source:"@site/guides/concepts/did-and-didcomm.md",sourceDirName:"concepts",slug:"/concepts/did-and-didcomm",permalink:"/guides/0.5/concepts/did-and-didcomm",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Agents",permalink:"/guides/0.5/concepts/agents"},next:{title:"Platform and Environment",permalink:"/guides/0.5/concepts/platform-and-environment"}},c={},d=[{value:"DIDs",id:"dids",level:3},{value:"DID Documents",id:"did-documents",level:3},{value:"DIDComm",id:"didcomm",level:3},{value:"Useful Resources",id:"useful-resources",level:3}],l={toc:d},m="wrapper";function u(e){let{components:t,...n}=e;return(0,o.kt)(m,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"dids-and-didcomm"},"DIDs and DIDComm"),(0,o.kt)("h3",{id:"dids"},"DIDs"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://www.w3.org/TR/did-core/"},"DIDs"),", short for Decentralized identifiers,\nare a type of identifier that enables verifiable, decentralized identity. A DID\ncan refer to any subject, a person, organization, etc. DIDs are decoupled from\ncentralized registries, identity providers and certificate authorities."),(0,o.kt)("h3",{id:"did-documents"},"DID Documents"),(0,o.kt)("p",null,"A DID by itself does not contain a lot of information. So in order to get some\nmetadata we have to resolve the DID to get a ",(0,o.kt)("a",{parentName:"p",href:"https://www.w3.org/TR/did-core/#dfn-did-documents"},"DID Document"),". With this\ndocument we can get data such as their public key, proof mechanisms and their\nservice endpoints. This means that we can check the validity, encrypt\none-to-one messages and send it to their service endpoint."),(0,o.kt)("h3",{id:"didcomm"},"DIDComm"),(0,o.kt)("p",null,"In the previous section sending a message to their service endpoint is\nmentioned. This is a nice feature, but is lacking a definition of how it should\nwork. ",(0,o.kt)("a",{parentName:"p",href:"https://identity.foundation/didcomm-messaging/spec/"},"DIDComm"),", we will\nonly discuss V1 here, defines this. DIDComm is designed to be private, secure,\ntransport-agnostic, interoperable and much more. This means that you can\nsecurely send a message from as Alice to Bob securely via bluetooth, HTTP,\nWebSockets, etc."),(0,o.kt)("p",null,"When working with the tools available inside the Credo ecosystem,\ndeep knowledge of DIDComm is not required."),(0,o.kt)("h3",{id:"useful-resources"},"Useful Resources"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://www.w3.org/TR/did-core/"},"DID spec")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://identity.foundation/didcomm-messaging/spec/"},"DIDComm spec"))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ca99fa15.7e5762c8.js b/assets/js/ca99fa15.7e5762c8.js new file mode 100644 index 00000000..b2c6ba9c --- /dev/null +++ b/assets/js/ca99fa15.7e5762c8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[3080],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),d=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=d(e.components);return r.createElement(c.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),m=d(n),p=o,f=m["".concat(c,".").concat(p)]||m[p]||u[p]||i;return n?r.createElement(f,a(a({ref:t},l),{},{components:n})):r.createElement(f,a({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=p;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[m]="string"==typeof e?e:o,a[1]=s;for(var d=2;d{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>d});var r=n(7462),o=(n(7294),n(3905));const i={},a="DIDs and DIDComm",s={unversionedId:"concepts/did-and-didcomm",id:"concepts/did-and-didcomm",title:"DIDs and DIDComm",description:"DIDs",source:"@site/guides/concepts/did-and-didcomm.md",sourceDirName:"concepts",slug:"/concepts/did-and-didcomm",permalink:"/guides/concepts/did-and-didcomm",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Agents",permalink:"/guides/concepts/agents"},next:{title:"Platform and Environment",permalink:"/guides/concepts/platform-and-environment"}},c={},d=[{value:"DIDs",id:"dids",level:3},{value:"DID Documents",id:"did-documents",level:3},{value:"DIDComm",id:"didcomm",level:3},{value:"Useful Resources",id:"useful-resources",level:3}],l={toc:d},m="wrapper";function u(e){let{components:t,...n}=e;return(0,o.kt)(m,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"dids-and-didcomm"},"DIDs and DIDComm"),(0,o.kt)("h3",{id:"dids"},"DIDs"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://www.w3.org/TR/did-core/"},"DIDs"),", short for Decentralized identifiers,\nare a type of identifier that enables verifiable, decentralized identity. A DID\ncan refer to any subject, a person, organization, etc. DIDs are decoupled from\ncentralized registries, identity providers and certificate authorities."),(0,o.kt)("h3",{id:"did-documents"},"DID Documents"),(0,o.kt)("p",null,"A DID by itself does not contain a lot of information. So in order to get some\nmetadata we have to resolve the DID to get a ",(0,o.kt)("a",{parentName:"p",href:"https://www.w3.org/TR/did-core/#dfn-did-documents"},"DID Document"),". With this\ndocument we can get data such as their public key, proof mechanisms and their\nservice endpoints. This means that we can check the validity, encrypt\none-to-one messages and send it to their service endpoint."),(0,o.kt)("h3",{id:"didcomm"},"DIDComm"),(0,o.kt)("p",null,"In the previous section sending a message to their service endpoint is\nmentioned. This is a nice feature, but is lacking a definition of how it should\nwork. ",(0,o.kt)("a",{parentName:"p",href:"https://identity.foundation/didcomm-messaging/spec/"},"DIDComm"),", we will\nonly discuss V1 here, defines this. DIDComm is designed to be private, secure,\ntransport-agnostic, interoperable and much more. This means that you can\nsecurely send a message from as Alice to Bob securely via bluetooth, HTTP,\nWebSockets, etc."),(0,o.kt)("p",null,"When working with the tools available inside the Credo ecosystem,\ndeep knowledge of DIDComm is not required."),(0,o.kt)("h3",{id:"useful-resources"},"Useful Resources"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://www.w3.org/TR/did-core/"},"DID spec")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://identity.foundation/didcomm-messaging/spec/"},"DIDComm spec"))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d26e5579.b67f5693.js b/assets/js/d26e5579.71d6e16f.js similarity index 61% rename from assets/js/d26e5579.b67f5693.js rename to assets/js/d26e5579.71d6e16f.js index 286385b7..aa1872b3 100644 --- a/assets/js/d26e5579.b67f5693.js +++ b/assets/js/d26e5579.71d6e16f.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[9080],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>b});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var u=r.createContext({}),s=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=s(e.components);return r.createElement(u.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,u=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),d=s(n),m=a,b=d["".concat(u,".").concat(m)]||d[m]||p[m]||l;return n?r.createElement(b,i(i({ref:t},c),{},{components:n})):r.createElement(b,i({ref:t},c))}));function b(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=n.length,i=new Array(l);i[0]=m;var o={};for(var u in t)hasOwnProperty.call(t,u)&&(o[u]=t[u]);o.originalType=e,o[d]="string"==typeof e?e:a,i[1]=o;for(var s=2;s{n.d(t,{Z:()=>i});var r=n(7294),a=n(6010);const l={tabItem:"tabItem_Ymn6"};function i(e){let{children:t,hidden:n,className:i}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(l.tabItem,i),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var r=n(7462),a=n(7294),l=n(6010),i=n(2466),o=n(6550),u=n(1980),s=n(7392),c=n(12);function d(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function p(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??d(n);return function(e){const t=(0,s.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function b(e){let{queryString:t=!1,groupId:n}=e;const r=(0,o.k6)(),l=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,u._X)(l),(0,a.useCallback)((e=>{if(!l)return;const t=new URLSearchParams(r.location.search);t.set(l,e),r.replace({...r.location,search:t.toString()})}),[l,r])]}function h(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,l=p(e),[i,o]=(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(!m({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 r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:l}))),[u,s]=b({queryString:n,groupId:r}),[d,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,l]=(0,c.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&l.set(e)}),[n,l])]}({groupId:r}),f=(()=>{const e=u??d;return m({value:e,tabValues:l})?e:null})();(0,a.useLayoutEffect)((()=>{f&&o(f)}),[f]);return{selectedValue:i,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:l}))throw new Error(`Can't select invalid tab value=${e}`);o(e),s(e),h(e)}),[s,h,l]),tabValues:l}}var f=n(2389);const y={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function g(e){let{className:t,block:n,selectedValue:o,selectValue:u,tabValues:s}=e;const c=[],{blockElementScrollPositionUntilNextRender:d}=(0,i.o5)(),p=e=>{const t=e.currentTarget,n=c.indexOf(t),r=s[n].value;r!==o&&(d(t),u(r))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.Z)("tabs",{"tabs--block":n},t)},s.map((e=>{let{value:t,label:n,attributes:i}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:o===t?0:-1,"aria-selected":o===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:p},i,{className:(0,l.Z)("tabs__item",y.tabItem,i?.className,{"tabs__item--active":o===t})}),n??t)})))}function v(e){let{lazy:t,children:n,selectedValue:r}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function k(e){const t=h(e);return a.createElement("div",{className:(0,l.Z)("tabs-container",y.tabList)},a.createElement(g,(0,r.Z)({},e,t)),a.createElement(v,(0,r.Z)({},e,t)))}function w(e){const t=(0,f.Z)();return a.createElement(k,(0,r.Z)({key:String(t)},e))}},9533:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>u,default:()=>b,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var r=n(7462),a=(n(7294),n(3905)),l=n(4866),i=n(5162);const o={},u="Linux",s={unversionedId:"getting-started/set-up/indy-sdk/linux",id:"version-0.4/getting-started/set-up/indy-sdk/linux",title:"Linux",description:"To install Indy SDK on Linux, a couple of dependencies are required. This guide covers the installation for the more popular Linux distributions.",source:"@site/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/linux.md",sourceDirName:"getting-started/set-up/indy-sdk",slug:"/getting-started/set-up/indy-sdk/linux",permalink:"/guides/getting-started/set-up/indy-sdk/linux",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Indy SDK",permalink:"/guides/getting-started/set-up/indy-sdk/"},next:{title:"Windows",permalink:"/guides/getting-started/set-up/indy-sdk/windows"}},c={},d=[{value:"Libsodium",id:"libsodium",level:3},{value:"Arch Linux",id:"arch-linux",level:4},{value:"Debian",id:"debian",level:4},{value:"Red Hat",id:"red-hat",level:4},{value:"Libzmq",id:"libzmq",level:3},{value:"Arch Linux",id:"arch-linux-1",level:4},{value:"Debian",id:"debian-1",level:4},{value:"Red Hat",id:"red-hat-1",level:4},{value:"Indy SDK",id:"indy-sdk",level:3},{value:"Confirm installation",id:"confirm-installation",level:3}],p={toc:d},m="wrapper";function b(e){let{components:t,...n}=e;return(0,a.kt)(m,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"linux"},"Linux"),(0,a.kt)("p",null,"To install ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk"},"Indy SDK")," on Linux, a couple of dependencies are required. This guide covers the installation for the more popular Linux distributions."),(0,a.kt)("h3",{id:"libsodium"},"Libsodium"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/jedisct1/libsodium"},"Libsodium")," is used by the Indy SDK for encryption, decryption, hashing and signing."),(0,a.kt)(l.Z,{mdxType:"Tabs"},(0,a.kt)(i.Z,{label:"Arch Linux",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"pacman -S libsodium\n"))),(0,a.kt)(i.Z,{label:"Debian",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"apt-get install libsodium-dev\n"))),(0,a.kt)(i.Z,{label:"Red Hat",value:"tab3",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"yum install libsodium libsodium-devel\n")))),(0,a.kt)("h3",{id:"libzmq"},"Libzmq"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/zeromq/libzmq"},"Libzmq")," is a lightweight messaging queue used by the Indy SDK."),(0,a.kt)(l.Z,{mdxType:"Tabs"},(0,a.kt)(i.Z,{label:"Arch Linux",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"pacman -S zeromq\n"))),(0,a.kt)(i.Z,{label:"Debian",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"apt-get install libzmq3-dev\n"))),(0,a.kt)(i.Z,{label:"Red Hat",value:"tab3",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"yum install libsodium zeromq-devel\n")))),(0,a.kt)("h3",{id:"indy-sdk"},"Indy SDK"),(0,a.kt)("p",null,"All the steps mentioned here are distribution independent. As the Indy SDK doesn't provide binaries for many releases, we will build it from source. This does mean that some additional requirements are necessary, like\n",(0,a.kt)("a",{parentName:"p",href:"https://www.rust-lang.org"},"Rust"),"."),(0,a.kt)("p",null,"Downloading ",(0,a.kt)("a",{parentName:"p",href:"https://www.rust-lang.org"},"Rust")," is as easy as executing the\nfollowing command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n")),(0,a.kt)("p",null,"This will install ",(0,a.kt)("a",{parentName:"p",href:"https://rustup.rs"},"Rustup")," which is the installer for\n",(0,a.kt)("a",{parentName:"p",href:"https://rust-lang.org"},"Rust"),"."),(0,a.kt)("p",null,"With ",(0,a.kt)("a",{parentName:"p",href:"https://rust-lang.org"},"Rust"),", we can now build the\nIndy SDK from source."),(0,a.kt)("p",null,"First, clone the repository in a temporary directory:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"git clone https://github.com/hyperledger/indy-sdk\n")),(0,a.kt)("p",null,"Secondly, go to the correct directory"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"cd indy-sdk/libindy\n")),(0,a.kt)("p",null,"Third, build the library"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"cargo build --release\n")),(0,a.kt)("p",null,"Lastly, move the library to the correct location"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"sudo mv target/release/libindy.so /usr/lib/libindy.so\n")),(0,a.kt)("h3",{id:"confirm-installation"},"Confirm installation"),(0,a.kt)("p",null,"To see whether the Indy SDK is correctly installed on your system, run the following command and it should not error."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"npx -p @aries-framework/node@^0.3 is-indy-installed\n")))}b.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[9080],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>b});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var u=r.createContext({}),s=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=s(e.components);return r.createElement(u.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,u=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),d=s(n),m=a,b=d["".concat(u,".").concat(m)]||d[m]||p[m]||l;return n?r.createElement(b,i(i({ref:t},c),{},{components:n})):r.createElement(b,i({ref:t},c))}));function b(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=n.length,i=new Array(l);i[0]=m;var o={};for(var u in t)hasOwnProperty.call(t,u)&&(o[u]=t[u]);o.originalType=e,o[d]="string"==typeof e?e:a,i[1]=o;for(var s=2;s{n.d(t,{Z:()=>i});var r=n(7294),a=n(6010);const l={tabItem:"tabItem_Ymn6"};function i(e){let{children:t,hidden:n,className:i}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(l.tabItem,i),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var r=n(7462),a=n(7294),l=n(6010),i=n(2466),o=n(6550),u=n(1980),s=n(7392),c=n(12);function d(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function p(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??d(n);return function(e){const t=(0,s.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function b(e){let{queryString:t=!1,groupId:n}=e;const r=(0,o.k6)(),l=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,u._X)(l),(0,a.useCallback)((e=>{if(!l)return;const t=new URLSearchParams(r.location.search);t.set(l,e),r.replace({...r.location,search:t.toString()})}),[l,r])]}function h(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,l=p(e),[i,o]=(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(!m({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 r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:l}))),[u,s]=b({queryString:n,groupId:r}),[d,h]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,l]=(0,c.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&l.set(e)}),[n,l])]}({groupId:r}),f=(()=>{const e=u??d;return m({value:e,tabValues:l})?e:null})();(0,a.useLayoutEffect)((()=>{f&&o(f)}),[f]);return{selectedValue:i,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:l}))throw new Error(`Can't select invalid tab value=${e}`);o(e),s(e),h(e)}),[s,h,l]),tabValues:l}}var f=n(2389);const y={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function g(e){let{className:t,block:n,selectedValue:o,selectValue:u,tabValues:s}=e;const c=[],{blockElementScrollPositionUntilNextRender:d}=(0,i.o5)(),p=e=>{const t=e.currentTarget,n=c.indexOf(t),r=s[n].value;r!==o&&(d(t),u(r))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.Z)("tabs",{"tabs--block":n},t)},s.map((e=>{let{value:t,label:n,attributes:i}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:o===t?0:-1,"aria-selected":o===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:p},i,{className:(0,l.Z)("tabs__item",y.tabItem,i?.className,{"tabs__item--active":o===t})}),n??t)})))}function v(e){let{lazy:t,children:n,selectedValue:r}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function k(e){const t=h(e);return a.createElement("div",{className:(0,l.Z)("tabs-container",y.tabList)},a.createElement(g,(0,r.Z)({},e,t)),a.createElement(v,(0,r.Z)({},e,t)))}function w(e){const t=(0,f.Z)();return a.createElement(k,(0,r.Z)({key:String(t)},e))}},9533:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>u,default:()=>b,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var r=n(7462),a=(n(7294),n(3905)),l=n(4866),i=n(5162);const o={},u="Linux",s={unversionedId:"getting-started/set-up/indy-sdk/linux",id:"version-0.4/getting-started/set-up/indy-sdk/linux",title:"Linux",description:"To install Indy SDK on Linux, a couple of dependencies are required. This guide covers the installation for the more popular Linux distributions.",source:"@site/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/linux.md",sourceDirName:"getting-started/set-up/indy-sdk",slug:"/getting-started/set-up/indy-sdk/linux",permalink:"/guides/0.4/getting-started/set-up/indy-sdk/linux",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Indy SDK",permalink:"/guides/0.4/getting-started/set-up/indy-sdk/"},next:{title:"Windows",permalink:"/guides/0.4/getting-started/set-up/indy-sdk/windows"}},c={},d=[{value:"Libsodium",id:"libsodium",level:3},{value:"Arch Linux",id:"arch-linux",level:4},{value:"Debian",id:"debian",level:4},{value:"Red Hat",id:"red-hat",level:4},{value:"Libzmq",id:"libzmq",level:3},{value:"Arch Linux",id:"arch-linux-1",level:4},{value:"Debian",id:"debian-1",level:4},{value:"Red Hat",id:"red-hat-1",level:4},{value:"Indy SDK",id:"indy-sdk",level:3},{value:"Confirm installation",id:"confirm-installation",level:3}],p={toc:d},m="wrapper";function b(e){let{components:t,...n}=e;return(0,a.kt)(m,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"linux"},"Linux"),(0,a.kt)("p",null,"To install ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk"},"Indy SDK")," on Linux, a couple of dependencies are required. This guide covers the installation for the more popular Linux distributions."),(0,a.kt)("h3",{id:"libsodium"},"Libsodium"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/jedisct1/libsodium"},"Libsodium")," is used by the Indy SDK for encryption, decryption, hashing and signing."),(0,a.kt)(l.Z,{mdxType:"Tabs"},(0,a.kt)(i.Z,{label:"Arch Linux",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"pacman -S libsodium\n"))),(0,a.kt)(i.Z,{label:"Debian",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"apt-get install libsodium-dev\n"))),(0,a.kt)(i.Z,{label:"Red Hat",value:"tab3",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"yum install libsodium libsodium-devel\n")))),(0,a.kt)("h3",{id:"libzmq"},"Libzmq"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/zeromq/libzmq"},"Libzmq")," is a lightweight messaging queue used by the Indy SDK."),(0,a.kt)(l.Z,{mdxType:"Tabs"},(0,a.kt)(i.Z,{label:"Arch Linux",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"pacman -S zeromq\n"))),(0,a.kt)(i.Z,{label:"Debian",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"apt-get install libzmq3-dev\n"))),(0,a.kt)(i.Z,{label:"Red Hat",value:"tab3",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"yum install libsodium zeromq-devel\n")))),(0,a.kt)("h3",{id:"indy-sdk"},"Indy SDK"),(0,a.kt)("p",null,"All the steps mentioned here are distribution independent. As the Indy SDK doesn't provide binaries for many releases, we will build it from source. This does mean that some additional requirements are necessary, like\n",(0,a.kt)("a",{parentName:"p",href:"https://www.rust-lang.org"},"Rust"),"."),(0,a.kt)("p",null,"Downloading ",(0,a.kt)("a",{parentName:"p",href:"https://www.rust-lang.org"},"Rust")," is as easy as executing the\nfollowing command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n")),(0,a.kt)("p",null,"This will install ",(0,a.kt)("a",{parentName:"p",href:"https://rustup.rs"},"Rustup")," which is the installer for\n",(0,a.kt)("a",{parentName:"p",href:"https://rust-lang.org"},"Rust"),"."),(0,a.kt)("p",null,"With ",(0,a.kt)("a",{parentName:"p",href:"https://rust-lang.org"},"Rust"),", we can now build the\nIndy SDK from source."),(0,a.kt)("p",null,"First, clone the repository in a temporary directory:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"git clone https://github.com/hyperledger/indy-sdk\n")),(0,a.kt)("p",null,"Secondly, go to the correct directory"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"cd indy-sdk/libindy\n")),(0,a.kt)("p",null,"Third, build the library"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"cargo build --release\n")),(0,a.kt)("p",null,"Lastly, move the library to the correct location"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"sudo mv target/release/libindy.so /usr/lib/libindy.so\n")),(0,a.kt)("h3",{id:"confirm-installation"},"Confirm installation"),(0,a.kt)("p",null,"To see whether the Indy SDK is correctly installed on your system, run the following command and it should not error."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"npx -p @aries-framework/node@^0.3 is-indy-installed\n")))}b.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/da788397.738bc3cb.js b/assets/js/da788397.2b0b15fd.js similarity index 67% rename from assets/js/da788397.738bc3cb.js rename to assets/js/da788397.2b0b15fd.js index 9ab7c91f..97741908 100644 --- a/assets/js/da788397.738bc3cb.js +++ b/assets/js/da788397.2b0b15fd.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4281],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),u=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=u(e.components);return r.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),d=u(n),m=a,f=d["".concat(l,".").concat(m)]||d[m]||p[m]||o;return n?r.createElement(f,s(s({ref:t},c),{},{components:n})):r.createElement(f,s({ref:t},c))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[d]="string"==typeof e?e:a,s[1]=i;for(var u=2;u{n.d(t,{Z:()=>s});var r=n(7294),a=n(6010);const o={tabItem:"tabItem_Ymn6"};function s(e){let{children:t,hidden:n,className:s}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(o.tabItem,s),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var r=n(7462),a=n(7294),o=n(6010),s=n(2466),i=n(6550),l=n(1980),u=n(7392),c=n(12);function d(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function p(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??d(n);return function(e){const t=(0,u.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:n}=e;const r=(0,i.k6)(),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,l._X)(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 g(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,o=p(e),[s,i]=(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(!m({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 r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:o}))),[l,u]=f({queryString:n,groupId:r}),[d,g]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,o]=(0,c.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:r}),h=(()=>{const e=l??d;return m({value:e,tabValues:o})?e:null})();(0,a.useLayoutEffect)((()=>{h&&i(h)}),[h]);return{selectedValue:s,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);i(e),u(e),g(e)}),[u,g,o]),tabValues:o}}var h=n(2389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){let{className:t,block:n,selectedValue:i,selectValue:l,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:d}=(0,s.o5)(),p=e=>{const t=e.currentTarget,n=c.indexOf(t),r=u[n].value;r!==i&&(d(t),l(r))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},u.map((e=>{let{value:t,label:n,attributes:s}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:p},s,{className:(0,o.Z)("tabs__item",b.tabItem,s?.className,{"tabs__item--active":i===t})}),n??t)})))}function v(e){let{lazy:t,children:n,selectedValue:r}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function k(e){const t=g(e);return a.createElement("div",{className:(0,o.Z)("tabs-container",b.tabList)},a.createElement(y,(0,r.Z)({},e,t)),a.createElement(v,(0,r.Z)({},e,t)))}function w(e){const t=(0,h.Z)();return a.createElement(k,(0,r.Z)({key:String(t)},e))}},3423:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>f,frontMatter:()=>i,metadata:()=>u,toc:()=>d});var r=n(7462),a=(n(7294),n(3905)),o=n(4866),s=n(5162);const i={},l="AnonCreds",u={unversionedId:"getting-started/set-up/anoncreds",id:"getting-started/set-up/anoncreds",title:"AnonCreds",description:"The AnonCreds module provides functionality for issuing and verifying AnonCreds credentials in Credo. The AnonCreds implementation is based on AnonCreds RS, a direct implementation of the AnonCreds V1.0 specification that provides functionality like; creating a schema object, creating a credential definition object, creating a credential, verifying a proof presentation and much more.",source:"@site/guides/getting-started/set-up/anoncreds.md",sourceDirName:"getting-started/set-up",slug:"/getting-started/set-up/anoncreds",permalink:"/guides/0.5/getting-started/set-up/anoncreds",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Aries Askar",permalink:"/guides/0.5/getting-started/set-up/aries-askar"},next:{title:"Indy VDR",permalink:"/guides/0.5/getting-started/set-up/indy-vdr"}},c={},d=[{value:"Installing",id:"installing",level:3},{value:"Adding AnonCreds to the agent",id:"adding-anoncreds-to-the-agent",level:3},{value:"Configuration",id:"configuration",level:3}],p={toc:d},m="wrapper";function f(e){let{components:t,...n}=e;return(0,a.kt)(m,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"anoncreds"},"AnonCreds"),(0,a.kt)("p",null,"The AnonCreds module provides functionality for issuing and verifying ",(0,a.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-spec/"},"AnonCreds")," credentials in Credo. The AnonCreds implementation is based on ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/anoncreds-rs"},"AnonCreds RS"),", a direct implementation of the ",(0,a.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-spec/"},"AnonCreds V1.0 specification")," that provides functionality like; creating a schema object, creating a credential definition object, creating a credential, verifying a proof presentation and much more."),(0,a.kt)("h3",{id:"installing"},"Installing"),(0,a.kt)("p",null,"When using Credo with AnonCreds, there are a few extra dependencies that need to be installed. We need to install ",(0,a.kt)("inlineCode",{parentName:"p"},"@credo-ts/anoncreds")," package, which contains the interfaces, and ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/anoncreds-")," package which is an implementation which depends on a wrapper of anoncreds-rs. Currently there are bindings for Node.JS, as ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/anoncreds-nodejs"),", and React Native as ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperlegder/anoncreds-react-native"),"."),(0,a.kt)(o.Z,{mdxType:"Tabs"},(0,a.kt)(s.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @credo-ts/anoncreds@^0.5.0 @hyperledger/anoncreds-nodejs@^0.2.0\n"))),(0,a.kt)(s.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @credo-ts/anoncreds@^0.5.0 @hyperledger/anoncreds-react-native@^0.2.0\n")))),(0,a.kt)("h3",{id:"adding-anoncreds-to-the-agent"},"Adding AnonCreds to the agent"),(0,a.kt)("p",null,"After installing the dependencies, we should register the ",(0,a.kt)("inlineCode",{parentName:"p"},"AnonCredsModule")," on the agent."),(0,a.kt)(o.Z,{mdxType:"Tabs"},(0,a.kt)(s.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-anoncreds.ts section-1",showLineNumbers:!0,"set-up-anoncreds.ts":!0,"section-1":!0},""))),(0,a.kt)(s.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-anoncreds-rn.ts section-1",showLineNumbers:!0,"set-up-anoncreds-rn.ts":!0,"section-1":!0},"")))),(0,a.kt)("h3",{id:"configuration"},"Configuration"),(0,a.kt)("p",null,"As you can see, the AnonCreds module takes a list of registry modules. These modules will be used to resolve the AnonCreds objects. ",(0,a.kt)("a",{parentName:"p",href:"./indy-vdr"},"Indy VDR")," can be used as an AnonCreds registry for Hyperledger Indy networks, and ",(0,a.kt)("a",{parentName:"p",href:"./cheqd"},"Cheqd")," can be used as an AnonCreds registry for Cheqd networks."))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4281],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),u=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=u(e.components);return r.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),d=u(n),m=a,f=d["".concat(l,".").concat(m)]||d[m]||p[m]||o;return n?r.createElement(f,s(s({ref:t},c),{},{components:n})):r.createElement(f,s({ref:t},c))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[d]="string"==typeof e?e:a,s[1]=i;for(var u=2;u{n.d(t,{Z:()=>s});var r=n(7294),a=n(6010);const o={tabItem:"tabItem_Ymn6"};function s(e){let{children:t,hidden:n,className:s}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(o.tabItem,s),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var r=n(7462),a=n(7294),o=n(6010),s=n(2466),i=n(6550),l=n(1980),u=n(7392),c=n(12);function d(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function p(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??d(n);return function(e){const t=(0,u.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:n}=e;const r=(0,i.k6)(),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,l._X)(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 g(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,o=p(e),[s,i]=(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(!m({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 r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:o}))),[l,u]=f({queryString:n,groupId:r}),[d,g]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,o]=(0,c.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:r}),h=(()=>{const e=l??d;return m({value:e,tabValues:o})?e:null})();(0,a.useLayoutEffect)((()=>{h&&i(h)}),[h]);return{selectedValue:s,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);i(e),u(e),g(e)}),[u,g,o]),tabValues:o}}var h=n(2389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){let{className:t,block:n,selectedValue:i,selectValue:l,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:d}=(0,s.o5)(),p=e=>{const t=e.currentTarget,n=c.indexOf(t),r=u[n].value;r!==i&&(d(t),l(r))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},u.map((e=>{let{value:t,label:n,attributes:s}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:p},s,{className:(0,o.Z)("tabs__item",b.tabItem,s?.className,{"tabs__item--active":i===t})}),n??t)})))}function v(e){let{lazy:t,children:n,selectedValue:r}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function k(e){const t=g(e);return a.createElement("div",{className:(0,o.Z)("tabs-container",b.tabList)},a.createElement(y,(0,r.Z)({},e,t)),a.createElement(v,(0,r.Z)({},e,t)))}function w(e){const t=(0,h.Z)();return a.createElement(k,(0,r.Z)({key:String(t)},e))}},3423:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>f,frontMatter:()=>i,metadata:()=>u,toc:()=>d});var r=n(7462),a=(n(7294),n(3905)),o=n(4866),s=n(5162);const i={},l="AnonCreds",u={unversionedId:"getting-started/set-up/anoncreds",id:"getting-started/set-up/anoncreds",title:"AnonCreds",description:"The AnonCreds module provides functionality for issuing and verifying AnonCreds credentials in Credo. The AnonCreds implementation is based on AnonCreds RS, a direct implementation of the AnonCreds V1.0 specification that provides functionality like; creating a schema object, creating a credential definition object, creating a credential, verifying a proof presentation and much more.",source:"@site/guides/getting-started/set-up/anoncreds.md",sourceDirName:"getting-started/set-up",slug:"/getting-started/set-up/anoncreds",permalink:"/guides/getting-started/set-up/anoncreds",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Aries Askar",permalink:"/guides/getting-started/set-up/aries-askar"},next:{title:"Indy VDR",permalink:"/guides/getting-started/set-up/indy-vdr"}},c={},d=[{value:"Installing",id:"installing",level:3},{value:"Adding AnonCreds to the agent",id:"adding-anoncreds-to-the-agent",level:3},{value:"Configuration",id:"configuration",level:3}],p={toc:d},m="wrapper";function f(e){let{components:t,...n}=e;return(0,a.kt)(m,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"anoncreds"},"AnonCreds"),(0,a.kt)("p",null,"The AnonCreds module provides functionality for issuing and verifying ",(0,a.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-spec/"},"AnonCreds")," credentials in Credo. The AnonCreds implementation is based on ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/anoncreds-rs"},"AnonCreds RS"),", a direct implementation of the ",(0,a.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-spec/"},"AnonCreds V1.0 specification")," that provides functionality like; creating a schema object, creating a credential definition object, creating a credential, verifying a proof presentation and much more."),(0,a.kt)("h3",{id:"installing"},"Installing"),(0,a.kt)("p",null,"When using Credo with AnonCreds, there are a few extra dependencies that need to be installed. We need to install ",(0,a.kt)("inlineCode",{parentName:"p"},"@credo-ts/anoncreds")," package, which contains the interfaces, and ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/anoncreds-")," package which is an implementation which depends on a wrapper of anoncreds-rs. Currently there are bindings for Node.JS, as ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/anoncreds-nodejs"),", and React Native as ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperlegder/anoncreds-react-native"),"."),(0,a.kt)(o.Z,{mdxType:"Tabs"},(0,a.kt)(s.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @credo-ts/anoncreds@^0.5.0 @hyperledger/anoncreds-nodejs@^0.2.0\n"))),(0,a.kt)(s.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @credo-ts/anoncreds@^0.5.0 @hyperledger/anoncreds-react-native@^0.2.0\n")))),(0,a.kt)("h3",{id:"adding-anoncreds-to-the-agent"},"Adding AnonCreds to the agent"),(0,a.kt)("p",null,"After installing the dependencies, we should register the ",(0,a.kt)("inlineCode",{parentName:"p"},"AnonCredsModule")," on the agent."),(0,a.kt)(o.Z,{mdxType:"Tabs"},(0,a.kt)(s.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-anoncreds.ts section-1",showLineNumbers:!0,"set-up-anoncreds.ts":!0,"section-1":!0},""))),(0,a.kt)(s.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-anoncreds-rn.ts section-1",showLineNumbers:!0,"set-up-anoncreds-rn.ts":!0,"section-1":!0},"")))),(0,a.kt)("h3",{id:"configuration"},"Configuration"),(0,a.kt)("p",null,"As you can see, the AnonCreds module takes a list of registry modules. These modules will be used to resolve the AnonCreds objects. ",(0,a.kt)("a",{parentName:"p",href:"./indy-vdr"},"Indy VDR")," can be used as an AnonCreds registry for Hyperledger Indy networks, and ",(0,a.kt)("a",{parentName:"p",href:"./cheqd"},"Cheqd")," can be used as an AnonCreds registry for Cheqd networks."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/daf4660b.4f649d69.js b/assets/js/daf4660b.4f649d69.js new file mode 100644 index 00000000..6c79b78b --- /dev/null +++ b/assets/js/daf4660b.4f649d69.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8692],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=a.createContext({}),d=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=d(e.components);return a.createElement(s.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),p=d(n),m=o,h=p["".concat(s,".").concat(m)]||p[m]||u[m]||i;return n?a.createElement(h,r(r({ref:t},c),{},{components:n})):a.createElement(h,r({ref:t},c))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:o,r[1]=l;for(var d=2;d{n.d(t,{Z:()=>r});var a=n(7294),o=n(6010);const i={tabItem:"tabItem_Ymn6"};function r(e){let{children:t,hidden:n,className:r}=e;return a.createElement("div",{role:"tabpanel",className:(0,o.Z)(i.tabItem,r),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),o=n(7294),i=n(6010),r=n(2466),l=n(6550),s=n(1980),d=n(7392),c=n(12);function p(e){return function(e){return o.Children.map(e,(e=>{if((0,o.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:o}}=e;return{value:t,label:n,attributes:a,default:o}}))}function u(e){const{values:t,children:n}=e;return(0,o.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,d.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const a=(0,l.k6)(),i=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._X)(i),(0,o.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(a.location.search);t.set(i,e),a.replace({...a.location,search:t.toString()})}),[i,a])]}function g(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,i=u(e),[r,l]=(0,o.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(!m({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:i}))),[s,d]=h({queryString:n,groupId:a}),[p,g]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,i]=(0,c.Nk)(n);return[a,(0,o.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:a}),f=(()=>{const e=s??p;return m({value:e,tabValues:i})?e:null})();(0,o.useLayoutEffect)((()=>{f&&l(f)}),[f]);return{selectedValue:r,selectValue:(0,o.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);l(e),d(e),g(e)}),[d,g,i]),tabValues:i}}var f=n(2389);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:n,selectedValue:l,selectValue:s,tabValues:d}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,r.o5)(),u=e=>{const t=e.currentTarget,n=c.indexOf(t),a=d[n].value;a!==l&&(p(t),s(a))},m=e=>{let t=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return o.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},d.map((e=>{let{value:t,label:n,attributes:r}=e;return o.createElement("li",(0,a.Z)({role:"tab",tabIndex:l===t?0:-1,"aria-selected":l===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:u},r,{className:(0,i.Z)("tabs__item",v.tabItem,r?.className,{"tabs__item--active":l===t})}),n??t)})))}function b(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,o.cloneElement)(e,{className:"margin-top--md"}):null}return o.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,o.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function y(e){const t=g(e);return o.createElement("div",{className:(0,i.Z)("tabs-container",v.tabList)},o.createElement(k,(0,a.Z)({},e,t)),o.createElement(b,(0,a.Z)({},e,t)))}function w(e){const t=(0,f.Z)();return o.createElement(y,(0,a.Z)({key:String(t)},e))}},1618:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>l,metadata:()=>d,toc:()=>p});var a=n(7462),o=(n(7294),n(3905)),i=n(4866),r=n(5162);const l={},s="Migrating from AFJ 0.1.0 to 0.2.x",d={unversionedId:"updating/versions/0.1-to-0.2",id:"version-0.3/updating/versions/0.1-to-0.2",title:"Migrating from AFJ 0.1.0 to 0.2.x",description:"This document describes everything you need to know for updating AFJ 0.1.0 to 0.2.x. If you're not aware of how updating in AFJ works make sure to first read the guide on Updating AFJ.",source:"@site/versioned_docs/version-0.3/updating/versions/0.1-to-0.2.md",sourceDirName:"updating/versions",slug:"/updating/versions/0.1-to-0.2",permalink:"/guides/0.3/updating/versions/0.1-to-0.2",draft:!1,tags:[],version:"0.3",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Update Assistant",permalink:"/guides/0.3/updating/update-assistant"},next:{title:"Migrating from AFJ 0.2.x to 0.3.x",permalink:"/guides/0.3/updating/versions/0.2-to-0.3"}},c={},p=[{value:"React Native",id:"react-native",level:4},{value:"Node",id:"node",level:4},{value:"Breaking Code Changes",id:"breaking-code-changes",level:2},{value:"Credentials Module",id:"credentials-module",level:3},{value:"Module API Updates",id:"module-api-updates",level:4},{value:"0.1.0",id:"010",level:5},{value:"0.2.x",id:"02x",level:5},{value:"Data from Received Messages only Stored in Record after Accepting",id:"data-from-received-messages-only-stored-in-record-after-accepting",level:4},{value:"0.1.0",id:"010-1",level:5},{value:"0.2.x",id:"02x-1",level:5},{value:"Messages Extracted from Credential Record",id:"messages-extracted-from-credential-record",level:4},{value:"0.1.0",id:"010-2",level:5},{value:"0.2.x",id:"02x-2",level:5},{value:"Connections Module",id:"connections-module",level:3},{value:"Creating a Legacy Invitation",id:"creating-a-legacy-invitation",level:4},{value:"0.1.0",id:"010-3",level:5},{value:"0.2.x",id:"02x-3",level:5},{value:"Receiving a Legacy Invitation",id:"receiving-a-legacy-invitation",level:4},{value:"0.1.0",id:"010-4",level:5},{value:"0.2.x",id:"02x-4",level:5},{value:"Updating to use DidExchangeState",id:"updating-to-use-didexchangestate",level:4},{value:"Updating Custom Messages to the New Message Type Objects",id:"updating-custom-messages-to-the-new-message-type-objects",level:3},{value:"0.1.0",id:"010-5",level:4},{value:"0.2.x",id:"02x-5",level:4},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:2},{value:"Credential Metadata",id:"credential-metadata",level:3},{value:"0.1.0",id:"010-6",level:4},{value:"0.2.x",id:"02x-6",level:4},{value:"Migrate Credential Record Properties",id:"migrate-credential-record-properties",level:3},{value:"0.1.0",id:"010-7",level:4},{value:"0.2.x",id:"02x-7",level:4},{value:"Mediation Record Role",id:"mediation-record-role",level:3},{value:"Extracting Did Documents to Did Repository",id:"extracting-did-documents-to-did-repository",level:3},{value:"0.1.0",id:"010-8",level:4},{value:"0.2.x",id:"02x-8",level:4},{value:"Migrating to the Out of Band Record",id:"migrating-to-the-out-of-band-record",level:3},{value:"0.1.0",id:"010-9",level:4},{value:"0.2.x",id:"02x-9",level:4},{value:"Unifying Connection States and Roles",id:"unifying-connection-states-and-roles",level:3},{value:"0.1.0",id:"010-10",level:4},{value:"0.2.0",id:"020",level:4}],u={toc:p},m="wrapper";function h(e){let{components:t,...n}=e;return(0,o.kt)(m,(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"migrating-from-afj-010-to-02x"},"Migrating from AFJ 0.1.0 to 0.2.x"),(0,o.kt)("p",null,"This document describes everything you need to know for updating AFJ 0.1.0 to 0.2.x. If you're not aware of how updating in AFJ works make sure to first read the guide on ",(0,o.kt)("a",{parentName:"p",href:"/guides/updating/"},"Updating AFJ"),"."),(0,o.kt)("p",null,"First of all, update you dependencies to the 0.2.x versions. This will also update the needed peer depedencnies. ",(0,o.kt)("strong",{parentName:"p"},"Extension packages are not updated with this command"),". You need to update these manually, and make sure they're up to date with the latest version of AFJ."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"React Native",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/react-native@^0.2.0 @aries-framework/core@^0.2.0 indy-sdk-react-native@^0.2.0\n\n# or NPM\nnpn install @aries-framework/react-native@^0.2.0 @aries-framework/core@^0.2.0 indy-sdk-react-native@^0.2.0\n"))),(0,o.kt)(r.Z,{label:"Node",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/node@^0.2.0 @aries-framework/core@^0.2.0\n\n# or NPM\nnpm install @aries-framework/node@^0.2.0 @aries-framework/core@^0.2.0\n")))),(0,o.kt)("h2",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,o.kt)("p",null,"This section will list all breaking changes made to the public API of AFJ between version 0.1.0 and 0.2.0."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here (e.g. see ",(0,o.kt)("a",{parentName:"p",href:"#updating-custom-messages-to-the-new-message-type-objects"},"Updating Custom Messages to the New Message Type Objects"),"), but it is possible some breaking changes are not documented here (feel free to open PRs).")),(0,o.kt)("h3",{id:"credentials-module"},"Credentials Module"),(0,o.kt)("h4",{id:"module-api-updates"},"Module API Updates"),(0,o.kt)("p",null,"With the addition of the issue credential v2 protocol and the preparation for multiple attachment formats (to be added in a later release), we've made some big changes to the credentials module API. Most changes are related to structure, so updating your code to the new API should be straightforward."),(0,o.kt)("p",null,"Basically for all methods in the credential module you should take the following steps to update your code:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Move all function parameters into a single object. All module methods now take a single object that contain all properties."),(0,o.kt)("li",{parentName:"ol"},"For methods that initiate a protocol (starting from offer, proposal), you should pass ",(0,o.kt)("inlineCode",{parentName:"li"},"protocolVersion: 'v1'")," to indicate we should use the v1 protocol. (v2 is also supported, but this focuses on the breaking changes, not the new features)."),(0,o.kt)("li",{parentName:"ol"},"All indy specific attributes (e.g. credentialDefinitionId) should be passed in the ",(0,o.kt)("inlineCode",{parentName:"li"},"credentialFormats.indy")," object."),(0,o.kt)("li",{parentName:"ol"},"The preview should now be passed as only the preview attributes (the the full preview) and provided in the ",(0,o.kt)("inlineCode",{parentName:"li"},"credentialFormats.indy")," object.")),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.credentials.offerCredential('connectionId', {\n autoAcceptCredential: AutoAcceptCredential.Always,\n comment: 'hello',\n\n credentialDefinitionId: 'credentialDefinitionId',\n preview: new CredentialPreview({\n attributes: [new CredentialPreviewAttribute({ name: 'key', value: 'value' })],\n }),\n})\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.credentials.offerCredential({\n connectionId: 'connectionId',\n protocolVersion: 'v1',\n\n autoAcceptCredential: AutoAcceptCredential.Always,\n comment: 'hello',\n\n credentialFormats: {\n indy: {\n credentialDefinitionId: 'credentialDefinitionId',\n attributes: [{ name: 'key', value: 'value' }],\n },\n },\n})\n")))),(0,o.kt)("h4",{id:"data-from-received-messages-only-stored-in-record-after-accepting"},"Data from Received Messages only Stored in Record after Accepting"),(0,o.kt)("p",null,"Previously when we received a message from another connection we would store the relevant data from the exchange in the credential record. The values we would store were the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialDefinitionId")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"schemaId")," in the credential metadata, and the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialAttributes")," field."),(0,o.kt)("p",null,"Starting with AFJ 0.2.0 the values are not stored in the credential record until after the message content has been accepted (in the case of an offer this means after sending the request message). This is to avoid ambiguity of the values in the credential record. If I have sent a proposal and then receive an offer, should the credential record contain the values from the proposal or the values from the offer? The first one reflects our view on what the data should be, the second one reflects the latest data."),(0,o.kt)("p",null,"We decided to make the record properties always hold our view of what the data should be, and only update it after accepting the contents of a received message (either using auto accept, or by calling the ",(0,o.kt)("inlineCode",{parentName:"p"},"acceptXXX")," methods on the credential module)."),(0,o.kt)("p",null,"This is an important change and requires some updates to how you extract the relevant data from the offer (or other messages such the proposal). We've added a new ",(0,o.kt)("inlineCode",{parentName:"p"},"getFormatData")," method on the credentials module that allows you to retrieve the attributes and format data for all messages in an exchange. One of the advantages of this approach is that we don't have to store all relevant data in the credential record anymore, which helps when adding new formats that don't match with the attributes used for indy credentials. In addition, the return value for this method is the same whether v1 or v2 of the protocol is used. This means your code should only care about the credential format (indy in this case) and doesn't have to worry about the protocol version."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"agent.events.on(\n CredentialEventTypes.CredentialStateChanged,\n ({ payload: { credentialRecord } }) => {\n const indyCredentialMetadata = credentialRecord.metadata.get(CredentialMetadataKeys.IndyCredential)\n\n // Get credential definition id, schema id and attributes from offer\n const credentialDefinitionId = indyCredentialMetadata?.credentialDefinitionId\n const schemaId = indyCredentialMetadata?.schemaId\n const attributes = credentialRecord.credentialAttributes\n }\n)\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"agent.events.on(\n CredentialEventTypes.CredentialStateChanged,\n async ({ payload: { credentialRecord } }) => {\n const formatData = await agent.credentials.getFormatData(credentialRecord.id)\n\n // Get credential definition id, schema id and attributes from offer\n const credentialDefinitionId = formatData.offer?.indy?.cred_def_id\n const schemaId = formatData.offer?.indy?.schema_id\n const attributes = formatData.offerAttributes\n }\n)\n")),(0,o.kt)("p",null,"The return value of the ",(0,o.kt)("inlineCode",{parentName:"p"},"getFormatData")," method is fully typed an directly returns the format data as encoded in the attachment. It also returns the ",(0,o.kt)("inlineCode",{parentName:"p"},"proposalAttributes")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"offerAttributes")," values which contain the attributes for the indy credential. This is not part of the attachment data itself, but can be seen as the format data for the credential."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"{\n proposalAttributes: [{ name: 'key', value: 'value' mimeType: 'text/plain' }],\n proposal: {\n indy: { } // indy proposal as described in RFC 0592\n },\n offerAttributes: [{ name: 'key', value: 'value' mimeType: 'text/plain' }],\n offer: {\n indy: { } // indy offer as described in RFC 0592\n },\n request: {\n indy: { } // indy request as described in RFC 0592\n }\n credential: {\n indy: { } // indy credential as described in RFC 0592\n }\n}\n")))),(0,o.kt)("h4",{id:"messages-extracted-from-credential-record"},"Messages Extracted from Credential Record"),(0,o.kt)("p",null,"The DIDComm messages that were previously stored on the credential record, have been extracted to separate DIDComm message records. This makes it easier to work with multiple versions of the protocol internally, and keeps the credential exchange record agnostic of the protocol version. Instead of accessing the messages through the ",(0,o.kt)("inlineCode",{parentName:"p"},"proposalMessage"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"offerMessage"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"requestMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialMessage")," parameters, we now expose dedicated methods on the credentials module to retrieve the message."),(0,o.kt)("p",null,"With the addition of the v2 messages, all v1 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," while v2 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V2")," (",(0,o.kt)("inlineCode",{parentName:"p"},"V1ProposeCredentialMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"V2ProposeCredentialMessage"),"). If you were using these messages classes throughout your codebase, update them to use the ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," prefix."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const credentialRecord = await agent.credentials.getById('credentialRecordId')\n\nconst proposalMessage = credentialRecord.proposalMessage\nconst offerMessage = credentialRecord.offerMessage\nconst requestMessage = credentialRecord.requestMessage\nconst credentialMessage = credentialRecord.credentialMessage\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const credentialRecord = await agent.credentials.getById('credentialRecordId')\n\nconst proposalMessage = await agent.credentials.findProposalMessage('credentialRecordId')\nconst offerMessage = await agent.credentials.findOfferMessage('credentialRecordId')\nconst requestMessage = await agent.credentials.findRequestMessage('credentialRecordId')\nconst credentialMessage = await agent.credentials.findCredentialMessage('credentialRecordId')\n")),(0,o.kt)("p",null,"Because AFJ now also supports the issue credential v2 protocol, the return type of this protocol has been changed to ",(0,o.kt)("inlineCode",{parentName:"p"},"V1XXXMessage | V2XXXMessage | null"),". Take this into account when working with the messages."),(0,o.kt)("p",null,"You can check if a message is a specific version by using the ",(0,o.kt)("inlineCode",{parentName:"p"},"instanceof")," operator:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"if (proposalMessage instanceof V1ProposeCredentialMessage) {\n // do something\n}\n")),(0,o.kt)("p",null,"Shared properties (e.g. the proposal messages for v1 and v2 both have the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialPreview")," property) can be accessed without doing an instance check."))),(0,o.kt)("h3",{id:"connections-module"},"Connections Module"),(0,o.kt)("p",null,"Version 0.2.0 added support for the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md"},"Out of Band protocol")," with support for the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0023-did-exchange"},"DID Exchange protocol"),". Internally AFJ now uses out of band invitations for all connections, even if you're connecting using the old invitations from the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0160-connection-protocol"},"Connection protocol"),"."),(0,o.kt)("h4",{id:"creating-a-legacy-invitation"},"Creating a Legacy Invitation"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"createInvitation")," method on the connections module has been moved to the out of band module and renamed to ",(0,o.kt)("inlineCode",{parentName:"p"},"createLegacyInvitation"),". The method is not planned to be removed in the near future, the legacy merely indicates this will create an RFC 0160 connection invitation. Internally AFJ creates an out of band invitation and transforms it into a legacy invitation. If you want to create an out of band invitation instead, you should use ",(0,o.kt)("inlineCode",{parentName:"p"},"oob.createInvitation"),"."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { connectionRecord, invitation } = await agent.connections.createInvitation({\n /* config */\n})\n\nconst invitationUrl = invitation.toUrl({ domain: 'https://example.com' })\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { outOfBandRecord, invitation } = await agent.oob.createLegacyInvitation({\n /* config */\n})\n\nconst invitationUrl = invitation.toUrl({ domain: 'https://example.com' })\n")),(0,o.kt)("p",null,"Important thing to note here is that the ",(0,o.kt)("inlineCode",{parentName:"p"},"oob.createLegacyInvitation")," does not return a connection record, but rather an out of band record. Because out of band also supports connection-less scenarios, a connection record is not created until a connection request is received (or sent in the case of the invitee role)."),(0,o.kt)("p",null,"You can listen for connection state change events that are associated with a specific out of band id. This allows you to link a connection to an invitation you created."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"// Listen for connection state changed events associated with the out of band record\nagent.events.on(ConnectionEventTypes.ConnectionStateChanged, (event) => {\n if (event.payload.connectionRecord.outOfBandId === outOfBandRecord.id) {\n console.log(`Connection state changed for connection with out of band id ${outOfBandRecord.id}`)\n }\n})\n")),(0,o.kt)("p",null,"It is also possible to retrieve all connection records associated with an out of band invitation. Because of multi use invitations, there could be multiple connection records associated with a single out of band invitation. Instead of having a separate connection record that will always stay in the invited state, the out of band record will now handle the multi use capabilities of an invitation."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"// Retrieve all connections associated with an out of band id\nconst connections = await agent.connections.findAllByOutOfBandId(outOfBandRecord.id)\n")))),(0,o.kt)("h4",{id:"receiving-a-legacy-invitation"},"Receiving a Legacy Invitation"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"receiveInvitation")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"receiveInvitationFromUrl")," methods on the connections module have also been moved to the out of band module. Both methods support the new out of band invitations and the legacy RFC 0160 connection invitations. Internally AFJ converts the old invitations to out of band invitations."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const invitationUrl = 'https://example.com?c_i=eyXXX'\n\n// Receive invitation directly from url\nconst connectionRecord = await agent.connections.receiveInvitationFromUrl(invitationUrl, {\n /* config */\n})\n\n// Parse invitation and receive invitation\nconst parsedInvitation = await ConnectionInvitationMessage.fromUrl(invitationUrl)\nconst connectionRecord = await agent.connections.receiveInvitation(parsedInvitation, {\n /* config */\n})\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const invitationUrl = 'https://example.com?c_i=eyXXX'\n\n// Receive invitation directly from url\nconst { outOfBandRecord, connectionRecord } = await agent.oob.receiveInvitationFromUrl(invitationUrl, {\n /* config */\n})\n\n// Parse invitation and receive invitation\nconst parsedInvitation = await agent.oob.parseInvitation(invitationUrl)\nconst secondConnectionRecord = await agent.oob.receiveInvitation(parsedInvitation, {\n /* config */\n})\n")),(0,o.kt)("p",null,"The new receive invitation methods on the out of band module won't always return a connection record anymore. The out of band invitation may not contain any handshake protocols. In the case of receiving a connection invitation you will always receive a connection record though, as you can't use it for connection-less invitations."))),(0,o.kt)("h4",{id:"updating-to-use-didexchangestate"},"Updating to use ",(0,o.kt)("inlineCode",{parentName:"h4"},"DidExchangeState")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," that was previously used for the state of the ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionRecord")," has been changed to use the ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," for both connections made using the RFC 0160 Connection Protocol, as well as the RFC 0023 DID Exchange Protocol."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," has the following values:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.Start"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.InvitationSent"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.InvitationReceived"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.RequestSent"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.RequestReceived"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.ResponseSent"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.ResponseReceived"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.Abandoned"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.Completed"))),(0,o.kt)("p",null,"If you still need to access the old ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," you can do so by accessing the computed ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionRecord.rfc0160State")," property. This will return the old ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," value."),(0,o.kt)("h3",{id:"updating-custom-messages-to-the-new-message-type-objects"},"Updating Custom Messages to the New Message Type Objects"),(0,o.kt)("p",null,"Although this isn't a breaking change to the public API of the framework, it is something that you will need to take into account when creating custom modules. Starting from AFJ 0.2.0 we now support handling messages with different minor versions (e.g. receive a message with ",(0,o.kt)("inlineCode",{parentName:"p"},"@type")," version 1.1 while we only support 1.0). With this change messages must now declare the message type as an ",(0,o.kt)("inlineCode",{parentName:"p"},"ParsedMessageType")," object. We've added an ",(0,o.kt)("inlineCode",{parentName:"p"},"parseMessageType")," util method that can help with this."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { AgentMessage } from '@aries-framework/core'\nimport { Equals } from 'class-validator'\n\nclass MyMessage extends AgentMessage {\n @Equals(MyMessage.type)\n public readonly type = MyMessage.type\n public static readonly type = 'https://didcomm.org/my-protocol/1.0/my-type'\n}\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { AgentMessage, IsValidMessageType, parseMessageType } from '@aries-framework/core'\nimport { Equals } from 'class-validator'\n\nclass MyMessage extends AgentMessage {\n // use IsValidMessageType instead of Equals\n @IsValidMessageType(MyMessage.type)\n // append .messageTypeUri to get the actual URI when instantiating a message\n public readonly type = MyMessage.type.messageTypeUri\n // use parseMessageType to get the message type object from a type. You can declare the object yourself, but this is the recommended way\n public static readonly type = parseMessageType('https://didcomm.org/my-protocol/1.0/my-type')\n}\n")))),(0,o.kt)("h2",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,o.kt)("p",null,"The 0.2.0 release is heavy on breaking changes to the storage format. This is not what we intend to do with every release. But as there's not that many people yet using the framework in production, and there were a lot of changes needed to keep the API straightforward, we decided to bundle a lot of breaking changes in this one release."),(0,o.kt)("p",null,"Below all breaking storage changes are explained in as much detail as possible. The update assistant provides all tools to migrate without a hassle, but it is important to know what has changed. All examples only show the keys that have changed, unrelated keys in records have been omitted."),(0,o.kt)("p",null,"See the ",(0,o.kt)("a",{parentName:"p",href:"/guides/updating/update-assistant"},"Update Assistant")," documentation for a guide on how to use the update assistant."),(0,o.kt)("p",null,"The following config can be provided to the update assistant to migrate from 0.1.0 to 0.2.0:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "v0_1ToV0_2": {\n "mediationRoleUpdateStrategy": ""\n }\n}\n')),(0,o.kt)("h3",{id:"credential-metadata"},"Credential Metadata"),(0,o.kt)("p",null,"The credential record had a custom ",(0,o.kt)("inlineCode",{parentName:"p"},"metadata")," property in pre-0.1.0 storage that contained the ",(0,o.kt)("inlineCode",{parentName:"p"},"requestMetadata"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"schemaId")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialDefinition")," properties. Later a generic metadata API was added that only allows objects to be stored. Therefore the properties were moved into a different structure."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "requestMetadata": ,\n "schemaId": "",\n "credentialDefinitionId": ""\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "_internal/indyRequest": ,\n "_internal/indyCredential": {\n "schemaId": "",\n "credentialDefinitionId": ""\n }\n}\n')),(0,o.kt)("p",null,"Accessing the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialDefinitionId")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"schemaId")," properties will now be done by retrieving the ",(0,o.kt)("inlineCode",{parentName:"p"},"CredentialMetadataKeys.IndyCredential")," metadata key."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const indyCredential = credentialRecord.metadata.get(CredentialMetadataKeys.IndyCredential)\n\n// both properties are optional\nindyCredential?.credentialDefinitionId\nindyCredential?.schemaId\n")))),(0,o.kt)("h3",{id:"migrate-credential-record-properties"},"Migrate Credential Record Properties"),(0,o.kt)("p",null,"In 0.2.0 the v1 DIDComm messages have been moved out of the credential record into separate records using the DidCommMessageRepository. The migration scripts extracts all messages (proposalMessage, offerMessage, requestMessage, credentialMessage) and moves them into the DidCommMessageRepository."),(0,o.kt)("p",null,"With the addition of support for different protocol versions the credential record now stores the protocol version. With the addition of issue credential v2 support, other credential formats than indy can be used, and multiple credentials can be issued at once. To account for this the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialId")," has been replaced by the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentials")," array. This is an array of objects containing the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialRecordId")," and the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialRecordType"),". For all current credentials the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialRecordType")," will always be ",(0,o.kt)("inlineCode",{parentName:"p"},"indy"),"."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "credentialId": "09e46da9-a575-4909-b016-040e96c3c539",\n "proposalMessage": { ... },\n "offerMessage": { ... },\n "requestMessage": { ... },\n "credentialMessage": { ... },\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "protocolVersion": "v1",\n "credentials": [\n {\n "credentialRecordId": "09e46da9-a575-4909-b016-040e96c3c539",\n "credentialRecordType": "indy"\n }\n ]\n}\n')))),(0,o.kt)("h3",{id:"mediation-record-role"},"Mediation Record Role"),(0,o.kt)("p",null,"The role in the mediation record was always being set to ",(0,o.kt)("inlineCode",{parentName:"p"},"MediationRole.Mediator")," for both mediators and recipients. This didn't cause any issues, but would return the wrong role for recipients."),(0,o.kt)("p",null,"In 0.2 a check is added to make sure the role of a mediation record matches with actions (e.g. a recipient can't grant mediation), which means it will throw an error if the role is not set correctly."),(0,o.kt)("p",null,"Because it's not always possible detect whether the role should actually be mediator or recipient, a number of configuration options are provided on how the role should be updated using the ",(0,o.kt)("inlineCode",{parentName:"p"},"v0_1ToV0_2.mediationRoleUpdateStrategy")," option:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"allMediator"),": The role is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Mediator")," for both mediators and recipients"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"allRecipient"),": The role is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Recipient")," for both mediators and recipients"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"recipientIfEndpoint")," (",(0,o.kt)("strong",{parentName:"li"},"default"),"): The role is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Recipient")," if their is an ",(0,o.kt)("inlineCode",{parentName:"li"},"endpoint")," configured on the record. The endpoint is not set when running as a mediator. There is one case where this could be problematic when the role should be recipient, if the mediation grant hasn't actually occurred (meaning the endpoint is not set). This is probably the best approach\notherwise it is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Mediator")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"doNotChange"),": The role is not changed")),(0,o.kt)("p",null,"Most agents only act as either the role of mediator or recipient, in which case the ",(0,o.kt)("inlineCode",{parentName:"p"},"allMediator")," or ",(0,o.kt)("inlineCode",{parentName:"p"},"allRecipient")," configuration is the most appropriate. If your agent acts as both a recipient and mediator, the ",(0,o.kt)("inlineCode",{parentName:"p"},"recipientIfEndpoint")," configuration is the most appropriate. The ",(0,o.kt)("inlineCode",{parentName:"p"},"doNotChange")," options is not recommended and can lead to errors if the role is not set correctly."),(0,o.kt)("h3",{id:"extracting-did-documents-to-did-repository"},"Extracting Did Documents to Did Repository"),(0,o.kt)("p",null,"The connection record previously stored both did documents from a connection in the connection record itself. Version 0.2.0 added a generic did storage that can be used for numerous usages, one of which is the storage of did documents for connection records."),(0,o.kt)("p",null,"The migration script extracts the did documents from the ",(0,o.kt)("inlineCode",{parentName:"p"},"didDoc")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"theirDidDoc")," properties from the connection record, updates them to did documents compliant with the did core spec, and stores them in the did repository. By doing so it also updates the unqualified DIDs in the ",(0,o.kt)("inlineCode",{parentName:"p"},"did")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"theirDid")," fields generated by the indy-sdk to fully qualified ",(0,o.kt)("inlineCode",{parentName:"p"},"did:peer")," DIDs compliant with the ",(0,o.kt)("a",{parentName:"p",href:"https://identity.foundation/peer-did-method-spec/"},"Peer DID Method Specification"),"."),(0,o.kt)("p",null,"To account for the fact that the mechanism to migrate legacy did document to peer did documents is not defined yet, the legacy did and did document are stored in the did record metadata. This will be deleted later if we can be certain the did doc conversion to a ",(0,o.kt)("inlineCode",{parentName:"p"},"did:peer")," did document is correct."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "did": "BBPoJqRKatdcfLEAFL7exC",\n "theirDid": "UppcJ5APts7ot5WX25943F",\n "verkey": "GAb4NUvpBcHVCvtP45vTVa5Bp74vFg3iXzdp1Gbd68Wf",\n "didDoc": ,\n "theirDidDoc": ,\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "did": "did:peer:1zQmXUaPPhPCbUVZ3hGYmQmGxWTwyDfhqESXCpMFhKaF9Y2A",\n "theirDid": "did:peer:1zQmZMygzYqNwU6Uhmewx5Xepf2VLp5S4HLSwwgf2aiKZuwa"\n}\n')))),(0,o.kt)("h3",{id:"migrating-to-the-out-of-band-record"},"Migrating to the Out of Band Record"),(0,o.kt)("p",null,"With the addition of the out of band protocol, invitations are now stored in the ",(0,o.kt)("inlineCode",{parentName:"p"},"OutOfBandRecord"),". In addition a new field ",(0,o.kt)("inlineCode",{parentName:"p"},"invitationDid")," is added to the connection record that is generated based on the invitation service or did. This allows to reuse existing connections."),(0,o.kt)("p",null,"The migration script extracts the invitation and other relevant data into a separate ",(0,o.kt)("inlineCode",{parentName:"p"},"OutOfBandRecord"),". By doing so it converts the old connection protocol invitation into the new Out of band invitation message. Based on the service or did of the invitation, the ",(0,o.kt)("inlineCode",{parentName:"p"},"invitationDid")," is populated."),(0,o.kt)("p",null,"Previously when creating a multi use invitation, a connection record would be created with the ",(0,o.kt)("inlineCode",{parentName:"p"},"multiUseInvitation")," set to true. The connection record would always be in state ",(0,o.kt)("inlineCode",{parentName:"p"},"invited"),". If a request for the multi use invitation came in, a new connection record would be created. With the addition of the out of band module, no connection records are created until a request is received. So for multi use invitation this means that the connection record with multiUseInvitation=true will be deleted, and instead all connections created using that out of band invitation will contain the ",(0,o.kt)("inlineCode",{parentName:"p"},"outOfBandId")," of the multi use invitation."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "invitation": {\n "@type": "https://didcomm.org/connections/1.0/invitation",\n "@id": "04a2c382-999e-4de9-a1d2-9dec0b2fa5e4",\n "recipientKeys": ["E6D1m3eERqCueX4ZgMCY14B4NceAr6XP2HyVqt55gDhu"],\n "serviceEndpoint": "https://example.com",\n "label": "test"\n },\n "multiUseInvitation": "false"\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "invitationDid": "did:peer:2.Ez6MksYU4MHtfmNhNm1uGMvANr9j4CBv2FymjiJtRgA36bSVH.SeyJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbSJ9",\n "outOfBandId": "04a2c382-999e-4de9-a1d2-9dec0b2fa5e4"\n}\n')))),(0,o.kt)("h3",{id:"unifying-connection-states-and-roles"},"Unifying Connection States and Roles"),(0,o.kt)("p",null,"With the addition of the did exchange protocol there are now two states and roles related to the connection record; for the did exchange protocol and for the connection protocol. To keep it easy to work with the connection record, all state and role values are updated to those of the ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeRole")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," enums."),(0,o.kt)("p",null,"The migration script transforms all connection record state and role values to their respective values of the ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeRole")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," enums. For convenience a getter\nproperty ",(0,o.kt)("inlineCode",{parentName:"p"},"rfc0160ConnectionState")," is added to the connection record which returns the ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," value."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "state": "invited",\n "role": "inviter"\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.0",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "state": "invitation-sent",\n "role": "responder"\n}\n')))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/daf4660b.999a8cea.js b/assets/js/daf4660b.999a8cea.js deleted file mode 100644 index b3aee185..00000000 --- a/assets/js/daf4660b.999a8cea.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8692],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=a.createContext({}),d=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=d(e.components);return a.createElement(s.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),p=d(n),m=o,h=p["".concat(s,".").concat(m)]||p[m]||u[m]||i;return n?a.createElement(h,r(r({ref:t},c),{},{components:n})):a.createElement(h,r({ref:t},c))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:o,r[1]=l;for(var d=2;d{n.d(t,{Z:()=>r});var a=n(7294),o=n(6010);const i={tabItem:"tabItem_Ymn6"};function r(e){let{children:t,hidden:n,className:r}=e;return a.createElement("div",{role:"tabpanel",className:(0,o.Z)(i.tabItem,r),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),o=n(7294),i=n(6010),r=n(2466),l=n(6550),s=n(1980),d=n(7392),c=n(12);function p(e){return function(e){return o.Children.map(e,(e=>{if((0,o.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:o}}=e;return{value:t,label:n,attributes:a,default:o}}))}function u(e){const{values:t,children:n}=e;return(0,o.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,d.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const a=(0,l.k6)(),i=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._X)(i),(0,o.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(a.location.search);t.set(i,e),a.replace({...a.location,search:t.toString()})}),[i,a])]}function g(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,i=u(e),[r,l]=(0,o.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(!m({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:i}))),[s,d]=h({queryString:n,groupId:a}),[p,g]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,i]=(0,c.Nk)(n);return[a,(0,o.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:a}),f=(()=>{const e=s??p;return m({value:e,tabValues:i})?e:null})();(0,o.useLayoutEffect)((()=>{f&&l(f)}),[f]);return{selectedValue:r,selectValue:(0,o.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);l(e),d(e),g(e)}),[d,g,i]),tabValues:i}}var f=n(2389);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:n,selectedValue:l,selectValue:s,tabValues:d}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,r.o5)(),u=e=>{const t=e.currentTarget,n=c.indexOf(t),a=d[n].value;a!==l&&(p(t),s(a))},m=e=>{let t=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return o.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},d.map((e=>{let{value:t,label:n,attributes:r}=e;return o.createElement("li",(0,a.Z)({role:"tab",tabIndex:l===t?0:-1,"aria-selected":l===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:u},r,{className:(0,i.Z)("tabs__item",v.tabItem,r?.className,{"tabs__item--active":l===t})}),n??t)})))}function b(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,o.cloneElement)(e,{className:"margin-top--md"}):null}return o.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,o.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function y(e){const t=g(e);return o.createElement("div",{className:(0,i.Z)("tabs-container",v.tabList)},o.createElement(k,(0,a.Z)({},e,t)),o.createElement(b,(0,a.Z)({},e,t)))}function w(e){const t=(0,f.Z)();return o.createElement(y,(0,a.Z)({key:String(t)},e))}},1618:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>l,metadata:()=>d,toc:()=>p});var a=n(7462),o=(n(7294),n(3905)),i=n(4866),r=n(5162);const l={},s="Migrating from AFJ 0.1.0 to 0.2.x",d={unversionedId:"updating/versions/0.1-to-0.2",id:"version-0.3/updating/versions/0.1-to-0.2",title:"Migrating from AFJ 0.1.0 to 0.2.x",description:"This document describes everything you need to know for updating AFJ 0.1.0 to 0.2.x. If you're not aware of how updating in AFJ works make sure to first read the guide on Updating AFJ.",source:"@site/versioned_docs/version-0.3/updating/versions/0.1-to-0.2.md",sourceDirName:"updating/versions",slug:"/updating/versions/0.1-to-0.2",permalink:"/guides/0.3/updating/versions/0.1-to-0.2",draft:!1,tags:[],version:"0.3",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Update Assistant",permalink:"/guides/0.3/updating/update-assistant"},next:{title:"Migrating from AFJ 0.2.x to 0.3.x",permalink:"/guides/0.3/updating/versions/0.2-to-0.3"}},c={},p=[{value:"React Native",id:"react-native",level:4},{value:"Node",id:"node",level:4},{value:"Breaking Code Changes",id:"breaking-code-changes",level:2},{value:"Credentials Module",id:"credentials-module",level:3},{value:"Module API Updates",id:"module-api-updates",level:4},{value:"0.1.0",id:"010",level:5},{value:"0.2.x",id:"02x",level:5},{value:"Data from Received Messages only Stored in Record after Accepting",id:"data-from-received-messages-only-stored-in-record-after-accepting",level:4},{value:"0.1.0",id:"010-1",level:5},{value:"0.2.x",id:"02x-1",level:5},{value:"Messages Extracted from Credential Record",id:"messages-extracted-from-credential-record",level:4},{value:"0.1.0",id:"010-2",level:5},{value:"0.2.x",id:"02x-2",level:5},{value:"Connections Module",id:"connections-module",level:3},{value:"Creating a Legacy Invitation",id:"creating-a-legacy-invitation",level:4},{value:"0.1.0",id:"010-3",level:5},{value:"0.2.x",id:"02x-3",level:5},{value:"Receiving a Legacy Invitation",id:"receiving-a-legacy-invitation",level:4},{value:"0.1.0",id:"010-4",level:5},{value:"0.2.x",id:"02x-4",level:5},{value:"Updating to use DidExchangeState",id:"updating-to-use-didexchangestate",level:4},{value:"Updating Custom Messages to the New Message Type Objects",id:"updating-custom-messages-to-the-new-message-type-objects",level:3},{value:"0.1.0",id:"010-5",level:4},{value:"0.2.x",id:"02x-5",level:4},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:2},{value:"Credential Metadata",id:"credential-metadata",level:3},{value:"0.1.0",id:"010-6",level:4},{value:"0.2.x",id:"02x-6",level:4},{value:"Migrate Credential Record Properties",id:"migrate-credential-record-properties",level:3},{value:"0.1.0",id:"010-7",level:4},{value:"0.2.x",id:"02x-7",level:4},{value:"Mediation Record Role",id:"mediation-record-role",level:3},{value:"Extracting Did Documents to Did Repository",id:"extracting-did-documents-to-did-repository",level:3},{value:"0.1.0",id:"010-8",level:4},{value:"0.2.x",id:"02x-8",level:4},{value:"Migrating to the Out of Band Record",id:"migrating-to-the-out-of-band-record",level:3},{value:"0.1.0",id:"010-9",level:4},{value:"0.2.x",id:"02x-9",level:4},{value:"Unifying Connection States and Roles",id:"unifying-connection-states-and-roles",level:3},{value:"0.1.0",id:"010-10",level:4},{value:"0.2.0",id:"020",level:4}],u={toc:p},m="wrapper";function h(e){let{components:t,...n}=e;return(0,o.kt)(m,(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"migrating-from-afj-010-to-02x"},"Migrating from AFJ 0.1.0 to 0.2.x"),(0,o.kt)("p",null,"This document describes everything you need to know for updating AFJ 0.1.0 to 0.2.x. If you're not aware of how updating in AFJ works make sure to first read the guide on ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.5/updating/"},"Updating AFJ"),"."),(0,o.kt)("p",null,"First of all, update you dependencies to the 0.2.x versions. This will also update the needed peer depedencnies. ",(0,o.kt)("strong",{parentName:"p"},"Extension packages are not updated with this command"),". You need to update these manually, and make sure they're up to date with the latest version of AFJ."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"React Native",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/react-native@^0.2.0 @aries-framework/core@^0.2.0 indy-sdk-react-native@^0.2.0\n\n# or NPM\nnpn install @aries-framework/react-native@^0.2.0 @aries-framework/core@^0.2.0 indy-sdk-react-native@^0.2.0\n"))),(0,o.kt)(r.Z,{label:"Node",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/node@^0.2.0 @aries-framework/core@^0.2.0\n\n# or NPM\nnpm install @aries-framework/node@^0.2.0 @aries-framework/core@^0.2.0\n")))),(0,o.kt)("h2",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,o.kt)("p",null,"This section will list all breaking changes made to the public API of AFJ between version 0.1.0 and 0.2.0."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here (e.g. see ",(0,o.kt)("a",{parentName:"p",href:"#updating-custom-messages-to-the-new-message-type-objects"},"Updating Custom Messages to the New Message Type Objects"),"), but it is possible some breaking changes are not documented here (feel free to open PRs).")),(0,o.kt)("h3",{id:"credentials-module"},"Credentials Module"),(0,o.kt)("h4",{id:"module-api-updates"},"Module API Updates"),(0,o.kt)("p",null,"With the addition of the issue credential v2 protocol and the preparation for multiple attachment formats (to be added in a later release), we've made some big changes to the credentials module API. Most changes are related to structure, so updating your code to the new API should be straightforward."),(0,o.kt)("p",null,"Basically for all methods in the credential module you should take the following steps to update your code:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Move all function parameters into a single object. All module methods now take a single object that contain all properties."),(0,o.kt)("li",{parentName:"ol"},"For methods that initiate a protocol (starting from offer, proposal), you should pass ",(0,o.kt)("inlineCode",{parentName:"li"},"protocolVersion: 'v1'")," to indicate we should use the v1 protocol. (v2 is also supported, but this focuses on the breaking changes, not the new features)."),(0,o.kt)("li",{parentName:"ol"},"All indy specific attributes (e.g. credentialDefinitionId) should be passed in the ",(0,o.kt)("inlineCode",{parentName:"li"},"credentialFormats.indy")," object."),(0,o.kt)("li",{parentName:"ol"},"The preview should now be passed as only the preview attributes (the the full preview) and provided in the ",(0,o.kt)("inlineCode",{parentName:"li"},"credentialFormats.indy")," object.")),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.credentials.offerCredential('connectionId', {\n autoAcceptCredential: AutoAcceptCredential.Always,\n comment: 'hello',\n\n credentialDefinitionId: 'credentialDefinitionId',\n preview: new CredentialPreview({\n attributes: [new CredentialPreviewAttribute({ name: 'key', value: 'value' })],\n }),\n})\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"await agent.credentials.offerCredential({\n connectionId: 'connectionId',\n protocolVersion: 'v1',\n\n autoAcceptCredential: AutoAcceptCredential.Always,\n comment: 'hello',\n\n credentialFormats: {\n indy: {\n credentialDefinitionId: 'credentialDefinitionId',\n attributes: [{ name: 'key', value: 'value' }],\n },\n },\n})\n")))),(0,o.kt)("h4",{id:"data-from-received-messages-only-stored-in-record-after-accepting"},"Data from Received Messages only Stored in Record after Accepting"),(0,o.kt)("p",null,"Previously when we received a message from another connection we would store the relevant data from the exchange in the credential record. The values we would store were the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialDefinitionId")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"schemaId")," in the credential metadata, and the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialAttributes")," field."),(0,o.kt)("p",null,"Starting with AFJ 0.2.0 the values are not stored in the credential record until after the message content has been accepted (in the case of an offer this means after sending the request message). This is to avoid ambiguity of the values in the credential record. If I have sent a proposal and then receive an offer, should the credential record contain the values from the proposal or the values from the offer? The first one reflects our view on what the data should be, the second one reflects the latest data."),(0,o.kt)("p",null,"We decided to make the record properties always hold our view of what the data should be, and only update it after accepting the contents of a received message (either using auto accept, or by calling the ",(0,o.kt)("inlineCode",{parentName:"p"},"acceptXXX")," methods on the credential module)."),(0,o.kt)("p",null,"This is an important change and requires some updates to how you extract the relevant data from the offer (or other messages such the proposal). We've added a new ",(0,o.kt)("inlineCode",{parentName:"p"},"getFormatData")," method on the credentials module that allows you to retrieve the attributes and format data for all messages in an exchange. One of the advantages of this approach is that we don't have to store all relevant data in the credential record anymore, which helps when adding new formats that don't match with the attributes used for indy credentials. In addition, the return value for this method is the same whether v1 or v2 of the protocol is used. This means your code should only care about the credential format (indy in this case) and doesn't have to worry about the protocol version."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"agent.events.on(\n CredentialEventTypes.CredentialStateChanged,\n ({ payload: { credentialRecord } }) => {\n const indyCredentialMetadata = credentialRecord.metadata.get(CredentialMetadataKeys.IndyCredential)\n\n // Get credential definition id, schema id and attributes from offer\n const credentialDefinitionId = indyCredentialMetadata?.credentialDefinitionId\n const schemaId = indyCredentialMetadata?.schemaId\n const attributes = credentialRecord.credentialAttributes\n }\n)\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"agent.events.on(\n CredentialEventTypes.CredentialStateChanged,\n async ({ payload: { credentialRecord } }) => {\n const formatData = await agent.credentials.getFormatData(credentialRecord.id)\n\n // Get credential definition id, schema id and attributes from offer\n const credentialDefinitionId = formatData.offer?.indy?.cred_def_id\n const schemaId = formatData.offer?.indy?.schema_id\n const attributes = formatData.offerAttributes\n }\n)\n")),(0,o.kt)("p",null,"The return value of the ",(0,o.kt)("inlineCode",{parentName:"p"},"getFormatData")," method is fully typed an directly returns the format data as encoded in the attachment. It also returns the ",(0,o.kt)("inlineCode",{parentName:"p"},"proposalAttributes")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"offerAttributes")," values which contain the attributes for the indy credential. This is not part of the attachment data itself, but can be seen as the format data for the credential."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"{\n proposalAttributes: [{ name: 'key', value: 'value' mimeType: 'text/plain' }],\n proposal: {\n indy: { } // indy proposal as described in RFC 0592\n },\n offerAttributes: [{ name: 'key', value: 'value' mimeType: 'text/plain' }],\n offer: {\n indy: { } // indy offer as described in RFC 0592\n },\n request: {\n indy: { } // indy request as described in RFC 0592\n }\n credential: {\n indy: { } // indy credential as described in RFC 0592\n }\n}\n")))),(0,o.kt)("h4",{id:"messages-extracted-from-credential-record"},"Messages Extracted from Credential Record"),(0,o.kt)("p",null,"The DIDComm messages that were previously stored on the credential record, have been extracted to separate DIDComm message records. This makes it easier to work with multiple versions of the protocol internally, and keeps the credential exchange record agnostic of the protocol version. Instead of accessing the messages through the ",(0,o.kt)("inlineCode",{parentName:"p"},"proposalMessage"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"offerMessage"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"requestMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialMessage")," parameters, we now expose dedicated methods on the credentials module to retrieve the message."),(0,o.kt)("p",null,"With the addition of the v2 messages, all v1 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," while v2 messages have been prefixed with ",(0,o.kt)("inlineCode",{parentName:"p"},"V2")," (",(0,o.kt)("inlineCode",{parentName:"p"},"V1ProposeCredentialMessage")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"V2ProposeCredentialMessage"),"). If you were using these messages classes throughout your codebase, update them to use the ",(0,o.kt)("inlineCode",{parentName:"p"},"V1")," prefix."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const credentialRecord = await agent.credentials.getById('credentialRecordId')\n\nconst proposalMessage = credentialRecord.proposalMessage\nconst offerMessage = credentialRecord.offerMessage\nconst requestMessage = credentialRecord.requestMessage\nconst credentialMessage = credentialRecord.credentialMessage\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const credentialRecord = await agent.credentials.getById('credentialRecordId')\n\nconst proposalMessage = await agent.credentials.findProposalMessage('credentialRecordId')\nconst offerMessage = await agent.credentials.findOfferMessage('credentialRecordId')\nconst requestMessage = await agent.credentials.findRequestMessage('credentialRecordId')\nconst credentialMessage = await agent.credentials.findCredentialMessage('credentialRecordId')\n")),(0,o.kt)("p",null,"Because AFJ now also supports the issue credential v2 protocol, the return type of this protocol has been changed to ",(0,o.kt)("inlineCode",{parentName:"p"},"V1XXXMessage | V2XXXMessage | null"),". Take this into account when working with the messages."),(0,o.kt)("p",null,"You can check if a message is a specific version by using the ",(0,o.kt)("inlineCode",{parentName:"p"},"instanceof")," operator:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"if (proposalMessage instanceof V1ProposeCredentialMessage) {\n // do something\n}\n")),(0,o.kt)("p",null,"Shared properties (e.g. the proposal messages for v1 and v2 both have the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialPreview")," property) can be accessed without doing an instance check."))),(0,o.kt)("h3",{id:"connections-module"},"Connections Module"),(0,o.kt)("p",null,"Version 0.2.0 added support for the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md"},"Out of Band protocol")," with support for the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0023-did-exchange"},"DID Exchange protocol"),". Internally AFJ now uses out of band invitations for all connections, even if you're connecting using the old invitations from the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/tree/main/features/0160-connection-protocol"},"Connection protocol"),"."),(0,o.kt)("h4",{id:"creating-a-legacy-invitation"},"Creating a Legacy Invitation"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"createInvitation")," method on the connections module has been moved to the out of band module and renamed to ",(0,o.kt)("inlineCode",{parentName:"p"},"createLegacyInvitation"),". The method is not planned to be removed in the near future, the legacy merely indicates this will create an RFC 0160 connection invitation. Internally AFJ creates an out of band invitation and transforms it into a legacy invitation. If you want to create an out of band invitation instead, you should use ",(0,o.kt)("inlineCode",{parentName:"p"},"oob.createInvitation"),"."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { connectionRecord, invitation } = await agent.connections.createInvitation({\n /* config */\n})\n\nconst invitationUrl = invitation.toUrl({ domain: 'https://example.com' })\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const { outOfBandRecord, invitation } = await agent.oob.createLegacyInvitation({\n /* config */\n})\n\nconst invitationUrl = invitation.toUrl({ domain: 'https://example.com' })\n")),(0,o.kt)("p",null,"Important thing to note here is that the ",(0,o.kt)("inlineCode",{parentName:"p"},"oob.createLegacyInvitation")," does not return a connection record, but rather an out of band record. Because out of band also supports connection-less scenarios, a connection record is not created until a connection request is received (or sent in the case of the invitee role)."),(0,o.kt)("p",null,"You can listen for connection state change events that are associated with a specific out of band id. This allows you to link a connection to an invitation you created."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"// Listen for connection state changed events associated with the out of band record\nagent.events.on(ConnectionEventTypes.ConnectionStateChanged, (event) => {\n if (event.payload.connectionRecord.outOfBandId === outOfBandRecord.id) {\n console.log(`Connection state changed for connection with out of band id ${outOfBandRecord.id}`)\n }\n})\n")),(0,o.kt)("p",null,"It is also possible to retrieve all connection records associated with an out of band invitation. Because of multi use invitations, there could be multiple connection records associated with a single out of band invitation. Instead of having a separate connection record that will always stay in the invited state, the out of band record will now handle the multi use capabilities of an invitation."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"// Retrieve all connections associated with an out of band id\nconst connections = await agent.connections.findAllByOutOfBandId(outOfBandRecord.id)\n")))),(0,o.kt)("h4",{id:"receiving-a-legacy-invitation"},"Receiving a Legacy Invitation"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"receiveInvitation")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"receiveInvitationFromUrl")," methods on the connections module have also been moved to the out of band module. Both methods support the new out of band invitations and the legacy RFC 0160 connection invitations. Internally AFJ converts the old invitations to out of band invitations."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const invitationUrl = 'https://example.com?c_i=eyXXX'\n\n// Receive invitation directly from url\nconst connectionRecord = await agent.connections.receiveInvitationFromUrl(invitationUrl, {\n /* config */\n})\n\n// Parse invitation and receive invitation\nconst parsedInvitation = await ConnectionInvitationMessage.fromUrl(invitationUrl)\nconst connectionRecord = await agent.connections.receiveInvitation(parsedInvitation, {\n /* config */\n})\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const invitationUrl = 'https://example.com?c_i=eyXXX'\n\n// Receive invitation directly from url\nconst { outOfBandRecord, connectionRecord } = await agent.oob.receiveInvitationFromUrl(invitationUrl, {\n /* config */\n})\n\n// Parse invitation and receive invitation\nconst parsedInvitation = await agent.oob.parseInvitation(invitationUrl)\nconst secondConnectionRecord = await agent.oob.receiveInvitation(parsedInvitation, {\n /* config */\n})\n")),(0,o.kt)("p",null,"The new receive invitation methods on the out of band module won't always return a connection record anymore. The out of band invitation may not contain any handshake protocols. In the case of receiving a connection invitation you will always receive a connection record though, as you can't use it for connection-less invitations."))),(0,o.kt)("h4",{id:"updating-to-use-didexchangestate"},"Updating to use ",(0,o.kt)("inlineCode",{parentName:"h4"},"DidExchangeState")),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," that was previously used for the state of the ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionRecord")," has been changed to use the ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," for both connections made using the RFC 0160 Connection Protocol, as well as the RFC 0023 DID Exchange Protocol."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," has the following values:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.Start"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.InvitationSent"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.InvitationReceived"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.RequestSent"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.RequestReceived"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.ResponseSent"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.ResponseReceived"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.Abandoned"),","),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"DidExchangeState.Completed"))),(0,o.kt)("p",null,"If you still need to access the old ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," you can do so by accessing the computed ",(0,o.kt)("inlineCode",{parentName:"p"},"connectionRecord.rfc0160State")," property. This will return the old ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," value."),(0,o.kt)("h3",{id:"updating-custom-messages-to-the-new-message-type-objects"},"Updating Custom Messages to the New Message Type Objects"),(0,o.kt)("p",null,"Although this isn't a breaking change to the public API of the framework, it is something that you will need to take into account when creating custom modules. Starting from AFJ 0.2.0 we now support handling messages with different minor versions (e.g. receive a message with ",(0,o.kt)("inlineCode",{parentName:"p"},"@type")," version 1.1 while we only support 1.0). With this change messages must now declare the message type as an ",(0,o.kt)("inlineCode",{parentName:"p"},"ParsedMessageType")," object. We've added an ",(0,o.kt)("inlineCode",{parentName:"p"},"parseMessageType")," util method that can help with this."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { AgentMessage } from '@aries-framework/core'\nimport { Equals } from 'class-validator'\n\nclass MyMessage extends AgentMessage {\n @Equals(MyMessage.type)\n public readonly type = MyMessage.type\n public static readonly type = 'https://didcomm.org/my-protocol/1.0/my-type'\n}\n"))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"import { AgentMessage, IsValidMessageType, parseMessageType } from '@aries-framework/core'\nimport { Equals } from 'class-validator'\n\nclass MyMessage extends AgentMessage {\n // use IsValidMessageType instead of Equals\n @IsValidMessageType(MyMessage.type)\n // append .messageTypeUri to get the actual URI when instantiating a message\n public readonly type = MyMessage.type.messageTypeUri\n // use parseMessageType to get the message type object from a type. You can declare the object yourself, but this is the recommended way\n public static readonly type = parseMessageType('https://didcomm.org/my-protocol/1.0/my-type')\n}\n")))),(0,o.kt)("h2",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,o.kt)("p",null,"The 0.2.0 release is heavy on breaking changes to the storage format. This is not what we intend to do with every release. But as there's not that many people yet using the framework in production, and there were a lot of changes needed to keep the API straightforward, we decided to bundle a lot of breaking changes in this one release."),(0,o.kt)("p",null,"Below all breaking storage changes are explained in as much detail as possible. The update assistant provides all tools to migrate without a hassle, but it is important to know what has changed. All examples only show the keys that have changed, unrelated keys in records have been omitted."),(0,o.kt)("p",null,"See the ",(0,o.kt)("a",{parentName:"p",href:"/guides/0.5/updating/update-assistant"},"Update Assistant")," documentation for a guide on how to use the update assistant."),(0,o.kt)("p",null,"The following config can be provided to the update assistant to migrate from 0.1.0 to 0.2.0:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "v0_1ToV0_2": {\n "mediationRoleUpdateStrategy": ""\n }\n}\n')),(0,o.kt)("h3",{id:"credential-metadata"},"Credential Metadata"),(0,o.kt)("p",null,"The credential record had a custom ",(0,o.kt)("inlineCode",{parentName:"p"},"metadata")," property in pre-0.1.0 storage that contained the ",(0,o.kt)("inlineCode",{parentName:"p"},"requestMetadata"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"schemaId")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialDefinition")," properties. Later a generic metadata API was added that only allows objects to be stored. Therefore the properties were moved into a different structure."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "requestMetadata": ,\n "schemaId": "",\n "credentialDefinitionId": ""\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "_internal/indyRequest": ,\n "_internal/indyCredential": {\n "schemaId": "",\n "credentialDefinitionId": ""\n }\n}\n')),(0,o.kt)("p",null,"Accessing the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialDefinitionId")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"schemaId")," properties will now be done by retrieving the ",(0,o.kt)("inlineCode",{parentName:"p"},"CredentialMetadataKeys.IndyCredential")," metadata key."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-ts"},"const indyCredential = credentialRecord.metadata.get(CredentialMetadataKeys.IndyCredential)\n\n// both properties are optional\nindyCredential?.credentialDefinitionId\nindyCredential?.schemaId\n")))),(0,o.kt)("h3",{id:"migrate-credential-record-properties"},"Migrate Credential Record Properties"),(0,o.kt)("p",null,"In 0.2.0 the v1 DIDComm messages have been moved out of the credential record into separate records using the DidCommMessageRepository. The migration scripts extracts all messages (proposalMessage, offerMessage, requestMessage, credentialMessage) and moves them into the DidCommMessageRepository."),(0,o.kt)("p",null,"With the addition of support for different protocol versions the credential record now stores the protocol version. With the addition of issue credential v2 support, other credential formats than indy can be used, and multiple credentials can be issued at once. To account for this the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialId")," has been replaced by the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentials")," array. This is an array of objects containing the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialRecordId")," and the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialRecordType"),". For all current credentials the ",(0,o.kt)("inlineCode",{parentName:"p"},"credentialRecordType")," will always be ",(0,o.kt)("inlineCode",{parentName:"p"},"indy"),"."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "credentialId": "09e46da9-a575-4909-b016-040e96c3c539",\n "proposalMessage": { ... },\n "offerMessage": { ... },\n "requestMessage": { ... },\n "credentialMessage": { ... },\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "protocolVersion": "v1",\n "credentials": [\n {\n "credentialRecordId": "09e46da9-a575-4909-b016-040e96c3c539",\n "credentialRecordType": "indy"\n }\n ]\n}\n')))),(0,o.kt)("h3",{id:"mediation-record-role"},"Mediation Record Role"),(0,o.kt)("p",null,"The role in the mediation record was always being set to ",(0,o.kt)("inlineCode",{parentName:"p"},"MediationRole.Mediator")," for both mediators and recipients. This didn't cause any issues, but would return the wrong role for recipients."),(0,o.kt)("p",null,"In 0.2 a check is added to make sure the role of a mediation record matches with actions (e.g. a recipient can't grant mediation), which means it will throw an error if the role is not set correctly."),(0,o.kt)("p",null,"Because it's not always possible detect whether the role should actually be mediator or recipient, a number of configuration options are provided on how the role should be updated using the ",(0,o.kt)("inlineCode",{parentName:"p"},"v0_1ToV0_2.mediationRoleUpdateStrategy")," option:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"allMediator"),": The role is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Mediator")," for both mediators and recipients"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"allRecipient"),": The role is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Recipient")," for both mediators and recipients"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"recipientIfEndpoint")," (",(0,o.kt)("strong",{parentName:"li"},"default"),"): The role is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Recipient")," if their is an ",(0,o.kt)("inlineCode",{parentName:"li"},"endpoint")," configured on the record. The endpoint is not set when running as a mediator. There is one case where this could be problematic when the role should be recipient, if the mediation grant hasn't actually occurred (meaning the endpoint is not set). This is probably the best approach\notherwise it is set to ",(0,o.kt)("inlineCode",{parentName:"li"},"MediationRole.Mediator")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"doNotChange"),": The role is not changed")),(0,o.kt)("p",null,"Most agents only act as either the role of mediator or recipient, in which case the ",(0,o.kt)("inlineCode",{parentName:"p"},"allMediator")," or ",(0,o.kt)("inlineCode",{parentName:"p"},"allRecipient")," configuration is the most appropriate. If your agent acts as both a recipient and mediator, the ",(0,o.kt)("inlineCode",{parentName:"p"},"recipientIfEndpoint")," configuration is the most appropriate. The ",(0,o.kt)("inlineCode",{parentName:"p"},"doNotChange")," options is not recommended and can lead to errors if the role is not set correctly."),(0,o.kt)("h3",{id:"extracting-did-documents-to-did-repository"},"Extracting Did Documents to Did Repository"),(0,o.kt)("p",null,"The connection record previously stored both did documents from a connection in the connection record itself. Version 0.2.0 added a generic did storage that can be used for numerous usages, one of which is the storage of did documents for connection records."),(0,o.kt)("p",null,"The migration script extracts the did documents from the ",(0,o.kt)("inlineCode",{parentName:"p"},"didDoc")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"theirDidDoc")," properties from the connection record, updates them to did documents compliant with the did core spec, and stores them in the did repository. By doing so it also updates the unqualified DIDs in the ",(0,o.kt)("inlineCode",{parentName:"p"},"did")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"theirDid")," fields generated by the indy-sdk to fully qualified ",(0,o.kt)("inlineCode",{parentName:"p"},"did:peer")," DIDs compliant with the ",(0,o.kt)("a",{parentName:"p",href:"https://identity.foundation/peer-did-method-spec/"},"Peer DID Method Specification"),"."),(0,o.kt)("p",null,"To account for the fact that the mechanism to migrate legacy did document to peer did documents is not defined yet, the legacy did and did document are stored in the did record metadata. This will be deleted later if we can be certain the did doc conversion to a ",(0,o.kt)("inlineCode",{parentName:"p"},"did:peer")," did document is correct."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "did": "BBPoJqRKatdcfLEAFL7exC",\n "theirDid": "UppcJ5APts7ot5WX25943F",\n "verkey": "GAb4NUvpBcHVCvtP45vTVa5Bp74vFg3iXzdp1Gbd68Wf",\n "didDoc": ,\n "theirDidDoc": ,\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "did": "did:peer:1zQmXUaPPhPCbUVZ3hGYmQmGxWTwyDfhqESXCpMFhKaF9Y2A",\n "theirDid": "did:peer:1zQmZMygzYqNwU6Uhmewx5Xepf2VLp5S4HLSwwgf2aiKZuwa"\n}\n')))),(0,o.kt)("h3",{id:"migrating-to-the-out-of-band-record"},"Migrating to the Out of Band Record"),(0,o.kt)("p",null,"With the addition of the out of band protocol, invitations are now stored in the ",(0,o.kt)("inlineCode",{parentName:"p"},"OutOfBandRecord"),". In addition a new field ",(0,o.kt)("inlineCode",{parentName:"p"},"invitationDid")," is added to the connection record that is generated based on the invitation service or did. This allows to reuse existing connections."),(0,o.kt)("p",null,"The migration script extracts the invitation and other relevant data into a separate ",(0,o.kt)("inlineCode",{parentName:"p"},"OutOfBandRecord"),". By doing so it converts the old connection protocol invitation into the new Out of band invitation message. Based on the service or did of the invitation, the ",(0,o.kt)("inlineCode",{parentName:"p"},"invitationDid")," is populated."),(0,o.kt)("p",null,"Previously when creating a multi use invitation, a connection record would be created with the ",(0,o.kt)("inlineCode",{parentName:"p"},"multiUseInvitation")," set to true. The connection record would always be in state ",(0,o.kt)("inlineCode",{parentName:"p"},"invited"),". If a request for the multi use invitation came in, a new connection record would be created. With the addition of the out of band module, no connection records are created until a request is received. So for multi use invitation this means that the connection record with multiUseInvitation=true will be deleted, and instead all connections created using that out of band invitation will contain the ",(0,o.kt)("inlineCode",{parentName:"p"},"outOfBandId")," of the multi use invitation."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "invitation": {\n "@type": "https://didcomm.org/connections/1.0/invitation",\n "@id": "04a2c382-999e-4de9-a1d2-9dec0b2fa5e4",\n "recipientKeys": ["E6D1m3eERqCueX4ZgMCY14B4NceAr6XP2HyVqt55gDhu"],\n "serviceEndpoint": "https://example.com",\n "label": "test"\n },\n "multiUseInvitation": "false"\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.x",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "invitationDid": "did:peer:2.Ez6MksYU4MHtfmNhNm1uGMvANr9j4CBv2FymjiJtRgA36bSVH.SeyJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbSJ9",\n "outOfBandId": "04a2c382-999e-4de9-a1d2-9dec0b2fa5e4"\n}\n')))),(0,o.kt)("h3",{id:"unifying-connection-states-and-roles"},"Unifying Connection States and Roles"),(0,o.kt)("p",null,"With the addition of the did exchange protocol there are now two states and roles related to the connection record; for the did exchange protocol and for the connection protocol. To keep it easy to work with the connection record, all state and role values are updated to those of the ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeRole")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," enums."),(0,o.kt)("p",null,"The migration script transforms all connection record state and role values to their respective values of the ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeRole")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"DidExchangeState")," enums. For convenience a getter\nproperty ",(0,o.kt)("inlineCode",{parentName:"p"},"rfc0160ConnectionState")," is added to the connection record which returns the ",(0,o.kt)("inlineCode",{parentName:"p"},"ConnectionState")," value."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{label:"0.1.0",value:"tab1",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "state": "invited",\n "role": "inviter"\n}\n'))),(0,o.kt)(r.Z,{label:"0.2.0",value:"tab2",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'{\n "state": "invitation-sent",\n "role": "responder"\n}\n')))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/dc62edf2.b9000ec6.js b/assets/js/dc62edf2.5763051f.js similarity index 72% rename from assets/js/dc62edf2.b9000ec6.js rename to assets/js/dc62edf2.5763051f.js index 3d4cab11..3b154f97 100644 --- a/assets/js/dc62edf2.b9000ec6.js +++ b/assets/js/dc62edf2.5763051f.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4827],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>g});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(r),m=a,g=d["".concat(l,".").concat(m)]||d[m]||p[m]||i;return r?n.createElement(g,o(o({ref:t},u),{},{components:r})):n.createElement(g,o({ref:t},u))}));function g(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:a,o[1]=s;for(var c=2;c{r.d(t,{Z:()=>y});var n=r(7294),a=r(6010),i=r(3438),o=r(9960),s=r(3919),l=r(5999);const c={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function u(e){let{href:t,children:r}=e;return n.createElement(o.Z,{href:t,className:(0,a.Z)("card padding--lg",c.cardContainer)},r)}function d(e){let{href:t,icon:r,title:i,description:o}=e;return n.createElement(u,{href:t},n.createElement("h2",{className:(0,a.Z)("text--truncate",c.cardTitle),title:i},r," ",i),o&&n.createElement("p",{className:(0,a.Z)("text--truncate",c.cardDescription),title:o},o))}function p(e){let{item:t}=e;const r=(0,i.Wl)(t);return r?n.createElement(d,{href:r,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,l.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function m(e){let{item:t}=e;const r=(0,s.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",a=(0,i.xz)(t.docId??void 0);return n.createElement(d,{href:t.href,icon:r,title:t.label,description:a?.description})}function g(e){let{item:t}=e;switch(t.type){case"link":return n.createElement(m,{item:t});case"category":return n.createElement(p,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function f(e){let{className:t}=e;const r=(0,i.jA)();return n.createElement(y,{items:r.items,className:t})}function y(e){const{items:t,className:r}=e;if(!t)return n.createElement(f,e);const o=(0,i.MN)(t);return n.createElement("section",{className:(0,a.Z)("row",r)},o.map(((e,t)=>n.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},n.createElement(g,{item:e})))))}},695:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>m,frontMatter:()=>o,metadata:()=>l,toc:()=>u});var n=r(7462),a=(r(7294),r(3905)),i=r(2991);const o={},s="Getting started",l={unversionedId:"getting-started/index",id:"getting-started/index",title:"Getting started",description:"In this section we will go over everything you need to get started on a technical level. First there are some general prerequisites for Node.JS and React Native. Credo works for creating both server-side applications (commonly but not always for creating issuer and verifier agents) and mobile applications (commonly holder agents).",source:"@site/guides/getting-started/index.md",sourceDirName:"getting-started",slug:"/getting-started/",permalink:"/guides/0.5/getting-started/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Intro",permalink:"/guides/0.5/"},next:{title:"Prerequisites",permalink:"/guides/0.5/getting-started/prerequisites"}},c={},u=[],d={toc:u},p="wrapper";function m(e){let{components:t,...r}=e;return(0,a.kt)(p,(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"getting-started"},"Getting started"),(0,a.kt)("p",null,"In this section we will go over everything you need to get started on a technical level. First there are some general prerequisites for Node.JS and React Native. Credo works for creating both server-side applications (commonly but not always for creating issuer and verifier agents) and mobile applications (commonly holder agents)."),(0,a.kt)("p",null,"Based on the platform you want to work on, the installation guides you should follow are the same, but some steps may differ."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Do you want to build a mobile app?")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Follow the ",(0,a.kt)("a",{parentName:"li",href:"/guides/0.5/getting-started/prerequisites"},"Prerequisites"),"."),(0,a.kt)("li",{parentName:"ul"},"Follow the ",(0,a.kt)("a",{parentName:"li",href:"/guides/0.5/getting-started/set-up/"},"Agent Setup")," guide.")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Do you want to build a server-side app?")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Follow the ",(0,a.kt)("a",{parentName:"li",href:"/guides/0.5/getting-started/prerequisites"},"Prerequisites"),"."),(0,a.kt)("li",{parentName:"ul"},"Follow the ",(0,a.kt)("a",{parentName:"li",href:"/guides/0.5/getting-started/set-up/"},"Agent Setup")," guide.")),(0,a.kt)(i.Z,{mdxType:"DocCardList"}))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4827],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>g});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(r),m=a,g=d["".concat(l,".").concat(m)]||d[m]||p[m]||i;return r?n.createElement(g,o(o({ref:t},u),{},{components:r})):n.createElement(g,o({ref:t},u))}));function g(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:a,o[1]=s;for(var c=2;c{r.d(t,{Z:()=>y});var n=r(7294),a=r(6010),i=r(3438),o=r(9960),s=r(3919),l=r(5999);const c={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function u(e){let{href:t,children:r}=e;return n.createElement(o.Z,{href:t,className:(0,a.Z)("card padding--lg",c.cardContainer)},r)}function d(e){let{href:t,icon:r,title:i,description:o}=e;return n.createElement(u,{href:t},n.createElement("h2",{className:(0,a.Z)("text--truncate",c.cardTitle),title:i},r," ",i),o&&n.createElement("p",{className:(0,a.Z)("text--truncate",c.cardDescription),title:o},o))}function p(e){let{item:t}=e;const r=(0,i.Wl)(t);return r?n.createElement(d,{href:r,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:(0,l.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function m(e){let{item:t}=e;const r=(0,s.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",a=(0,i.xz)(t.docId??void 0);return n.createElement(d,{href:t.href,icon:r,title:t.label,description:a?.description})}function g(e){let{item:t}=e;switch(t.type){case"link":return n.createElement(m,{item:t});case"category":return n.createElement(p,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function f(e){let{className:t}=e;const r=(0,i.jA)();return n.createElement(y,{items:r.items,className:t})}function y(e){const{items:t,className:r}=e;if(!t)return n.createElement(f,e);const o=(0,i.MN)(t);return n.createElement("section",{className:(0,a.Z)("row",r)},o.map(((e,t)=>n.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},n.createElement(g,{item:e})))))}},695:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>m,frontMatter:()=>o,metadata:()=>l,toc:()=>u});var n=r(7462),a=(r(7294),r(3905)),i=r(2991);const o={},s="Getting started",l={unversionedId:"getting-started/index",id:"getting-started/index",title:"Getting started",description:"In this section we will go over everything you need to get started on a technical level. First there are some general prerequisites for Node.JS and React Native. Credo works for creating both server-side applications (commonly but not always for creating issuer and verifier agents) and mobile applications (commonly holder agents).",source:"@site/guides/getting-started/index.md",sourceDirName:"getting-started",slug:"/getting-started/",permalink:"/guides/getting-started/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Intro",permalink:"/guides/"},next:{title:"Prerequisites",permalink:"/guides/getting-started/prerequisites"}},c={},u=[],d={toc:u},p="wrapper";function m(e){let{components:t,...r}=e;return(0,a.kt)(p,(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"getting-started"},"Getting started"),(0,a.kt)("p",null,"In this section we will go over everything you need to get started on a technical level. First there are some general prerequisites for Node.JS and React Native. Credo works for creating both server-side applications (commonly but not always for creating issuer and verifier agents) and mobile applications (commonly holder agents)."),(0,a.kt)("p",null,"Based on the platform you want to work on, the installation guides you should follow are the same, but some steps may differ."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Do you want to build a mobile app?")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Follow the ",(0,a.kt)("a",{parentName:"li",href:"/guides/getting-started/prerequisites"},"Prerequisites"),"."),(0,a.kt)("li",{parentName:"ul"},"Follow the ",(0,a.kt)("a",{parentName:"li",href:"/guides/getting-started/set-up/"},"Agent Setup")," guide.")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Do you want to build a server-side app?")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Follow the ",(0,a.kt)("a",{parentName:"li",href:"/guides/getting-started/prerequisites"},"Prerequisites"),"."),(0,a.kt)("li",{parentName:"ul"},"Follow the ",(0,a.kt)("a",{parentName:"li",href:"/guides/getting-started/set-up/"},"Agent Setup")," guide.")),(0,a.kt)(i.Z,{mdxType:"DocCardList"}))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/debd89ec.3d8e9f3b.js b/assets/js/debd89ec.3d8e9f3b.js new file mode 100644 index 00000000..878e0789 --- /dev/null +++ b/assets/js/debd89ec.3d8e9f3b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4767],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var o=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function i(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var g=o.createContext({}),s=function(e){var n=o.useContext(g),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},c=function(e){var n=s(e.components);return o.createElement(g.Provider,{value:n},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},u=o.forwardRef((function(e,n){var t=e.components,r=e.mdxType,a=e.originalType,g=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),p=s(t),u=r,m=p["".concat(g,".").concat(u)]||p[u]||d[u]||a;return t?o.createElement(m,i(i({ref:n},c),{},{components:t})):o.createElement(m,i({ref:n},c))}));function m(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var a=t.length,i=new Array(a);i[0]=u;var l={};for(var g in n)hasOwnProperty.call(n,g)&&(l[g]=n[g]);l.originalType=e,l[p]="string"==typeof e?e:r,i[1]=l;for(var s=2;s{t.r(n),t.d(n,{assets:()=>g,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>l,toc:()=>s});var o=t(7462),r=(t(7294),t(3905));const a={},i="Logging",l={unversionedId:"tutorials/agent-config/logging",id:"version-0.4/tutorials/agent-config/logging",title:"Logging",description:"Using the Default ConsoleLogger",source:"@site/versioned_docs/version-0.4/tutorials/agent-config/logging.md",sourceDirName:"tutorials/agent-config",slug:"/tutorials/agent-config/logging",permalink:"/guides/0.4/tutorials/agent-config/logging",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Agent Config",permalink:"/guides/0.4/tutorials/agent-config/"},next:{title:"Create a connection",permalink:"/guides/0.4/tutorials/create-a-connection"}},g={},s=[{value:"Using the Default ConsoleLogger",id:"using-the-default-consolelogger",level:2},{value:"Creating your own Logger",id:"creating-your-own-logger",level:2},{value:"Indy Logs",id:"indy-logs",level:2}],c={toc:s},p="wrapper";function d(e){let{components:n,...t}=e;return(0,r.kt)(p,(0,o.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"logging"},"Logging"),(0,r.kt)("h2",{id:"using-the-default-consolelogger"},"Using the Default ConsoleLogger"),(0,r.kt)("p",null,"To enable logging inside the framework a logger must be passed to the agent config. A simple ",(0,r.kt)("inlineCode",{parentName:"p"},"ConsoleLogger")," can be imported from the framework."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import type { InitConfig } from '@aries-framework/core'\nimport { ConsoleLogger, LogLevel } from '@aries-framework/core'\n\nconst agentConfig: InitConfig = {\n // ... other config properties ...\n logger: new ConsoleLogger(LogLevel.info),\n}\n")),(0,r.kt)("h2",{id:"creating-your-own-logger"},"Creating your own Logger"),(0,r.kt)("p",null,"For more advanced use cases the ",(0,r.kt)("inlineCode",{parentName:"p"},"Logger")," interface can be implemented. See the example below."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Logger, LogLevel } from '@aries-framework/core'\n\nclass MyCustomLogger implements Logger {\n public logLevel: LogLevel\n\n public constructor(logLevel: LogLevel = LogLevel.off) {\n this.logLevel = logLevel\n }\n\n public test(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public trace(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public debug(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public info(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public warn(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public error(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public fatal(message: string, data?: Record): void {\n console.log(message, data)\n }\n}\n")),(0,r.kt)("h2",{id:"indy-logs"},"Indy Logs"),(0,r.kt)("p",null,"To enable logging in the underlying Rust framework, either ",(0,r.kt)("inlineCode",{parentName:"p"},"setLogger")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"setDefaultLogger")," must be called on the indy dependency, as seen ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk/tree/master/wrappers/nodejs#logger"},"here"),"."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"The ",(0,r.kt)("inlineCode",{parentName:"p"},"setLogger")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"setDefaultLogger")," methods have only been implemented in the Node.JS wrapper of the indy sdk. This won't work when importing from ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/react-native"))),(0,r.kt)("p",null,"The easiest way to do this from AFJ is through the ",(0,r.kt)("inlineCode",{parentName:"p"},"indy")," property of ",(0,r.kt)("inlineCode",{parentName:"p"},"agentDependencies"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { agentDependencies } from '@aries-framework/node'\nagentDependencies.indy.setDefaultLogger('trace')\n\n// OR\n\nagentDependencies.indy.setLogger((level, target, message, modulePath, file, line) => {\n console.log('libindy said:', level, target, message, modulePath, file, line)\n})\n")),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"WARNING: You can only set the logger once. Call indy_set_default_logger, indy_set_logger, not both. Once it's been set, libindy won't let you change it.")),(0,r.kt)("p",null,"You can also set the environment variable ",(0,r.kt)("inlineCode",{parentName:"p"},"RUST_LOG")," to log at specified log levels.\nSee ",(0,r.kt)("a",{parentName:"p",href:"https://crates.io/crates/env_logger"},"https://crates.io/crates/env_logger")," for more information."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/debd89ec.fbbc5ac8.js b/assets/js/debd89ec.fbbc5ac8.js deleted file mode 100644 index 36f4c765..00000000 --- a/assets/js/debd89ec.fbbc5ac8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4767],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var o=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function i(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var g=o.createContext({}),s=function(e){var n=o.useContext(g),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},c=function(e){var n=s(e.components);return o.createElement(g.Provider,{value:n},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},u=o.forwardRef((function(e,n){var t=e.components,r=e.mdxType,a=e.originalType,g=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),p=s(t),u=r,m=p["".concat(g,".").concat(u)]||p[u]||d[u]||a;return t?o.createElement(m,i(i({ref:n},c),{},{components:t})):o.createElement(m,i({ref:n},c))}));function m(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var a=t.length,i=new Array(a);i[0]=u;var l={};for(var g in n)hasOwnProperty.call(n,g)&&(l[g]=n[g]);l.originalType=e,l[p]="string"==typeof e?e:r,i[1]=l;for(var s=2;s{t.r(n),t.d(n,{assets:()=>g,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>l,toc:()=>s});var o=t(7462),r=(t(7294),t(3905));const a={},i="Logging",l={unversionedId:"tutorials/agent-config/logging",id:"version-0.4/tutorials/agent-config/logging",title:"Logging",description:"Using the Default ConsoleLogger",source:"@site/versioned_docs/version-0.4/tutorials/agent-config/logging.md",sourceDirName:"tutorials/agent-config",slug:"/tutorials/agent-config/logging",permalink:"/guides/tutorials/agent-config/logging",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Agent Config",permalink:"/guides/tutorials/agent-config/"},next:{title:"Create a connection",permalink:"/guides/tutorials/create-a-connection"}},g={},s=[{value:"Using the Default ConsoleLogger",id:"using-the-default-consolelogger",level:2},{value:"Creating your own Logger",id:"creating-your-own-logger",level:2},{value:"Indy Logs",id:"indy-logs",level:2}],c={toc:s},p="wrapper";function d(e){let{components:n,...t}=e;return(0,r.kt)(p,(0,o.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"logging"},"Logging"),(0,r.kt)("h2",{id:"using-the-default-consolelogger"},"Using the Default ConsoleLogger"),(0,r.kt)("p",null,"To enable logging inside the framework a logger must be passed to the agent config. A simple ",(0,r.kt)("inlineCode",{parentName:"p"},"ConsoleLogger")," can be imported from the framework."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import type { InitConfig } from '@aries-framework/core'\nimport { ConsoleLogger, LogLevel } from '@aries-framework/core'\n\nconst agentConfig: InitConfig = {\n // ... other config properties ...\n logger: new ConsoleLogger(LogLevel.info),\n}\n")),(0,r.kt)("h2",{id:"creating-your-own-logger"},"Creating your own Logger"),(0,r.kt)("p",null,"For more advanced use cases the ",(0,r.kt)("inlineCode",{parentName:"p"},"Logger")," interface can be implemented. See the example below."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Logger, LogLevel } from '@aries-framework/core'\n\nclass MyCustomLogger implements Logger {\n public logLevel: LogLevel\n\n public constructor(logLevel: LogLevel = LogLevel.off) {\n this.logLevel = logLevel\n }\n\n public test(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public trace(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public debug(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public info(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public warn(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public error(message: string, data?: Record): void {\n console.log(message, data)\n }\n\n public fatal(message: string, data?: Record): void {\n console.log(message, data)\n }\n}\n")),(0,r.kt)("h2",{id:"indy-logs"},"Indy Logs"),(0,r.kt)("p",null,"To enable logging in the underlying Rust framework, either ",(0,r.kt)("inlineCode",{parentName:"p"},"setLogger")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"setDefaultLogger")," must be called on the indy dependency, as seen ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk/tree/master/wrappers/nodejs#logger"},"here"),"."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"The ",(0,r.kt)("inlineCode",{parentName:"p"},"setLogger")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"setDefaultLogger")," methods have only been implemented in the Node.JS wrapper of the indy sdk. This won't work when importing from ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/react-native"))),(0,r.kt)("p",null,"The easiest way to do this from AFJ is through the ",(0,r.kt)("inlineCode",{parentName:"p"},"indy")," property of ",(0,r.kt)("inlineCode",{parentName:"p"},"agentDependencies"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { agentDependencies } from '@aries-framework/node'\nagentDependencies.indy.setDefaultLogger('trace')\n\n// OR\n\nagentDependencies.indy.setLogger((level, target, message, modulePath, file, line) => {\n console.log('libindy said:', level, target, message, modulePath, file, line)\n})\n")),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"WARNING: You can only set the logger once. Call indy_set_default_logger, indy_set_logger, not both. Once it's been set, libindy won't let you change it.")),(0,r.kt)("p",null,"You can also set the environment variable ",(0,r.kt)("inlineCode",{parentName:"p"},"RUST_LOG")," to log at specified log levels.\nSee ",(0,r.kt)("a",{parentName:"p",href:"https://crates.io/crates/env_logger"},"https://crates.io/crates/env_logger")," for more information."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e38b62c8.f5742f56.js b/assets/js/e38b62c8.8016e30a.js similarity index 73% rename from assets/js/e38b62c8.f5742f56.js rename to assets/js/e38b62c8.8016e30a.js index 9efdf765..9efba676 100644 --- a/assets/js/e38b62c8.f5742f56.js +++ b/assets/js/e38b62c8.8016e30a.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7162],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=p(r),m=o,f=d["".concat(c,".").concat(m)]||d[m]||u[m]||a;return r?n.createElement(f,i(i({ref:t},l),{},{components:r})):n.createElement(f,i({ref:t},l))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:o,i[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const a={},i="Platform and Environment",s={unversionedId:"concepts/platform-and-environment",id:"version-0.4/concepts/platform-and-environment",title:"Platform and Environment",description:"Aries framework JavaScript is developed to support a Node.JS and React Native environment. With this it is entirely possible to build an entire SSI ecosystem with Aries Framework JavaScript. This would use Node.JS as an issuer as a verifier, and uses React Native as a holder.",source:"@site/versioned_docs/version-0.4/concepts/platform-and-environment.md",sourceDirName:"concepts",slug:"/concepts/platform-and-environment",permalink:"/guides/concepts/platform-and-environment",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"DIDs and DIDComm",permalink:"/guides/concepts/did-and-didcomm"},next:{title:"Tutorials",permalink:"/guides/tutorials/"}},c={},p=[],l={toc:p},d="wrapper";function u(e){let{components:t,...r}=e;return(0,o.kt)(d,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"platform-and-environment"},"Platform and Environment"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript"},"Aries framework JavaScript")," is developed to support a ",(0,o.kt)("a",{parentName:"p",href:"https://nodejs.org"},"Node.JS")," and ",(0,o.kt)("a",{parentName:"p",href:"https://reactnative.dev"},"React Native")," environment. With this it is entirely possible to build an entire SSI ecosystem with Aries Framework JavaScript. This would use Node.JS as an issuer as a verifier, and uses React Native as a holder."))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7162],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=p(r),m=o,f=d["".concat(c,".").concat(m)]||d[m]||u[m]||a;return r?n.createElement(f,i(i({ref:t},l),{},{components:r})):n.createElement(f,i({ref:t},l))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:o,i[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const a={},i="Platform and Environment",s={unversionedId:"concepts/platform-and-environment",id:"version-0.4/concepts/platform-and-environment",title:"Platform and Environment",description:"Aries framework JavaScript is developed to support a Node.JS and React Native environment. With this it is entirely possible to build an entire SSI ecosystem with Aries Framework JavaScript. This would use Node.JS as an issuer as a verifier, and uses React Native as a holder.",source:"@site/versioned_docs/version-0.4/concepts/platform-and-environment.md",sourceDirName:"concepts",slug:"/concepts/platform-and-environment",permalink:"/guides/0.4/concepts/platform-and-environment",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"DIDs and DIDComm",permalink:"/guides/0.4/concepts/did-and-didcomm"},next:{title:"Tutorials",permalink:"/guides/0.4/tutorials/"}},c={},p=[],l={toc:p},d="wrapper";function u(e){let{components:t,...r}=e;return(0,o.kt)(d,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"platform-and-environment"},"Platform and Environment"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript"},"Aries framework JavaScript")," is developed to support a ",(0,o.kt)("a",{parentName:"p",href:"https://nodejs.org"},"Node.JS")," and ",(0,o.kt)("a",{parentName:"p",href:"https://reactnative.dev"},"React Native")," environment. With this it is entirely possible to build an entire SSI ecosystem with Aries Framework JavaScript. This would use Node.JS as an issuer as a verifier, and uses React Native as a holder."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e5a09f30.08310c1c.js b/assets/js/e5a09f30.08310c1c.js new file mode 100644 index 00000000..a0d084c4 --- /dev/null +++ b/assets/js/e5a09f30.08310c1c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[2254],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>f});var r=t(7294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var l=r.createContext({}),u=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},p=function(e){var n=u(e.components);return r.createElement(l.Provider,{value:n},e.children)},d="mdxType",c={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},m=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=u(t),m=a,f=d["".concat(l,".").concat(m)]||d[m]||c[m]||o;return t?r.createElement(f,s(s({ref:n},p),{},{components:t})):r.createElement(f,s({ref:n},p))}));function f(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var o=t.length,s=new Array(o);s[0]=m;var i={};for(var l in n)hasOwnProperty.call(n,l)&&(i[l]=n[l]);i.originalType=e,i[d]="string"==typeof e?e:a,s[1]=i;for(var u=2;u{t.d(n,{Z:()=>s});var r=t(7294),a=t(6010);const o={tabItem:"tabItem_Ymn6"};function s(e){let{children:n,hidden:t,className:s}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(o.tabItem,s),hidden:t},n)}},4866:(e,n,t)=>{t.d(n,{Z:()=>N});var r=t(7462),a=t(7294),o=t(6010),s=t(2466),i=t(6550),l=t(1980),u=t(7392),p=t(12);function d(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:n,label:t,attributes:r,default:a}}=e;return{value:n,label:t,attributes:r,default:a}}))}function c(e){const{values:n,children:t}=e;return(0,a.useMemo)((()=>{const e=n??d(t);return function(e){const n=(0,u.l)(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 m(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 r=(0,i.k6)(),o=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,l._X)(o),(0,a.useCallback)((e=>{if(!o)return;const n=new URLSearchParams(r.location.search);n.set(o,e),r.replace({...r.location,search:n.toString()})}),[o,r])]}function h(e){const{defaultValue:n,queryString:t=!1,groupId:r}=e,o=c(e),[s,i]=(0,a.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(!m({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 r=t.find((e=>e.default))??t[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:n,tabValues:o}))),[l,u]=f({queryString:t,groupId:r}),[d,h]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[r,o]=(0,p.Nk)(t);return[r,(0,a.useCallback)((e=>{t&&o.set(e)}),[t,o])]}({groupId:r}),g=(()=>{const e=l??d;return m({value:e,tabValues:o})?e:null})();(0,a.useLayoutEffect)((()=>{g&&i(g)}),[g]);return{selectedValue:s,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);i(e),u(e),h(e)}),[u,h,o]),tabValues:o}}var g=t(2389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:n,block:t,selectedValue:i,selectValue:l,tabValues:u}=e;const p=[],{blockElementScrollPositionUntilNextRender:d}=(0,s.o5)(),c=e=>{const n=e.currentTarget,t=p.indexOf(n),r=u[t].value;r!==i&&(d(n),l(r))},m=e=>{let n=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const t=p.indexOf(e.currentTarget)+1;n=p[t]??p[0];break}case"ArrowLeft":{const t=p.indexOf(e.currentTarget)-1;n=p[t]??p[p.length-1];break}}n?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":t},n)},u.map((e=>{let{value:n,label:t,attributes:s}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:i===n?0:-1,"aria-selected":i===n,key:n,ref:e=>p.push(e),onKeyDown:m,onClick:c},s,{className:(0,o.Z)("tabs__item",b.tabItem,s?.className,{"tabs__item--active":i===n})}),t??n)})))}function y(e){let{lazy:n,children:t,selectedValue:r}=e;if(t=Array.isArray(t)?t:[t],n){const e=t.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},t.map(((e,n)=>(0,a.cloneElement)(e,{key:n,hidden:e.props.value!==r}))))}function v(e){const n=h(e);return a.createElement("div",{className:(0,o.Z)("tabs-container",b.tabList)},a.createElement(k,(0,r.Z)({},e,n)),a.createElement(y,(0,r.Z)({},e,n)))}function N(e){const n=(0,g.Z)();return a.createElement(v,(0,r.Z)({key:String(n)},e))}},3570:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>l,default:()=>f,frontMatter:()=>i,metadata:()=>u,toc:()=>d});var r=t(7462),a=(t(7294),t(3905)),o=t(4866),s=t(5162);const i={},l="AnonCreds RS",u={unversionedId:"getting-started/set-up/anoncreds-rs",id:"version-0.4/getting-started/set-up/anoncreds-rs",title:"AnonCreds RS",description:"AnonCreds RS is a direct implementation of the AnonCreds V1.0 specification that provides functionality like; creating a schema object, creating a credential definition object, creating a credential, verifying a proof presentation and much more.",source:"@site/versioned_docs/version-0.4/getting-started/set-up/anoncreds-rs.md",sourceDirName:"getting-started/set-up",slug:"/getting-started/set-up/anoncreds-rs",permalink:"/guides/0.4/getting-started/set-up/anoncreds-rs",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"React Native",permalink:"/guides/0.4/getting-started/set-up/indy-sdk/react-native"},next:{title:"Indy VDR",permalink:"/guides/0.4/getting-started/set-up/indy-vdr"}},p={},d=[{value:"Installing AnonCreds RS",id:"installing-anoncreds-rs",level:3},{value:"Adding AnonCreds RS to the agent",id:"adding-anoncreds-rs-to-the-agent",level:3},{value:"Configuration",id:"configuration",level:3},{value:"Supported Node.JS versions for AnonCreds RS",id:"supported-nodejs-versions-for-anoncreds-rs",level:3}],c={toc:d},m="wrapper";function f(e){let{components:n,...t}=e;return(0,a.kt)(m,(0,r.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"anoncreds-rs"},"AnonCreds RS"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/anoncreds-rs"},"AnonCreds RS")," is a direct implementation of the ",(0,a.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-spec/"},"AnonCreds V1.0 specification")," that provides functionality like; creating a schema object, creating a credential definition object, creating a credential, verifying a proof presentation and much more."),(0,a.kt)("admonition",{type:"caution"},(0,a.kt)("p",{parentName:"admonition"},"Support for the AnonCreds RS library in Aries Framework JavaScript is currently experimental. We recommend new projects to use AnonCreds RS from the start, and also to migrate existing projects to AnonCreds, from the Indy Sdk. However, projects may experience some issues. If you encounter any issues, please ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript/issues/new"},"open an issue"),"."),(0,a.kt)("p",{parentName:"admonition"},"Currently, there are few limitations to using AnonCreds RS."),(0,a.kt)("ul",{parentName:"admonition"},(0,a.kt)("li",{parentName:"ul"},"When running in Node.JS, only Node.JS 18 is supported for now. See ",(0,a.kt)("a",{parentName:"li",href:"#supported-nodejs-versions-for-anoncreds-rs"},"Supported Node.JS versions for AnonCreds RS")),(0,a.kt)("li",{parentName:"ul"},"Install scripts rely on bash command substitution to get the proper binaries for each system architecture and platform. Therefore, if you are under Windows, you must configure ",(0,a.kt)("inlineCode",{parentName:"li"},"npm")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"yarn")," to use a bash-compliant shell (e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},'npm config set script-shell "C:\\\\Program Files\\\\git\\\\bin\\\\bash.exe"'),")"))),(0,a.kt)("h3",{id:"installing-anoncreds-rs"},"Installing AnonCreds RS"),(0,a.kt)("p",null,"When using Aries Framework JavaScript with AnonCreds RS, there are a few extra dependencies that need to be installed. We need to install ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/anoncreds")," package, which contains the interfaces, and ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/anoncreds-rs")," package which is an implementation which depends on a wrapper of anoncreds-rs. Secondly, we need to add native bindings for the specific platform ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/anoncreds-"),". Currently there are bindings for Node.JS, as ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/anoncreds-nodejs"),", and React Native as ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperlegder/anoncreds-react-native"),"."),(0,a.kt)(o.Z,{mdxType:"Tabs"},(0,a.kt)(s.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @aries-framework/anoncreds@^0.4.0 @aries-framework/anoncreds-rs@^0.4.0 @hyperledger/anoncreds-nodejs@^0.1.0\n"))),(0,a.kt)(s.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @aries-framework/anoncreds@^0.4.0 @aries-framework/anoncreds-rs@^0.4.0 @hyperledger/anoncreds-react-native@^0.1.0\n")))),(0,a.kt)("h3",{id:"adding-anoncreds-rs-to-the-agent"},"Adding AnonCreds RS to the agent"),(0,a.kt)("p",null,"After installing the dependencies, we should register both the ",(0,a.kt)("inlineCode",{parentName:"p"},"AnonCreds")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"AnonCredsRs")," module on the agent."),(0,a.kt)(o.Z,{mdxType:"Tabs"},(0,a.kt)(s.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-anoncreds-rs.ts section-1",showLineNumbers:!0,"set-up-anoncreds-rs.ts":!0,"section-1":!0},""))),(0,a.kt)(s.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-anoncreds-rs-rn.ts section-1",showLineNumbers:!0,"set-up-anoncreds-rs-rn.ts":!0,"section-1":!0},"")))),(0,a.kt)("h3",{id:"configuration"},"Configuration"),(0,a.kt)("p",null,"As you can see, the AnonCreds module takes a list of registry modules. These modules will be used to resolve the AnonCreds objects. We recommend ",(0,a.kt)("a",{parentName:"p",href:"./indy-vdr"},"Indy VDR")," as an AnonCreds registry for Hyperledger Indy networks, but ",(0,a.kt)("a",{parentName:"p",href:"./indy-sdk"},"Indy SDK")," can also be used."),(0,a.kt)("h3",{id:"supported-nodejs-versions-for-anoncreds-rs"},"Supported Node.JS versions for AnonCreds RS"),(0,a.kt)("p",null,"Due to an issue in ",(0,a.kt)("inlineCode",{parentName:"p"},"ref-napi")," (which is used in the Node.JS bindings for AnonCreds RS), performance for AnonCreds RS in Node.JS is not as expected. A patched version for ",(0,a.kt)("inlineCode",{parentName:"p"},"ref-napi")," has been published that fixes this issue, but this only works in Node.JS 18+."),(0,a.kt)("p",null,"To use AnonCreds RS in Node.JS, make sure you're using Node.JS 18 and patch the ",(0,a.kt)("inlineCode",{parentName:"p"},"ref-napi")," package to point towards ",(0,a.kt)("inlineCode",{parentName:"p"},"@2060.io/ref-napi")," in your ",(0,a.kt)("inlineCode",{parentName:"p"},"package.json"),":"),(0,a.kt)(o.Z,{mdxType:"Tabs"},(0,a.kt)(s.Z,{label:"NPM",value:"tab1",mdxType:"TabItem"},(0,a.kt)("p",null,"Using ",(0,a.kt)("a",{parentName:"p",href:"https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides"},"NPM ",(0,a.kt)("inlineCode",{parentName:"a"},"overrides"))," we can point the ",(0,a.kt)("inlineCode",{parentName:"p"},"ref-napi")," package to ",(0,a.kt)("inlineCode",{parentName:"p"},"@2060.io/ref-napi"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'{\n "overrides": {\n "ref-napi": "npm:@2060.io/ref-napi"\n }\n}\n'))),(0,a.kt)(s.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,a.kt)("p",null,"Using ",(0,a.kt)("a",{parentName:"p",href:"https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/"},"Yarn ",(0,a.kt)("inlineCode",{parentName:"a"},"resolutions"))," we can point the ",(0,a.kt)("inlineCode",{parentName:"p"},"ref-napi")," package to ",(0,a.kt)("inlineCode",{parentName:"p"},"@2060.io/ref-napi"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'{\n "resolutions": {\n "ref-napi": "npm:@2060.io/ref-napi"\n }\n}\n')))),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"See the following issues for more information on the performance botleneck"),(0,a.kt)("ul",{parentName:"admonition"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-askar/issues/76"},"https://github.com/hyperledger/aries-askar/issues/76")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/node-ffi-napi/ref-napi/issues/72"},"https://github.com/node-ffi-napi/ref-napi/issues/72")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/node-ffi-napi/ref-napi/pull/73"},"https://github.com/node-ffi-napi/ref-napi/pull/73")))))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e5a09f30.d00f0bc2.js b/assets/js/e5a09f30.d00f0bc2.js deleted file mode 100644 index 37d38ce1..00000000 --- a/assets/js/e5a09f30.d00f0bc2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[2254],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>f});var r=t(7294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var l=r.createContext({}),u=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},p=function(e){var n=u(e.components);return r.createElement(l.Provider,{value:n},e.children)},d="mdxType",c={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},m=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=u(t),m=a,f=d["".concat(l,".").concat(m)]||d[m]||c[m]||o;return t?r.createElement(f,s(s({ref:n},p),{},{components:t})):r.createElement(f,s({ref:n},p))}));function f(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var o=t.length,s=new Array(o);s[0]=m;var i={};for(var l in n)hasOwnProperty.call(n,l)&&(i[l]=n[l]);i.originalType=e,i[d]="string"==typeof e?e:a,s[1]=i;for(var u=2;u{t.d(n,{Z:()=>s});var r=t(7294),a=t(6010);const o={tabItem:"tabItem_Ymn6"};function s(e){let{children:n,hidden:t,className:s}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(o.tabItem,s),hidden:t},n)}},4866:(e,n,t)=>{t.d(n,{Z:()=>N});var r=t(7462),a=t(7294),o=t(6010),s=t(2466),i=t(6550),l=t(1980),u=t(7392),p=t(12);function d(e){return function(e){return a.Children.map(e,(e=>{if((0,a.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:n,label:t,attributes:r,default:a}}=e;return{value:n,label:t,attributes:r,default:a}}))}function c(e){const{values:n,children:t}=e;return(0,a.useMemo)((()=>{const e=n??d(t);return function(e){const n=(0,u.l)(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 m(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 r=(0,i.k6)(),o=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,l._X)(o),(0,a.useCallback)((e=>{if(!o)return;const n=new URLSearchParams(r.location.search);n.set(o,e),r.replace({...r.location,search:n.toString()})}),[o,r])]}function h(e){const{defaultValue:n,queryString:t=!1,groupId:r}=e,o=c(e),[s,i]=(0,a.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(!m({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 r=t.find((e=>e.default))??t[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:n,tabValues:o}))),[l,u]=f({queryString:t,groupId:r}),[d,h]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[r,o]=(0,p.Nk)(t);return[r,(0,a.useCallback)((e=>{t&&o.set(e)}),[t,o])]}({groupId:r}),g=(()=>{const e=l??d;return m({value:e,tabValues:o})?e:null})();(0,a.useLayoutEffect)((()=>{g&&i(g)}),[g]);return{selectedValue:s,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);i(e),u(e),h(e)}),[u,h,o]),tabValues:o}}var g=t(2389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:n,block:t,selectedValue:i,selectValue:l,tabValues:u}=e;const p=[],{blockElementScrollPositionUntilNextRender:d}=(0,s.o5)(),c=e=>{const n=e.currentTarget,t=p.indexOf(n),r=u[t].value;r!==i&&(d(n),l(r))},m=e=>{let n=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const t=p.indexOf(e.currentTarget)+1;n=p[t]??p[0];break}case"ArrowLeft":{const t=p.indexOf(e.currentTarget)-1;n=p[t]??p[p.length-1];break}}n?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":t},n)},u.map((e=>{let{value:n,label:t,attributes:s}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:i===n?0:-1,"aria-selected":i===n,key:n,ref:e=>p.push(e),onKeyDown:m,onClick:c},s,{className:(0,o.Z)("tabs__item",b.tabItem,s?.className,{"tabs__item--active":i===n})}),t??n)})))}function y(e){let{lazy:n,children:t,selectedValue:r}=e;if(t=Array.isArray(t)?t:[t],n){const e=t.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},t.map(((e,n)=>(0,a.cloneElement)(e,{key:n,hidden:e.props.value!==r}))))}function v(e){const n=h(e);return a.createElement("div",{className:(0,o.Z)("tabs-container",b.tabList)},a.createElement(k,(0,r.Z)({},e,n)),a.createElement(y,(0,r.Z)({},e,n)))}function N(e){const n=(0,g.Z)();return a.createElement(v,(0,r.Z)({key:String(n)},e))}},3570:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>l,default:()=>f,frontMatter:()=>i,metadata:()=>u,toc:()=>d});var r=t(7462),a=(t(7294),t(3905)),o=t(4866),s=t(5162);const i={},l="AnonCreds RS",u={unversionedId:"getting-started/set-up/anoncreds-rs",id:"version-0.4/getting-started/set-up/anoncreds-rs",title:"AnonCreds RS",description:"AnonCreds RS is a direct implementation of the AnonCreds V1.0 specification that provides functionality like; creating a schema object, creating a credential definition object, creating a credential, verifying a proof presentation and much more.",source:"@site/versioned_docs/version-0.4/getting-started/set-up/anoncreds-rs.md",sourceDirName:"getting-started/set-up",slug:"/getting-started/set-up/anoncreds-rs",permalink:"/guides/getting-started/set-up/anoncreds-rs",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"React Native",permalink:"/guides/getting-started/set-up/indy-sdk/react-native"},next:{title:"Indy VDR",permalink:"/guides/getting-started/set-up/indy-vdr"}},p={},d=[{value:"Installing AnonCreds RS",id:"installing-anoncreds-rs",level:3},{value:"Adding AnonCreds RS to the agent",id:"adding-anoncreds-rs-to-the-agent",level:3},{value:"Configuration",id:"configuration",level:3},{value:"Supported Node.JS versions for AnonCreds RS",id:"supported-nodejs-versions-for-anoncreds-rs",level:3}],c={toc:d},m="wrapper";function f(e){let{components:n,...t}=e;return(0,a.kt)(m,(0,r.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"anoncreds-rs"},"AnonCreds RS"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/anoncreds-rs"},"AnonCreds RS")," is a direct implementation of the ",(0,a.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-spec/"},"AnonCreds V1.0 specification")," that provides functionality like; creating a schema object, creating a credential definition object, creating a credential, verifying a proof presentation and much more."),(0,a.kt)("admonition",{type:"caution"},(0,a.kt)("p",{parentName:"admonition"},"Support for the AnonCreds RS library in Aries Framework JavaScript is currently experimental. We recommend new projects to use AnonCreds RS from the start, and also to migrate existing projects to AnonCreds, from the Indy Sdk. However, projects may experience some issues. If you encounter any issues, please ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript/issues/new"},"open an issue"),"."),(0,a.kt)("p",{parentName:"admonition"},"Currently, there are few limitations to using AnonCreds RS."),(0,a.kt)("ul",{parentName:"admonition"},(0,a.kt)("li",{parentName:"ul"},"When running in Node.JS, only Node.JS 18 is supported for now. See ",(0,a.kt)("a",{parentName:"li",href:"#supported-nodejs-versions-for-anoncreds-rs"},"Supported Node.JS versions for AnonCreds RS")),(0,a.kt)("li",{parentName:"ul"},"Install scripts rely on bash command substitution to get the proper binaries for each system architecture and platform. Therefore, if you are under Windows, you must configure ",(0,a.kt)("inlineCode",{parentName:"li"},"npm")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"yarn")," to use a bash-compliant shell (e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},'npm config set script-shell "C:\\\\Program Files\\\\git\\\\bin\\\\bash.exe"'),")"))),(0,a.kt)("h3",{id:"installing-anoncreds-rs"},"Installing AnonCreds RS"),(0,a.kt)("p",null,"When using Aries Framework JavaScript with AnonCreds RS, there are a few extra dependencies that need to be installed. We need to install ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/anoncreds")," package, which contains the interfaces, and ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/anoncreds-rs")," package which is an implementation which depends on a wrapper of anoncreds-rs. Secondly, we need to add native bindings for the specific platform ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/anoncreds-"),". Currently there are bindings for Node.JS, as ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperledger/anoncreds-nodejs"),", and React Native as ",(0,a.kt)("inlineCode",{parentName:"p"},"@hyperlegder/anoncreds-react-native"),"."),(0,a.kt)(o.Z,{mdxType:"Tabs"},(0,a.kt)(s.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @aries-framework/anoncreds@^0.4.0 @aries-framework/anoncreds-rs@^0.4.0 @hyperledger/anoncreds-nodejs@^0.1.0\n"))),(0,a.kt)(s.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @aries-framework/anoncreds@^0.4.0 @aries-framework/anoncreds-rs@^0.4.0 @hyperledger/anoncreds-react-native@^0.1.0\n")))),(0,a.kt)("h3",{id:"adding-anoncreds-rs-to-the-agent"},"Adding AnonCreds RS to the agent"),(0,a.kt)("p",null,"After installing the dependencies, we should register both the ",(0,a.kt)("inlineCode",{parentName:"p"},"AnonCreds")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"AnonCredsRs")," module on the agent."),(0,a.kt)(o.Z,{mdxType:"Tabs"},(0,a.kt)(s.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-anoncreds-rs.ts section-1",showLineNumbers:!0,"set-up-anoncreds-rs.ts":!0,"section-1":!0},""))),(0,a.kt)(s.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-anoncreds-rs-rn.ts section-1",showLineNumbers:!0,"set-up-anoncreds-rs-rn.ts":!0,"section-1":!0},"")))),(0,a.kt)("h3",{id:"configuration"},"Configuration"),(0,a.kt)("p",null,"As you can see, the AnonCreds module takes a list of registry modules. These modules will be used to resolve the AnonCreds objects. We recommend ",(0,a.kt)("a",{parentName:"p",href:"./indy-vdr"},"Indy VDR")," as an AnonCreds registry for Hyperledger Indy networks, but ",(0,a.kt)("a",{parentName:"p",href:"./indy-sdk"},"Indy SDK")," can also be used."),(0,a.kt)("h3",{id:"supported-nodejs-versions-for-anoncreds-rs"},"Supported Node.JS versions for AnonCreds RS"),(0,a.kt)("p",null,"Due to an issue in ",(0,a.kt)("inlineCode",{parentName:"p"},"ref-napi")," (which is used in the Node.JS bindings for AnonCreds RS), performance for AnonCreds RS in Node.JS is not as expected. A patched version for ",(0,a.kt)("inlineCode",{parentName:"p"},"ref-napi")," has been published that fixes this issue, but this only works in Node.JS 18+."),(0,a.kt)("p",null,"To use AnonCreds RS in Node.JS, make sure you're using Node.JS 18 and patch the ",(0,a.kt)("inlineCode",{parentName:"p"},"ref-napi")," package to point towards ",(0,a.kt)("inlineCode",{parentName:"p"},"@2060.io/ref-napi")," in your ",(0,a.kt)("inlineCode",{parentName:"p"},"package.json"),":"),(0,a.kt)(o.Z,{mdxType:"Tabs"},(0,a.kt)(s.Z,{label:"NPM",value:"tab1",mdxType:"TabItem"},(0,a.kt)("p",null,"Using ",(0,a.kt)("a",{parentName:"p",href:"https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides"},"NPM ",(0,a.kt)("inlineCode",{parentName:"a"},"overrides"))," we can point the ",(0,a.kt)("inlineCode",{parentName:"p"},"ref-napi")," package to ",(0,a.kt)("inlineCode",{parentName:"p"},"@2060.io/ref-napi"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'{\n "overrides": {\n "ref-napi": "npm:@2060.io/ref-napi"\n }\n}\n'))),(0,a.kt)(s.Z,{label:"Yarn",value:"tab2",mdxType:"TabItem"},(0,a.kt)("p",null,"Using ",(0,a.kt)("a",{parentName:"p",href:"https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/"},"Yarn ",(0,a.kt)("inlineCode",{parentName:"a"},"resolutions"))," we can point the ",(0,a.kt)("inlineCode",{parentName:"p"},"ref-napi")," package to ",(0,a.kt)("inlineCode",{parentName:"p"},"@2060.io/ref-napi"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'{\n "resolutions": {\n "ref-napi": "npm:@2060.io/ref-napi"\n }\n}\n')))),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"See the following issues for more information on the performance botleneck"),(0,a.kt)("ul",{parentName:"admonition"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-askar/issues/76"},"https://github.com/hyperledger/aries-askar/issues/76")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/node-ffi-napi/ref-napi/issues/72"},"https://github.com/node-ffi-napi/ref-napi/issues/72")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/node-ffi-napi/ref-napi/pull/73"},"https://github.com/node-ffi-napi/ref-napi/pull/73")))))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e5f12b68.e769ce15.js b/assets/js/e5f12b68.5a852a24.js similarity index 83% rename from assets/js/e5f12b68.e769ce15.js rename to assets/js/e5f12b68.5a852a24.js index 79cc15c0..c568cc71 100644 --- a/assets/js/e5f12b68.e769ce15.js +++ b/assets/js/e5f12b68.5a852a24.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4656],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>h});var n=a(7294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var l=n.createContext({}),u=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},p=function(e){var t=u(e.components);return n.createElement(l.Provider,{value:t},e.children)},d="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),d=u(a),c=i,h=d["".concat(l,".").concat(c)]||d[c]||g[c]||r;return a?n.createElement(h,s(s({ref:t},p),{},{components:a})):n.createElement(h,s({ref:t},p))}));function h(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=a.length,s=new Array(r);s[0]=c;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[d]="string"==typeof e?e:i,s[1]=o;for(var u=2;u{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>g,frontMatter:()=>r,metadata:()=>o,toc:()=>u});var n=a(7462),i=(a(7294),a(3905));const r={},s="Update Assistant",o={unversionedId:"updating/update-assistant",id:"version-0.3/updating/update-assistant",title:"Update Assistant",description:"The Update Assistant helps you update the storage objects from AFJ to newer versions. This documents describes the different ways you can leverage the Update Assistant from fully managed to more manual approaches.",source:"@site/versioned_docs/version-0.3/updating/update-assistant.md",sourceDirName:"updating",slug:"/updating/update-assistant",permalink:"/guides/0.3/updating/update-assistant",draft:!1,tags:[],version:"0.3",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Updating AFJ",permalink:"/guides/0.3/updating/"},next:{title:"Migrating from AFJ 0.1.0 to 0.2.x",permalink:"/guides/0.3/updating/versions/0.1-to-0.2"}},l={},u=[{value:"Update Strategies",id:"update-strategies",level:2},{value:"Manually instantiating the update assistant on agent startup",id:"manually-instantiating-the-update-assistant-on-agent-startup",level:3},{value:"Storing the agent storage version outside of the agent storage",id:"storing-the-agent-storage-version-outside-of-the-agent-storage",level:3},{value:"Automatically update on agent startup",id:"automatically-update-on-agent-startup",level:3},{value:"Backups",id:"backups",level:2}],p={toc:u},d="wrapper";function g(e){let{components:t,...a}=e;return(0,i.kt)(d,(0,n.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"update-assistant"},"Update Assistant"),(0,i.kt)("p",null,"The Update Assistant helps you update the storage objects from AFJ to newer versions. This documents describes the different ways you can leverage the Update Assistant from fully managed to more manual approaches."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#update-strategies"},"Update Strategies"),(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#manually-instantiating-the-update-assistant-on-agent-startup"},"Manually instantiating the update assistant on agent startup")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#storing-the-agent-storage-version-outside-of-the-agent-storage"},"Storing the agent storage version outside of the agent storage")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#automatically-update-on-agent-startup"},"Automatically update on agent startup")))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#backups"},"Backups"))),(0,i.kt)("h2",{id:"update-strategies"},"Update Strategies"),(0,i.kt)("p",null,"There are three options on how to leverage the update assistant on agent startup:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Manually instantiating the update assistant on agent startup"),(0,i.kt)("li",{parentName:"ol"},"Storing the agent storage version outside of the agent storage"),(0,i.kt)("li",{parentName:"ol"},"Automatically update on agent startup")),(0,i.kt)("h3",{id:"manually-instantiating-the-update-assistant-on-agent-startup"},"Manually instantiating the update assistant on agent startup"),(0,i.kt)("p",null,"When the version of the storage is stored inside the agent storage, it means we need to check if the agent needs to be updated on every agent startup. We'll initialize the update assistant and check whether the storage is up to date. The advantage of this approach is that you don't have to store anything yourself, and have full control over the workflow."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts"},"import { UpdateAssistant, Agent } from '@aries-framework/core'\n\n// or @aries-framework/node\nimport { agentDependencies } from '@aries-framework/react-native'\n\n// First create the agent\nconst agent = new Agent({\n config,\n dependencies: agentDependencies,\n})\n\n// Then initialize the update assistant with the update config\nconst updateAssistant = new UpdateAssistant(agent, {\n v0_1ToV0_2: {\n mediationRoleUpdateStrategy: 'allMediator',\n },\n})\n\n// Initialize the update assistant so we can read the current storage version\n// from the wallet. If you manually initialize the wallet you should do this _before_\n// calling initialize on the update assistant\n// await agent.wallet.initialize(walletConfig)\nawait updateAssistant.initialize()\n\n// Check if the agent is up to date, if not call update\nif (!(await updateAssistant.isUpToDate())) {\n await updateAssistant.update()\n}\n\n// Once finished initialize the agent. You should do this on every launch of the agent\nawait agent.initialize()\n")),(0,i.kt)("h3",{id:"storing-the-agent-storage-version-outside-of-the-agent-storage"},"Storing the agent storage version outside of the agent storage"),(0,i.kt)("p",null,"When the version of the storage is stored outside of the agent storage, you don't have to initialize the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," on every agent agent startup. You can just check if the storage version is up to date and instantiate the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," if not. The advantage of this approach is that you don't have to instantiate the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," on every agent startup, but this does mean that you have to store the storage version yourself."),(0,i.kt)("p",null,"When a wallet has been exported and later imported you don't always have the latest version available. If this is the case you can always rely on Method 1 or 2 for updating the wallet, and storing the version yourself afterwards. You can also get the current version by calling ",(0,i.kt)("inlineCode",{parentName:"p"},"await updateAssistant.getCurrentAgentStorageVersion()"),". Do note the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," needs to be initialized before calling this method."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts"},"import { UpdateAssistant, Agent } from '@aries-framework/core'\n\n// or @aries-framework/node\nimport { agentDependencies } from '@aries-framework/react-native'\n\n// The storage version will normally be stored in e.g. persistent storage on a mobile device\nlet currentStorageVersion: VersionString = '0.1'\n\n// First create the agent\nconst agent = new Agent({\n config,\n dependencies: agentDependencies,\n})\n\n// We only initialize the update assistant if our stored version is not equal\n// to the frameworkStorageVersion of the UpdateAssistant. The advantage of this\n// is that we don't have to initialize the UpdateAssistant to retrieve the current\n// storage version.\nif (currentStorageVersion !== UpdateAssistant.frameworkStorageVersion) {\n const updateAssistant = new UpdateAssistant(agent, {\n v0_1ToV0_2: {\n mediationRoleUpdateStrategy: 'recipientIfEndpoint',\n },\n })\n\n // Same as with the previous strategy, if you normally call agent.wallet.initialize() manually\n // you need to call this before calling updateAssistant.initialize()\n await updateAssistant.initialize()\n\n await updateAssistant.update()\n\n // Store the version so we can leverage it during the next agent startup and don't have\n // to initialize the update assistant again until a new version is released\n currentStorageVersion = UpdateAssistant.frameworkStorageVersion\n}\n\n// Once finished initialize the agent. You should do this on every launch of the agent\nawait agent.initialize()\n")),(0,i.kt)("h3",{id:"automatically-update-on-agent-startup"},"Automatically update on agent startup"),(0,i.kt)("p",null,"This is by far the easiest way to update the agent, but has the least amount of flexibility and is not configurable. This means you will have to use the default update options to update the agent storage. You can find the default update config in the respective version migration guides (e.g. in ",(0,i.kt)("a",{parentName:"p",href:"/guides/0.5/updating/versions/0.1-to-0.2"},"0.1-to-0.2"),")."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts"},"import { UpdateAssistant, Agent } from '@aries-framework/core'\n\n// or @aries-framework/node\nimport { agentDependencies } from '@aries-framework/react-native'\n\n// First create the agent, setting the autoUpdateStorageOnStartup option to true\nconst agent = new Agent({\n config: {\n ...config,\n autoUpdateStorageOnStartup: true,\n },\n dependencies: agentDependencies,\n})\n\n// Then we call initialize, which under the hood will call the update assistant if the storage is not update to date.\nawait agent.initialize()\n")),(0,i.kt)("h2",{id:"backups"},"Backups"),(0,i.kt)("p",null,"Before starting the update, the update assistant will automatically create a backup of the wallet. If the migration succeeds the backup won't be used. If the backup fails, another backup will be made of the migrated wallet, after which the backup will be restored."),(0,i.kt)("p",null,"The backups can be found at the following locations. The ",(0,i.kt)("inlineCode",{parentName:"p"},"backupIdentifier")," is generated at the start of the update process and generated based on the current timestamp."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Backup path: ",(0,i.kt)("inlineCode",{parentName:"li"},"${agent.config.fileSystem.basePath}/afj/migration/backup/${backupIdentifier}")),(0,i.kt)("li",{parentName:"ul"},"Migration backup: ",(0,i.kt)("inlineCode",{parentName:"li"},"${agent.config.fileSystem.basePath}/afj/migration/backup/${backupIdentifier}-error"))),(0,i.kt)("blockquote",null,(0,i.kt)("p",{parentName:"blockquote"},"In the future the backup assistant will make a number of improvements to the recovery process. Namely:"),(0,i.kt)("ul",{parentName:"blockquote"},(0,i.kt)("li",{parentName:"ul"},"Do not throw an error if the update fails, but rather return an object that contains the status, and include the backup paths and backup identifiers."))))}g.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[4656],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>h});var n=a(7294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var l=n.createContext({}),u=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},p=function(e){var t=u(e.components);return n.createElement(l.Provider,{value:t},e.children)},d="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),d=u(a),c=i,h=d["".concat(l,".").concat(c)]||d[c]||g[c]||r;return a?n.createElement(h,s(s({ref:t},p),{},{components:a})):n.createElement(h,s({ref:t},p))}));function h(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=a.length,s=new Array(r);s[0]=c;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[d]="string"==typeof e?e:i,s[1]=o;for(var u=2;u{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>g,frontMatter:()=>r,metadata:()=>o,toc:()=>u});var n=a(7462),i=(a(7294),a(3905));const r={},s="Update Assistant",o={unversionedId:"updating/update-assistant",id:"version-0.3/updating/update-assistant",title:"Update Assistant",description:"The Update Assistant helps you update the storage objects from AFJ to newer versions. This documents describes the different ways you can leverage the Update Assistant from fully managed to more manual approaches.",source:"@site/versioned_docs/version-0.3/updating/update-assistant.md",sourceDirName:"updating",slug:"/updating/update-assistant",permalink:"/guides/0.3/updating/update-assistant",draft:!1,tags:[],version:"0.3",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Updating AFJ",permalink:"/guides/0.3/updating/"},next:{title:"Migrating from AFJ 0.1.0 to 0.2.x",permalink:"/guides/0.3/updating/versions/0.1-to-0.2"}},l={},u=[{value:"Update Strategies",id:"update-strategies",level:2},{value:"Manually instantiating the update assistant on agent startup",id:"manually-instantiating-the-update-assistant-on-agent-startup",level:3},{value:"Storing the agent storage version outside of the agent storage",id:"storing-the-agent-storage-version-outside-of-the-agent-storage",level:3},{value:"Automatically update on agent startup",id:"automatically-update-on-agent-startup",level:3},{value:"Backups",id:"backups",level:2}],p={toc:u},d="wrapper";function g(e){let{components:t,...a}=e;return(0,i.kt)(d,(0,n.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"update-assistant"},"Update Assistant"),(0,i.kt)("p",null,"The Update Assistant helps you update the storage objects from AFJ to newer versions. This documents describes the different ways you can leverage the Update Assistant from fully managed to more manual approaches."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#update-strategies"},"Update Strategies"),(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#manually-instantiating-the-update-assistant-on-agent-startup"},"Manually instantiating the update assistant on agent startup")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#storing-the-agent-storage-version-outside-of-the-agent-storage"},"Storing the agent storage version outside of the agent storage")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#automatically-update-on-agent-startup"},"Automatically update on agent startup")))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"#backups"},"Backups"))),(0,i.kt)("h2",{id:"update-strategies"},"Update Strategies"),(0,i.kt)("p",null,"There are three options on how to leverage the update assistant on agent startup:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Manually instantiating the update assistant on agent startup"),(0,i.kt)("li",{parentName:"ol"},"Storing the agent storage version outside of the agent storage"),(0,i.kt)("li",{parentName:"ol"},"Automatically update on agent startup")),(0,i.kt)("h3",{id:"manually-instantiating-the-update-assistant-on-agent-startup"},"Manually instantiating the update assistant on agent startup"),(0,i.kt)("p",null,"When the version of the storage is stored inside the agent storage, it means we need to check if the agent needs to be updated on every agent startup. We'll initialize the update assistant and check whether the storage is up to date. The advantage of this approach is that you don't have to store anything yourself, and have full control over the workflow."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts"},"import { UpdateAssistant, Agent } from '@aries-framework/core'\n\n// or @aries-framework/node\nimport { agentDependencies } from '@aries-framework/react-native'\n\n// First create the agent\nconst agent = new Agent({\n config,\n dependencies: agentDependencies,\n})\n\n// Then initialize the update assistant with the update config\nconst updateAssistant = new UpdateAssistant(agent, {\n v0_1ToV0_2: {\n mediationRoleUpdateStrategy: 'allMediator',\n },\n})\n\n// Initialize the update assistant so we can read the current storage version\n// from the wallet. If you manually initialize the wallet you should do this _before_\n// calling initialize on the update assistant\n// await agent.wallet.initialize(walletConfig)\nawait updateAssistant.initialize()\n\n// Check if the agent is up to date, if not call update\nif (!(await updateAssistant.isUpToDate())) {\n await updateAssistant.update()\n}\n\n// Once finished initialize the agent. You should do this on every launch of the agent\nawait agent.initialize()\n")),(0,i.kt)("h3",{id:"storing-the-agent-storage-version-outside-of-the-agent-storage"},"Storing the agent storage version outside of the agent storage"),(0,i.kt)("p",null,"When the version of the storage is stored outside of the agent storage, you don't have to initialize the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," on every agent agent startup. You can just check if the storage version is up to date and instantiate the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," if not. The advantage of this approach is that you don't have to instantiate the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," on every agent startup, but this does mean that you have to store the storage version yourself."),(0,i.kt)("p",null,"When a wallet has been exported and later imported you don't always have the latest version available. If this is the case you can always rely on Method 1 or 2 for updating the wallet, and storing the version yourself afterwards. You can also get the current version by calling ",(0,i.kt)("inlineCode",{parentName:"p"},"await updateAssistant.getCurrentAgentStorageVersion()"),". Do note the ",(0,i.kt)("inlineCode",{parentName:"p"},"UpdateAssistant")," needs to be initialized before calling this method."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts"},"import { UpdateAssistant, Agent } from '@aries-framework/core'\n\n// or @aries-framework/node\nimport { agentDependencies } from '@aries-framework/react-native'\n\n// The storage version will normally be stored in e.g. persistent storage on a mobile device\nlet currentStorageVersion: VersionString = '0.1'\n\n// First create the agent\nconst agent = new Agent({\n config,\n dependencies: agentDependencies,\n})\n\n// We only initialize the update assistant if our stored version is not equal\n// to the frameworkStorageVersion of the UpdateAssistant. The advantage of this\n// is that we don't have to initialize the UpdateAssistant to retrieve the current\n// storage version.\nif (currentStorageVersion !== UpdateAssistant.frameworkStorageVersion) {\n const updateAssistant = new UpdateAssistant(agent, {\n v0_1ToV0_2: {\n mediationRoleUpdateStrategy: 'recipientIfEndpoint',\n },\n })\n\n // Same as with the previous strategy, if you normally call agent.wallet.initialize() manually\n // you need to call this before calling updateAssistant.initialize()\n await updateAssistant.initialize()\n\n await updateAssistant.update()\n\n // Store the version so we can leverage it during the next agent startup and don't have\n // to initialize the update assistant again until a new version is released\n currentStorageVersion = UpdateAssistant.frameworkStorageVersion\n}\n\n// Once finished initialize the agent. You should do this on every launch of the agent\nawait agent.initialize()\n")),(0,i.kt)("h3",{id:"automatically-update-on-agent-startup"},"Automatically update on agent startup"),(0,i.kt)("p",null,"This is by far the easiest way to update the agent, but has the least amount of flexibility and is not configurable. This means you will have to use the default update options to update the agent storage. You can find the default update config in the respective version migration guides (e.g. in ",(0,i.kt)("a",{parentName:"p",href:"/guides/updating/versions/0.1-to-0.2"},"0.1-to-0.2"),")."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-ts"},"import { UpdateAssistant, Agent } from '@aries-framework/core'\n\n// or @aries-framework/node\nimport { agentDependencies } from '@aries-framework/react-native'\n\n// First create the agent, setting the autoUpdateStorageOnStartup option to true\nconst agent = new Agent({\n config: {\n ...config,\n autoUpdateStorageOnStartup: true,\n },\n dependencies: agentDependencies,\n})\n\n// Then we call initialize, which under the hood will call the update assistant if the storage is not update to date.\nawait agent.initialize()\n")),(0,i.kt)("h2",{id:"backups"},"Backups"),(0,i.kt)("p",null,"Before starting the update, the update assistant will automatically create a backup of the wallet. If the migration succeeds the backup won't be used. If the backup fails, another backup will be made of the migrated wallet, after which the backup will be restored."),(0,i.kt)("p",null,"The backups can be found at the following locations. The ",(0,i.kt)("inlineCode",{parentName:"p"},"backupIdentifier")," is generated at the start of the update process and generated based on the current timestamp."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Backup path: ",(0,i.kt)("inlineCode",{parentName:"li"},"${agent.config.fileSystem.basePath}/afj/migration/backup/${backupIdentifier}")),(0,i.kt)("li",{parentName:"ul"},"Migration backup: ",(0,i.kt)("inlineCode",{parentName:"li"},"${agent.config.fileSystem.basePath}/afj/migration/backup/${backupIdentifier}-error"))),(0,i.kt)("blockquote",null,(0,i.kt)("p",{parentName:"blockquote"},"In the future the backup assistant will make a number of improvements to the recovery process. Namely:"),(0,i.kt)("ul",{parentName:"blockquote"},(0,i.kt)("li",{parentName:"ul"},"Do not throw an error if the update fails, but rather return an object that contains the status, and include the backup paths and backup identifiers."))))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ece13197.116727d2.js b/assets/js/ece13197.116727d2.js new file mode 100644 index 00000000..aef9963e --- /dev/null +++ b/assets/js/ece13197.116727d2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[9852],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(n),h=a,m=u["".concat(l,".").concat(h)]||u[h]||d[h]||i;return n?r.createElement(m,o(o({ref:t},p),{},{components:n})):r.createElement(m,o({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:a,o[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var r=n(7462),a=(n(7294),n(3905));const i={},o="Agents",s={unversionedId:"concepts/agents",id:"version-0.4/concepts/agents",title:"Agents",description:"When working with any Aries implementation, you will interact with an Aries",source:"@site/versioned_docs/version-0.4/concepts/agents.md",sourceDirName:"concepts",slug:"/concepts/agents",permalink:"/guides/0.4/concepts/agents",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Concepts",permalink:"/guides/0.4/concepts/"},next:{title:"DIDs and DIDComm",permalink:"/guides/0.4/concepts/did-and-didcomm"}},l={},c=[{value:"Characteristics",id:"characteristics",level:3},{value:"Categories",id:"categories",level:3},{value:"Examples",id:"examples",level:3},{value:"Useful resources",id:"useful-resources",level:3}],p={toc:c},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"agents"},"Agents"),(0,a.kt)("p",null,"When working with any Aries implementation, you will interact with an Aries\nagent. This will be either directly or via a REST API, like ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts-ext/tree/main/packages/rest"},"the Credo REST\nAPI"),"."),(0,a.kt)("h3",{id:"characteristics"},"Characteristics"),(0,a.kt)("p",null,"An Aries agent has three essential characteristics:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"It acts as a fiduciary on behalf of a single identity owner (or, for agents\nof things like IoT devices, pets, and similar things, a single controller)."),(0,a.kt)("li",{parentName:"ol"},"It holds cryptographic keys that uniquely embody its delegated\nauthorization."),(0,a.kt)("li",{parentName:"ol"},"It interacts using interoperable DIDComm protocols, more on that later.")),(0,a.kt)("p",null,"What this means is that an Aries agent will act your behalf to issue create\nconnections, issue credentials, send messages etc. It also have a cryptographic\ntoolkit with which it can uniquely, securely and verifiably operate. And lastly\nit interacts with other entities, this could be another agent, via ",(0,a.kt)("a",{parentName:"p",href:"https://identity.foundation/didcomm-messaging/spec/"},"DIDComm\nprotocols")," later on. The\nAries agent in the context of the Aries JavaScript ecosystem is your entry-point\nto all of the functionality."),(0,a.kt)("h3",{id:"categories"},"Categories"),(0,a.kt)("p",null,'There are many categories of Aries agents and we will group them into two\ncategories; a mobile agent and a cloud agent. These agents are grouped based on\ntheir "location", e.g. a mobile wallet or server. Some other categories are a\nstatic, thin, thick and rich Aries agents. These agents are grouped based on\ntheir complexity instead of their "location". The Aries JavaScript ecosystem\nallows you to create a mobile agent and a cloud agent. It also allows any of\nthe complexity categorized agents.'),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("p",null,"Some examples of things that are Aries agent-like (since the definition can be\nbit loose, these examples might help to get a clearer picture):"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"A mobile wallet")),(0,a.kt)("p",null,"A mobile wallet, like\n",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-mobile-agent-react-native"},"aries-mobile-agent-react-native"),"\n, can be used to create connections, send basic messages, hold credentials,\netc. In the real world this could be an application that contains data like an\nofficial drivers license."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"An Identity hub")),(0,a.kt)("p",null,"An ",(0,a.kt)("a",{parentName:"p",href:"https://didproject.azurewebsites.net/docs/hub-overview.html"},"Identity Hub"),"\nis a personal data store that gives complete control to their owner. It allows\nfor secure sensitive data storage and sharing. Since everyone has multiple\ndevices these can be used as a more central point for your data."),(0,a.kt)("h3",{id:"useful-resources"},"Useful resources"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0004-agents/README.md"},"Hyperledger Aries RFC - 004:\nAgents")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/openwallet-foundation/credo-ts-docs/tree/main/versioned_docs/version-0.4/getting-started"},"Credo - Getting\nStarted"))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ece13197.ebf2d838.js b/assets/js/ece13197.ebf2d838.js deleted file mode 100644 index a2cb628e..00000000 --- a/assets/js/ece13197.ebf2d838.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[9852],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(n),h=a,m=u["".concat(l,".").concat(h)]||u[h]||d[h]||i;return n?r.createElement(m,o(o({ref:t},p),{},{components:n})):r.createElement(m,o({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:a,o[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var r=n(7462),a=(n(7294),n(3905));const i={},o="Agents",s={unversionedId:"concepts/agents",id:"version-0.4/concepts/agents",title:"Agents",description:"When working with any Aries implementation, you will interact with an Aries",source:"@site/versioned_docs/version-0.4/concepts/agents.md",sourceDirName:"concepts",slug:"/concepts/agents",permalink:"/guides/concepts/agents",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Concepts",permalink:"/guides/concepts/"},next:{title:"DIDs and DIDComm",permalink:"/guides/concepts/did-and-didcomm"}},l={},c=[{value:"Characteristics",id:"characteristics",level:3},{value:"Categories",id:"categories",level:3},{value:"Examples",id:"examples",level:3},{value:"Useful resources",id:"useful-resources",level:3}],p={toc:c},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"agents"},"Agents"),(0,a.kt)("p",null,"When working with any Aries implementation, you will interact with an Aries\nagent. This will be either directly or via a REST API, like ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts-ext/tree/main/packages/rest"},"the Credo REST\nAPI"),"."),(0,a.kt)("h3",{id:"characteristics"},"Characteristics"),(0,a.kt)("p",null,"An Aries agent has three essential characteristics:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"It acts as a fiduciary on behalf of a single identity owner (or, for agents\nof things like IoT devices, pets, and similar things, a single controller)."),(0,a.kt)("li",{parentName:"ol"},"It holds cryptographic keys that uniquely embody its delegated\nauthorization."),(0,a.kt)("li",{parentName:"ol"},"It interacts using interoperable DIDComm protocols, more on that later.")),(0,a.kt)("p",null,"What this means is that an Aries agent will act your behalf to issue create\nconnections, issue credentials, send messages etc. It also have a cryptographic\ntoolkit with which it can uniquely, securely and verifiably operate. And lastly\nit interacts with other entities, this could be another agent, via ",(0,a.kt)("a",{parentName:"p",href:"https://identity.foundation/didcomm-messaging/spec/"},"DIDComm\nprotocols")," later on. The\nAries agent in the context of the Aries JavaScript ecosystem is your entry-point\nto all of the functionality."),(0,a.kt)("h3",{id:"categories"},"Categories"),(0,a.kt)("p",null,'There are many categories of Aries agents and we will group them into two\ncategories; a mobile agent and a cloud agent. These agents are grouped based on\ntheir "location", e.g. a mobile wallet or server. Some other categories are a\nstatic, thin, thick and rich Aries agents. These agents are grouped based on\ntheir complexity instead of their "location". The Aries JavaScript ecosystem\nallows you to create a mobile agent and a cloud agent. It also allows any of\nthe complexity categorized agents.'),(0,a.kt)("h3",{id:"examples"},"Examples"),(0,a.kt)("p",null,"Some examples of things that are Aries agent-like (since the definition can be\nbit loose, these examples might help to get a clearer picture):"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"A mobile wallet")),(0,a.kt)("p",null,"A mobile wallet, like\n",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-mobile-agent-react-native"},"aries-mobile-agent-react-native"),"\n, can be used to create connections, send basic messages, hold credentials,\netc. In the real world this could be an application that contains data like an\nofficial drivers license."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"An Identity hub")),(0,a.kt)("p",null,"An ",(0,a.kt)("a",{parentName:"p",href:"https://didproject.azurewebsites.net/docs/hub-overview.html"},"Identity Hub"),"\nis a personal data store that gives complete control to their owner. It allows\nfor secure sensitive data storage and sharing. Since everyone has multiple\ndevices these can be used as a more central point for your data."),(0,a.kt)("h3",{id:"useful-resources"},"Useful resources"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0004-agents/README.md"},"Hyperledger Aries RFC - 004:\nAgents")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/openwallet-foundation/credo-ts-docs/tree/main/versioned_docs/version-0.4/getting-started"},"Credo - Getting\nStarted"))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ee7869b6.39442c96.js b/assets/js/ee7869b6.39442c96.js deleted file mode 100644 index e876ef67..00000000 --- a/assets/js/ee7869b6.39442c96.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7240],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),d=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=d(e.components);return r.createElement(s.Provider,{value:t},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),p=d(n),u=a,h=p["".concat(s,".").concat(u)]||p[u]||m[u]||i;return n?r.createElement(h,o(o({ref:t},c),{},{components:n})):r.createElement(h,o({ref:t},c))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:a,o[1]=l;for(var d=2;d{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>m,frontMatter:()=>i,metadata:()=>l,toc:()=>d});var r=n(7462),a=(n(7294),n(3905));const i={},o="macOS (ARM)",l={unversionedId:"getting-started/set-up/indy-sdk/macos-arm",id:"version-0.4/getting-started/set-up/indy-sdk/macos-arm",title:"macOS (ARM)",description:"To install Indy SDK on macOS, a couple of dependencies are required. This guide covers the installation of the Indy SDK for macs with an ARM processor. For installing the Indy SDK on Intel based macs, please refer to the Indy SDK macOS (Intel) guide.",source:"@site/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/macos-arm.md",sourceDirName:"getting-started/set-up/indy-sdk",slug:"/getting-started/set-up/indy-sdk/macos-arm",permalink:"/guides/getting-started/set-up/indy-sdk/macos-arm",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"macOS (Intel)",permalink:"/guides/getting-started/set-up/indy-sdk/macos-intel"},next:{title:"React Native",permalink:"/guides/getting-started/set-up/indy-sdk/react-native"}},s={},d=[{value:"Libsodium",id:"libsodium",level:3},{value:"Libzmq",id:"libzmq",level:3},{value:"Indy SDK",id:"indy-sdk",level:3},{value:"Confirm installation",id:"confirm-installation",level:3}],c={toc:d},p="wrapper";function m(e){let{components:t,...n}=e;return(0,a.kt)(p,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"macos-arm"},"macOS (ARM)"),(0,a.kt)("p",null,"To install ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk"},"Indy SDK")," on macOS, a couple of dependencies are required. This guide covers the installation of the Indy SDK for macs with an ARM processor. For installing the Indy SDK on Intel based macs, please refer to the ",(0,a.kt)("a",{parentName:"p",href:"./macos-intel"},"Indy SDK macOS (Intel)")," guide."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"This installation assumes that you have ",(0,a.kt)("a",{parentName:"p",href:"https://brew.sh"},"brew")," installed. If not, please install it via this command:"),(0,a.kt)("pre",{parentName:"admonition"},(0,a.kt)("code",{parentName:"pre"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n'))),(0,a.kt)("h3",{id:"libsodium"},"Libsodium"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/jedisct1/libsodium"},"Libsodium")," is used by the Indy SDK for encryption, decryption, hashing and signing."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"brew install libsodium\n")),(0,a.kt)("h3",{id:"libzmq"},"Libzmq"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/zeromq/libzmq"},"Libzmq")," is a lightweight messaging queue used by the Indy SDK."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"brew install zeromq\n")),(0,a.kt)("h3",{id:"indy-sdk"},"Indy SDK"),(0,a.kt)("p",null,"The Indy SDK does not been distributed properly for macOS. We have a pre-built library available that can\nbe downloaded. If you prefer to build from source, you can follow the instructions in the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk#how-to-build-indy-sdk-from-source"},"Indy SDK repository")),(0,a.kt)("p",null,"First, download the pre-built library from ",(0,a.kt)("a",{parentName:"p",href:"https://drive.google.com/file/d/1JaRqAEAyodjeh120YYZ0t42zfhN3wHiW/view"},"Google Drive"),"."),(0,a.kt)("p",null,"After this, open ",(0,a.kt)("inlineCode",{parentName:"p"},"Finder"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"control+click")," on the library and click on ",(0,a.kt)("inlineCode",{parentName:"p"},"open"),".\nThis is something that has to be done as the library is not properly signed."),(0,a.kt)("p",null,"Lastly the library just has to be moved to the correct location."),(0,a.kt)("admonition",{type:"caution"},(0,a.kt)("p",{parentName:"admonition"},"If you downloaded the file in another directory, please change the first part of this command")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"sudo mv ~/Downloads/libindy.dylib /usr/local/lib/\n")),(0,a.kt)("h3",{id:"confirm-installation"},"Confirm installation"),(0,a.kt)("p",null,"To see whether the Indy SDK is correctly installed on your system, run the following command and it should not error."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"npx -p @aries-framework/node@^0.3 is-indy-installed\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ee7869b6.593c6ac3.js b/assets/js/ee7869b6.593c6ac3.js new file mode 100644 index 00000000..82bc4c38 --- /dev/null +++ b/assets/js/ee7869b6.593c6ac3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7240],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),d=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=d(e.components);return r.createElement(s.Provider,{value:t},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),p=d(n),u=a,h=p["".concat(s,".").concat(u)]||p[u]||m[u]||i;return n?r.createElement(h,o(o({ref:t},c),{},{components:n})):r.createElement(h,o({ref:t},c))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:a,o[1]=l;for(var d=2;d{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>m,frontMatter:()=>i,metadata:()=>l,toc:()=>d});var r=n(7462),a=(n(7294),n(3905));const i={},o="macOS (ARM)",l={unversionedId:"getting-started/set-up/indy-sdk/macos-arm",id:"version-0.4/getting-started/set-up/indy-sdk/macos-arm",title:"macOS (ARM)",description:"To install Indy SDK on macOS, a couple of dependencies are required. This guide covers the installation of the Indy SDK for macs with an ARM processor. For installing the Indy SDK on Intel based macs, please refer to the Indy SDK macOS (Intel) guide.",source:"@site/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/macos-arm.md",sourceDirName:"getting-started/set-up/indy-sdk",slug:"/getting-started/set-up/indy-sdk/macos-arm",permalink:"/guides/0.4/getting-started/set-up/indy-sdk/macos-arm",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"macOS (Intel)",permalink:"/guides/0.4/getting-started/set-up/indy-sdk/macos-intel"},next:{title:"React Native",permalink:"/guides/0.4/getting-started/set-up/indy-sdk/react-native"}},s={},d=[{value:"Libsodium",id:"libsodium",level:3},{value:"Libzmq",id:"libzmq",level:3},{value:"Indy SDK",id:"indy-sdk",level:3},{value:"Confirm installation",id:"confirm-installation",level:3}],c={toc:d},p="wrapper";function m(e){let{components:t,...n}=e;return(0,a.kt)(p,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"macos-arm"},"macOS (ARM)"),(0,a.kt)("p",null,"To install ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk"},"Indy SDK")," on macOS, a couple of dependencies are required. This guide covers the installation of the Indy SDK for macs with an ARM processor. For installing the Indy SDK on Intel based macs, please refer to the ",(0,a.kt)("a",{parentName:"p",href:"./macos-intel"},"Indy SDK macOS (Intel)")," guide."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"This installation assumes that you have ",(0,a.kt)("a",{parentName:"p",href:"https://brew.sh"},"brew")," installed. If not, please install it via this command:"),(0,a.kt)("pre",{parentName:"admonition"},(0,a.kt)("code",{parentName:"pre"},'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n'))),(0,a.kt)("h3",{id:"libsodium"},"Libsodium"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/jedisct1/libsodium"},"Libsodium")," is used by the Indy SDK for encryption, decryption, hashing and signing."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"brew install libsodium\n")),(0,a.kt)("h3",{id:"libzmq"},"Libzmq"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/zeromq/libzmq"},"Libzmq")," is a lightweight messaging queue used by the Indy SDK."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"brew install zeromq\n")),(0,a.kt)("h3",{id:"indy-sdk"},"Indy SDK"),(0,a.kt)("p",null,"The Indy SDK does not been distributed properly for macOS. We have a pre-built library available that can\nbe downloaded. If you prefer to build from source, you can follow the instructions in the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-sdk#how-to-build-indy-sdk-from-source"},"Indy SDK repository")),(0,a.kt)("p",null,"First, download the pre-built library from ",(0,a.kt)("a",{parentName:"p",href:"https://drive.google.com/file/d/1JaRqAEAyodjeh120YYZ0t42zfhN3wHiW/view"},"Google Drive"),"."),(0,a.kt)("p",null,"After this, open ",(0,a.kt)("inlineCode",{parentName:"p"},"Finder"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"control+click")," on the library and click on ",(0,a.kt)("inlineCode",{parentName:"p"},"open"),".\nThis is something that has to be done as the library is not properly signed."),(0,a.kt)("p",null,"Lastly the library just has to be moved to the correct location."),(0,a.kt)("admonition",{type:"caution"},(0,a.kt)("p",{parentName:"admonition"},"If you downloaded the file in another directory, please change the first part of this command")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"sudo mv ~/Downloads/libindy.dylib /usr/local/lib/\n")),(0,a.kt)("h3",{id:"confirm-installation"},"Confirm installation"),(0,a.kt)("p",null,"To see whether the Indy SDK is correctly installed on your system, run the following command and it should not error."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-console"},"npx -p @aries-framework/node@^0.3 is-indy-installed\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ee898636.249ae573.js b/assets/js/ee898636.249ae573.js new file mode 100644 index 00000000..3fcb5901 --- /dev/null +++ b/assets/js/ee898636.249ae573.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[9233],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=c(n),m=r,h=p["".concat(l,".").concat(m)]||p[m]||d[m]||o;return n?a.createElement(h,i(i({ref:t},u),{},{components:n})):a.createElement(h,i({ref:t},u))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var c=2;c{n.d(t,{Z:()=>i});var a=n(7294),r=n(6010);const o={tabItem:"tabItem_Ymn6"};function i(e){let{children:t,hidden:n,className:i}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(o.tabItem,i),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),r=n(7294),o=n(6010),i=n(2466),s=n(6550),l=n(1980),c=n(7392),u=n(12);function p(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function d(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,c.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const a=(0,s.k6)(),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,l._X)(o),(0,r.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(a.location.search);t.set(o,e),a.replace({...a.location,search:t.toString()})}),[o,a])]}function b(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,o=d(e),[i,s]=(0,r.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(!m({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}))),[l,c]=h({queryString:n,groupId:a}),[p,b]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,o]=(0,u.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:a}),g=(()=>{const e=l??p;return m({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{g&&s(g)}),[g]);return{selectedValue:i,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);s(e),c(e),b(e)}),[c,b,o]),tabValues:o}}var g=n(2389);const f={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function v(e){let{className:t,block:n,selectedValue:s,selectValue:l,tabValues:c}=e;const u=[],{blockElementScrollPositionUntilNextRender:p}=(0,i.o5)(),d=e=>{const t=e.currentTarget,n=u.indexOf(t),a=c[n].value;a!==s&&(p(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=u.indexOf(e.currentTarget)+1;t=u[n]??u[0];break}case"ArrowLeft":{const n=u.indexOf(e.currentTarget)-1;t=u[n]??u[u.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},c.map((e=>{let{value:t,label:n,attributes:i}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>u.push(e),onKeyDown:m,onClick:d},i,{className:(0,o.Z)("tabs__item",f.tabItem,i?.className,{"tabs__item--active":s===t})}),n??t)})))}function k(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function y(e){const t=b(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",f.tabList)},r.createElement(v,(0,a.Z)({},e,t)),r.createElement(k,(0,a.Z)({},e,t)))}function w(e){const t=(0,g.Z)();return r.createElement(y,(0,a.Z)({key:String(t)},e))}},2757:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>p});var a=n(7462),r=(n(7294),n(3905)),o=n(4866),i=n(5162);const s={},l="Create a connection",c={unversionedId:"tutorials/create-a-connection",id:"version-0.4/tutorials/create-a-connection",title:"Create a connection",description:"In this tutorial we will create a connection as Acme Corp with Bob. We will",source:"@site/versioned_docs/version-0.4/tutorials/create-a-connection.md",sourceDirName:"tutorials",slug:"/tutorials/create-a-connection",permalink:"/guides/0.4/tutorials/create-a-connection",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Logging",permalink:"/guides/0.4/tutorials/agent-config/logging"},next:{title:"Cheqd Did Module",permalink:"/guides/0.4/tutorials/cheqd/"}},u={},p=[{value:"1. Setting up the agents",id:"1-setting-up-the-agents",level:3},{value:"Bob",id:"bob",level:4},{value:"Acme",id:"acme",level:4},{value:"2. Creating an invitation",id:"2-creating-an-invitation",level:4},{value:"3. Receiving the invitation",id:"3-receiving-the-invitation",level:3},{value:"4. (additional) listen to incoming connection responses",id:"4-additional-listen-to-incoming-connection-responses",level:3},{value:"5. Full code snippets",id:"5-full-code-snippets",level:3},{value:"Useful resources",id:"useful-resources",level:3}],d={toc:p},m="wrapper";function h(e){let{components:t,...n}=e;return(0,r.kt)(m,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"create-a-connection"},"Create a connection"),(0,r.kt)("p",null,"In this tutorial we will create a connection as ",(0,r.kt)("em",{parentName:"p"},"Acme Corp")," with ",(0,r.kt)("em",{parentName:"p"},"Bob"),". We will\nstart with setting up both their agents with the minimal configuration required\nto follow this tutorial. After the initialization we will then create an\ninvitation as ",(0,r.kt)("em",{parentName:"p"},"Acme Corp")," and send it over to ",(0,r.kt)("em",{parentName:"p"},"Bob"),". ",(0,r.kt)("em",{parentName:"p"},"Bob")," will then accept\nthis invitation and at that point they have established a connection and they\nknow how to reach each other for sending a basic message, issuing a credential,\nverifying a proof, etc."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This section assumes that"),(0,r.kt)("ol",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ol"},"You have ",(0,r.kt)("a",{parentName:"li",href:"../getting-started"},"set-up your development environment"),"."),(0,r.kt)("li",{parentName:"ol"},"You have basic knowledge of the required fields in the ",(0,r.kt)("a",{parentName:"li",href:"./agent-config"},"Agent Config")))),(0,r.kt)("h3",{id:"1-setting-up-the-agents"},"1. Setting up the agents"),(0,r.kt)("p",null,"First for both agents we must setup and initialize an agent to work with.\nDepending on your target, ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/react-native"},"React\nNative")," or\n",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/react-native"},"Node.js"),", it might vary."),(0,r.kt)("p",null,"In this tutorial ",(0,r.kt)("em",{parentName:"p"},"Bob")," will be in a ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/react-native"},"React Native\nenvironment")," and ",(0,r.kt)("em",{parentName:"p"},"Acme Corp")," in\na ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/nodejs"},"Node.js environment"),"."),(0,r.kt)("h4",{id:"bob"},"Bob"),(0,r.kt)("p",null,"For bob we need to setup a basic agent with a wallet, mediator and outbound\ntransport."),(0,r.kt)("admonition",{type:"bob"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts section-1",showLineNumbers:!0,"create-a-connection.ts":!0,"section-1":!0},""))),(0,r.kt)("h4",{id:"acme"},"Acme"),(0,r.kt)("p",null,"For Acme we need to setup a basic agent with a wallet, inbound and outbound\ntransport."),(0,r.kt)("admonition",{type:"acme"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts section-2",showLineNumbers:!0,"create-a-connection.ts":!0,"section-2":!0},""))),(0,r.kt)("h4",{id:"2-creating-an-invitation"},"2. Creating an invitation"),(0,r.kt)("p",null,"Now that we have setup both agents, we can create an invitation from ",(0,r.kt)("em",{parentName:"p"},"Acme Corp"),"."),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(i.Z,{label:"New",value:"tab1",mdxType:"TabItem"},(0,r.kt)("p",null,"This method will create an invitation using the legacy method according to ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md"},"0434: Out-of-Band Protocol 1.1"),"."),(0,r.kt)("admonition",{type:"acme"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts section-3",showLineNumbers:!0,"create-a-connection.ts":!0,"section-3":!0},"const outOfBandRecord = await agent.oob.createInvitation()\n\nconst serializedInvitation = outOfBandRecord.outOfBandInvitation.toUrl({ domain: 'https://example.org' })\n")))),(0,r.kt)(i.Z,{label:"Legacy",value:"tab2",mdxType:"TabItem"},(0,r.kt)("p",null,"This method will create an invitation using the legacy method according to ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0160-connection-protocol/README.md"},"0160: Connection Protocol"),"."),(0,r.kt)("admonition",{type:"acme"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts section-4",showLineNumbers:!0,"create-a-connection.ts":!0,"section-4":!0},""))))),(0,r.kt)("h3",{id:"3-receiving-the-invitation"},"3. Receiving the invitation"),(0,r.kt)("p",null,"After we have created the invitation we have to transmit it to the other\nagent. Common practise, when sending it to a holder, it to embed the url inside\na QR code. This QR code can then be scanned by the holder, in this case ",(0,r.kt)("em",{parentName:"p"},"Bob"),".\nAfter this, because both have set ",(0,r.kt)("inlineCode",{parentName:"p"},"autoAcceptConnections")," to ",(0,r.kt)("inlineCode",{parentName:"p"},"true"),", the\nconnection is established."),(0,r.kt)("admonition",{type:"bob"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"create-a-connection.ts section-5","create-a-connection.ts":!0,"section-5":!0},""))),(0,r.kt)("h3",{id:"4-additional-listen-to-incoming-connection-responses"},"4. (additional) listen to incoming connection responses"),(0,r.kt)("p",null,"When you quickly want to use the event or the data of a response to a\nconnection request, you can start an ",(0,r.kt)("a",{parentName:"p",href:"https://example.org"},"TODO: agent event\nlistener"),"."),(0,r.kt)("p",null,"Another use case for this would be to get the ",(0,r.kt)("inlineCode",{parentName:"p"},"connectionRecord")," of the\nconnection as it is only created when the invitation has been received by the\nother agent. The ",(0,r.kt)("inlineCode",{parentName:"p"},"connectionRecord")," is very essential in processes like ",(0,r.kt)("a",{parentName:"p",href:"https://example.org"},"TODO:\nissuing a credential")," or ",(0,r.kt)("a",{parentName:"p",href:"https://example.org"},"TODO: verifying a\nproof"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"connectionRecord")," can also be retrieved with\n",(0,r.kt)("inlineCode",{parentName:"p"},"agent.connections.findAllByOutOfBandId(id)"),", but with this method there is no\nway of knowing if the invitation has been received."),(0,r.kt)("admonition",{type:"acme"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts section-6",showLineNumbers:!0,"create-a-connection.ts":!0,"section-6":!0},""))),(0,r.kt)("h3",{id:"5-full-code-snippets"},"5. Full code snippets"),(0,r.kt)("p",null,"Below are both code snippets for each agent. These can be used as base but\nshould be edited to fit your use case. The\n",(0,r.kt)("a",{parentName:"p",href:"./agent-config#walletconfigkey"},(0,r.kt)("inlineCode",{parentName:"a"},"walletConfig.key")),' must be changed as it can\nlead to other people knowing your "password" to your wallet.'),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts",showLineNumbers:!0,"create-a-connection.ts":!0},"")),(0,r.kt)("h3",{id:"useful-resources"},"Useful resources"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0160-connection-protocol/README.md"},"0160: Connection Protocol")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md"},"0434: Out-of-Band Protocol 1.1"))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ee898636.ccf696ac.js b/assets/js/ee898636.ccf696ac.js deleted file mode 100644 index 73fec593..00000000 --- a/assets/js/ee898636.ccf696ac.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[9233],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=c(n),m=r,h=p["".concat(l,".").concat(m)]||p[m]||d[m]||o;return n?a.createElement(h,i(i({ref:t},u),{},{components:n})):a.createElement(h,i({ref:t},u))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var c=2;c{n.d(t,{Z:()=>i});var a=n(7294),r=n(6010);const o={tabItem:"tabItem_Ymn6"};function i(e){let{children:t,hidden:n,className:i}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(o.tabItem,i),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),r=n(7294),o=n(6010),i=n(2466),s=n(6550),l=n(1980),c=n(7392),u=n(12);function p(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function d(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,c.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const a=(0,s.k6)(),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,l._X)(o),(0,r.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(a.location.search);t.set(o,e),a.replace({...a.location,search:t.toString()})}),[o,a])]}function b(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,o=d(e),[i,s]=(0,r.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(!m({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}))),[l,c]=h({queryString:n,groupId:a}),[p,b]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,o]=(0,u.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:a}),g=(()=>{const e=l??p;return m({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{g&&s(g)}),[g]);return{selectedValue:i,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);s(e),c(e),b(e)}),[c,b,o]),tabValues:o}}var g=n(2389);const f={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function v(e){let{className:t,block:n,selectedValue:s,selectValue:l,tabValues:c}=e;const u=[],{blockElementScrollPositionUntilNextRender:p}=(0,i.o5)(),d=e=>{const t=e.currentTarget,n=u.indexOf(t),a=c[n].value;a!==s&&(p(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=u.indexOf(e.currentTarget)+1;t=u[n]??u[0];break}case"ArrowLeft":{const n=u.indexOf(e.currentTarget)-1;t=u[n]??u[u.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},c.map((e=>{let{value:t,label:n,attributes:i}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>u.push(e),onKeyDown:m,onClick:d},i,{className:(0,o.Z)("tabs__item",f.tabItem,i?.className,{"tabs__item--active":s===t})}),n??t)})))}function k(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function y(e){const t=b(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",f.tabList)},r.createElement(v,(0,a.Z)({},e,t)),r.createElement(k,(0,a.Z)({},e,t)))}function w(e){const t=(0,g.Z)();return r.createElement(y,(0,a.Z)({key:String(t)},e))}},2757:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>p});var a=n(7462),r=(n(7294),n(3905)),o=n(4866),i=n(5162);const s={},l="Create a connection",c={unversionedId:"tutorials/create-a-connection",id:"version-0.4/tutorials/create-a-connection",title:"Create a connection",description:"In this tutorial we will create a connection as Acme Corp with Bob. We will",source:"@site/versioned_docs/version-0.4/tutorials/create-a-connection.md",sourceDirName:"tutorials",slug:"/tutorials/create-a-connection",permalink:"/guides/tutorials/create-a-connection",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Logging",permalink:"/guides/tutorials/agent-config/logging"},next:{title:"Cheqd Did Module",permalink:"/guides/tutorials/cheqd/"}},u={},p=[{value:"1. Setting up the agents",id:"1-setting-up-the-agents",level:3},{value:"Bob",id:"bob",level:4},{value:"Acme",id:"acme",level:4},{value:"2. Creating an invitation",id:"2-creating-an-invitation",level:4},{value:"3. Receiving the invitation",id:"3-receiving-the-invitation",level:3},{value:"4. (additional) listen to incoming connection responses",id:"4-additional-listen-to-incoming-connection-responses",level:3},{value:"5. Full code snippets",id:"5-full-code-snippets",level:3},{value:"Useful resources",id:"useful-resources",level:3}],d={toc:p},m="wrapper";function h(e){let{components:t,...n}=e;return(0,r.kt)(m,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"create-a-connection"},"Create a connection"),(0,r.kt)("p",null,"In this tutorial we will create a connection as ",(0,r.kt)("em",{parentName:"p"},"Acme Corp")," with ",(0,r.kt)("em",{parentName:"p"},"Bob"),". We will\nstart with setting up both their agents with the minimal configuration required\nto follow this tutorial. After the initialization we will then create an\ninvitation as ",(0,r.kt)("em",{parentName:"p"},"Acme Corp")," and send it over to ",(0,r.kt)("em",{parentName:"p"},"Bob"),". ",(0,r.kt)("em",{parentName:"p"},"Bob")," will then accept\nthis invitation and at that point they have established a connection and they\nknow how to reach each other for sending a basic message, issuing a credential,\nverifying a proof, etc."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This section assumes that"),(0,r.kt)("ol",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ol"},"You have ",(0,r.kt)("a",{parentName:"li",href:"../getting-started"},"set-up your development environment"),"."),(0,r.kt)("li",{parentName:"ol"},"You have basic knowledge of the required fields in the ",(0,r.kt)("a",{parentName:"li",href:"./agent-config"},"Agent Config")))),(0,r.kt)("h3",{id:"1-setting-up-the-agents"},"1. Setting up the agents"),(0,r.kt)("p",null,"First for both agents we must setup and initialize an agent to work with.\nDepending on your target, ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/react-native"},"React\nNative")," or\n",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/react-native"},"Node.js"),", it might vary."),(0,r.kt)("p",null,"In this tutorial ",(0,r.kt)("em",{parentName:"p"},"Bob")," will be in a ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/react-native"},"React Native\nenvironment")," and ",(0,r.kt)("em",{parentName:"p"},"Acme Corp")," in\na ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/nodejs"},"Node.js environment"),"."),(0,r.kt)("h4",{id:"bob"},"Bob"),(0,r.kt)("p",null,"For bob we need to setup a basic agent with a wallet, mediator and outbound\ntransport."),(0,r.kt)("admonition",{type:"bob"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts section-1",showLineNumbers:!0,"create-a-connection.ts":!0,"section-1":!0},""))),(0,r.kt)("h4",{id:"acme"},"Acme"),(0,r.kt)("p",null,"For Acme we need to setup a basic agent with a wallet, inbound and outbound\ntransport."),(0,r.kt)("admonition",{type:"acme"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts section-2",showLineNumbers:!0,"create-a-connection.ts":!0,"section-2":!0},""))),(0,r.kt)("h4",{id:"2-creating-an-invitation"},"2. Creating an invitation"),(0,r.kt)("p",null,"Now that we have setup both agents, we can create an invitation from ",(0,r.kt)("em",{parentName:"p"},"Acme Corp"),"."),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(i.Z,{label:"New",value:"tab1",mdxType:"TabItem"},(0,r.kt)("p",null,"This method will create an invitation using the legacy method according to ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md"},"0434: Out-of-Band Protocol 1.1"),"."),(0,r.kt)("admonition",{type:"acme"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts section-3",showLineNumbers:!0,"create-a-connection.ts":!0,"section-3":!0},"const outOfBandRecord = await agent.oob.createInvitation()\n\nconst serializedInvitation = outOfBandRecord.outOfBandInvitation.toUrl({ domain: 'https://example.org' })\n")))),(0,r.kt)(i.Z,{label:"Legacy",value:"tab2",mdxType:"TabItem"},(0,r.kt)("p",null,"This method will create an invitation using the legacy method according to ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0160-connection-protocol/README.md"},"0160: Connection Protocol"),"."),(0,r.kt)("admonition",{type:"acme"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts section-4",showLineNumbers:!0,"create-a-connection.ts":!0,"section-4":!0},""))))),(0,r.kt)("h3",{id:"3-receiving-the-invitation"},"3. Receiving the invitation"),(0,r.kt)("p",null,"After we have created the invitation we have to transmit it to the other\nagent. Common practise, when sending it to a holder, it to embed the url inside\na QR code. This QR code can then be scanned by the holder, in this case ",(0,r.kt)("em",{parentName:"p"},"Bob"),".\nAfter this, because both have set ",(0,r.kt)("inlineCode",{parentName:"p"},"autoAcceptConnections")," to ",(0,r.kt)("inlineCode",{parentName:"p"},"true"),", the\nconnection is established."),(0,r.kt)("admonition",{type:"bob"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"create-a-connection.ts section-5","create-a-connection.ts":!0,"section-5":!0},""))),(0,r.kt)("h3",{id:"4-additional-listen-to-incoming-connection-responses"},"4. (additional) listen to incoming connection responses"),(0,r.kt)("p",null,"When you quickly want to use the event or the data of a response to a\nconnection request, you can start an ",(0,r.kt)("a",{parentName:"p",href:"https://example.org"},"TODO: agent event\nlistener"),"."),(0,r.kt)("p",null,"Another use case for this would be to get the ",(0,r.kt)("inlineCode",{parentName:"p"},"connectionRecord")," of the\nconnection as it is only created when the invitation has been received by the\nother agent. The ",(0,r.kt)("inlineCode",{parentName:"p"},"connectionRecord")," is very essential in processes like ",(0,r.kt)("a",{parentName:"p",href:"https://example.org"},"TODO:\nissuing a credential")," or ",(0,r.kt)("a",{parentName:"p",href:"https://example.org"},"TODO: verifying a\nproof"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"connectionRecord")," can also be retrieved with\n",(0,r.kt)("inlineCode",{parentName:"p"},"agent.connections.findAllByOutOfBandId(id)"),", but with this method there is no\nway of knowing if the invitation has been received."),(0,r.kt)("admonition",{type:"acme"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts section-6",showLineNumbers:!0,"create-a-connection.ts":!0,"section-6":!0},""))),(0,r.kt)("h3",{id:"5-full-code-snippets"},"5. Full code snippets"),(0,r.kt)("p",null,"Below are both code snippets for each agent. These can be used as base but\nshould be edited to fit your use case. The\n",(0,r.kt)("a",{parentName:"p",href:"./agent-config#walletconfigkey"},(0,r.kt)("inlineCode",{parentName:"a"},"walletConfig.key")),' must be changed as it can\nlead to other people knowing your "password" to your wallet.'),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts",showLineNumbers:!0,"create-a-connection.ts":!0},"")),(0,r.kt)("h3",{id:"useful-resources"},"Useful resources"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0160-connection-protocol/README.md"},"0160: Connection Protocol")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md"},"0434: Out-of-Band Protocol 1.1"))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/eeecf87c.4f538e64.js b/assets/js/eeecf87c.23345818.js similarity index 73% rename from assets/js/eeecf87c.4f538e64.js rename to assets/js/eeecf87c.23345818.js index 64b352d3..dda0d74d 100644 --- a/assets/js/eeecf87c.4f538e64.js +++ b/assets/js/eeecf87c.23345818.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7547],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=p(r),m=o,f=d["".concat(c,".").concat(m)]||d[m]||u[m]||a;return r?n.createElement(f,i(i({ref:t},l),{},{components:r})):n.createElement(f,i({ref:t},l))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:o,i[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const a={},i="Platform and Environment",s={unversionedId:"concepts/platform-and-environment",id:"concepts/platform-and-environment",title:"Platform and Environment",description:"Credo is developed to support a Node.JS and React Native environment. With this it is entirely possible to build an entire SSI ecosystem with Credo. This would use Node.JS as an issuer as a verifier, and uses React Native as a holder.",source:"@site/guides/concepts/platform-and-environment.md",sourceDirName:"concepts",slug:"/concepts/platform-and-environment",permalink:"/guides/0.5/concepts/platform-and-environment",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"DIDs and DIDComm",permalink:"/guides/0.5/concepts/did-and-didcomm"},next:{title:"Supported Features",permalink:"/guides/0.5/features/"}},c={},p=[],l={toc:p},d="wrapper";function u(e){let{components:t,...r}=e;return(0,o.kt)(d,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"platform-and-environment"},"Platform and Environment"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts"},"Credo")," is developed to support a ",(0,o.kt)("a",{parentName:"p",href:"https://nodejs.org"},"Node.JS")," and ",(0,o.kt)("a",{parentName:"p",href:"https://reactnative.dev"},"React Native")," environment. With this it is entirely possible to build an entire SSI ecosystem with Credo. This would use Node.JS as an issuer as a verifier, and uses React Native as a holder."))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[7547],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=p(r),m=o,f=d["".concat(c,".").concat(m)]||d[m]||u[m]||a;return r?n.createElement(f,i(i({ref:t},l),{},{components:r})):n.createElement(f,i({ref:t},l))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:o,i[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const a={},i="Platform and Environment",s={unversionedId:"concepts/platform-and-environment",id:"concepts/platform-and-environment",title:"Platform and Environment",description:"Credo is developed to support a Node.JS and React Native environment. With this it is entirely possible to build an entire SSI ecosystem with Credo. This would use Node.JS as an issuer as a verifier, and uses React Native as a holder.",source:"@site/guides/concepts/platform-and-environment.md",sourceDirName:"concepts",slug:"/concepts/platform-and-environment",permalink:"/guides/concepts/platform-and-environment",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"DIDs and DIDComm",permalink:"/guides/concepts/did-and-didcomm"},next:{title:"Supported Features",permalink:"/guides/features/"}},c={},p=[],l={toc:p},d="wrapper";function u(e){let{components:t,...r}=e;return(0,o.kt)(d,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"platform-and-environment"},"Platform and Environment"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://github.com/openwallet-foundation/credo-ts"},"Credo")," is developed to support a ",(0,o.kt)("a",{parentName:"p",href:"https://nodejs.org"},"Node.JS")," and ",(0,o.kt)("a",{parentName:"p",href:"https://reactnative.dev"},"React Native")," environment. With this it is entirely possible to build an entire SSI ecosystem with Credo. This would use Node.JS as an issuer as a verifier, and uses React Native as a holder."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ef7acecf.05fbba14.js b/assets/js/ef7acecf.05fbba14.js deleted file mode 100644 index 76a3dfdc..00000000 --- a/assets/js/ef7acecf.05fbba14.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[2925],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=c(n),m=r,h=p["".concat(l,".").concat(m)]||p[m]||d[m]||o;return n?a.createElement(h,i(i({ref:t},u),{},{components:n})):a.createElement(h,i({ref:t},u))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var c=2;c{n.d(t,{Z:()=>i});var a=n(7294),r=n(6010);const o={tabItem:"tabItem_Ymn6"};function i(e){let{children:t,hidden:n,className:i}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(o.tabItem,i),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),r=n(7294),o=n(6010),i=n(2466),s=n(6550),l=n(1980),c=n(7392),u=n(12);function p(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function d(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,c.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const a=(0,s.k6)(),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,l._X)(o),(0,r.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(a.location.search);t.set(o,e),a.replace({...a.location,search:t.toString()})}),[o,a])]}function b(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,o=d(e),[i,s]=(0,r.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(!m({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}))),[l,c]=h({queryString:n,groupId:a}),[p,b]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,o]=(0,u.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:a}),g=(()=>{const e=l??p;return m({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{g&&s(g)}),[g]);return{selectedValue:i,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);s(e),c(e),b(e)}),[c,b,o]),tabValues:o}}var g=n(2389);const f={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function v(e){let{className:t,block:n,selectedValue:s,selectValue:l,tabValues:c}=e;const u=[],{blockElementScrollPositionUntilNextRender:p}=(0,i.o5)(),d=e=>{const t=e.currentTarget,n=u.indexOf(t),a=c[n].value;a!==s&&(p(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=u.indexOf(e.currentTarget)+1;t=u[n]??u[0];break}case"ArrowLeft":{const n=u.indexOf(e.currentTarget)-1;t=u[n]??u[u.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},c.map((e=>{let{value:t,label:n,attributes:i}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>u.push(e),onKeyDown:m,onClick:d},i,{className:(0,o.Z)("tabs__item",f.tabItem,i?.className,{"tabs__item--active":s===t})}),n??t)})))}function k(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function y(e){const t=b(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",f.tabList)},r.createElement(v,(0,a.Z)({},e,t)),r.createElement(k,(0,a.Z)({},e,t)))}function w(e){const t=(0,g.Z)();return r.createElement(y,(0,a.Z)({key:String(t)},e))}},2960:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>p});var a=n(7462),r=(n(7294),n(3905)),o=n(4866),i=n(5162);const s={},l="Create a connection",c={unversionedId:"tutorials/create-a-connection",id:"tutorials/create-a-connection",title:"Create a connection",description:"In this tutorial we will create a connection as Acme Corp with Bob. We will",source:"@site/guides/tutorials/create-a-connection.md",sourceDirName:"tutorials",slug:"/tutorials/create-a-connection",permalink:"/guides/0.5/tutorials/create-a-connection",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Logging",permalink:"/guides/0.5/tutorials/agent-config/logging"},next:{title:"Cheqd Did Module",permalink:"/guides/0.5/tutorials/cheqd/"}},u={},p=[{value:"1. Setting up the agents",id:"1-setting-up-the-agents",level:3},{value:"Bob",id:"bob",level:4},{value:"Acme",id:"acme",level:4},{value:"2. Creating an invitation",id:"2-creating-an-invitation",level:4},{value:"3. Receiving the invitation",id:"3-receiving-the-invitation",level:3},{value:"4. (additional) listen to incoming connection responses",id:"4-additional-listen-to-incoming-connection-responses",level:3},{value:"5. Full code snippets",id:"5-full-code-snippets",level:3},{value:"Useful resources",id:"useful-resources",level:3}],d={toc:p},m="wrapper";function h(e){let{components:t,...n}=e;return(0,r.kt)(m,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"create-a-connection"},"Create a connection"),(0,r.kt)("p",null,"In this tutorial we will create a connection as ",(0,r.kt)("em",{parentName:"p"},"Acme Corp")," with ",(0,r.kt)("em",{parentName:"p"},"Bob"),". We will\nstart with setting up both their agents with the minimal configuration required\nto follow this tutorial. After the initialization we will then create an\ninvitation as ",(0,r.kt)("em",{parentName:"p"},"Acme Corp")," and send it over to ",(0,r.kt)("em",{parentName:"p"},"Bob"),". ",(0,r.kt)("em",{parentName:"p"},"Bob")," will then accept\nthis invitation and at that point they have established a connection and they\nknow how to reach each other for sending a basic message, issuing a credential,\nverifying a proof, etc."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This section assumes that"),(0,r.kt)("ol",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ol"},"You have ",(0,r.kt)("a",{parentName:"li",href:"../getting-started"},"set-up your development environment"),"."),(0,r.kt)("li",{parentName:"ol"},"You have basic knowledge of the required fields in the ",(0,r.kt)("a",{parentName:"li",href:"./agent-config"},"Agent Config")))),(0,r.kt)("h3",{id:"1-setting-up-the-agents"},"1. Setting up the agents"),(0,r.kt)("p",null,"First for both agents we must setup and initialize an agent to work with.\nDepending on your target, ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/react-native"},"React\nNative")," or\n",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/react-native"},"Node.js"),", it might vary."),(0,r.kt)("p",null,"In this tutorial ",(0,r.kt)("em",{parentName:"p"},"Bob")," will be in a ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/react-native"},"React Native\nenvironment")," and ",(0,r.kt)("em",{parentName:"p"},"Acme Corp")," in\na ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/nodejs"},"Node.js environment"),"."),(0,r.kt)("h4",{id:"bob"},"Bob"),(0,r.kt)("p",null,"For bob we need to setup a basic agent with a wallet, mediator and outbound\ntransport."),(0,r.kt)("admonition",{type:"bob"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts section-1",showLineNumbers:!0,"create-a-connection.ts":!0,"section-1":!0},""))),(0,r.kt)("h4",{id:"acme"},"Acme"),(0,r.kt)("p",null,"For Acme we need to setup a basic agent with a wallet, inbound and outbound\ntransport."),(0,r.kt)("admonition",{type:"acme"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts section-2",showLineNumbers:!0,"create-a-connection.ts":!0,"section-2":!0},""))),(0,r.kt)("h4",{id:"2-creating-an-invitation"},"2. Creating an invitation"),(0,r.kt)("p",null,"Now that we have setup both agents, we can create an invitation from ",(0,r.kt)("em",{parentName:"p"},"Acme Corp"),"."),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(i.Z,{label:"New",value:"tab1",mdxType:"TabItem"},(0,r.kt)("p",null,"This method will create an invitation using the legacy method according to ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md"},"0434: Out-of-Band Protocol 1.1"),"."),(0,r.kt)("admonition",{type:"acme"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts section-3",showLineNumbers:!0,"create-a-connection.ts":!0,"section-3":!0},"const outOfBandRecord = await agent.oob.createInvitation()\n\nconst serializedInvitation = outOfBandRecord.outOfBandInvitation.toUrl({ domain: 'https://example.org' })\n")))),(0,r.kt)(i.Z,{label:"Legacy",value:"tab2",mdxType:"TabItem"},(0,r.kt)("p",null,"This method will create an invitation using the legacy method according to ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0160-connection-protocol/README.md"},"0160: Connection Protocol"),"."),(0,r.kt)("admonition",{type:"acme"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts section-4",showLineNumbers:!0,"create-a-connection.ts":!0,"section-4":!0},""))))),(0,r.kt)("h3",{id:"3-receiving-the-invitation"},"3. Receiving the invitation"),(0,r.kt)("p",null,"After we have created the invitation we have to transmit it to the other\nagent. Common practise, when sending it to a holder, it to embed the url inside\na QR code. This QR code can then be scanned by the holder, in this case ",(0,r.kt)("em",{parentName:"p"},"Bob"),".\nAfter this, because both have set ",(0,r.kt)("inlineCode",{parentName:"p"},"autoAcceptConnections")," to ",(0,r.kt)("inlineCode",{parentName:"p"},"true"),", the\nconnection is established."),(0,r.kt)("admonition",{type:"bob"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"create-a-connection.ts section-5","create-a-connection.ts":!0,"section-5":!0},""))),(0,r.kt)("h3",{id:"4-additional-listen-to-incoming-connection-responses"},"4. (additional) listen to incoming connection responses"),(0,r.kt)("p",null,"When you quickly want to use the event or the data of a response to a\nconnection request, you can start an ",(0,r.kt)("a",{parentName:"p",href:"https://example.org"},"TODO: agent event\nlistener"),"."),(0,r.kt)("p",null,"Another use case for this would be to get the ",(0,r.kt)("inlineCode",{parentName:"p"},"connectionRecord")," of the\nconnection as it is only created when the invitation has been received by the\nother agent. The ",(0,r.kt)("inlineCode",{parentName:"p"},"connectionRecord")," is very essential in processes like ",(0,r.kt)("a",{parentName:"p",href:"https://example.org"},"TODO:\nissuing a credential")," or ",(0,r.kt)("a",{parentName:"p",href:"https://example.org"},"TODO: verifying a\nproof"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"connectionRecord")," can also be retrieved with\n",(0,r.kt)("inlineCode",{parentName:"p"},"agent.connections.findAllByOutOfBandId(id)"),", but with this method there is no\nway of knowing if the invitation has been received."),(0,r.kt)("admonition",{type:"acme"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts section-6",showLineNumbers:!0,"create-a-connection.ts":!0,"section-6":!0},""))),(0,r.kt)("h3",{id:"5-full-code-snippets"},"5. Full code snippets"),(0,r.kt)("p",null,"Below are both code snippets for each agent. These can be used as base but\nshould be edited to fit your use case. The\n",(0,r.kt)("a",{parentName:"p",href:"./agent-config#walletconfigkey"},(0,r.kt)("inlineCode",{parentName:"a"},"walletConfig.key")),' must be changed as it can\nlead to other people knowing your "password" to your wallet.'),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts",showLineNumbers:!0,"create-a-connection.ts":!0},"")),(0,r.kt)("h3",{id:"useful-resources"},"Useful resources"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0160-connection-protocol/README.md"},"0160: Connection Protocol")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md"},"0434: Out-of-Band Protocol 1.1"))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ef7acecf.9f514215.js b/assets/js/ef7acecf.9f514215.js new file mode 100644 index 00000000..060c0dde --- /dev/null +++ b/assets/js/ef7acecf.9f514215.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[2925],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=c(n),m=r,h=p["".concat(l,".").concat(m)]||p[m]||d[m]||o;return n?a.createElement(h,i(i({ref:t},u),{},{components:n})):a.createElement(h,i({ref:t},u))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var c=2;c{n.d(t,{Z:()=>i});var a=n(7294),r=n(6010);const o={tabItem:"tabItem_Ymn6"};function i(e){let{children:t,hidden:n,className:i}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(o.tabItem,i),hidden:n},t)}},4866:(e,t,n)=>{n.d(t,{Z:()=>w});var a=n(7462),r=n(7294),o=n(6010),i=n(2466),s=n(6550),l=n(1980),c=n(7392),u=n(12);function p(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function d(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,c.l)(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 m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:n}=e;const a=(0,s.k6)(),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,l._X)(o),(0,r.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(a.location.search);t.set(o,e),a.replace({...a.location,search:t.toString()})}),[o,a])]}function b(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,o=d(e),[i,s]=(0,r.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(!m({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}))),[l,c]=h({queryString:n,groupId:a}),[p,b]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,o]=(0,u.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:a}),g=(()=>{const e=l??p;return m({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{g&&s(g)}),[g]);return{selectedValue:i,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);s(e),c(e),b(e)}),[c,b,o]),tabValues:o}}var g=n(2389);const f={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function v(e){let{className:t,block:n,selectedValue:s,selectValue:l,tabValues:c}=e;const u=[],{blockElementScrollPositionUntilNextRender:p}=(0,i.o5)(),d=e=>{const t=e.currentTarget,n=u.indexOf(t),a=c[n].value;a!==s&&(p(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=u.indexOf(e.currentTarget)+1;t=u[n]??u[0];break}case"ArrowLeft":{const n=u.indexOf(e.currentTarget)-1;t=u[n]??u[u.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},c.map((e=>{let{value:t,label:n,attributes:i}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>u.push(e),onKeyDown:m,onClick:d},i,{className:(0,o.Z)("tabs__item",f.tabItem,i?.className,{"tabs__item--active":s===t})}),n??t)})))}function k(e){let{lazy:t,children:n,selectedValue:a}=e;if(n=Array.isArray(n)?n:[n],t){const e=n.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},n.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function y(e){const t=b(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",f.tabList)},r.createElement(v,(0,a.Z)({},e,t)),r.createElement(k,(0,a.Z)({},e,t)))}function w(e){const t=(0,g.Z)();return r.createElement(y,(0,a.Z)({key:String(t)},e))}},2960:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>p});var a=n(7462),r=(n(7294),n(3905)),o=n(4866),i=n(5162);const s={},l="Create a connection",c={unversionedId:"tutorials/create-a-connection",id:"tutorials/create-a-connection",title:"Create a connection",description:"In this tutorial we will create a connection as Acme Corp with Bob. We will",source:"@site/guides/tutorials/create-a-connection.md",sourceDirName:"tutorials",slug:"/tutorials/create-a-connection",permalink:"/guides/tutorials/create-a-connection",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Logging",permalink:"/guides/tutorials/agent-config/logging"},next:{title:"Cheqd Did Module",permalink:"/guides/tutorials/cheqd/"}},u={},p=[{value:"1. Setting up the agents",id:"1-setting-up-the-agents",level:3},{value:"Bob",id:"bob",level:4},{value:"Acme",id:"acme",level:4},{value:"2. Creating an invitation",id:"2-creating-an-invitation",level:4},{value:"3. Receiving the invitation",id:"3-receiving-the-invitation",level:3},{value:"4. (additional) listen to incoming connection responses",id:"4-additional-listen-to-incoming-connection-responses",level:3},{value:"5. Full code snippets",id:"5-full-code-snippets",level:3},{value:"Useful resources",id:"useful-resources",level:3}],d={toc:p},m="wrapper";function h(e){let{components:t,...n}=e;return(0,r.kt)(m,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"create-a-connection"},"Create a connection"),(0,r.kt)("p",null,"In this tutorial we will create a connection as ",(0,r.kt)("em",{parentName:"p"},"Acme Corp")," with ",(0,r.kt)("em",{parentName:"p"},"Bob"),". We will\nstart with setting up both their agents with the minimal configuration required\nto follow this tutorial. After the initialization we will then create an\ninvitation as ",(0,r.kt)("em",{parentName:"p"},"Acme Corp")," and send it over to ",(0,r.kt)("em",{parentName:"p"},"Bob"),". ",(0,r.kt)("em",{parentName:"p"},"Bob")," will then accept\nthis invitation and at that point they have established a connection and they\nknow how to reach each other for sending a basic message, issuing a credential,\nverifying a proof, etc."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This section assumes that"),(0,r.kt)("ol",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ol"},"You have ",(0,r.kt)("a",{parentName:"li",href:"../getting-started"},"set-up your development environment"),"."),(0,r.kt)("li",{parentName:"ol"},"You have basic knowledge of the required fields in the ",(0,r.kt)("a",{parentName:"li",href:"./agent-config"},"Agent Config")))),(0,r.kt)("h3",{id:"1-setting-up-the-agents"},"1. Setting up the agents"),(0,r.kt)("p",null,"First for both agents we must setup and initialize an agent to work with.\nDepending on your target, ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/react-native"},"React\nNative")," or\n",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/react-native"},"Node.js"),", it might vary."),(0,r.kt)("p",null,"In this tutorial ",(0,r.kt)("em",{parentName:"p"},"Bob")," will be in a ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/react-native"},"React Native\nenvironment")," and ",(0,r.kt)("em",{parentName:"p"},"Acme Corp")," in\na ",(0,r.kt)("a",{parentName:"p",href:"../getting-started/installation/nodejs"},"Node.js environment"),"."),(0,r.kt)("h4",{id:"bob"},"Bob"),(0,r.kt)("p",null,"For bob we need to setup a basic agent with a wallet, mediator and outbound\ntransport."),(0,r.kt)("admonition",{type:"bob"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts section-1",showLineNumbers:!0,"create-a-connection.ts":!0,"section-1":!0},""))),(0,r.kt)("h4",{id:"acme"},"Acme"),(0,r.kt)("p",null,"For Acme we need to setup a basic agent with a wallet, inbound and outbound\ntransport."),(0,r.kt)("admonition",{type:"acme"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts section-2",showLineNumbers:!0,"create-a-connection.ts":!0,"section-2":!0},""))),(0,r.kt)("h4",{id:"2-creating-an-invitation"},"2. Creating an invitation"),(0,r.kt)("p",null,"Now that we have setup both agents, we can create an invitation from ",(0,r.kt)("em",{parentName:"p"},"Acme Corp"),"."),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(i.Z,{label:"New",value:"tab1",mdxType:"TabItem"},(0,r.kt)("p",null,"This method will create an invitation using the legacy method according to ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md"},"0434: Out-of-Band Protocol 1.1"),"."),(0,r.kt)("admonition",{type:"acme"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts section-3",showLineNumbers:!0,"create-a-connection.ts":!0,"section-3":!0},"const outOfBandRecord = await agent.oob.createInvitation()\n\nconst serializedInvitation = outOfBandRecord.outOfBandInvitation.toUrl({ domain: 'https://example.org' })\n")))),(0,r.kt)(i.Z,{label:"Legacy",value:"tab2",mdxType:"TabItem"},(0,r.kt)("p",null,"This method will create an invitation using the legacy method according to ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0160-connection-protocol/README.md"},"0160: Connection Protocol"),"."),(0,r.kt)("admonition",{type:"acme"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts section-4",showLineNumbers:!0,"create-a-connection.ts":!0,"section-4":!0},""))))),(0,r.kt)("h3",{id:"3-receiving-the-invitation"},"3. Receiving the invitation"),(0,r.kt)("p",null,"After we have created the invitation we have to transmit it to the other\nagent. Common practise, when sending it to a holder, it to embed the url inside\na QR code. This QR code can then be scanned by the holder, in this case ",(0,r.kt)("em",{parentName:"p"},"Bob"),".\nAfter this, because both have set ",(0,r.kt)("inlineCode",{parentName:"p"},"autoAcceptConnections")," to ",(0,r.kt)("inlineCode",{parentName:"p"},"true"),", the\nconnection is established."),(0,r.kt)("admonition",{type:"bob"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"create-a-connection.ts section-5","create-a-connection.ts":!0,"section-5":!0},""))),(0,r.kt)("h3",{id:"4-additional-listen-to-incoming-connection-responses"},"4. (additional) listen to incoming connection responses"),(0,r.kt)("p",null,"When you quickly want to use the event or the data of a response to a\nconnection request, you can start an ",(0,r.kt)("a",{parentName:"p",href:"https://example.org"},"TODO: agent event\nlistener"),"."),(0,r.kt)("p",null,"Another use case for this would be to get the ",(0,r.kt)("inlineCode",{parentName:"p"},"connectionRecord")," of the\nconnection as it is only created when the invitation has been received by the\nother agent. The ",(0,r.kt)("inlineCode",{parentName:"p"},"connectionRecord")," is very essential in processes like ",(0,r.kt)("a",{parentName:"p",href:"https://example.org"},"TODO:\nissuing a credential")," or ",(0,r.kt)("a",{parentName:"p",href:"https://example.org"},"TODO: verifying a\nproof"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"connectionRecord")," can also be retrieved with\n",(0,r.kt)("inlineCode",{parentName:"p"},"agent.connections.findAllByOutOfBandId(id)"),", but with this method there is no\nway of knowing if the invitation has been received."),(0,r.kt)("admonition",{type:"acme"},(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts section-6",showLineNumbers:!0,"create-a-connection.ts":!0,"section-6":!0},""))),(0,r.kt)("h3",{id:"5-full-code-snippets"},"5. Full code snippets"),(0,r.kt)("p",null,"Below are both code snippets for each agent. These can be used as base but\nshould be edited to fit your use case. The\n",(0,r.kt)("a",{parentName:"p",href:"./agent-config#walletconfigkey"},(0,r.kt)("inlineCode",{parentName:"a"},"walletConfig.key")),' must be changed as it can\nlead to other people knowing your "password" to your wallet.'),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers create-a-connection.ts",showLineNumbers:!0,"create-a-connection.ts":!0},"")),(0,r.kt)("h3",{id:"useful-resources"},"Useful resources"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0160-connection-protocol/README.md"},"0160: Connection Protocol")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md"},"0434: Out-of-Band Protocol 1.1"))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f30d32a5.957af3a2.js b/assets/js/f30d32a5.957af3a2.js new file mode 100644 index 00000000..8acccb14 --- /dev/null +++ b/assets/js/f30d32a5.957af3a2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[2637],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var s=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);t&&(s=s.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,s)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(s=0;s=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=s.createContext({}),p=function(e){var t=s.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=p(e.components);return s.createElement(l.Provider,{value:t},e.children)},d="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return s.createElement(s.Fragment,{},t)}},c=s.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),d=p(n),c=r,m=d["".concat(l,".").concat(c)]||d[c]||g[c]||i;return n?s.createElement(m,a(a({ref:t},u),{},{components:n})):s.createElement(m,a({ref:t},u))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=c;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[d]="string"==typeof e?e:r,a[1]=o;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>g,frontMatter:()=>i,metadata:()=>o,toc:()=>p});var s=n(7462),r=(n(7294),n(3905));const i={},a="Postgres Setup for Linux",o={unversionedId:"tutorials/indy-sdk-postgres-database-nodejs/linux",id:"version-0.4/tutorials/indy-sdk-postgres-database-nodejs/linux",title:"Postgres Setup for Linux",description:"Prerequisites",source:"@site/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/linux.md",sourceDirName:"tutorials/indy-sdk-postgres-database-nodejs",slug:"/tutorials/indy-sdk-postgres-database-nodejs/linux",permalink:"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/linux",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Using PostgreSQL as Database for Indy SDK in Node.js",permalink:"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/"},next:{title:"Postgres Setup for macOS",permalink:"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/macos"}},l={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Step 1: installing the dependencies using apt",id:"step-1-installing-the-dependencies-using-apt",level:2},{value:"Debian based (Ubuntu, Mint, Kali, Deepin, etc.)",id:"debian-based-ubuntu-mint-kali-deepin-etc",level:3},{value:"Step 2: Build Postgres plugin",id:"step-2-build-postgres-plugin",level:2},{value:"Step 2.1: Cloning the indy-sdk",id:"step-21-cloning-the-indy-sdk",level:3},{value:"Step 2.2: Building Postgres plugin",id:"step-22-building-postgres-plugin",level:3},{value:"Step 2.3: Moving the file",id:"step-23-moving-the-file",level:3}],u={toc:p},d="wrapper";function g(e){let{components:t,...n}=e;return(0,r.kt)(d,(0,s.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"postgres-setup-for-linux"},"Postgres Setup for Linux"),(0,r.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"A system package manager (like APT, Pacman, etc.)"),(0,r.kt)("li",{parentName:"ul"},"Cargo (We have to build Postgres plugin from source)"),(0,r.kt)("li",{parentName:"ul"},"git (to clone a repo, could also be done with downloading the zip from the GitHub page)")),(0,r.kt)("h2",{id:"step-1-installing-the-dependencies-using-apt"},"Step 1: installing the dependencies using apt"),(0,r.kt)("h3",{id:"debian-based-ubuntu-mint-kali-deepin-etc"},"Debian based (Ubuntu, Mint, Kali, Deepin, etc.)"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"sudo apt install libzmq3-dev libsodium-dev libssl-dev\n")),(0,r.kt)("h2",{id:"step-2-build-postgres-plugin"},"Step 2: Build Postgres plugin"),(0,r.kt)("p",null,"Building Postgres plugin from the indy-sdk repo with cargo."),(0,r.kt)("h3",{id:"step-21-cloning-the-indy-sdk"},"Step 2.1: Cloning the indy-sdk"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"git clone https://github.com/hyperledger/indy-sdk.git\n\ncd indy-sdk/experimental/plugins/postgres_storage\n")),(0,r.kt)("h3",{id:"step-22-building-postgres-plugin"},"Step 2.2: Building Postgres plugin"),(0,r.kt)("p",null,"If this step throws any errors, it might be because you miss some packages. Step 1 of this guide provided the dependencies that are required, but it also assumed that you have some basic development packages installed. If you are missing some packages, you can install them with your package manager."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"pwd\n\n# OUTPUT: .../indy-sdk/experimental/plugins/postgres_storage\n\ncargo build --release\n")),(0,r.kt)("h3",{id:"step-23-moving-the-file"},"Step 2.3: Moving the file"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"pwd\n\n# OUTPUT: .../indy-sdk/experimental/plugins/postgres_storage\n\nsudo mv ./target/release/libindystrgpostgres.so /usr/local/lib/libindystrgpostgres.so\n")))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f30d32a5.b3461c1e.js b/assets/js/f30d32a5.b3461c1e.js deleted file mode 100644 index 8fe89028..00000000 --- a/assets/js/f30d32a5.b3461c1e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[2637],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var s=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);t&&(s=s.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,s)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(s=0;s=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=s.createContext({}),p=function(e){var t=s.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=p(e.components);return s.createElement(l.Provider,{value:t},e.children)},d="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return s.createElement(s.Fragment,{},t)}},c=s.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),d=p(n),c=r,m=d["".concat(l,".").concat(c)]||d[c]||g[c]||i;return n?s.createElement(m,a(a({ref:t},u),{},{components:n})):s.createElement(m,a({ref:t},u))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=c;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[d]="string"==typeof e?e:r,a[1]=o;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>g,frontMatter:()=>i,metadata:()=>o,toc:()=>p});var s=n(7462),r=(n(7294),n(3905));const i={},a="Postgres Setup for Linux",o={unversionedId:"tutorials/indy-sdk-postgres-database-nodejs/linux",id:"version-0.4/tutorials/indy-sdk-postgres-database-nodejs/linux",title:"Postgres Setup for Linux",description:"Prerequisites",source:"@site/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/linux.md",sourceDirName:"tutorials/indy-sdk-postgres-database-nodejs",slug:"/tutorials/indy-sdk-postgres-database-nodejs/linux",permalink:"/guides/tutorials/indy-sdk-postgres-database-nodejs/linux",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Using PostgreSQL as Database for Indy SDK in Node.js",permalink:"/guides/tutorials/indy-sdk-postgres-database-nodejs/"},next:{title:"Postgres Setup for macOS",permalink:"/guides/tutorials/indy-sdk-postgres-database-nodejs/macos"}},l={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Step 1: installing the dependencies using apt",id:"step-1-installing-the-dependencies-using-apt",level:2},{value:"Debian based (Ubuntu, Mint, Kali, Deepin, etc.)",id:"debian-based-ubuntu-mint-kali-deepin-etc",level:3},{value:"Step 2: Build Postgres plugin",id:"step-2-build-postgres-plugin",level:2},{value:"Step 2.1: Cloning the indy-sdk",id:"step-21-cloning-the-indy-sdk",level:3},{value:"Step 2.2: Building Postgres plugin",id:"step-22-building-postgres-plugin",level:3},{value:"Step 2.3: Moving the file",id:"step-23-moving-the-file",level:3}],u={toc:p},d="wrapper";function g(e){let{components:t,...n}=e;return(0,r.kt)(d,(0,s.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"postgres-setup-for-linux"},"Postgres Setup for Linux"),(0,r.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"A system package manager (like APT, Pacman, etc.)"),(0,r.kt)("li",{parentName:"ul"},"Cargo (We have to build Postgres plugin from source)"),(0,r.kt)("li",{parentName:"ul"},"git (to clone a repo, could also be done with downloading the zip from the GitHub page)")),(0,r.kt)("h2",{id:"step-1-installing-the-dependencies-using-apt"},"Step 1: installing the dependencies using apt"),(0,r.kt)("h3",{id:"debian-based-ubuntu-mint-kali-deepin-etc"},"Debian based (Ubuntu, Mint, Kali, Deepin, etc.)"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"sudo apt install libzmq3-dev libsodium-dev libssl-dev\n")),(0,r.kt)("h2",{id:"step-2-build-postgres-plugin"},"Step 2: Build Postgres plugin"),(0,r.kt)("p",null,"Building Postgres plugin from the indy-sdk repo with cargo."),(0,r.kt)("h3",{id:"step-21-cloning-the-indy-sdk"},"Step 2.1: Cloning the indy-sdk"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"git clone https://github.com/hyperledger/indy-sdk.git\n\ncd indy-sdk/experimental/plugins/postgres_storage\n")),(0,r.kt)("h3",{id:"step-22-building-postgres-plugin"},"Step 2.2: Building Postgres plugin"),(0,r.kt)("p",null,"If this step throws any errors, it might be because you miss some packages. Step 1 of this guide provided the dependencies that are required, but it also assumed that you have some basic development packages installed. If you are missing some packages, you can install them with your package manager."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"pwd\n\n# OUTPUT: .../indy-sdk/experimental/plugins/postgres_storage\n\ncargo build --release\n")),(0,r.kt)("h3",{id:"step-23-moving-the-file"},"Step 2.3: Moving the file"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"pwd\n\n# OUTPUT: .../indy-sdk/experimental/plugins/postgres_storage\n\nsudo mv ./target/release/libindystrgpostgres.so /usr/local/lib/libindystrgpostgres.so\n")))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f800d23c.1a67a51b.js b/assets/js/f800d23c.b03d6bcd.js similarity index 69% rename from assets/js/f800d23c.1a67a51b.js rename to assets/js/f800d23c.b03d6bcd.js index 8b5885f9..773a320d 100644 --- a/assets/js/f800d23c.1a67a51b.js +++ b/assets/js/f800d23c.b03d6bcd.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8251],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>g});var a=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function i(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=a.createContext({}),u=function(e){var t=a.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},c=function(e){var t=u(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,s=e.originalType,l=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),d=u(r),m=n,g=d["".concat(l,".").concat(m)]||d[m]||p[m]||s;return r?a.createElement(g,i(i({ref:t},c),{},{components:r})):a.createElement(g,i({ref:t},c))}));function g(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var s=r.length,i=new Array(s);i[0]=m;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[d]="string"==typeof e?e:n,i[1]=o;for(var u=2;u{r.d(t,{Z:()=>i});var a=r(7294),n=r(6010);const s={tabItem:"tabItem_Ymn6"};function i(e){let{children:t,hidden:r,className:i}=e;return a.createElement("div",{role:"tabpanel",className:(0,n.Z)(s.tabItem,i),hidden:r},t)}},4866:(e,t,r)=>{r.d(t,{Z:()=>w});var a=r(7462),n=r(7294),s=r(6010),i=r(2466),o=r(6550),l=r(1980),u=r(7392),c=r(12);function d(e){return function(e){return n.Children.map(e,(e=>{if((0,n.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:r,attributes:a,default:n}}=e;return{value:t,label:r,attributes:a,default:n}}))}function p(e){const{values:t,children:r}=e;return(0,n.useMemo)((()=>{const e=t??d(r);return function(e){const t=(0,u.l)(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,r])}function m(e){let{value:t,tabValues:r}=e;return r.some((e=>e.value===t))}function g(e){let{queryString:t=!1,groupId:r}=e;const a=(0,o.k6)(),s=function(e){let{queryString:t=!1,groupId:r}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!r)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 r??null}({queryString:t,groupId:r});return[(0,l._X)(s),(0,n.useCallback)((e=>{if(!s)return;const t=new URLSearchParams(a.location.search);t.set(s,e),a.replace({...a.location,search:t.toString()})}),[s,a])]}function f(e){const{defaultValue:t,queryString:r=!1,groupId:a}=e,s=p(e),[i,o]=(0,n.useState)((()=>function(e){let{defaultValue:t,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:r}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const a=r.find((e=>e.default))??r[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:t,tabValues:s}))),[l,u]=g({queryString:r,groupId:a}),[d,f]=function(e){let{groupId:t}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,s]=(0,c.Nk)(r);return[a,(0,n.useCallback)((e=>{r&&s.set(e)}),[r,s])]}({groupId:a}),b=(()=>{const e=l??d;return m({value:e,tabValues:s})?e:null})();(0,n.useLayoutEffect)((()=>{b&&o(b)}),[b]);return{selectedValue:i,selectValue:(0,n.useCallback)((e=>{if(!m({value:e,tabValues:s}))throw new Error(`Can't select invalid tab value=${e}`);o(e),u(e),f(e)}),[u,f,s]),tabValues:s}}var b=r(2389);const h={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:r,selectedValue:o,selectValue:l,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:d}=(0,i.o5)(),p=e=>{const t=e.currentTarget,r=c.indexOf(t),a=u[r].value;a!==o&&(d(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const r=c.indexOf(e.currentTarget)+1;t=c[r]??c[0];break}case"ArrowLeft":{const r=c.indexOf(e.currentTarget)-1;t=c[r]??c[c.length-1];break}}t?.focus()};return n.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.Z)("tabs",{"tabs--block":r},t)},u.map((e=>{let{value:t,label:r,attributes:i}=e;return n.createElement("li",(0,a.Z)({role:"tab",tabIndex:o===t?0:-1,"aria-selected":o===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:p},i,{className:(0,s.Z)("tabs__item",h.tabItem,i?.className,{"tabs__item--active":o===t})}),r??t)})))}function y(e){let{lazy:t,children:r,selectedValue:a}=e;if(r=Array.isArray(r)?r:[r],t){const e=r.find((e=>e.props.value===a));return e?(0,n.cloneElement)(e,{className:"margin-top--md"}):null}return n.createElement("div",{className:"margin-top--md"},r.map(((e,t)=>(0,n.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function v(e){const t=f(e);return n.createElement("div",{className:(0,s.Z)("tabs-container",h.tabList)},n.createElement(k,(0,a.Z)({},e,t)),n.createElement(y,(0,a.Z)({},e,t)))}function w(e){const t=(0,b.Z)();return n.createElement(v,(0,a.Z)({key:String(t)},e))}},440:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>g,frontMatter:()=>o,metadata:()=>u,toc:()=>d});var a=r(7462),n=(r(7294),r(3905)),s=r(4866),i=r(5162);const o={},l="Aries Askar",u={unversionedId:"getting-started/set-up/aries-askar",id:"getting-started/set-up/aries-askar",title:"Aries Askar",description:"Aries Askar provides secure, encrypted storage and cryptographic support for encrypting, decrypting, signing and verifying data. It also provides both the Wallet and StorageService implementations for the agent.",source:"@site/guides/getting-started/set-up/aries-askar.md",sourceDirName:"getting-started/set-up",slug:"/getting-started/set-up/aries-askar",permalink:"/guides/0.5/getting-started/set-up/aries-askar",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Agent Setup",permalink:"/guides/0.5/getting-started/set-up/"},next:{title:"AnonCreds",permalink:"/guides/0.5/getting-started/set-up/anoncreds"}},c={},d=[{value:"Installing Aries Askar",id:"installing-aries-askar",level:3},{value:"Adding Aries Askar to the Agent",id:"adding-aries-askar-to-the-agent",level:3}],p={toc:d},m="wrapper";function g(e){let{components:t,...r}=e;return(0,n.kt)(m,(0,a.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"aries-askar"},"Aries Askar"),(0,n.kt)("p",null,(0,n.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-askar"},"Aries Askar")," provides secure, encrypted storage and cryptographic support for encrypting, decrypting, signing and verifying data. It also provides both the ",(0,n.kt)("inlineCode",{parentName:"p"},"Wallet")," and ",(0,n.kt)("inlineCode",{parentName:"p"},"StorageService")," implementations for the agent."),(0,n.kt)("admonition",{type:"tip"},(0,n.kt)("p",{parentName:"admonition"},"If you're upgrading from the Indy SDK to Aries Askar, see ",(0,n.kt)("a",{parentName:"p",href:"../updating/update-indy-sdk-to-askar"},"Migrating from an Indy SDK Wallet to Aries Askar"))),(0,n.kt)("h3",{id:"installing-aries-askar"},"Installing Aries Askar"),(0,n.kt)("p",null,"When using Credo with Aries Askar, there are a few extra dependencies that need to be installed. We need to install the ",(0,n.kt)("inlineCode",{parentName:"p"},"@credo-ts/askar")," package, which implements the needed interfaces for the agent. Secondly, we need to add native bindings for the specific platform ",(0,n.kt)("inlineCode",{parentName:"p"},"@hyperledger/aries-askar-"),". Currently there are bindings for Node.JS, as ",(0,n.kt)("inlineCode",{parentName:"p"},"@hyperledger/aries-askar-nodejs"),", and React Native as ",(0,n.kt)("inlineCode",{parentName:"p"},"@hyperlegder/aries-askar-react-native"),"."),(0,n.kt)(s.Z,{mdxType:"Tabs"},(0,n.kt)(i.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @credo-ts/askar@^0.5.0 @hyperledger/aries-askar-nodejs@^0.2.0\n"))),(0,n.kt)(i.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @credo-ts/askar@^0.5.0 @hyperledger/aries-askar-react-native@^0.2.0\n")))),(0,n.kt)("h3",{id:"adding-aries-askar-to-the-agent"},"Adding Aries Askar to the Agent"),(0,n.kt)("p",null,"After installing the dependencies, we can register the Askar Module on the agent."),(0,n.kt)(s.Z,{mdxType:"Tabs"},(0,n.kt)(i.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-askar.ts section-1",showLineNumbers:!0,"set-up-askar.ts":!0,"section-1":!0},""))),(0,n.kt)(i.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-askar-rn.ts section-1",showLineNumbers:!0,"set-up-askar-rn.ts":!0,"section-1":!0},"")))))}g.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[8251],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>g});var a=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function i(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=a.createContext({}),u=function(e){var t=a.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},c=function(e){var t=u(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,s=e.originalType,l=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),d=u(r),m=n,g=d["".concat(l,".").concat(m)]||d[m]||p[m]||s;return r?a.createElement(g,i(i({ref:t},c),{},{components:r})):a.createElement(g,i({ref:t},c))}));function g(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var s=r.length,i=new Array(s);i[0]=m;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[d]="string"==typeof e?e:n,i[1]=o;for(var u=2;u{r.d(t,{Z:()=>i});var a=r(7294),n=r(6010);const s={tabItem:"tabItem_Ymn6"};function i(e){let{children:t,hidden:r,className:i}=e;return a.createElement("div",{role:"tabpanel",className:(0,n.Z)(s.tabItem,i),hidden:r},t)}},4866:(e,t,r)=>{r.d(t,{Z:()=>w});var a=r(7462),n=r(7294),s=r(6010),i=r(2466),o=r(6550),l=r(1980),u=r(7392),c=r(12);function d(e){return function(e){return n.Children.map(e,(e=>{if((0,n.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:t,label:r,attributes:a,default:n}}=e;return{value:t,label:r,attributes:a,default:n}}))}function p(e){const{values:t,children:r}=e;return(0,n.useMemo)((()=>{const e=t??d(r);return function(e){const t=(0,u.l)(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,r])}function m(e){let{value:t,tabValues:r}=e;return r.some((e=>e.value===t))}function g(e){let{queryString:t=!1,groupId:r}=e;const a=(0,o.k6)(),s=function(e){let{queryString:t=!1,groupId:r}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!r)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 r??null}({queryString:t,groupId:r});return[(0,l._X)(s),(0,n.useCallback)((e=>{if(!s)return;const t=new URLSearchParams(a.location.search);t.set(s,e),a.replace({...a.location,search:t.toString()})}),[s,a])]}function f(e){const{defaultValue:t,queryString:r=!1,groupId:a}=e,s=p(e),[i,o]=(0,n.useState)((()=>function(e){let{defaultValue:t,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:r}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const a=r.find((e=>e.default))??r[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:t,tabValues:s}))),[l,u]=g({queryString:r,groupId:a}),[d,f]=function(e){let{groupId:t}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,s]=(0,c.Nk)(r);return[a,(0,n.useCallback)((e=>{r&&s.set(e)}),[r,s])]}({groupId:a}),b=(()=>{const e=l??d;return m({value:e,tabValues:s})?e:null})();(0,n.useLayoutEffect)((()=>{b&&o(b)}),[b]);return{selectedValue:i,selectValue:(0,n.useCallback)((e=>{if(!m({value:e,tabValues:s}))throw new Error(`Can't select invalid tab value=${e}`);o(e),u(e),f(e)}),[u,f,s]),tabValues:s}}var b=r(2389);const h={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:r,selectedValue:o,selectValue:l,tabValues:u}=e;const c=[],{blockElementScrollPositionUntilNextRender:d}=(0,i.o5)(),p=e=>{const t=e.currentTarget,r=c.indexOf(t),a=u[r].value;a!==o&&(d(t),l(a))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const r=c.indexOf(e.currentTarget)+1;t=c[r]??c[0];break}case"ArrowLeft":{const r=c.indexOf(e.currentTarget)-1;t=c[r]??c[c.length-1];break}}t?.focus()};return n.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.Z)("tabs",{"tabs--block":r},t)},u.map((e=>{let{value:t,label:r,attributes:i}=e;return n.createElement("li",(0,a.Z)({role:"tab",tabIndex:o===t?0:-1,"aria-selected":o===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:p},i,{className:(0,s.Z)("tabs__item",h.tabItem,i?.className,{"tabs__item--active":o===t})}),r??t)})))}function y(e){let{lazy:t,children:r,selectedValue:a}=e;if(r=Array.isArray(r)?r:[r],t){const e=r.find((e=>e.props.value===a));return e?(0,n.cloneElement)(e,{className:"margin-top--md"}):null}return n.createElement("div",{className:"margin-top--md"},r.map(((e,t)=>(0,n.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function v(e){const t=f(e);return n.createElement("div",{className:(0,s.Z)("tabs-container",h.tabList)},n.createElement(k,(0,a.Z)({},e,t)),n.createElement(y,(0,a.Z)({},e,t)))}function w(e){const t=(0,b.Z)();return n.createElement(v,(0,a.Z)({key:String(t)},e))}},440:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>g,frontMatter:()=>o,metadata:()=>u,toc:()=>d});var a=r(7462),n=(r(7294),r(3905)),s=r(4866),i=r(5162);const o={},l="Aries Askar",u={unversionedId:"getting-started/set-up/aries-askar",id:"getting-started/set-up/aries-askar",title:"Aries Askar",description:"Aries Askar provides secure, encrypted storage and cryptographic support for encrypting, decrypting, signing and verifying data. It also provides both the Wallet and StorageService implementations for the agent.",source:"@site/guides/getting-started/set-up/aries-askar.md",sourceDirName:"getting-started/set-up",slug:"/getting-started/set-up/aries-askar",permalink:"/guides/getting-started/set-up/aries-askar",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Agent Setup",permalink:"/guides/getting-started/set-up/"},next:{title:"AnonCreds",permalink:"/guides/getting-started/set-up/anoncreds"}},c={},d=[{value:"Installing Aries Askar",id:"installing-aries-askar",level:3},{value:"Adding Aries Askar to the Agent",id:"adding-aries-askar-to-the-agent",level:3}],p={toc:d},m="wrapper";function g(e){let{components:t,...r}=e;return(0,n.kt)(m,(0,a.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"aries-askar"},"Aries Askar"),(0,n.kt)("p",null,(0,n.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-askar"},"Aries Askar")," provides secure, encrypted storage and cryptographic support for encrypting, decrypting, signing and verifying data. It also provides both the ",(0,n.kt)("inlineCode",{parentName:"p"},"Wallet")," and ",(0,n.kt)("inlineCode",{parentName:"p"},"StorageService")," implementations for the agent."),(0,n.kt)("admonition",{type:"tip"},(0,n.kt)("p",{parentName:"admonition"},"If you're upgrading from the Indy SDK to Aries Askar, see ",(0,n.kt)("a",{parentName:"p",href:"../updating/update-indy-sdk-to-askar"},"Migrating from an Indy SDK Wallet to Aries Askar"))),(0,n.kt)("h3",{id:"installing-aries-askar"},"Installing Aries Askar"),(0,n.kt)("p",null,"When using Credo with Aries Askar, there are a few extra dependencies that need to be installed. We need to install the ",(0,n.kt)("inlineCode",{parentName:"p"},"@credo-ts/askar")," package, which implements the needed interfaces for the agent. Secondly, we need to add native bindings for the specific platform ",(0,n.kt)("inlineCode",{parentName:"p"},"@hyperledger/aries-askar-"),". Currently there are bindings for Node.JS, as ",(0,n.kt)("inlineCode",{parentName:"p"},"@hyperledger/aries-askar-nodejs"),", and React Native as ",(0,n.kt)("inlineCode",{parentName:"p"},"@hyperlegder/aries-askar-react-native"),"."),(0,n.kt)(s.Z,{mdxType:"Tabs"},(0,n.kt)(i.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @credo-ts/askar@^0.5.0 @hyperledger/aries-askar-nodejs@^0.2.0\n"))),(0,n.kt)(i.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-console"},"yarn add @credo-ts/askar@^0.5.0 @hyperledger/aries-askar-react-native@^0.2.0\n")))),(0,n.kt)("h3",{id:"adding-aries-askar-to-the-agent"},"Adding Aries Askar to the Agent"),(0,n.kt)("p",null,"After installing the dependencies, we can register the Askar Module on the agent."),(0,n.kt)(s.Z,{mdxType:"Tabs"},(0,n.kt)(i.Z,{label:"Node.JS",value:"tab1",mdxType:"TabItem"},(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-askar.ts section-1",showLineNumbers:!0,"set-up-askar.ts":!0,"section-1":!0},""))),(0,n.kt)(i.Z,{label:"React Native",value:"tab2",mdxType:"TabItem"},(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-typescript",metastring:"showLineNumbers set-up-askar-rn.ts section-1",showLineNumbers:!0,"set-up-askar-rn.ts":!0,"section-1":!0},"")))))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/fd1a8f62.53d966df.js b/assets/js/fd1a8f62.53d966df.js deleted file mode 100644 index b95eb68b..00000000 --- a/assets/js/fd1a8f62.53d966df.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[77],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>h});var a=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function o(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var s=a.createContext({}),l=function(e){var n=a.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},p=function(e){var n=l(e.components);return a.createElement(s.Provider,{value:n},e.children)},c="mdxType",m={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},u=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,p=d(e,["components","mdxType","originalType","parentName"]),c=l(t),u=r,h=c["".concat(s,".").concat(u)]||c[u]||m[u]||i;return t?a.createElement(h,o(o({ref:n},p),{},{components:t})):a.createElement(h,o({ref:n},p))}));function h(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var i=t.length,o=new Array(i);o[0]=u;var d={};for(var s in n)hasOwnProperty.call(n,s)&&(d[s]=n[s]);d.originalType=e,d[c]="string"==typeof e?e:r,o[1]=d;for(var l=2;l{t.d(n,{Z:()=>o});var a=t(7294),r=t(6010);const i={tabItem:"tabItem_Ymn6"};function o(e){let{children:n,hidden:t,className:o}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(i.tabItem,o),hidden:t},n)}},4866:(e,n,t)=>{t.d(n,{Z:()=>w});var a=t(7462),r=t(7294),i=t(6010),o=t(2466),d=t(6550),s=t(1980),l=t(7392),p=t(12);function c(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:n,label:t,attributes:a,default:r}}=e;return{value:n,label:t,attributes:a,default:r}}))}function m(e){const{values:n,children:t}=e;return(0,r.useMemo)((()=>{const e=n??c(t);return function(e){const n=(0,l.l)(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 u(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function h(e){let{queryString:n=!1,groupId:t}=e;const a=(0,d.k6)(),i=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,s._X)(i),(0,r.useCallback)((e=>{if(!i)return;const n=new URLSearchParams(a.location.search);n.set(i,e),a.replace({...a.location,search:n.toString()})}),[i,a])]}function k(e){const{defaultValue:n,queryString:t=!1,groupId:a}=e,i=m(e),[o,d]=(0,r.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(!u({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 a=t.find((e=>e.default))??t[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:n,tabValues:i}))),[s,l]=h({queryString:t,groupId:a}),[c,k]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[a,i]=(0,p.Nk)(t);return[a,(0,r.useCallback)((e=>{t&&i.set(e)}),[t,i])]}({groupId:a}),g=(()=>{const e=s??c;return u({value:e,tabValues:i})?e:null})();(0,r.useLayoutEffect)((()=>{g&&d(g)}),[g]);return{selectedValue:o,selectValue:(0,r.useCallback)((e=>{if(!u({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);d(e),l(e),k(e)}),[l,k,i]),tabValues:i}}var g=t(2389);const f={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){let{className:n,block:t,selectedValue:d,selectValue:s,tabValues:l}=e;const p=[],{blockElementScrollPositionUntilNextRender:c}=(0,o.o5)(),m=e=>{const n=e.currentTarget,t=p.indexOf(n),a=l[t].value;a!==d&&(c(n),s(a))},u=e=>{let n=null;switch(e.key){case"Enter":m(e);break;case"ArrowRight":{const t=p.indexOf(e.currentTarget)+1;n=p[t]??p[0];break}case"ArrowLeft":{const t=p.indexOf(e.currentTarget)-1;n=p[t]??p[p.length-1];break}}n?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":t},n)},l.map((e=>{let{value:n,label:t,attributes:o}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:d===n?0:-1,"aria-selected":d===n,key:n,ref:e=>p.push(e),onKeyDown:u,onClick:m},o,{className:(0,i.Z)("tabs__item",f.tabItem,o?.className,{"tabs__item--active":d===n})}),t??n)})))}function v(e){let{lazy:n,children:t,selectedValue:a}=e;if(t=Array.isArray(t)?t:[t],n){const e=t.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},t.map(((e,n)=>(0,r.cloneElement)(e,{key:n,hidden:e.props.value!==a}))))}function b(e){const n=k(e);return r.createElement("div",{className:(0,i.Z)("tabs-container",f.tabList)},r.createElement(y,(0,a.Z)({},e,n)),r.createElement(v,(0,a.Z)({},e,n)))}function w(e){const n=(0,g.Z)();return r.createElement(b,(0,a.Z)({key:String(n)},e))}},9522:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>s,default:()=>h,frontMatter:()=>d,metadata:()=>l,toc:()=>c});var a=t(7462),r=(t(7294),t(3905)),i=t(4866),o=t(5162);const d={},s="Migrating from AFJ 0.3.x to 0.4.x",l={unversionedId:"updating/versions/0.3-to-0.4",id:"version-0.4/updating/versions/0.3-to-0.4",title:"Migrating from AFJ 0.3.x to 0.4.x",description:"This document describes everything you need to know for updating AFJ 0.3.x to 0.4.x. If you're not aware of how updating in AFJ works make sure to first read the guide on Updating AFJ.",source:"@site/versioned_docs/version-0.4/updating/versions/0.3-to-0.4.md",sourceDirName:"updating/versions",slug:"/updating/versions/0.3-to-0.4",permalink:"/guides/updating/versions/0.3-to-0.4",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Migrating from AFJ 0.2.x to 0.3.x",permalink:"/guides/updating/versions/0.2-to-0.3"},next:{title:"The Aries JavaScript Ecosystem",permalink:"/guides/ecosystem/"}},p={},c=[{value:"React Native",id:"react-native",level:4},{value:"Node",id:"node",level:4},{value:"Breaking Code Changes",id:"breaking-code-changes",level:2},{value:"Agent Creation",id:"agent-creation",level:3},{value:"0.3.x",id:"03x",level:5},{value:"0.4.x",id:"04x",level:5},{value:"Indy Network Configuration",id:"indy-network-configuration",level:3},{value:"0.3.x",id:"03x-1",level:5},{value:"0.4.x",id:"04x-1",level:5},{value:"Changes to wallet",id:"changes-to-wallet",level:3},{value:"Did Resolver and Registrar",id:"did-resolver-and-registrar",level:3},{value:"0.3.x",id:"03x-2",level:5},{value:"0.4.x",id:"04x-2",level:5},{value:"Removal of publicDidSeed and publicDid",id:"removal-of-publicdidseed-and-publicdid",level:3},{value:"0.3.x",id:"03x-3",level:5},{value:"0.4.x",id:"04x-3",level:5},{value:"More Granular Usage of Legacy did:sov Prefix in DIDComm Messages",id:"more-granular-usage-of-legacy-didsov-prefix-in-didcomm-messages",level:3},{value:"0.3.x",id:"03x-4",level:5},{value:"0.4.x",id:"04x-4",level:5},{value:"Removal of injectionContainer property from the agent",id:"removal-of-injectioncontainer-property-from-the-agent",level:3},{value:"connection has been updated to connectionId in TransportSession",id:"connection-has-been-updated-to-connectionid-in-transportsession",level:3},{value:"Replacement of Ledger Module with new AnonCreds Module",id:"replacement-of-ledger-module-with-new-anoncreds-module",level:3},{value:"0.3.x",id:"03x-5",level:5},{value:"0.4.x",id:"04x-5",level:5},{value:"Changes to the Credentials and Proofs modules",id:"changes-to-the-credentials-and-proofs-modules",level:3},{value:"Changes to the AnonCreds Credential and Proof Format",id:"changes-to-the-anoncreds-credential-and-proof-format",level:3},{value:"0.3.x",id:"03x-6",level:5},{value:"0.4.x",id:"04x-6",level:5},{value:"Removal of AnonCreds Master Secret management from Wallet",id:"removal-of-anoncreds-master-secret-management-from-wallet",level:3},{value:"Default Outbound DIDComm Content Type now application/didcomm-envelope-enc",id:"default-outbound-didcomm-content-type-now-applicationdidcomm-envelope-enc",level:3},{value:"0.3.x",id:"03x-7",level:5},{value:"0.4.x",id:"04x-7",level:5},{value:"Generalizing Indy properties in CredentialExchangeRecord",id:"generalizing-indy-properties-in-credentialexchangerecord",level:3},{value:"credentialRecordType",id:"credentialrecordtype",level:4},{value:"0.3.x",id:"03x-8",level:5},{value:"0.4.x",id:"04x-8",level:5},{value:"Metadata",id:"metadata",level:4},{value:"0.3.x",id:"03x-9",level:5},{value:"0.4.x",id:"04x-9",level:5},{value:"More paths in FileSystem",id:"more-paths-in-filesystem",level:3},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:2}],m={toc:c},u="wrapper";function h(e){let{components:n,...t}=e;return(0,r.kt)(u,(0,a.Z)({},m,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"migrating-from-afj-03x-to-04x"},"Migrating from AFJ 0.3.x to 0.4.x"),(0,r.kt)("p",null,"This document describes everything you need to know for updating AFJ 0.3.x to 0.4.x. If you're not aware of how updating in AFJ works make sure to first read the guide on ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.5/updating/"},"Updating AFJ"),"."),(0,r.kt)("p",null,"First of all, update you dependencies to the 0.4.x versions. This will also update the needed peer dependencies. ",(0,r.kt)("strong",{parentName:"p"},"Extension packages are not updated with this command"),". You need to update these manually, and make sure they're up to date with the latest version of AFJ."),(0,r.kt)("p",null,"Aries Framework JavaScript 0.4.0 is a major release that introduces a lot of new features and changes to the public API. Specifically, this release removed the dependency on the Indy SDK from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/core")," package. Agent setup is more flexible, but it also means the setup is more complex. Follow the mentioned steps in this document carefully to make the upgrade as smooth as possible."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"The migration guide only covers how to migrate from 0.3.x to 0.4.x while keeping the same behavior and dependencies. AFJ 0.4.0 introduced a lot of new features and adds support for ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-askar"},"Aries Askar"),", ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-vdr"},"Indy VDR")," and ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/anoncreds-rs"},"AnonCreds RS")," as a replacement for the Indy SDK."),(0,r.kt)("p",{parentName:"admonition"},"Migrating to these new components requires additional migration steps, which need to be closely followed to prevent loss of data. These can be found at the ",(0,r.kt)("a",{parentName:"p",href:"/guides/updating/update-indy-sdk-to-askar"},"Update Indy SDK to Askar guide"),"."),(0,r.kt)("p",{parentName:"admonition"},"As noted in the ",(0,r.kt)("a",{parentName:"p",href:"/guides/updating/update-indy-sdk-to-askar"},"Update Indy SDK to Askar guide"),", it is very important that the 0.3.x to 0.4.x update is started after migrating from the Indy SDK to Aries Askar.")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Multi-tenancy is not covered in the 0.3.x to 0.4.x migration guide. If you're using multi-tenancy in 0.3.x and want to migrate to 0.4.x, please open an issue on ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript"},"Github"),".")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"The following APIs, modules and features are experimental and therefore not covered by the semver versioning in Aries Framework JavaScript. If you're using any of these features, make sure to use an exact version of AFJ (",(0,r.kt)("inlineCode",{parentName:"p"},"0.4.0"),") instead of a range (",(0,r.kt)("inlineCode",{parentName:"p"},"^0.4.0"),"):"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},"Implementing your own ",(0,r.kt)("inlineCode",{parentName:"li"},"AnonCredsRegistry")," and AnonCreds service implementation. Using the default implementations (Indy SDK, AnonCreds RS) is fine."),(0,r.kt)("li",{parentName:"ul"},"Using the shared component libraries from ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/aries-askar"),", ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/indy-vdr")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/anoncreds-rs")),(0,r.kt)("li",{parentName:"ul"},"Using OpenID4VC from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/openid4vc-client")," module"),(0,r.kt)("li",{parentName:"ul"},"W3C JWT Verifiable Credentials"),(0,r.kt)("li",{parentName:"ul"},"Using multi-tenancy from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/tenants")," module"))),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"React Native",value:"tab1",mdxType:"TabItem"},(0,r.kt)("p",null,"First install the updated dependencies. Make sure to also install the new ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/indy-sdk")," package, which is a wrapper around the Indy SDK and install the ",(0,r.kt)("inlineCode",{parentName:"p"},"indy-sdk-react-native")," package."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/react-native@^0.4.0 @aries-framework/core@^0.4.0 @aries-framework/indy-sdk@^0.4.0 @aries-framework/anoncreds@^0.4.0 indy-sdk-react-native@^0.3.1\n\n# or NPM\nnpn install @aries-framework/react-native@^0.4.0 @aries-framework/core@^0.4.0 @aries-framework/indy-sdk@^0.4.0 @aries-framework/anoncreds@^0.4.0 indy-sdk-react-native@^0.3.1\n")),(0,r.kt)("p",null,"We also need to install types for the ",(0,r.kt)("inlineCode",{parentName:"p"},"indy-sdk-react-native")," package, which we take from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@types/indy-sdk")," package."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add --dev @types/indy-sdk-react-native@npm:@types/indy-sdk\n\n# or NPM\nnpm install --save-dev @types/indy-sdk-react-native@npm:@types/indy-sdk\n"))),(0,r.kt)(o.Z,{label:"Node",value:"tab2",mdxType:"TabItem"},(0,r.kt)("p",null,"First install the updated dependencies. Make sure to also install the new ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/indy-sdk")," package, which is a wrapper around the Indy SDK and install the ",(0,r.kt)("inlineCode",{parentName:"p"},"indy-sdk")," package itself."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/node@^0.4.0 @aries-framework/core@^0.4.0 @aries-framework/indy-sdk@^0.4.0 @aries-framework/anoncreds@^0.4.0 indy-sdk\n\n# or NPM\nnpm install @aries-framework/node@^0.4.0 @aries-framework/core@^0.4.0 @aries-framework/indy-sdk@^0.4.0 @aries-framework/anoncreds@^0.4.0 indy-sdk\n")),(0,r.kt)("p",null,"We also need to install types for the ",(0,r.kt)("inlineCode",{parentName:"p"},"indy-sdk")," package, which are available in the ",(0,r.kt)("inlineCode",{parentName:"p"},"@types/indy-sdk")," package."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add --dev @types/indy-sdk\n\n# or NPM\nnpm install --save-dev @types/indy-sdk\n")))),(0,r.kt)("h2",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,r.kt)("p",null,"This section will list all breaking changes made to the public API of AFJ between version 0.3.x and 0.4.0."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here, but it is possible some breaking changes are not documented here (feel free to open a pull request).")),(0,r.kt)("h3",{id:"agent-creation"},"Agent Creation"),(0,r.kt)("p",null,"With the dependency on the Indy SDK removed from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/core")," package, we now need to register the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," to still leverage the functionality the Indy SDK provides."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\nimport { IndySdkModule } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n // Register the IndySdkModule and provide the indySdk dependency\n indySdk: new IndySdkModule({\n indySdk,\n }),\n },\n})\n")))),(0,r.kt)("h3",{id:"indy-network-configuration"},"Indy Network Configuration"),(0,r.kt)("p",null,"With the Indy SDK being extracted out of core, the ",(0,r.kt)("inlineCode",{parentName:"p"},"indyLedger")," configuration option is no longer available on the ",(0,r.kt)("inlineCode",{parentName:"p"},"AgentConfig")," interface. Instead, the ",(0,r.kt)("inlineCode",{parentName:"p"},"networks")," configuration option is now available on the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," configuration."),(0,r.kt)("p",null,"In addition the ",(0,r.kt)("inlineCode",{parentName:"p"},"connectToIndyLedgersOnStartup")," property has been removed in favor of a per-network ",(0,r.kt)("inlineCode",{parentName:"p"},"connectOnStartup")," property that allows more fine-grained control over which networks to connect to on startup."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n connectToIndyLedgersOnStartup: true,\n indyLedgers: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\nimport { IndySdkModule } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n // Register the IndySdkModule and provide the indySdk dependency\n indySdk: new IndySdkModule({\n indySdk,\n\n // add networks as a replacement for indyLedgers\n networks: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n // new connectOnStartup property\n connectOnStartup: true,\n },\n ],\n }),\n },\n})\n")))),(0,r.kt)("h3",{id:"changes-to-wallet"},"Changes to wallet"),(0,r.kt)("p",null,"Throughout the framework it was possible to provide a ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," for deterministic key generation. Recently it was discovered that the ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," property in the Indy SDK was not actually used as a seed, but directly as the private key."),(0,r.kt)("p",null,"Therefore a new ",(0,r.kt)("inlineCode",{parentName:"p"},"privateKey")," property was added to the ",(0,r.kt)("inlineCode",{parentName:"p"},"Wallet")," interface in addition to the ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," property. When using the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," this now means you can ",(0,r.kt)("strong",{parentName:"p"},"only")," provide the ",(0,r.kt)("inlineCode",{parentName:"p"},"privateKey")," property. The ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," property is no longer supported ",(0,r.kt)("strong",{parentName:"p"},"by the ",(0,r.kt)("inlineCode",{parentName:"strong"},"IndySdkModule")),"."),(0,r.kt)("p",null,"The type of the ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," property has also been changed to ",(0,r.kt)("inlineCode",{parentName:"p"},"Buffer")," to make it more consistent with ",(0,r.kt)("inlineCode",{parentName:"p"},"privateKey")," property, and remove the ambiguity of what the encoding of the string variant of the ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," property should be."),(0,r.kt)("h3",{id:"did-resolver-and-registrar"},"Did Resolver and Registrar"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"did:sov")," resolver and registrar were registered by default in 0.3.x of the agent. In 0.4.0 they've been moved to the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/indy-sdk")," package and are thus not registered by default on the DIDs module anymore. In addition, the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkSovDidRegistrar")," has been replaced in favor of the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkIndyDidRegistrar")," which provides similar behavior, but leverages the new ",(0,r.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/indy-did-method/#indy-did-method-identifiers"},(0,r.kt)("inlineCode",{parentName:"a"},"did:indy")," method"),", which removes ambiguity about which network to use. You can still use the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkSovDidResolver")," to resolve ",(0,r.kt)("inlineCode",{parentName:"p"},"did:sov")," DIDs."),(0,r.kt)("p",null,"Note that the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," MUST be registered when using the Indy SDK did resolvers and registrars (see ",(0,r.kt)("a",{parentName:"p",href:"#agent-creation"},"Agent Creation"),"). The networks supported by the resolvers and registrar is determined by the ",(0,r.kt)("inlineCode",{parentName:"p"},"networks")," registered on the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," (see ",(0,r.kt)("a",{parentName:"p",href:"#indy-network-configuration"},"Indy Network Configuration"),")."),(0,r.kt)("p",null,"Also note that by default the ",(0,r.kt)("inlineCode",{parentName:"p"},"WebDidResolver"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"KeyDidResolver")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"PeerDidResolver")," are registered, and setting the ",(0,r.kt)("inlineCode",{parentName:"p"},"resolvers")," property on the ",(0,r.kt)("inlineCode",{parentName:"p"},"DidsModule")," configuration will override the default resolvers (an exception is the ",(0,r.kt)("inlineCode",{parentName:"p"},"PeerDidResolver")," as it is required for creating connections, and thus will always be registered)."),(0,r.kt)("p",null,"The same thing is true for the ",(0,r.kt)("inlineCode",{parentName:"p"},"registrars"),", for which the ",(0,r.kt)("inlineCode",{parentName:"p"},"KeyDidRegistrar")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"PeerDidRegistrar")," are registered by default. If defining the ",(0,r.kt)("inlineCode",{parentName:"p"},"resolvers")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"registrars"),", make sure to include the default registrars if you want to keep the previous behavior."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent, DidsModule } from '@aries-framework/core'\nimport { IndySdkModule } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n // note that the IndySdkModule MUST be registered for the resolvers and registrars to work\n // they are left out for brevity and can bee\n dids: new DidsModule({\n registrars: [new IndySdkIndyDidRegistrar()],\n resolvers: [new IndySdkSovDidResolver(), new IndySdkIndyDidResolver()],\n }),\n },\n})\n")))),(0,r.kt)("h3",{id:"removal-of-publicdidseed-and-publicdid"},"Removal of ",(0,r.kt)("inlineCode",{parentName:"h3"},"publicDidSeed")," and ",(0,r.kt)("inlineCode",{parentName:"h3"},"publicDid")),(0,r.kt)("p",null,"To make AFJ more generic, and less focused on Hyperledger Indy, and Indy dids, the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDidSeed")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDid")," properties have been removed from the agent configuration, the agent class, and the ",(0,r.kt)("inlineCode",{parentName:"p"},"Wallet")," interface."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDid")," property was used as the did to register items in the ledger module. The approach had some limitations:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"An agent could only have a single ",(0,r.kt)("inlineCode",{parentName:"li"},"publicDid")," property. This means that if you wanted to write to multiple ledgers you would have to create multiple agents"),(0,r.kt)("li",{parentName:"ul"},"The property assumed only Indy ledgers would be used, and didn't take into account the possibility of other ledgers.")),(0,r.kt)("p",null,"AFJ now provides generic APIs that can work with any ledger, and thus the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDid")," property is no longer needed. Different sections of this migration guide will explain the different parts of how to use the new APIs, this section just focuses on how to replace the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDid")," property."),(0,r.kt)("p",null,"The most common use case for the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDid")," property was for registering an endorser did that can endorse (read: pay for) transactions on the ledger. This can now be done by importing the did into agent, after which it can be used by the AnonCreds module to register schemas and credential definitions, and the did registrar to register DIDs."),(0,r.kt)("p",null,"There's a ",(0,r.kt)("strong",{parentName:"p"},"one-time import")," that needs to be done to import the did into the agent using the ",(0,r.kt)("inlineCode",{parentName:"p"},"DidsApi.import")," method. If you've previously used the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDidSeed")," property, providing the private key is optional, as it is already stored in the wallet. Note that the ",(0,r.kt)("inlineCode",{parentName:"p"},"privateKey")," is the same as the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDidSeed"),", see ",(0,r.kt)("a",{parentName:"p",href:"#changes-to-wallet"},"Changes to Wallet")," for context). The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," method will resolve the did passed to the ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," method (so make sure to register the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkIndyDidResolver"),"). It is recommended to import the endorser did as an ",(0,r.kt)("inlineCode",{parentName:"p"},"did:indy")," did rather than a ",(0,r.kt)("inlineCode",{parentName:"p"},"did:sov")," did, as the ",(0,r.kt)("inlineCode",{parentName:"p"},"did:sov")," method is deprecated for creation. The ",(0,r.kt)("inlineCode",{parentName:"p"},"did:indy")," did can be constructed by replacing ",(0,r.kt)("inlineCode",{parentName:"p"},"sov")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"indy:"),", where ",(0,r.kt)("inlineCode",{parentName:"p"},"")," should be replaced with a namespace as registered in the ",(0,r.kt)("inlineCode",{parentName:"p"},"networks")," property of the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," (see ",(0,r.kt)("a",{parentName:"p",href:"#indy-network-configuration"},"Indy Network Configuration"),")."),(0,r.kt)("p",null,"An initial list of namespace identifiers can be found in an ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-did-networks/issues/3"},"issue in the Indy Did Networks Repository"),". In the future this list will be maintained in the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-did-networks"},"Indy DID Networks repository")," itself."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n publicDidSeed: '01eafa4de4e22ed4fc2ee522b6ce2731',\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent, DidsModule, KeyType, TypedArrayEncoder } from '@aries-framework/core'\nimport { IndySdkModule, IndySdkIndyDidResolver } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n indySdk: new IndySdkModule({\n indySdk,\n networks: [\n {\n id: 'Sovrin Mainnet',\n // Important: make sure to pick the correct indy namespace for the network you're connecting to\n // See: https://github.com/hyperledger/indy-did-networks/issues/3\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n }),\n dids: new DidsModule({\n // Important: Make sure to register the IndySdkIndyDidResolver\n resolvers: [new IndySdkIndyDidResolver()],\n }),\n },\n})\n\n// Important: the `import` method only has to be called once, and the agent MUST be initialized before calling it.\n// The private key is optional if you've used the publicDidSeed property before (as the key will already be in the wallet),\nawait agent.initialize()\nawait agent.dids.import({\n did: 'did:indy:sovrin:KEPUoXHcswsfsHkXGfmXB7',\n privateKeys: [\n {\n keyType: KeyType.Ed25519,\n privateKey: TypedArrayEncoder.fromString('01eafa4de4e22ed4fc2ee522b6ce2731'),\n },\n ],\n})\n")))),(0,r.kt)("h3",{id:"more-granular-usage-of-legacy-didsov-prefix-in-didcomm-messages"},"More Granular Usage of Legacy ",(0,r.kt)("inlineCode",{parentName:"h3"},"did:sov")," Prefix in DIDComm Messages"),(0,r.kt)("p",null,"AFJ 0.3.0 used the ",(0,r.kt)("inlineCode",{parentName:"p"},"useLegacyDidSovPrefix")," to use the legacy ",(0,r.kt)("inlineCode",{parentName:"p"},"did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/")," as the prefix in the ",(0,r.kt)("inlineCode",{parentName:"p"},"@type")," of DIDComm message instead of the new ",(0,r.kt)("inlineCode",{parentName:"p"},"https://didcomm.org")," prefix. Over time it has proven that this approach leads to undesired behavior as all messages (even protocols that were defined after the new prefix was the default) would use the legacy prefix. However, due to not all implementations having support for new prefix, disabling the legacy prefixes proved to be a problem."),(0,r.kt)("p",null,"Therefore, in AFJ 0.4.0 the ",(0,r.kt)("inlineCode",{parentName:"p"},"useLegacyDidSovPrefix")," property has been replaced with the ",(0,r.kt)("inlineCode",{parentName:"p"},"useDidSovPrefixWhereAllowed")," property. This property will only use the legacy prefix for protocols that were defined before the new prefix was the default. This means that protocols that were defined after the new prefix was the default will use the new prefix independent of the value of the ",(0,r.kt)("inlineCode",{parentName:"p"},"useDidSovPrefixWhereAllowed")," property. We hope this will allow us to slowly migrate away from the legacy prefix as new protocols are defined without breaking backwards compatibility."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n useLegacyDidSovPrefix: true,\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n useDidSovPrefixWhereAllowed: true,\n },\n dependencies: agentDependencies,\n})\n")))),(0,r.kt)("h3",{id:"removal-of-injectioncontainer-property-from-the-agent"},"Removal of ",(0,r.kt)("inlineCode",{parentName:"h3"},"injectionContainer")," property from the agent"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"injectionContainer")," property on the ",(0,r.kt)("inlineCode",{parentName:"p"},"Agent")," has been replaced by the ",(0,r.kt)("inlineCode",{parentName:"p"},"dependencyManager")," property. The ",(0,r.kt)("inlineCode",{parentName:"p"},"dependencyManager")," property is an instance of the ",(0,r.kt)("inlineCode",{parentName:"p"},"DependencyManager")," class and wraps the injection container from ",(0,r.kt)("inlineCode",{parentName:"p"},"tsyringe"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"DependencyManager")," ",(0,r.kt)("em",{parentName:"p"},"should")," provide all functionality that is needed, and it is recommended to not use the injection directly. If you need to use the injection container directly, you can access it via the ",(0,r.kt)("inlineCode",{parentName:"p"},"container")," property on the ",(0,r.kt)("inlineCode",{parentName:"p"},"DependencyManager")," instance, but please raise an issue to discuss if the functionality you need should be added to the ",(0,r.kt)("inlineCode",{parentName:"p"},"DependencyManager")," class."),(0,r.kt)("h3",{id:"connection-has-been-updated-to-connectionid-in-transportsession"},(0,r.kt)("inlineCode",{parentName:"h3"},"connection")," has been updated to ",(0,r.kt)("inlineCode",{parentName:"h3"},"connectionId")," in ",(0,r.kt)("inlineCode",{parentName:"h3"},"TransportSession")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"connection")," property on the ",(0,r.kt)("inlineCode",{parentName:"p"},"TransportSession")," has been changed to ",(0,r.kt)("inlineCode",{parentName:"p"},"connectionId")," and now only holds a reference to the connection id instead of the connection record itself."),(0,r.kt)("p",null,"Accessing the connection on a transport session is an advanced case that is mostly only relevant when implementing a custom transport. If you are using the default transports, you should not be affected by this change."),(0,r.kt)("h3",{id:"replacement-of-ledger-module-with-new-anoncreds-module"},"Replacement of Ledger Module with new AnonCreds Module"),(0,r.kt)("p",null,"The ledger module has been available in AFJ since the very beginning, and was due for a big overhaul. With the addition of the dids module a while ago we already had a replacement for the ",(0,r.kt)("inlineCode",{parentName:"p"},"registerPublicDid")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"getPublicDid")," methods on the ledger module. The other methods of the ledger module have been replaced by the AnonCreds module."),(0,r.kt)("p",null,"In AFJ 0.4.0 AnonCreds credential support is not part of the core framework anymore, and needs to be manually registered on the agent. The first part is enabling the AnonCreds module, which allows to manage AnonCreds objects, interact with the ledger, and issuer, hold and verify AnonCreds credentials and is explained in this section. The second part is actually allowing AnonCreds credentials to be exchanged in the Issue Credential and Present Proof protocols, which is explained in the ",(0,r.kt)("a",{parentName:"p",href:"#manually-register-anoncreds-support-in-credentials-and-proofs-modules"},"Manually Register AnonCreds Support in Credentials and Proofs Modules")," section."),(0,r.kt)("p",null,"There's a few important takeaways based on the code example below:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"The ",(0,r.kt)("inlineCode",{parentName:"li"},"anoncreds")," module can be accessed under the ",(0,r.kt)("inlineCode",{parentName:"li"},"agent.modules.anoncreds")," property."),(0,r.kt)("li",{parentName:"ul"},"The interfaces are set up as generically as possible based on the ",(0,r.kt)("a",{parentName:"li",href:"https://identity.foundation/did-registration/"},"DID Registration")," and ",(0,r.kt)("a",{parentName:"li",href:"https://w3c-ccg.github.io/did-resolution/"},"DID Resolution")," specifications."),(0,r.kt)("li",{parentName:"ul"},"AnonCreds registries need to be manually registered so it's important to register the ",(0,r.kt)("inlineCode",{parentName:"li"},"IndySdkAnonCredsRegistry")," on the ",(0,r.kt)("inlineCode",{parentName:"li"},"AnonCredsModule"),"."),(0,r.kt)("li",{parentName:"ul"},"It is now required to pass an ",(0,r.kt)("inlineCode",{parentName:"li"},"issuerId")," when registering AnonCreds objects, according to the ",(0,r.kt)("a",{parentName:"li",href:"https://hyperledger.github.io/anoncreds-spec/"},"AnonCreds Specification"),". Only ",(0,r.kt)("inlineCode",{parentName:"li"},"did:indy")," issuer identifiers are allowed (based on the ",(0,r.kt)("a",{parentName:"li",href:"https://hyperledger.github.io/anoncreds-methods-registry/#didindy-anoncreds-method"},(0,r.kt)("inlineCode",{parentName:"a"},"did:indy")," AnonCreds Method"),"), so the network can be inferred from the issuer identifier.")),(0,r.kt)("p",null,"As will be explained in the ",(0,r.kt)("a",{parentName:"p",href:"#manually-register-anoncreds-support-in-credentials-and-proofs-modules"},"Manually Register AnonCreds Support in Credentials and Proofs Modules"),", you can still use the unqualified issuer identifiers (best known as the ",(0,r.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-methods-registry/#hyperledger-indy-legacy-anoncreds-method"},"Hyperledger Indy Legacy AnonCreds Method"),") in credential and proof exchanges."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n publicDidSeed: '01eafa4de4e22ed4fc2ee522b6ce2731',\n indyLedgers: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n },\n dependencies: agentDependencies,\n})\n\nawait agent.initialize()\n\nconst schema = await agent.ledger.registerSchema({\n attributes: ['name'],\n name: 'Example Schema',\n version: '1.0.1',\n})\n\nconst credentialDefinition = await agent.ledger.registerCredentialDefinition({\n schema,\n supportRevocation: false,\n tag: 'default',\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { AnonCredsModule } from '@aries-framework/anoncreds'\nimport { Agent, DidsModule, KeyType, TypedArrayEncoder } from '@aries-framework/core'\nimport { IndySdkAnonCredsRegistry, IndySdkModule, IndySdkIndyDidResolver } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n indySdk: new IndySdkModule({\n indySdk,\n networks: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n }),\n // Important: register the IndySdkAnonCredsRegistry so that the anoncreds module can resolver/register anoncreds objects based on the networks configured in the IndySdkModule\n anoncreds: new AnonCredsModule({\n registries: [new IndySdkAnonCredsRegistry()],\n }),\n // Important: register the IndySdkIndyDidResolver so that the anoncreds module can resolve DIDs based on the networks configured in the IndySdkModule\n dids: new DidsModule({\n resolvers: [new IndySdkIndyDidResolver()],\n }),\n },\n})\n\n// Agent MUST be initialized before the anoncreds module can be used\nawait agent.initialize()\n\n// Important: the issuerId (did) MUST be available to the dids module in the agent. You can either create the did using the dids module, or import it as described in this migration guide.\nconst schemaResult = await agent.modules.anoncreds.registerSchema({\n schema: {\n attrNames: ['name'],\n issuerId: 'did:indy:sovrin:KEPUoXHcswsfsHkXGfmXB7',\n name: 'Example Schema',\n version: '1.0.0',\n },\n options: {},\n})\n\n// The resolver and registrar follow the same pattern as the Did Registration\n// and Did Resolver interfaces as used by the did module.\nif (schemaResult.schemaState.state !== 'finished') {\n console.error(schemaResult)\n throw new Error(`Error creating schema`)\n}\n\nconst credentialDefinitionResult = await agent.modules.anoncreds.registerCredentialDefinition({\n credentialDefinition: {\n issuerId: 'did:indy:sovrin:KEPUoXHcswsfsHkXGfmXB7',\n schemaId: schemaResult.schemaState.schemaId,\n tag: 'default',\n },\n options: {},\n})\n")))),(0,r.kt)("h3",{id:"changes-to-the-credentials-and-proofs-modules"},"Changes to the Credentials and Proofs modules"),(0,r.kt)("p",null,"A lot of small, and some bigger changes have been made to the Credentials, and primarily, the Proofs modules. These changes have been made to make the modules more consistent and generic so that they can be used in a wider range of use cases, removing any focus on AnonCreds and Indy credentials."),(0,r.kt)("p",null,"Changes to the Proofs module include:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"getRequestedCredentialsForProofRequest")," has been renamed to ",(0,r.kt)("inlineCode",{parentName:"li"},"getCredentialsForRequest")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"autoSelectCredentialsForProofRequest")," has been renamed to ",(0,r.kt)("inlineCode",{parentName:"li"},"selectCredentialsForRequest")),(0,r.kt)("li",{parentName:"ul"},"The ",(0,r.kt)("inlineCode",{parentName:"li"},"config")," parameter for both methods has been removed and those have been replaced by proof format specific configuration options. In this case, the ",(0,r.kt)("inlineCode",{parentName:"li"},"config.filterByNonRevocationRequirements")," has been added as ",(0,r.kt)("inlineCode",{parentName:"li"},"proofFormats.indy.filterByNonRevocationRequirements")," (if the ",(0,r.kt)("inlineCode",{parentName:"li"},"indy")," format is registered as explained in the next section). The ",(0,r.kt)("inlineCode",{parentName:"li"},"config.filterByPresentationPreview")," has been removed as the presentation preview was only present in the present proof V1 protocol, and due to it's limited applicability (the holder starts with a proposal) we've decided to remove this method for now. You can still filter the credentials yourself by using the ",(0,r.kt)("inlineCode",{parentName:"li"},"getCredentialsForRequest")," method."),(0,r.kt)("li",{parentName:"ul"},"Interfaces have been renamed to be more consistent with the method names. Please refer to the ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-framework-javascript/blob/v0.4.0/packages/core/src/modules/credentials/CredentialsApiOptions.ts"},(0,r.kt)("inlineCode",{parentName:"a"},"CredentialsApiOptions"))," and ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-framework-javascript/blob/v0.4.0/packages/core/src/modules/proofs/ProofsApiOptions.ts"},(0,r.kt)("inlineCode",{parentName:"a"},"ProofsApiOptions"))," for the interface names that can be imported.")),(0,r.kt)("p",null,"If you encounter any other breaking changes in the Proofs and Credentials modules, please open an issue in the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-javascript-docs"},"Aries JavaScript Docs")," repository."),(0,r.kt)("h3",{id:"changes-to-the-anoncreds-credential-and-proof-format"},"Changes to the AnonCreds Credential and Proof Format"),(0,r.kt)("p",null,"With the 0.4.0 release, AFJ now provides a pluggable AnonCreds interface, and requires support AnonCreds credentials to be explicitly registered on the agent. This is also the case for registering the credential and proof formats."),(0,r.kt)("p",null,"In 0.3.x, the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndyProofFormatService")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"IndyCredentialFormatService")," were registered by default. In 0.4.x, these services are no longer registered by default and they should be imported from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/anoncreds")," package as ",(0,r.kt)("inlineCode",{parentName:"p"},"LegacyIndyProofFormatService")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"LegacyIndyCredentialFormatService")," and are based on ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0592-indy-attachments/README.md"},"Aries RFC 0592"),". In a future version the new ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsCredentialFormatService")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsProofFormatService")," will be added to the AnonCreds package, which are based on ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/pull/771"},"Aries RFC 0771")," and allow for AnonCreds credentials to be exchanged based on the new ledger agnostic ",(0,r.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-spec/"},"AnonCreds Specification"),"."),(0,r.kt)("p",null,"In addition, the ",(0,r.kt)("inlineCode",{parentName:"p"},"V1CredentialProtocol")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"V1ProofProtocol")," have been extracted into the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/anoncreds")," package, as they only support exchange of (legacy Indy) AnonCreds credentials."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n indyLedgers: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import {\n AnonCredsModule,\n LegacyIndyCredentialFormatService,\n LegacyIndyProofFormatService,\n V1CredentialProtocol,\n V1ProofProtocol,\n} from '@aries-framework/anoncreds'\nimport { Agent, CredentialsModule, ProofsModule, V2CredentialProtocol, V2ProofProtocol } from '@aries-framework/core'\nimport { IndySdkAnonCredsRegistry, IndySdkModule } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst legacyIndyCredentialFormat = new LegacyIndyCredentialFormatService()\nconst legacyIndyProofFormat = new LegacyIndyProofFormatService()\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n indySdk: new IndySdkModule({\n indySdk,\n networks: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n }),\n // Important: the AnonCreds module MUST be registered with a registry that can resolve\n // legacy unqualified Indy anoncreds identifiers\n anoncreds: new AnonCredsModule({\n registries: [new IndySdkAnonCredsRegistry()],\n }),\n // Define the proofs module with support for both v1 and v2 of the proof protocols\n // both of which support the legacy Indy proof format\n proofs: new ProofsModule({\n proofProtocols: [\n new V1ProofProtocol({\n indyProofFormat: legacyIndyProofFormat,\n }),\n new V2ProofProtocol({\n proofFormats: [legacyIndyProofFormat],\n }),\n ],\n }),\n // Define the credentials module with support for both v1 and v2 of the credential protocols\n // both of which support the legacy Indy proof format\n credentials: new CredentialsModule({\n credentialProtocols: [\n new V1CredentialProtocol({\n indyCredentialFormat: legacyIndyCredentialFormat,\n }),\n new V2CredentialProtocol({\n credentialFormats: [legacyIndyCredentialFormat],\n }),\n ],\n }),\n },\n})\n")))),(0,r.kt)("h3",{id:"removal-of-anoncreds-master-secret-management-from-wallet"},"Removal of AnonCreds Master Secret management from ",(0,r.kt)("inlineCode",{parentName:"h3"},"Wallet")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"Wallet")," class no longer manages the creation and deletion of AnonCreds master secrets (which are now called Link Secrets in AnonCreds module and specification). If you haven't provided a custom ",(0,r.kt)("inlineCode",{parentName:"p"},"masterSecretId")," to the ",(0,r.kt)("inlineCode",{parentName:"p"},"walletConfig")," before, the storage migration script should have automatically created an ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsLinkSecretRecord")," for you based on the ",(0,r.kt)("inlineCode",{parentName:"p"},"walletConfig.id"),"."),(0,r.kt)("p",null,"For new agents however, you now need to explicitly create a link secret before you can create requests for AnonCreds credential offers. You can do this using the ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsApi.createLinkSecret")," method."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"If you previously used a custom ",(0,r.kt)("inlineCode",{parentName:"p"},"masterSecretId")," in the ",(0,r.kt)("inlineCode",{parentName:"p"},"walletConfig")," the migration script will have created an incorrect ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsLinkSecretRecord")," based on the ",(0,r.kt)("inlineCode",{parentName:"p"},"walletConfig.id"),". You will need to manually override the link secret record with the correct ",(0,r.kt)("inlineCode",{parentName:"p"},"linkSecretId"),"."),(0,r.kt)("p",{parentName:"admonition"},"You ",(0,r.kt)("strong",{parentName:"p"},"ONLY")," need to do this if you're not migrating from Indy SDK to Askar, as in that case the migration script will have created the correct ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsLinkSecretRecord")," for you."),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { AnonCredsLinkSecretRepository } from '@aries-framework/anoncreds'\n\nconst linkSecretRepository = agent.dependencyManager.resolve(AnonCredsLinkSecretRepository)\nconst defaultLinkSecret = await linkSecretRepository.findDefault(agent.context)\n\nif (defaultLinkSecret) {\n defaultLinkSecret.linkSecretId = 'my-custom-link-secret-id'\n await linkSecretRepository.update(agent.context, defaultLinkSecret)\n}\n"))),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { AnonCredsModule } from '@aries-framework/anoncreds'\nimport { Agent } from '@aries-framework/core'\nimport { IndySdkAnonCredsRegistry, IndySdkModule } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n indySdk: new IndySdkModule({\n indySdk,\n }),\n anoncreds: new AnonCredsModule({\n registries: [new IndySdkAnonCredsRegistry()],\n }),\n },\n})\n\n// the agent MUST be initialized before calling it.\nawait agent.wallet.initialize({\n id: 'wallet-id',\n key: 'wallet-key',\n})\n\nawait agent.modules.anoncreds.createLinkSecret({\n // first one will be set to default automatically\n setAsDefault: true,\n\n // will be generated if not provided.\n // linkSecretId: 'link-secret-id'\n})\n")),(0,r.kt)("h3",{id:"default-outbound-didcomm-content-type-now-applicationdidcomm-envelope-enc"},"Default Outbound DIDComm Content Type now ",(0,r.kt)("inlineCode",{parentName:"h3"},"application/didcomm-envelope-enc")),(0,r.kt)("p",null,"The default outbound DIDComm content type has been changed from ",(0,r.kt)("inlineCode",{parentName:"p"},"DidCommMimeType.V0")," (",(0,r.kt)("inlineCode",{parentName:"p"},"application/ssi-agent-wire"),") to ",(0,r.kt)("inlineCode",{parentName:"p"},"DidCommMimeType.V1")," (",(0,r.kt)("inlineCode",{parentName:"p"},"application/didcomm-envelope-enc"),"). V1 is the default for DIDComm V1 (as ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0044-didcomm-file-and-mime-types/README.md#detecting-didcomm-versions"},"defined in Aries RFC 0044"),"). In the past, V0 resulted in better interoperability, but since it has been the default for so long it makes sense to change the default behavior."),(0,r.kt)("p",null,"It is advised to use the default value as configured by the agent (V1). If you want to keep the old behavior, you can ",(0,r.kt)("a",{parentName:"p",href:"/guides/tutorials/agent-config#didcommmimetype"},"configure the ",(0,r.kt)("inlineCode",{parentName:"a"},"didCommMimeType")," property in the agent configuration"),"."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent, DidCommMimeType } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n didCommMimeType: DidCommMimeType.V0,\n },\n dependencies: agentDependencies,\n})\n")))),(0,r.kt)("h3",{id:"generalizing-indy-properties-in-credentialexchangerecord"},"Generalizing Indy properties in ",(0,r.kt)("inlineCode",{parentName:"h3"},"CredentialExchangeRecord")),(0,r.kt)("p",null,"With AnonCreds credentials now being generalized to support multiple ledgers, the properties specific to Hyperledger Indy have now been generalized into a generic AnonCreds properties."),(0,r.kt)("h4",{id:"credentialrecordtype"},(0,r.kt)("inlineCode",{parentName:"h4"},"credentialRecordType")),(0,r.kt)("p",null,"First off, the ",(0,r.kt)("inlineCode",{parentName:"p"},"credentialRecordType")," that was used to reference stored AnonCreds credentials has been renamed from ",(0,r.kt)("inlineCode",{parentName:"p"},"indy")," to ",(0,r.kt)("inlineCode",{parentName:"p"},"anoncreds"),". The migration script takes care of the update to the storage, but you need to make sure to update all places that expect a ",(0,r.kt)("inlineCode",{parentName:"p"},"credentialRecordType")," of ",(0,r.kt)("inlineCode",{parentName:"p"},"indy")," to be defined."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="CredentialExchangeRecord"',title:'"CredentialExchangeRecord"'},'{\n "credentials": [\n {\n "credentialRecordType": "indy",\n "credentialRecordId": "credential-id"\n }\n ]\n}\n'))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="CredentialExchangeRecord"',title:'"CredentialExchangeRecord"'},'{\n "credentials": [\n {\n "credentialRecordType": "anoncreds",\n "credentialRecordId": "credential-id"\n }\n ]\n}\n')))),(0,r.kt)("h4",{id:"metadata"},"Metadata"),(0,r.kt)("p",null,"Second, the metadata keys and values have been renamed to be AnonCreds specific rather than Indy specific. The ",(0,r.kt)("inlineCode",{parentName:"p"},"CredentialMetadataKeys")," have been replaced by the ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsCredentialMetadataKey")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsCredentialRequestMetadataKey")," constants which can be imported from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/anoncreds")," package."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="CredentialExchangeRecord"',title:'"CredentialExchangeRecord"'},'{\n "metadata": {\n "_internal/indyCredential": {\n "schemaId": "schema-id",\n "credentialDefinitionId": "cred-def-id",\n "indyRevocationRegistryId": "rev-reg-id",\n "indyCredentialRevocationId": "cred-rev-id"\n },\n "_internal/indyRequest": {\n "master_secret_blinding_data": {\n "v_prime": "string",\n "vr_prime": "string"\n },\n "master_secret_name": "string",\n "nonce": "string"\n }\n }\n}\n'))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="CredentialExchangeRecord"',title:'"CredentialExchangeRecord"'},'{\n "metadata": {\n "_anoncreds/credential": {\n "schemaId": "schema-id",\n "credentialDefinitionId": "cred-def-id",\n "revocationRegistryId": "rev-reg-id",\n "credentialRevocationId": "cred-rev-id"\n },\n "_anoncreds/credentialRequest": {\n "master_secret_blinding_data": {\n "v_prime": "string",\n "vr_prime": "string"\n },\n "master_secret_name": "string",\n "nonce": "string"\n }\n }\n}\n')))),(0,r.kt)("h3",{id:"more-paths-in-filesystem"},"More paths in ",(0,r.kt)("inlineCode",{parentName:"h3"},"FileSystem")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"FileSystem")," interface has been extended to support multiple base paths. The previous interface had a single ",(0,r.kt)("inlineCode",{parentName:"p"},"basePath")," property which was used for storing of files across the framework."),(0,r.kt)("p",null,"With the different lifetimes of different objects, the ",(0,r.kt)("inlineCode",{parentName:"p"},"FileSystem")," interface has been extended to now support three different base paths:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"cachePath")," - files used for caching purposes. It's okay if the files are cleared from time to time."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"dataPath")," - files that are used for long-term reliable storage purposes. These files will never be cleared."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"tempPath")," - files that are used for temporary storage purposes. It's okay if the files are cleared from time to time.")),(0,r.kt)("p",null,"If you're using the framework, you don't need to worry about this change. The agent may need to download some objects again after the update. If you've made a custom implementation of the ",(0,r.kt)("inlineCode",{parentName:"p"},"FileSystem"),", make sure to support all three base paths, and make sure to correctly handle the life-cycle of the files. Items stored under the ",(0,r.kt)("inlineCode",{parentName:"p"},"dataPath")," ",(0,r.kt)("strong",{parentName:"p"},"should never be cleared"),"."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Indy SDK SQLite wallets do not use the paths defined by the ",(0,r.kt)("inlineCode",{parentName:"p"},"FileSystem")," interface, and thus will not be influenced by this change. When upgrading to Aries Askar, the ",(0,r.kt)("inlineCode",{parentName:"p"},"dataPath")," will be used as the base path for storing the SQLite wallet data.")),(0,r.kt)("h2",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,r.kt)("p",null,"The 0.4.0 release introduces some breaking changes to the storage format."),(0,r.kt)("p",null,"Below all breaking storage changes are explained in as much detail as possible. The update assistant provides all tools to migrate without a hassle, but it is important to know what has changed. All examples only show the keys that have changed, unrelated keys in records have been omitted."),(0,r.kt)("p",null,"See the ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.5/updating/update-assistant"},"Update Assistant")," documentation for a guide on how to use the update assistant."),(0,r.kt)("p",null,"There are no configuration parameters to be provided to the update assistant to migrate from 0.3.x to 0.4.x."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"TODO")))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/fd1a8f62.a136feac.js b/assets/js/fd1a8f62.a136feac.js new file mode 100644 index 00000000..0e079615 --- /dev/null +++ b/assets/js/fd1a8f62.a136feac.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[77],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>h});var a=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function o(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var s=a.createContext({}),l=function(e){var n=a.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},p=function(e){var n=l(e.components);return a.createElement(s.Provider,{value:n},e.children)},c="mdxType",m={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},u=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,p=d(e,["components","mdxType","originalType","parentName"]),c=l(t),u=r,h=c["".concat(s,".").concat(u)]||c[u]||m[u]||i;return t?a.createElement(h,o(o({ref:n},p),{},{components:t})):a.createElement(h,o({ref:n},p))}));function h(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var i=t.length,o=new Array(i);o[0]=u;var d={};for(var s in n)hasOwnProperty.call(n,s)&&(d[s]=n[s]);d.originalType=e,d[c]="string"==typeof e?e:r,o[1]=d;for(var l=2;l{t.d(n,{Z:()=>o});var a=t(7294),r=t(6010);const i={tabItem:"tabItem_Ymn6"};function o(e){let{children:n,hidden:t,className:o}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(i.tabItem,o),hidden:t},n)}},4866:(e,n,t)=>{t.d(n,{Z:()=>w});var a=t(7462),r=t(7294),i=t(6010),o=t(2466),d=t(6550),s=t(1980),l=t(7392),p=t(12);function c(e){return function(e){return r.Children.map(e,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)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.`)}))}(e).map((e=>{let{props:{value:n,label:t,attributes:a,default:r}}=e;return{value:n,label:t,attributes:a,default:r}}))}function m(e){const{values:n,children:t}=e;return(0,r.useMemo)((()=>{const e=n??c(t);return function(e){const n=(0,l.l)(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 u(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function h(e){let{queryString:n=!1,groupId:t}=e;const a=(0,d.k6)(),i=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,s._X)(i),(0,r.useCallback)((e=>{if(!i)return;const n=new URLSearchParams(a.location.search);n.set(i,e),a.replace({...a.location,search:n.toString()})}),[i,a])]}function k(e){const{defaultValue:n,queryString:t=!1,groupId:a}=e,i=m(e),[o,d]=(0,r.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(!u({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 a=t.find((e=>e.default))??t[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:n,tabValues:i}))),[s,l]=h({queryString:t,groupId:a}),[c,k]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[a,i]=(0,p.Nk)(t);return[a,(0,r.useCallback)((e=>{t&&i.set(e)}),[t,i])]}({groupId:a}),g=(()=>{const e=s??c;return u({value:e,tabValues:i})?e:null})();(0,r.useLayoutEffect)((()=>{g&&d(g)}),[g]);return{selectedValue:o,selectValue:(0,r.useCallback)((e=>{if(!u({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);d(e),l(e),k(e)}),[l,k,i]),tabValues:i}}var g=t(2389);const f={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){let{className:n,block:t,selectedValue:d,selectValue:s,tabValues:l}=e;const p=[],{blockElementScrollPositionUntilNextRender:c}=(0,o.o5)(),m=e=>{const n=e.currentTarget,t=p.indexOf(n),a=l[t].value;a!==d&&(c(n),s(a))},u=e=>{let n=null;switch(e.key){case"Enter":m(e);break;case"ArrowRight":{const t=p.indexOf(e.currentTarget)+1;n=p[t]??p[0];break}case"ArrowLeft":{const t=p.indexOf(e.currentTarget)-1;n=p[t]??p[p.length-1];break}}n?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":t},n)},l.map((e=>{let{value:n,label:t,attributes:o}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:d===n?0:-1,"aria-selected":d===n,key:n,ref:e=>p.push(e),onKeyDown:u,onClick:m},o,{className:(0,i.Z)("tabs__item",f.tabItem,o?.className,{"tabs__item--active":d===n})}),t??n)})))}function v(e){let{lazy:n,children:t,selectedValue:a}=e;if(t=Array.isArray(t)?t:[t],n){const e=t.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},t.map(((e,n)=>(0,r.cloneElement)(e,{key:n,hidden:e.props.value!==a}))))}function b(e){const n=k(e);return r.createElement("div",{className:(0,i.Z)("tabs-container",f.tabList)},r.createElement(y,(0,a.Z)({},e,n)),r.createElement(v,(0,a.Z)({},e,n)))}function w(e){const n=(0,g.Z)();return r.createElement(b,(0,a.Z)({key:String(n)},e))}},9522:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>s,default:()=>h,frontMatter:()=>d,metadata:()=>l,toc:()=>c});var a=t(7462),r=(t(7294),t(3905)),i=t(4866),o=t(5162);const d={},s="Migrating from AFJ 0.3.x to 0.4.x",l={unversionedId:"updating/versions/0.3-to-0.4",id:"version-0.4/updating/versions/0.3-to-0.4",title:"Migrating from AFJ 0.3.x to 0.4.x",description:"This document describes everything you need to know for updating AFJ 0.3.x to 0.4.x. If you're not aware of how updating in AFJ works make sure to first read the guide on Updating AFJ.",source:"@site/versioned_docs/version-0.4/updating/versions/0.3-to-0.4.md",sourceDirName:"updating/versions",slug:"/updating/versions/0.3-to-0.4",permalink:"/guides/0.4/updating/versions/0.3-to-0.4",draft:!1,tags:[],version:"0.4",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Migrating from AFJ 0.2.x to 0.3.x",permalink:"/guides/0.4/updating/versions/0.2-to-0.3"},next:{title:"The Aries JavaScript Ecosystem",permalink:"/guides/0.4/ecosystem/"}},p={},c=[{value:"React Native",id:"react-native",level:4},{value:"Node",id:"node",level:4},{value:"Breaking Code Changes",id:"breaking-code-changes",level:2},{value:"Agent Creation",id:"agent-creation",level:3},{value:"0.3.x",id:"03x",level:5},{value:"0.4.x",id:"04x",level:5},{value:"Indy Network Configuration",id:"indy-network-configuration",level:3},{value:"0.3.x",id:"03x-1",level:5},{value:"0.4.x",id:"04x-1",level:5},{value:"Changes to wallet",id:"changes-to-wallet",level:3},{value:"Did Resolver and Registrar",id:"did-resolver-and-registrar",level:3},{value:"0.3.x",id:"03x-2",level:5},{value:"0.4.x",id:"04x-2",level:5},{value:"Removal of publicDidSeed and publicDid",id:"removal-of-publicdidseed-and-publicdid",level:3},{value:"0.3.x",id:"03x-3",level:5},{value:"0.4.x",id:"04x-3",level:5},{value:"More Granular Usage of Legacy did:sov Prefix in DIDComm Messages",id:"more-granular-usage-of-legacy-didsov-prefix-in-didcomm-messages",level:3},{value:"0.3.x",id:"03x-4",level:5},{value:"0.4.x",id:"04x-4",level:5},{value:"Removal of injectionContainer property from the agent",id:"removal-of-injectioncontainer-property-from-the-agent",level:3},{value:"connection has been updated to connectionId in TransportSession",id:"connection-has-been-updated-to-connectionid-in-transportsession",level:3},{value:"Replacement of Ledger Module with new AnonCreds Module",id:"replacement-of-ledger-module-with-new-anoncreds-module",level:3},{value:"0.3.x",id:"03x-5",level:5},{value:"0.4.x",id:"04x-5",level:5},{value:"Changes to the Credentials and Proofs modules",id:"changes-to-the-credentials-and-proofs-modules",level:3},{value:"Changes to the AnonCreds Credential and Proof Format",id:"changes-to-the-anoncreds-credential-and-proof-format",level:3},{value:"0.3.x",id:"03x-6",level:5},{value:"0.4.x",id:"04x-6",level:5},{value:"Removal of AnonCreds Master Secret management from Wallet",id:"removal-of-anoncreds-master-secret-management-from-wallet",level:3},{value:"Default Outbound DIDComm Content Type now application/didcomm-envelope-enc",id:"default-outbound-didcomm-content-type-now-applicationdidcomm-envelope-enc",level:3},{value:"0.3.x",id:"03x-7",level:5},{value:"0.4.x",id:"04x-7",level:5},{value:"Generalizing Indy properties in CredentialExchangeRecord",id:"generalizing-indy-properties-in-credentialexchangerecord",level:3},{value:"credentialRecordType",id:"credentialrecordtype",level:4},{value:"0.3.x",id:"03x-8",level:5},{value:"0.4.x",id:"04x-8",level:5},{value:"Metadata",id:"metadata",level:4},{value:"0.3.x",id:"03x-9",level:5},{value:"0.4.x",id:"04x-9",level:5},{value:"More paths in FileSystem",id:"more-paths-in-filesystem",level:3},{value:"Breaking Storage Changes",id:"breaking-storage-changes",level:2}],m={toc:c},u="wrapper";function h(e){let{components:n,...t}=e;return(0,r.kt)(u,(0,a.Z)({},m,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"migrating-from-afj-03x-to-04x"},"Migrating from AFJ 0.3.x to 0.4.x"),(0,r.kt)("p",null,"This document describes everything you need to know for updating AFJ 0.3.x to 0.4.x. If you're not aware of how updating in AFJ works make sure to first read the guide on ",(0,r.kt)("a",{parentName:"p",href:"/guides/updating/"},"Updating AFJ"),"."),(0,r.kt)("p",null,"First of all, update you dependencies to the 0.4.x versions. This will also update the needed peer dependencies. ",(0,r.kt)("strong",{parentName:"p"},"Extension packages are not updated with this command"),". You need to update these manually, and make sure they're up to date with the latest version of AFJ."),(0,r.kt)("p",null,"Aries Framework JavaScript 0.4.0 is a major release that introduces a lot of new features and changes to the public API. Specifically, this release removed the dependency on the Indy SDK from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/core")," package. Agent setup is more flexible, but it also means the setup is more complex. Follow the mentioned steps in this document carefully to make the upgrade as smooth as possible."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"The migration guide only covers how to migrate from 0.3.x to 0.4.x while keeping the same behavior and dependencies. AFJ 0.4.0 introduced a lot of new features and adds support for ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-askar"},"Aries Askar"),", ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-vdr"},"Indy VDR")," and ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/anoncreds-rs"},"AnonCreds RS")," as a replacement for the Indy SDK."),(0,r.kt)("p",{parentName:"admonition"},"Migrating to these new components requires additional migration steps, which need to be closely followed to prevent loss of data. These can be found at the ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.4/updating/update-indy-sdk-to-askar"},"Update Indy SDK to Askar guide"),"."),(0,r.kt)("p",{parentName:"admonition"},"As noted in the ",(0,r.kt)("a",{parentName:"p",href:"/guides/0.4/updating/update-indy-sdk-to-askar"},"Update Indy SDK to Askar guide"),", it is very important that the 0.3.x to 0.4.x update is started after migrating from the Indy SDK to Aries Askar.")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Multi-tenancy is not covered in the 0.3.x to 0.4.x migration guide. If you're using multi-tenancy in 0.3.x and want to migrate to 0.4.x, please open an issue on ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-framework-javascript"},"Github"),".")),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"The following APIs, modules and features are experimental and therefore not covered by the semver versioning in Aries Framework JavaScript. If you're using any of these features, make sure to use an exact version of AFJ (",(0,r.kt)("inlineCode",{parentName:"p"},"0.4.0"),") instead of a range (",(0,r.kt)("inlineCode",{parentName:"p"},"^0.4.0"),"):"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},"Implementing your own ",(0,r.kt)("inlineCode",{parentName:"li"},"AnonCredsRegistry")," and AnonCreds service implementation. Using the default implementations (Indy SDK, AnonCreds RS) is fine."),(0,r.kt)("li",{parentName:"ul"},"Using the shared component libraries from ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/aries-askar"),", ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/indy-vdr")," and ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/anoncreds-rs")),(0,r.kt)("li",{parentName:"ul"},"Using OpenID4VC from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/openid4vc-client")," module"),(0,r.kt)("li",{parentName:"ul"},"W3C JWT Verifiable Credentials"),(0,r.kt)("li",{parentName:"ul"},"Using multi-tenancy from the ",(0,r.kt)("inlineCode",{parentName:"li"},"@aries-framework/tenants")," module"))),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"React Native",value:"tab1",mdxType:"TabItem"},(0,r.kt)("p",null,"First install the updated dependencies. Make sure to also install the new ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/indy-sdk")," package, which is a wrapper around the Indy SDK and install the ",(0,r.kt)("inlineCode",{parentName:"p"},"indy-sdk-react-native")," package."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/react-native@^0.4.0 @aries-framework/core@^0.4.0 @aries-framework/indy-sdk@^0.4.0 @aries-framework/anoncreds@^0.4.0 indy-sdk-react-native@^0.3.1\n\n# or NPM\nnpn install @aries-framework/react-native@^0.4.0 @aries-framework/core@^0.4.0 @aries-framework/indy-sdk@^0.4.0 @aries-framework/anoncreds@^0.4.0 indy-sdk-react-native@^0.3.1\n")),(0,r.kt)("p",null,"We also need to install types for the ",(0,r.kt)("inlineCode",{parentName:"p"},"indy-sdk-react-native")," package, which we take from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@types/indy-sdk")," package."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add --dev @types/indy-sdk-react-native@npm:@types/indy-sdk\n\n# or NPM\nnpm install --save-dev @types/indy-sdk-react-native@npm:@types/indy-sdk\n"))),(0,r.kt)(o.Z,{label:"Node",value:"tab2",mdxType:"TabItem"},(0,r.kt)("p",null,"First install the updated dependencies. Make sure to also install the new ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/indy-sdk")," package, which is a wrapper around the Indy SDK and install the ",(0,r.kt)("inlineCode",{parentName:"p"},"indy-sdk")," package itself."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @aries-framework/node@^0.4.0 @aries-framework/core@^0.4.0 @aries-framework/indy-sdk@^0.4.0 @aries-framework/anoncreds@^0.4.0 indy-sdk\n\n# or NPM\nnpm install @aries-framework/node@^0.4.0 @aries-framework/core@^0.4.0 @aries-framework/indy-sdk@^0.4.0 @aries-framework/anoncreds@^0.4.0 indy-sdk\n")),(0,r.kt)("p",null,"We also need to install types for the ",(0,r.kt)("inlineCode",{parentName:"p"},"indy-sdk")," package, which are available in the ",(0,r.kt)("inlineCode",{parentName:"p"},"@types/indy-sdk")," package."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add --dev @types/indy-sdk\n\n# or NPM\nnpm install --save-dev @types/indy-sdk\n")))),(0,r.kt)("h2",{id:"breaking-code-changes"},"Breaking Code Changes"),(0,r.kt)("p",null,"This section will list all breaking changes made to the public API of AFJ between version 0.3.x and 0.4.0."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"If you have custom modules take into account there could be a lot more breaking changes that aren't documented here. We try to make sure that the biggest breaking changes to the internal API are also documented here, but it is possible some breaking changes are not documented here (feel free to open a pull request).")),(0,r.kt)("h3",{id:"agent-creation"},"Agent Creation"),(0,r.kt)("p",null,"With the dependency on the Indy SDK removed from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/core")," package, we now need to register the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," to still leverage the functionality the Indy SDK provides."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\nimport { IndySdkModule } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n // Register the IndySdkModule and provide the indySdk dependency\n indySdk: new IndySdkModule({\n indySdk,\n }),\n },\n})\n")))),(0,r.kt)("h3",{id:"indy-network-configuration"},"Indy Network Configuration"),(0,r.kt)("p",null,"With the Indy SDK being extracted out of core, the ",(0,r.kt)("inlineCode",{parentName:"p"},"indyLedger")," configuration option is no longer available on the ",(0,r.kt)("inlineCode",{parentName:"p"},"AgentConfig")," interface. Instead, the ",(0,r.kt)("inlineCode",{parentName:"p"},"networks")," configuration option is now available on the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," configuration."),(0,r.kt)("p",null,"In addition the ",(0,r.kt)("inlineCode",{parentName:"p"},"connectToIndyLedgersOnStartup")," property has been removed in favor of a per-network ",(0,r.kt)("inlineCode",{parentName:"p"},"connectOnStartup")," property that allows more fine-grained control over which networks to connect to on startup."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n connectToIndyLedgersOnStartup: true,\n indyLedgers: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\nimport { IndySdkModule } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n // Register the IndySdkModule and provide the indySdk dependency\n indySdk: new IndySdkModule({\n indySdk,\n\n // add networks as a replacement for indyLedgers\n networks: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n // new connectOnStartup property\n connectOnStartup: true,\n },\n ],\n }),\n },\n})\n")))),(0,r.kt)("h3",{id:"changes-to-wallet"},"Changes to wallet"),(0,r.kt)("p",null,"Throughout the framework it was possible to provide a ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," for deterministic key generation. Recently it was discovered that the ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," property in the Indy SDK was not actually used as a seed, but directly as the private key."),(0,r.kt)("p",null,"Therefore a new ",(0,r.kt)("inlineCode",{parentName:"p"},"privateKey")," property was added to the ",(0,r.kt)("inlineCode",{parentName:"p"},"Wallet")," interface in addition to the ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," property. When using the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," this now means you can ",(0,r.kt)("strong",{parentName:"p"},"only")," provide the ",(0,r.kt)("inlineCode",{parentName:"p"},"privateKey")," property. The ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," property is no longer supported ",(0,r.kt)("strong",{parentName:"p"},"by the ",(0,r.kt)("inlineCode",{parentName:"strong"},"IndySdkModule")),"."),(0,r.kt)("p",null,"The type of the ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," property has also been changed to ",(0,r.kt)("inlineCode",{parentName:"p"},"Buffer")," to make it more consistent with ",(0,r.kt)("inlineCode",{parentName:"p"},"privateKey")," property, and remove the ambiguity of what the encoding of the string variant of the ",(0,r.kt)("inlineCode",{parentName:"p"},"seed")," property should be."),(0,r.kt)("h3",{id:"did-resolver-and-registrar"},"Did Resolver and Registrar"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"did:sov")," resolver and registrar were registered by default in 0.3.x of the agent. In 0.4.0 they've been moved to the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/indy-sdk")," package and are thus not registered by default on the DIDs module anymore. In addition, the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkSovDidRegistrar")," has been replaced in favor of the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkIndyDidRegistrar")," which provides similar behavior, but leverages the new ",(0,r.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/indy-did-method/#indy-did-method-identifiers"},(0,r.kt)("inlineCode",{parentName:"a"},"did:indy")," method"),", which removes ambiguity about which network to use. You can still use the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkSovDidResolver")," to resolve ",(0,r.kt)("inlineCode",{parentName:"p"},"did:sov")," DIDs."),(0,r.kt)("p",null,"Note that the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," MUST be registered when using the Indy SDK did resolvers and registrars (see ",(0,r.kt)("a",{parentName:"p",href:"#agent-creation"},"Agent Creation"),"). The networks supported by the resolvers and registrar is determined by the ",(0,r.kt)("inlineCode",{parentName:"p"},"networks")," registered on the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," (see ",(0,r.kt)("a",{parentName:"p",href:"#indy-network-configuration"},"Indy Network Configuration"),")."),(0,r.kt)("p",null,"Also note that by default the ",(0,r.kt)("inlineCode",{parentName:"p"},"WebDidResolver"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"KeyDidResolver")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"PeerDidResolver")," are registered, and setting the ",(0,r.kt)("inlineCode",{parentName:"p"},"resolvers")," property on the ",(0,r.kt)("inlineCode",{parentName:"p"},"DidsModule")," configuration will override the default resolvers (an exception is the ",(0,r.kt)("inlineCode",{parentName:"p"},"PeerDidResolver")," as it is required for creating connections, and thus will always be registered)."),(0,r.kt)("p",null,"The same thing is true for the ",(0,r.kt)("inlineCode",{parentName:"p"},"registrars"),", for which the ",(0,r.kt)("inlineCode",{parentName:"p"},"KeyDidRegistrar")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"PeerDidRegistrar")," are registered by default. If defining the ",(0,r.kt)("inlineCode",{parentName:"p"},"resolvers")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"registrars"),", make sure to include the default registrars if you want to keep the previous behavior."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent, DidsModule } from '@aries-framework/core'\nimport { IndySdkModule } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n // note that the IndySdkModule MUST be registered for the resolvers and registrars to work\n // they are left out for brevity and can bee\n dids: new DidsModule({\n registrars: [new IndySdkIndyDidRegistrar()],\n resolvers: [new IndySdkSovDidResolver(), new IndySdkIndyDidResolver()],\n }),\n },\n})\n")))),(0,r.kt)("h3",{id:"removal-of-publicdidseed-and-publicdid"},"Removal of ",(0,r.kt)("inlineCode",{parentName:"h3"},"publicDidSeed")," and ",(0,r.kt)("inlineCode",{parentName:"h3"},"publicDid")),(0,r.kt)("p",null,"To make AFJ more generic, and less focused on Hyperledger Indy, and Indy dids, the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDidSeed")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDid")," properties have been removed from the agent configuration, the agent class, and the ",(0,r.kt)("inlineCode",{parentName:"p"},"Wallet")," interface."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDid")," property was used as the did to register items in the ledger module. The approach had some limitations:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"An agent could only have a single ",(0,r.kt)("inlineCode",{parentName:"li"},"publicDid")," property. This means that if you wanted to write to multiple ledgers you would have to create multiple agents"),(0,r.kt)("li",{parentName:"ul"},"The property assumed only Indy ledgers would be used, and didn't take into account the possibility of other ledgers.")),(0,r.kt)("p",null,"AFJ now provides generic APIs that can work with any ledger, and thus the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDid")," property is no longer needed. Different sections of this migration guide will explain the different parts of how to use the new APIs, this section just focuses on how to replace the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDid")," property."),(0,r.kt)("p",null,"The most common use case for the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDid")," property was for registering an endorser did that can endorse (read: pay for) transactions on the ledger. This can now be done by importing the did into agent, after which it can be used by the AnonCreds module to register schemas and credential definitions, and the did registrar to register DIDs."),(0,r.kt)("p",null,"There's a ",(0,r.kt)("strong",{parentName:"p"},"one-time import")," that needs to be done to import the did into the agent using the ",(0,r.kt)("inlineCode",{parentName:"p"},"DidsApi.import")," method. If you've previously used the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDidSeed")," property, providing the private key is optional, as it is already stored in the wallet. Note that the ",(0,r.kt)("inlineCode",{parentName:"p"},"privateKey")," is the same as the ",(0,r.kt)("inlineCode",{parentName:"p"},"publicDidSeed"),", see ",(0,r.kt)("a",{parentName:"p",href:"#changes-to-wallet"},"Changes to Wallet")," for context). The ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," method will resolve the did passed to the ",(0,r.kt)("inlineCode",{parentName:"p"},"import")," method (so make sure to register the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkIndyDidResolver"),"). It is recommended to import the endorser did as an ",(0,r.kt)("inlineCode",{parentName:"p"},"did:indy")," did rather than a ",(0,r.kt)("inlineCode",{parentName:"p"},"did:sov")," did, as the ",(0,r.kt)("inlineCode",{parentName:"p"},"did:sov")," method is deprecated for creation. The ",(0,r.kt)("inlineCode",{parentName:"p"},"did:indy")," did can be constructed by replacing ",(0,r.kt)("inlineCode",{parentName:"p"},"sov")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"indy:"),", where ",(0,r.kt)("inlineCode",{parentName:"p"},"")," should be replaced with a namespace as registered in the ",(0,r.kt)("inlineCode",{parentName:"p"},"networks")," property of the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndySdkModule")," (see ",(0,r.kt)("a",{parentName:"p",href:"#indy-network-configuration"},"Indy Network Configuration"),")."),(0,r.kt)("p",null,"An initial list of namespace identifiers can be found in an ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-did-networks/issues/3"},"issue in the Indy Did Networks Repository"),". In the future this list will be maintained in the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/indy-did-networks"},"Indy DID Networks repository")," itself."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n publicDidSeed: '01eafa4de4e22ed4fc2ee522b6ce2731',\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent, DidsModule, KeyType, TypedArrayEncoder } from '@aries-framework/core'\nimport { IndySdkModule, IndySdkIndyDidResolver } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n indySdk: new IndySdkModule({\n indySdk,\n networks: [\n {\n id: 'Sovrin Mainnet',\n // Important: make sure to pick the correct indy namespace for the network you're connecting to\n // See: https://github.com/hyperledger/indy-did-networks/issues/3\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n }),\n dids: new DidsModule({\n // Important: Make sure to register the IndySdkIndyDidResolver\n resolvers: [new IndySdkIndyDidResolver()],\n }),\n },\n})\n\n// Important: the `import` method only has to be called once, and the agent MUST be initialized before calling it.\n// The private key is optional if you've used the publicDidSeed property before (as the key will already be in the wallet),\nawait agent.initialize()\nawait agent.dids.import({\n did: 'did:indy:sovrin:KEPUoXHcswsfsHkXGfmXB7',\n privateKeys: [\n {\n keyType: KeyType.Ed25519,\n privateKey: TypedArrayEncoder.fromString('01eafa4de4e22ed4fc2ee522b6ce2731'),\n },\n ],\n})\n")))),(0,r.kt)("h3",{id:"more-granular-usage-of-legacy-didsov-prefix-in-didcomm-messages"},"More Granular Usage of Legacy ",(0,r.kt)("inlineCode",{parentName:"h3"},"did:sov")," Prefix in DIDComm Messages"),(0,r.kt)("p",null,"AFJ 0.3.0 used the ",(0,r.kt)("inlineCode",{parentName:"p"},"useLegacyDidSovPrefix")," to use the legacy ",(0,r.kt)("inlineCode",{parentName:"p"},"did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/")," as the prefix in the ",(0,r.kt)("inlineCode",{parentName:"p"},"@type")," of DIDComm message instead of the new ",(0,r.kt)("inlineCode",{parentName:"p"},"https://didcomm.org")," prefix. Over time it has proven that this approach leads to undesired behavior as all messages (even protocols that were defined after the new prefix was the default) would use the legacy prefix. However, due to not all implementations having support for new prefix, disabling the legacy prefixes proved to be a problem."),(0,r.kt)("p",null,"Therefore, in AFJ 0.4.0 the ",(0,r.kt)("inlineCode",{parentName:"p"},"useLegacyDidSovPrefix")," property has been replaced with the ",(0,r.kt)("inlineCode",{parentName:"p"},"useDidSovPrefixWhereAllowed")," property. This property will only use the legacy prefix for protocols that were defined before the new prefix was the default. This means that protocols that were defined after the new prefix was the default will use the new prefix independent of the value of the ",(0,r.kt)("inlineCode",{parentName:"p"},"useDidSovPrefixWhereAllowed")," property. We hope this will allow us to slowly migrate away from the legacy prefix as new protocols are defined without breaking backwards compatibility."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n useLegacyDidSovPrefix: true,\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n useDidSovPrefixWhereAllowed: true,\n },\n dependencies: agentDependencies,\n})\n")))),(0,r.kt)("h3",{id:"removal-of-injectioncontainer-property-from-the-agent"},"Removal of ",(0,r.kt)("inlineCode",{parentName:"h3"},"injectionContainer")," property from the agent"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"injectionContainer")," property on the ",(0,r.kt)("inlineCode",{parentName:"p"},"Agent")," has been replaced by the ",(0,r.kt)("inlineCode",{parentName:"p"},"dependencyManager")," property. The ",(0,r.kt)("inlineCode",{parentName:"p"},"dependencyManager")," property is an instance of the ",(0,r.kt)("inlineCode",{parentName:"p"},"DependencyManager")," class and wraps the injection container from ",(0,r.kt)("inlineCode",{parentName:"p"},"tsyringe"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"DependencyManager")," ",(0,r.kt)("em",{parentName:"p"},"should")," provide all functionality that is needed, and it is recommended to not use the injection directly. If you need to use the injection container directly, you can access it via the ",(0,r.kt)("inlineCode",{parentName:"p"},"container")," property on the ",(0,r.kt)("inlineCode",{parentName:"p"},"DependencyManager")," instance, but please raise an issue to discuss if the functionality you need should be added to the ",(0,r.kt)("inlineCode",{parentName:"p"},"DependencyManager")," class."),(0,r.kt)("h3",{id:"connection-has-been-updated-to-connectionid-in-transportsession"},(0,r.kt)("inlineCode",{parentName:"h3"},"connection")," has been updated to ",(0,r.kt)("inlineCode",{parentName:"h3"},"connectionId")," in ",(0,r.kt)("inlineCode",{parentName:"h3"},"TransportSession")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"connection")," property on the ",(0,r.kt)("inlineCode",{parentName:"p"},"TransportSession")," has been changed to ",(0,r.kt)("inlineCode",{parentName:"p"},"connectionId")," and now only holds a reference to the connection id instead of the connection record itself."),(0,r.kt)("p",null,"Accessing the connection on a transport session is an advanced case that is mostly only relevant when implementing a custom transport. If you are using the default transports, you should not be affected by this change."),(0,r.kt)("h3",{id:"replacement-of-ledger-module-with-new-anoncreds-module"},"Replacement of Ledger Module with new AnonCreds Module"),(0,r.kt)("p",null,"The ledger module has been available in AFJ since the very beginning, and was due for a big overhaul. With the addition of the dids module a while ago we already had a replacement for the ",(0,r.kt)("inlineCode",{parentName:"p"},"registerPublicDid")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"getPublicDid")," methods on the ledger module. The other methods of the ledger module have been replaced by the AnonCreds module."),(0,r.kt)("p",null,"In AFJ 0.4.0 AnonCreds credential support is not part of the core framework anymore, and needs to be manually registered on the agent. The first part is enabling the AnonCreds module, which allows to manage AnonCreds objects, interact with the ledger, and issuer, hold and verify AnonCreds credentials and is explained in this section. The second part is actually allowing AnonCreds credentials to be exchanged in the Issue Credential and Present Proof protocols, which is explained in the ",(0,r.kt)("a",{parentName:"p",href:"#manually-register-anoncreds-support-in-credentials-and-proofs-modules"},"Manually Register AnonCreds Support in Credentials and Proofs Modules")," section."),(0,r.kt)("p",null,"There's a few important takeaways based on the code example below:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"The ",(0,r.kt)("inlineCode",{parentName:"li"},"anoncreds")," module can be accessed under the ",(0,r.kt)("inlineCode",{parentName:"li"},"agent.modules.anoncreds")," property."),(0,r.kt)("li",{parentName:"ul"},"The interfaces are set up as generically as possible based on the ",(0,r.kt)("a",{parentName:"li",href:"https://identity.foundation/did-registration/"},"DID Registration")," and ",(0,r.kt)("a",{parentName:"li",href:"https://w3c-ccg.github.io/did-resolution/"},"DID Resolution")," specifications."),(0,r.kt)("li",{parentName:"ul"},"AnonCreds registries need to be manually registered so it's important to register the ",(0,r.kt)("inlineCode",{parentName:"li"},"IndySdkAnonCredsRegistry")," on the ",(0,r.kt)("inlineCode",{parentName:"li"},"AnonCredsModule"),"."),(0,r.kt)("li",{parentName:"ul"},"It is now required to pass an ",(0,r.kt)("inlineCode",{parentName:"li"},"issuerId")," when registering AnonCreds objects, according to the ",(0,r.kt)("a",{parentName:"li",href:"https://hyperledger.github.io/anoncreds-spec/"},"AnonCreds Specification"),". Only ",(0,r.kt)("inlineCode",{parentName:"li"},"did:indy")," issuer identifiers are allowed (based on the ",(0,r.kt)("a",{parentName:"li",href:"https://hyperledger.github.io/anoncreds-methods-registry/#didindy-anoncreds-method"},(0,r.kt)("inlineCode",{parentName:"a"},"did:indy")," AnonCreds Method"),"), so the network can be inferred from the issuer identifier.")),(0,r.kt)("p",null,"As will be explained in the ",(0,r.kt)("a",{parentName:"p",href:"#manually-register-anoncreds-support-in-credentials-and-proofs-modules"},"Manually Register AnonCreds Support in Credentials and Proofs Modules"),", you can still use the unqualified issuer identifiers (best known as the ",(0,r.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-methods-registry/#hyperledger-indy-legacy-anoncreds-method"},"Hyperledger Indy Legacy AnonCreds Method"),") in credential and proof exchanges."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n publicDidSeed: '01eafa4de4e22ed4fc2ee522b6ce2731',\n indyLedgers: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n },\n dependencies: agentDependencies,\n})\n\nawait agent.initialize()\n\nconst schema = await agent.ledger.registerSchema({\n attributes: ['name'],\n name: 'Example Schema',\n version: '1.0.1',\n})\n\nconst credentialDefinition = await agent.ledger.registerCredentialDefinition({\n schema,\n supportRevocation: false,\n tag: 'default',\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { AnonCredsModule } from '@aries-framework/anoncreds'\nimport { Agent, DidsModule, KeyType, TypedArrayEncoder } from '@aries-framework/core'\nimport { IndySdkAnonCredsRegistry, IndySdkModule, IndySdkIndyDidResolver } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n indySdk: new IndySdkModule({\n indySdk,\n networks: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n }),\n // Important: register the IndySdkAnonCredsRegistry so that the anoncreds module can resolver/register anoncreds objects based on the networks configured in the IndySdkModule\n anoncreds: new AnonCredsModule({\n registries: [new IndySdkAnonCredsRegistry()],\n }),\n // Important: register the IndySdkIndyDidResolver so that the anoncreds module can resolve DIDs based on the networks configured in the IndySdkModule\n dids: new DidsModule({\n resolvers: [new IndySdkIndyDidResolver()],\n }),\n },\n})\n\n// Agent MUST be initialized before the anoncreds module can be used\nawait agent.initialize()\n\n// Important: the issuerId (did) MUST be available to the dids module in the agent. You can either create the did using the dids module, or import it as described in this migration guide.\nconst schemaResult = await agent.modules.anoncreds.registerSchema({\n schema: {\n attrNames: ['name'],\n issuerId: 'did:indy:sovrin:KEPUoXHcswsfsHkXGfmXB7',\n name: 'Example Schema',\n version: '1.0.0',\n },\n options: {},\n})\n\n// The resolver and registrar follow the same pattern as the Did Registration\n// and Did Resolver interfaces as used by the did module.\nif (schemaResult.schemaState.state !== 'finished') {\n console.error(schemaResult)\n throw new Error(`Error creating schema`)\n}\n\nconst credentialDefinitionResult = await agent.modules.anoncreds.registerCredentialDefinition({\n credentialDefinition: {\n issuerId: 'did:indy:sovrin:KEPUoXHcswsfsHkXGfmXB7',\n schemaId: schemaResult.schemaState.schemaId,\n tag: 'default',\n },\n options: {},\n})\n")))),(0,r.kt)("h3",{id:"changes-to-the-credentials-and-proofs-modules"},"Changes to the Credentials and Proofs modules"),(0,r.kt)("p",null,"A lot of small, and some bigger changes have been made to the Credentials, and primarily, the Proofs modules. These changes have been made to make the modules more consistent and generic so that they can be used in a wider range of use cases, removing any focus on AnonCreds and Indy credentials."),(0,r.kt)("p",null,"Changes to the Proofs module include:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"getRequestedCredentialsForProofRequest")," has been renamed to ",(0,r.kt)("inlineCode",{parentName:"li"},"getCredentialsForRequest")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"autoSelectCredentialsForProofRequest")," has been renamed to ",(0,r.kt)("inlineCode",{parentName:"li"},"selectCredentialsForRequest")),(0,r.kt)("li",{parentName:"ul"},"The ",(0,r.kt)("inlineCode",{parentName:"li"},"config")," parameter for both methods has been removed and those have been replaced by proof format specific configuration options. In this case, the ",(0,r.kt)("inlineCode",{parentName:"li"},"config.filterByNonRevocationRequirements")," has been added as ",(0,r.kt)("inlineCode",{parentName:"li"},"proofFormats.indy.filterByNonRevocationRequirements")," (if the ",(0,r.kt)("inlineCode",{parentName:"li"},"indy")," format is registered as explained in the next section). The ",(0,r.kt)("inlineCode",{parentName:"li"},"config.filterByPresentationPreview")," has been removed as the presentation preview was only present in the present proof V1 protocol, and due to it's limited applicability (the holder starts with a proposal) we've decided to remove this method for now. You can still filter the credentials yourself by using the ",(0,r.kt)("inlineCode",{parentName:"li"},"getCredentialsForRequest")," method."),(0,r.kt)("li",{parentName:"ul"},"Interfaces have been renamed to be more consistent with the method names. Please refer to the ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-framework-javascript/blob/v0.4.0/packages/core/src/modules/credentials/CredentialsApiOptions.ts"},(0,r.kt)("inlineCode",{parentName:"a"},"CredentialsApiOptions"))," and ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/hyperledger/aries-framework-javascript/blob/v0.4.0/packages/core/src/modules/proofs/ProofsApiOptions.ts"},(0,r.kt)("inlineCode",{parentName:"a"},"ProofsApiOptions"))," for the interface names that can be imported.")),(0,r.kt)("p",null,"If you encounter any other breaking changes in the Proofs and Credentials modules, please open an issue in the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-javascript-docs"},"Aries JavaScript Docs")," repository."),(0,r.kt)("h3",{id:"changes-to-the-anoncreds-credential-and-proof-format"},"Changes to the AnonCreds Credential and Proof Format"),(0,r.kt)("p",null,"With the 0.4.0 release, AFJ now provides a pluggable AnonCreds interface, and requires support AnonCreds credentials to be explicitly registered on the agent. This is also the case for registering the credential and proof formats."),(0,r.kt)("p",null,"In 0.3.x, the ",(0,r.kt)("inlineCode",{parentName:"p"},"IndyProofFormatService")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"IndyCredentialFormatService")," were registered by default. In 0.4.x, these services are no longer registered by default and they should be imported from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/anoncreds")," package as ",(0,r.kt)("inlineCode",{parentName:"p"},"LegacyIndyProofFormatService")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"LegacyIndyCredentialFormatService")," and are based on ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0592-indy-attachments/README.md"},"Aries RFC 0592"),". In a future version the new ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsCredentialFormatService")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsProofFormatService")," will be added to the AnonCreds package, which are based on ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/pull/771"},"Aries RFC 0771")," and allow for AnonCreds credentials to be exchanged based on the new ledger agnostic ",(0,r.kt)("a",{parentName:"p",href:"https://hyperledger.github.io/anoncreds-spec/"},"AnonCreds Specification"),"."),(0,r.kt)("p",null,"In addition, the ",(0,r.kt)("inlineCode",{parentName:"p"},"V1CredentialProtocol")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"V1ProofProtocol")," have been extracted into the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/anoncreds")," package, as they only support exchange of (legacy Indy) AnonCreds credentials."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n indyLedgers: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import {\n AnonCredsModule,\n LegacyIndyCredentialFormatService,\n LegacyIndyProofFormatService,\n V1CredentialProtocol,\n V1ProofProtocol,\n} from '@aries-framework/anoncreds'\nimport { Agent, CredentialsModule, ProofsModule, V2CredentialProtocol, V2ProofProtocol } from '@aries-framework/core'\nimport { IndySdkAnonCredsRegistry, IndySdkModule } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst legacyIndyCredentialFormat = new LegacyIndyCredentialFormatService()\nconst legacyIndyProofFormat = new LegacyIndyProofFormatService()\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n indySdk: new IndySdkModule({\n indySdk,\n networks: [\n {\n id: 'Sovrin Mainnet',\n indyNamespace: 'sovrin',\n isProduction: true,\n genesisPath: './genesis/sovrin-genesis.txn',\n },\n ],\n }),\n // Important: the AnonCreds module MUST be registered with a registry that can resolve\n // legacy unqualified Indy anoncreds identifiers\n anoncreds: new AnonCredsModule({\n registries: [new IndySdkAnonCredsRegistry()],\n }),\n // Define the proofs module with support for both v1 and v2 of the proof protocols\n // both of which support the legacy Indy proof format\n proofs: new ProofsModule({\n proofProtocols: [\n new V1ProofProtocol({\n indyProofFormat: legacyIndyProofFormat,\n }),\n new V2ProofProtocol({\n proofFormats: [legacyIndyProofFormat],\n }),\n ],\n }),\n // Define the credentials module with support for both v1 and v2 of the credential protocols\n // both of which support the legacy Indy proof format\n credentials: new CredentialsModule({\n credentialProtocols: [\n new V1CredentialProtocol({\n indyCredentialFormat: legacyIndyCredentialFormat,\n }),\n new V2CredentialProtocol({\n credentialFormats: [legacyIndyCredentialFormat],\n }),\n ],\n }),\n },\n})\n")))),(0,r.kt)("h3",{id:"removal-of-anoncreds-master-secret-management-from-wallet"},"Removal of AnonCreds Master Secret management from ",(0,r.kt)("inlineCode",{parentName:"h3"},"Wallet")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"Wallet")," class no longer manages the creation and deletion of AnonCreds master secrets (which are now called Link Secrets in AnonCreds module and specification). If you haven't provided a custom ",(0,r.kt)("inlineCode",{parentName:"p"},"masterSecretId")," to the ",(0,r.kt)("inlineCode",{parentName:"p"},"walletConfig")," before, the storage migration script should have automatically created an ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsLinkSecretRecord")," for you based on the ",(0,r.kt)("inlineCode",{parentName:"p"},"walletConfig.id"),"."),(0,r.kt)("p",null,"For new agents however, you now need to explicitly create a link secret before you can create requests for AnonCreds credential offers. You can do this using the ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsApi.createLinkSecret")," method."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"If you previously used a custom ",(0,r.kt)("inlineCode",{parentName:"p"},"masterSecretId")," in the ",(0,r.kt)("inlineCode",{parentName:"p"},"walletConfig")," the migration script will have created an incorrect ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsLinkSecretRecord")," based on the ",(0,r.kt)("inlineCode",{parentName:"p"},"walletConfig.id"),". You will need to manually override the link secret record with the correct ",(0,r.kt)("inlineCode",{parentName:"p"},"linkSecretId"),"."),(0,r.kt)("p",{parentName:"admonition"},"You ",(0,r.kt)("strong",{parentName:"p"},"ONLY")," need to do this if you're not migrating from Indy SDK to Askar, as in that case the migration script will have created the correct ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsLinkSecretRecord")," for you."),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { AnonCredsLinkSecretRepository } from '@aries-framework/anoncreds'\n\nconst linkSecretRepository = agent.dependencyManager.resolve(AnonCredsLinkSecretRepository)\nconst defaultLinkSecret = await linkSecretRepository.findDefault(agent.context)\n\nif (defaultLinkSecret) {\n defaultLinkSecret.linkSecretId = 'my-custom-link-secret-id'\n await linkSecretRepository.update(agent.context, defaultLinkSecret)\n}\n"))),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { AnonCredsModule } from '@aries-framework/anoncreds'\nimport { Agent } from '@aries-framework/core'\nimport { IndySdkAnonCredsRegistry, IndySdkModule } from '@aries-framework/indy-sdk'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\n// Import from indy-sdk-react-native in React Native\nimport indySdk from 'indy-sdk'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n modules: {\n indySdk: new IndySdkModule({\n indySdk,\n }),\n anoncreds: new AnonCredsModule({\n registries: [new IndySdkAnonCredsRegistry()],\n }),\n },\n})\n\n// the agent MUST be initialized before calling it.\nawait agent.wallet.initialize({\n id: 'wallet-id',\n key: 'wallet-key',\n})\n\nawait agent.modules.anoncreds.createLinkSecret({\n // first one will be set to default automatically\n setAsDefault: true,\n\n // will be generated if not provided.\n // linkSecretId: 'link-secret-id'\n})\n")),(0,r.kt)("h3",{id:"default-outbound-didcomm-content-type-now-applicationdidcomm-envelope-enc"},"Default Outbound DIDComm Content Type now ",(0,r.kt)("inlineCode",{parentName:"h3"},"application/didcomm-envelope-enc")),(0,r.kt)("p",null,"The default outbound DIDComm content type has been changed from ",(0,r.kt)("inlineCode",{parentName:"p"},"DidCommMimeType.V0")," (",(0,r.kt)("inlineCode",{parentName:"p"},"application/ssi-agent-wire"),") to ",(0,r.kt)("inlineCode",{parentName:"p"},"DidCommMimeType.V1")," (",(0,r.kt)("inlineCode",{parentName:"p"},"application/didcomm-envelope-enc"),"). V1 is the default for DIDComm V1 (as ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/hyperledger/aries-rfcs/blob/main/features/0044-didcomm-file-and-mime-types/README.md#detecting-didcomm-versions"},"defined in Aries RFC 0044"),"). In the past, V0 resulted in better interoperability, but since it has been the default for so long it makes sense to change the default behavior."),(0,r.kt)("p",null,"It is advised to use the default value as configured by the agent (V1). If you want to keep the old behavior, you can ",(0,r.kt)("a",{parentName:"p",href:"/guides/tutorials/agent-config#didcommmimetype"},"configure the ",(0,r.kt)("inlineCode",{parentName:"a"},"didCommMimeType")," property in the agent configuration"),"."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n /* ... */\n },\n dependencies: agentDependencies,\n})\n"))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"import { Agent, DidCommMimeType } from '@aries-framework/core'\n\n// Import from @aries-framework/react-native in React Native\nimport { agentDependencies } from '@aries-framework/node'\n\nconst agent = new Agent({\n config: {\n didCommMimeType: DidCommMimeType.V0,\n },\n dependencies: agentDependencies,\n})\n")))),(0,r.kt)("h3",{id:"generalizing-indy-properties-in-credentialexchangerecord"},"Generalizing Indy properties in ",(0,r.kt)("inlineCode",{parentName:"h3"},"CredentialExchangeRecord")),(0,r.kt)("p",null,"With AnonCreds credentials now being generalized to support multiple ledgers, the properties specific to Hyperledger Indy have now been generalized into a generic AnonCreds properties."),(0,r.kt)("h4",{id:"credentialrecordtype"},(0,r.kt)("inlineCode",{parentName:"h4"},"credentialRecordType")),(0,r.kt)("p",null,"First off, the ",(0,r.kt)("inlineCode",{parentName:"p"},"credentialRecordType")," that was used to reference stored AnonCreds credentials has been renamed from ",(0,r.kt)("inlineCode",{parentName:"p"},"indy")," to ",(0,r.kt)("inlineCode",{parentName:"p"},"anoncreds"),". The migration script takes care of the update to the storage, but you need to make sure to update all places that expect a ",(0,r.kt)("inlineCode",{parentName:"p"},"credentialRecordType")," of ",(0,r.kt)("inlineCode",{parentName:"p"},"indy")," to be defined."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="CredentialExchangeRecord"',title:'"CredentialExchangeRecord"'},'{\n "credentials": [\n {\n "credentialRecordType": "indy",\n "credentialRecordId": "credential-id"\n }\n ]\n}\n'))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="CredentialExchangeRecord"',title:'"CredentialExchangeRecord"'},'{\n "credentials": [\n {\n "credentialRecordType": "anoncreds",\n "credentialRecordId": "credential-id"\n }\n ]\n}\n')))),(0,r.kt)("h4",{id:"metadata"},"Metadata"),(0,r.kt)("p",null,"Second, the metadata keys and values have been renamed to be AnonCreds specific rather than Indy specific. The ",(0,r.kt)("inlineCode",{parentName:"p"},"CredentialMetadataKeys")," have been replaced by the ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsCredentialMetadataKey")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"AnonCredsCredentialRequestMetadataKey")," constants which can be imported from the ",(0,r.kt)("inlineCode",{parentName:"p"},"@aries-framework/anoncreds")," package."),(0,r.kt)(i.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{label:"0.3.x",value:"tab1",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="CredentialExchangeRecord"',title:'"CredentialExchangeRecord"'},'{\n "metadata": {\n "_internal/indyCredential": {\n "schemaId": "schema-id",\n "credentialDefinitionId": "cred-def-id",\n "indyRevocationRegistryId": "rev-reg-id",\n "indyCredentialRevocationId": "cred-rev-id"\n },\n "_internal/indyRequest": {\n "master_secret_blinding_data": {\n "v_prime": "string",\n "vr_prime": "string"\n },\n "master_secret_name": "string",\n "nonce": "string"\n }\n }\n}\n'))),(0,r.kt)(o.Z,{label:"0.4.x",value:"tab2",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="CredentialExchangeRecord"',title:'"CredentialExchangeRecord"'},'{\n "metadata": {\n "_anoncreds/credential": {\n "schemaId": "schema-id",\n "credentialDefinitionId": "cred-def-id",\n "revocationRegistryId": "rev-reg-id",\n "credentialRevocationId": "cred-rev-id"\n },\n "_anoncreds/credentialRequest": {\n "master_secret_blinding_data": {\n "v_prime": "string",\n "vr_prime": "string"\n },\n "master_secret_name": "string",\n "nonce": "string"\n }\n }\n}\n')))),(0,r.kt)("h3",{id:"more-paths-in-filesystem"},"More paths in ",(0,r.kt)("inlineCode",{parentName:"h3"},"FileSystem")),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"FileSystem")," interface has been extended to support multiple base paths. The previous interface had a single ",(0,r.kt)("inlineCode",{parentName:"p"},"basePath")," property which was used for storing of files across the framework."),(0,r.kt)("p",null,"With the different lifetimes of different objects, the ",(0,r.kt)("inlineCode",{parentName:"p"},"FileSystem")," interface has been extended to now support three different base paths:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"cachePath")," - files used for caching purposes. It's okay if the files are cleared from time to time."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"dataPath")," - files that are used for long-term reliable storage purposes. These files will never be cleared."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"tempPath")," - files that are used for temporary storage purposes. It's okay if the files are cleared from time to time.")),(0,r.kt)("p",null,"If you're using the framework, you don't need to worry about this change. The agent may need to download some objects again after the update. If you've made a custom implementation of the ",(0,r.kt)("inlineCode",{parentName:"p"},"FileSystem"),", make sure to support all three base paths, and make sure to correctly handle the life-cycle of the files. Items stored under the ",(0,r.kt)("inlineCode",{parentName:"p"},"dataPath")," ",(0,r.kt)("strong",{parentName:"p"},"should never be cleared"),"."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Indy SDK SQLite wallets do not use the paths defined by the ",(0,r.kt)("inlineCode",{parentName:"p"},"FileSystem")," interface, and thus will not be influenced by this change. When upgrading to Aries Askar, the ",(0,r.kt)("inlineCode",{parentName:"p"},"dataPath")," will be used as the base path for storing the SQLite wallet data.")),(0,r.kt)("h2",{id:"breaking-storage-changes"},"Breaking Storage Changes"),(0,r.kt)("p",null,"The 0.4.0 release introduces some breaking changes to the storage format."),(0,r.kt)("p",null,"Below all breaking storage changes are explained in as much detail as possible. The update assistant provides all tools to migrate without a hassle, but it is important to know what has changed. All examples only show the keys that have changed, unrelated keys in records have been omitted."),(0,r.kt)("p",null,"See the ",(0,r.kt)("a",{parentName:"p",href:"/guides/updating/update-assistant"},"Update Assistant")," documentation for a guide on how to use the update assistant."),(0,r.kt)("p",null,"There are no configuration parameters to be provided to the update assistant to migrate from 0.3.x to 0.4.x."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"TODO")))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/main.33f87f5b.js b/assets/js/main.33f87f5b.js new file mode 100644 index 00000000..f78a5f69 --- /dev/null +++ b/assets/js/main.33f87f5b.js @@ -0,0 +1,2 @@ +/*! For license information please see main.33f87f5b.js.LICENSE.txt */ +(self.webpackChunkcredo_ts_docs=self.webpackChunkcredo_ts_docs||[]).push([[179],{723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7294),i=n(7462),a=n(8356),o=n.n(a),s=n(6887);const l={"05113313":[()=>n.e(5062).then(n.t.bind(n,6524,19)),"~docs/default/version-0-3-metadata-prop-dd4.json",6524],"07ca6c5c":[()=>n.e(35).then(n.bind(n,6141)),"@site/versioned_docs/version-0.3/tutorials/postgres-database-nodejs/linux.md",6141],"08ca7335":[()=>Promise.all([n.e(532),n.e(7303)]).then(n.bind(n,929)),"@site/versioned_docs/version-0.3/tutorials/issue-a-credential.md",929],"09958099":[()=>n.e(2743).then(n.bind(n,2588)),"@site/versioned_docs/version-0.4/tutorials/cheqd/index.md",2588],"0a88801c":[()=>Promise.all([n.e(532),n.e(2215)]).then(n.bind(n,1824)),"@site/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/index.md",1824],"0c824aea":[()=>Promise.all([n.e(532),n.e(1350)]).then(n.bind(n,7114)),"@site/guides/getting-started/set-up/cheqd/index.md",7114],"0d8c2653":[()=>n.e(4105).then(n.bind(n,3141)),"@site/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/windows.md",3141],"0e983491":[()=>n.e(8026).then(n.bind(n,5075)),"@site/versioned_docs/version-0.3/getting-started/installation/react-native/android.md",5075],"0ecb752f":[()=>n.e(7824).then(n.bind(n,7057)),"@site/guides/updating/update-indy-sdk-to-askar.md",7057],"0f95bd9e":[()=>n.e(7885).then(n.bind(n,6449)),"@site/guides/concepts/agents.md",6449],12357581:[()=>n.e(6657).then(n.bind(n,6511)),"@site/versioned_docs/version-0.3/concepts/did-and-didcomm.md",6511],"14973ffc":[()=>Promise.all([n.e(532),n.e(5554)]).then(n.bind(n,4814)),"@site/versioned_docs/version-0.4/extensions/redux-store.md",4814],"14e53ecf":[()=>Promise.all([n.e(532),n.e(1904)]).then(n.bind(n,3635)),"@site/guides/updating/versions/0.3-to-0.4.md",3635],17896441:[()=>Promise.all([n.e(532),n.e(8929),n.e(903),n.e(7918)]).then(n.bind(n,903)),"@theme/DocItem",903],"17b50570":[()=>n.e(9593).then(n.t.bind(n,6514,19)),"~docs/default/version-0-4-metadata-prop-a32.json",6514],"1bb97b5b":[()=>n.e(5252).then(n.bind(n,6907)),"@site/versioned_docs/version-0.3/extensions/rest/setup.md",6907],"1be78505":[()=>Promise.all([n.e(532),n.e(9514)]).then(n.bind(n,9963)),"@theme/DocPage",9963],"1c0f7eb0":[()=>Promise.all([n.e(532),n.e(6614)]).then(n.bind(n,3018)),"@site/versioned_docs/version-0.4/getting-started/set-up/index.md",3018],"1cc62cef":[()=>n.e(9626).then(n.bind(n,5627)),"@site/versioned_docs/version-0.4/ecosystem/index.md",5627],"1df93b7f":[()=>Promise.all([n.e(532),n.e(3237)]).then(n.bind(n,8391)),"@site/src/pages/index.tsx",8391],"1f391b9e":[()=>Promise.all([n.e(532),n.e(8929),n.e(3085)]).then(n.bind(n,4247)),"@theme/MDXPage",4247],"2003ac23":[()=>Promise.all([n.e(532),n.e(7529)]).then(n.bind(n,6314)),"@site/guides/concepts/index.md",6314],"207a1e16":[()=>n.e(6407).then(n.bind(n,4590)),"@site/versioned_docs/version-0.4/extensions/rest.md",4590],"224ce49c":[()=>n.e(8135).then(n.bind(n,7563)),"@site/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/macos-intel.md",7563],"232d48ef":[()=>Promise.all([n.e(532),n.e(2959)]).then(n.bind(n,189)),"@site/versioned_docs/version-0.4/updating/index.md",189],"2332f431":[()=>Promise.all([n.e(532),n.e(82)]).then(n.bind(n,8278)),"@site/guides/getting-started/set-up/index.md",8278],"27320d50":[()=>Promise.all([n.e(532),n.e(8377)]).then(n.bind(n,7665)),"@site/versioned_docs/version-0.3/extensions/index.md",7665],"29b62a39":[()=>n.e(1498).then(n.bind(n,740)),"@site/guides/index.md",740],"2bf743db":[()=>n.e(5880).then(n.bind(n,4275)),"@site/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/windows.md",4275],"2e77271a":[()=>Promise.all([n.e(532),n.e(7024)]).then(n.bind(n,7079)),"@site/versioned_docs/version-0.4/updating/versions/0.2-to-0.3.md",7079],"30ebf81b":[()=>Promise.all([n.e(532),n.e(1912)]).then(n.bind(n,2286)),"@site/versioned_docs/version-0.4/getting-started/prerequisites.md",2286],32456564:[()=>n.e(8937).then(n.bind(n,4462)),"@site/guides/updating/update-assistant.md",4462],"331e6edf":[()=>Promise.all([n.e(532),n.e(9196)]).then(n.bind(n,8856)),"@site/guides/updating/index.md",8856],"334d54c0":[()=>Promise.all([n.e(532),n.e(37)]).then(n.bind(n,1251)),"@site/versioned_docs/version-0.3/concepts/index.md",1251],"3483c478":[()=>n.e(3338).then(n.bind(n,6329)),"@site/versioned_docs/version-0.3/getting-started/installation/nodejs/index.md",6329],"34eb4307":[()=>n.e(7314).then(n.bind(n,684)),"@site/versioned_docs/version-0.4/index.md",684],"365d3941":[()=>Promise.all([n.e(532),n.e(6347)]).then(n.bind(n,8412)),"@site/guides/updating/versions/0.2-to-0.3.md",8412],"369c14e0":[()=>n.e(2913).then(n.bind(n,6998)),"@site/guides/features/openid4vc.md",6998],"36fa027f":[()=>n.e(241).then(n.bind(n,3844)),"@site/versioned_docs/version-0.3/getting-started/installation/index.md",3844],"393be207":[()=>n.e(7414).then(n.bind(n,3123)),"@site/src/pages/markdown-page.md",3123],"394d7bf2":[()=>Promise.all([n.e(532),n.e(8368)]).then(n.bind(n,3172)),"@site/guides/getting-started/set-up/indy-vdr.md",3172],"41c1fec5":[()=>n.e(8796).then(n.bind(n,5669)),"@site/guides/features/dids.md",5669],"4359f0b8":[()=>n.e(3143).then(n.bind(n,480)),"@site/versioned_docs/version-0.3/getting-started/installation/nodejs/apple-intel.md",480],"43e7938e":[()=>Promise.all([n.e(532),n.e(5846)]).then(n.bind(n,6230)),"@site/versioned_docs/version-0.4/tutorials/issue-a-credential.md",6230],"466eb4b6":[()=>n.e(4354).then(n.bind(n,5772)),"@site/guides/tutorials/registering-schema-and-credential-definition.md",5772],"470c56a2":[()=>Promise.all([n.e(532),n.e(9474)]).then(n.bind(n,8354)),"@site/versioned_docs/version-0.3/updating/versions/0.2-to-0.3.md",8354],"4a99cab5":[()=>Promise.all([n.e(532),n.e(4378)]).then(n.bind(n,2655)),"@site/versioned_docs/version-0.4/getting-started/set-up/cheqd/index.md",2655],"4e1c6ae4":[()=>n.e(7873).then(n.bind(n,3865)),"@site/versioned_docs/version-0.3/tutorials/agent-config/index.md",3865],"4ee9ed1d":[()=>n.e(9567).then(n.bind(n,5175)),"@site/versioned_docs/version-0.3/getting-started/installation/react-native/index.md",5175],"514aaf1d":[()=>n.e(2050).then(n.bind(n,9138)),"@site/guides/features/aries.md",9138],"52db191f":[()=>n.e(6059).then(n.bind(n,7242)),"@site/versioned_docs/version-0.4/tutorials/agent-config/index.md",7242],"58e9d200":[()=>n.e(6974).then(n.bind(n,8463)),"@site/versioned_docs/version-0.4/updating/update-indy-sdk-to-askar.md",8463],"5a512b94":[()=>Promise.all([n.e(532),n.e(4602)]).then(n.bind(n,1548)),"@site/versioned_docs/version-0.4/getting-started/set-up/aries-askar.md",1548],"5d1c397c":[()=>n.e(6840).then(n.bind(n,6770)),"@site/guides/tutorials/agent-config/logging.md",6770],"5d8cec60":[()=>Promise.all([n.e(532),n.e(6751)]).then(n.bind(n,1156)),"@site/guides/extensions/index.md",1156],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,6809)),"@generated/docusaurus.config",6809],60053357:[()=>n.e(6266).then(n.bind(n,7147)),"@site/guides/tutorials/mediation.md",7147],"636a146f":[()=>n.e(5313).then(n.bind(n,3097)),"@site/guides/ecosystem/index.md",3097],"6414033c":[()=>Promise.all([n.e(532),n.e(4226)]).then(n.bind(n,7574)),"@site/guides/features/index.md",7574],"655fc6f5":[()=>n.e(2562).then(n.bind(n,7731)),"@site/versioned_docs/version-0.3/getting-started/installation/nodejs/windows.md",7731],"65c86d7b":[()=>Promise.all([n.e(532),n.e(6295)]).then(n.bind(n,9234)),"@site/guides/updating/versions/0.1-to-0.2.md",9234],"67da112e":[()=>n.e(5666).then(n.bind(n,7625)),"@site/guides/tutorials/agent-config/index.md",7625],"69f8e48e":[()=>n.e(9047).then(n.bind(n,3474)),"@site/versioned_docs/version-0.3/extensions/react-hooks/index.md",3474],"6c6797b5":[()=>n.e(1229).then(n.bind(n,749)),"@site/versioned_docs/version-0.4/concepts/did-and-didcomm.md",749],"6d44cf95":[()=>Promise.all([n.e(532),n.e(7798)]).then(n.bind(n,160)),"@site/versioned_docs/version-0.4/tutorials/index.md",160],"6d708c3d":[()=>Promise.all([n.e(532),n.e(3666)]).then(n.bind(n,7342)),"@site/versioned_docs/version-0.4/getting-started/index.md",7342],"6df87a7d":[()=>Promise.all([n.e(532),n.e(7844)]).then(n.bind(n,4766)),"@site/versioned_docs/version-0.3/getting-started/index.md",4766],"6e4808e6":[()=>Promise.all([n.e(532),n.e(1271)]).then(n.bind(n,1752)),"@site/guides/extensions/react-hooks.md",1752],"70f061b3":[()=>n.e(3531).then(n.t.bind(n,5745,19)),"/home/runner/work/credo-ts-docs/credo-ts-docs/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",5745],"7138c4a2":[()=>n.e(6718).then(n.bind(n,8937)),"@site/versioned_docs/version-0.3/extensions/rest/index.md",8937],"74ce5ee1":[()=>n.e(1454).then(n.bind(n,4474)),"@site/versioned_docs/version-0.3/concepts/agents.md",4474],"7697e6e6":[()=>n.e(7867).then(n.bind(n,5064)),"@site/guides/features/credentials.md",5064],"76f8726c":[()=>n.e(8440).then(n.bind(n,708)),"@site/guides/tutorials/cheqd/index.md",708],"7852f2cc":[()=>n.e(9910).then(n.bind(n,4813)),"@site/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/macos.md",4813],"7bb6402a":[()=>n.e(8980).then(n.bind(n,9050)),"@site/versioned_docs/version-0.3/tutorials/agent-config/logging.md",9050],"7d0a541a":[()=>Promise.all([n.e(532),n.e(397)]).then(n.bind(n,4689)),"@site/versioned_docs/version-0.4/concepts/index.md",4689],"7d25e484":[()=>Promise.all([n.e(532),n.e(6696)]).then(n.bind(n,8505)),"@site/versioned_docs/version-0.3/extensions/push-notifications/setup.md",8505],"862058fd":[()=>n.e(8709).then(n.bind(n,8286)),"@site/versioned_docs/version-0.4/tutorials/mediation.md",8286],"8b37bb4b":[()=>Promise.all([n.e(532),n.e(4565)]).then(n.bind(n,3624)),"@site/versioned_docs/version-0.4/getting-started/set-up/indy-vdr.md",3624],"8b5bb00b":[()=>Promise.all([n.e(532),n.e(8417)]).then(n.bind(n,8610)),"@site/versioned_docs/version-0.4/updating/versions/0.1-to-0.2.md",8610],"8c506fba":[()=>n.e(8866).then(n.bind(n,7709)),"@site/versioned_docs/version-0.3/getting-started/prerequisites/index.md",7709],"91053f61":[()=>n.e(4809).then(n.bind(n,4634)),"@site/versioned_docs/version-0.3/index.md",4634],92188087:[()=>n.e(537).then(n.bind(n,4228)),"@site/guides/extensions/rest.md",4228],"926eb7a7":[()=>n.e(792).then(n.bind(n,1026)),"@site/versioned_docs/version-0.3/tutorials/postgres-database-nodejs/index.md",1026],"93020ce9":[()=>n.e(3859).then(n.bind(n,8658)),"@site/versioned_docs/version-0.3/extensions/redux-store/index.md",8658],"935f2afb":[()=>n.e(53).then(n.t.bind(n,1109,19)),"~docs/default/version-current-metadata-prop-751.json",1109],"9436892d":[()=>n.e(5260).then(n.bind(n,1593)),"@site/versioned_docs/version-0.3/extensions/push-notifications/index.md",1593],95261082:[()=>Promise.all([n.e(532),n.e(2086)]).then(n.bind(n,3418)),"@site/guides/extensions/push-notifications.md",3418],"96bb78d2":[()=>Promise.all([n.e(532),n.e(7988)]).then(n.bind(n,1131)),"@site/versioned_docs/version-0.3/extensions/redux-store/setup.md",1131],"996925d9":[()=>Promise.all([n.e(532),n.e(3901)]).then(n.bind(n,1089)),"@site/guides/getting-started/prerequisites.md",1089],"997e3d85":[()=>Promise.all([n.e(532),n.e(2680)]).then(n.bind(n,3583)),"@site/versioned_docs/version-0.4/extensions/index.md",3583],"9cd8fd3e":[()=>n.e(8399).then(n.bind(n,7438)),"@site/versioned_docs/version-0.3/getting-started/installation/nodejs/apple-arm.md",7438],"9edc454f":[()=>n.e(7854).then(n.bind(n,4797)),"@site/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/react-native.md",4797],a1dc5557:[()=>n.e(8230).then(n.bind(n,4087)),"@site/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/index.md",4087],a2a3716e:[()=>Promise.all([n.e(532),n.e(644)]).then(n.bind(n,4789)),"@site/guides/tutorials/index.md",4789],a690f229:[()=>n.e(9841).then(n.bind(n,8211)),"@site/versioned_docs/version-0.4/updating/update-assistant.md",8211],a69e7b9a:[()=>Promise.all([n.e(532),n.e(4365)]).then(n.bind(n,6935)),"@site/guides/extensions/redux-store.md",6935],a9c79318:[()=>Promise.all([n.e(532),n.e(6625)]).then(n.bind(n,534)),"@site/versioned_docs/version-0.3/getting-started/set-up/index.md",534],acdd3ecd:[()=>n.e(1317).then(n.bind(n,8693)),"@site/versioned_docs/version-0.3/ecosystem/index.md",8693],b1d5f389:[()=>Promise.all([n.e(532),n.e(9843)]).then(n.bind(n,6457)),"@site/versioned_docs/version-0.4/extensions/react-hooks.md",6457],b56c3f57:[()=>Promise.all([n.e(532),n.e(7610)]).then(n.bind(n,9387)),"@site/versioned_docs/version-0.3/tutorials/index.md",9387],bcace162:[()=>Promise.all([n.e(532),n.e(752)]).then(n.bind(n,8150)),"@site/versioned_docs/version-0.4/extensions/push-notifications.md",8150],bd127040:[()=>Promise.all([n.e(532),n.e(6142)]).then(n.bind(n,1e3)),"@site/versioned_docs/version-0.3/getting-started/installation/nodejs/linux.md",1e3],bd5be9ae:[()=>Promise.all([n.e(532),n.e(1993)]).then(n.bind(n,2347)),"@site/guides/tutorials/issue-a-credential.md",2347],bf52c953:[()=>n.e(4220).then(n.bind(n,9083)),"@site/versioned_docs/version-0.3/concepts/platform-and-environment.md",9083],c2afb9af:[()=>Promise.all([n.e(532),n.e(1389)]).then(n.bind(n,5331)),"@site/versioned_docs/version-0.3/extensions/react-hooks/setup.md",5331],c5cd793e:[()=>n.e(8925).then(n.bind(n,2290)),"@site/versioned_docs/version-0.4/tutorials/registering-schema-and-credential-definition.md",2290],c970593d:[()=>Promise.all([n.e(532),n.e(703)]).then(n.bind(n,4933)),"@site/versioned_docs/version-0.3/updating/index.md",4933],ca99fa15:[()=>n.e(3080).then(n.bind(n,8626)),"@site/guides/concepts/did-and-didcomm.md",8626],d1089d1d:[()=>n.e(1270).then(n.bind(n,3147)),"@site/versioned_docs/version-0.3/tutorials/postgres-database-nodejs/macos.md",3147],d26e5579:[()=>Promise.all([n.e(532),n.e(9080)]).then(n.bind(n,9533)),"@site/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/linux.md",9533],d42e1e6c:[()=>Promise.all([n.e(532),n.e(2226)]).then(n.bind(n,8433)),"@site/versioned_docs/version-0.3/tutorials/create-a-connection.md",8433],d68982b8:[()=>n.e(7608).then(n.bind(n,8161)),"@site/versioned_docs/version-0.3/getting-started/installation/react-native/ios.md",8161],da788397:[()=>Promise.all([n.e(532),n.e(4281)]).then(n.bind(n,3423)),"@site/guides/getting-started/set-up/anoncreds.md",3423],daf4660b:[()=>Promise.all([n.e(532),n.e(8692)]).then(n.bind(n,1618)),"@site/versioned_docs/version-0.3/updating/versions/0.1-to-0.2.md",1618],dc62edf2:[()=>Promise.all([n.e(532),n.e(4827)]).then(n.bind(n,695)),"@site/guides/getting-started/index.md",695],debd89ec:[()=>n.e(4767).then(n.bind(n,9494)),"@site/versioned_docs/version-0.4/tutorials/agent-config/logging.md",9494],e38b62c8:[()=>n.e(7162).then(n.bind(n,1289)),"@site/versioned_docs/version-0.4/concepts/platform-and-environment.md",1289],e4252094:[()=>n.e(1776).then(n.t.bind(n,3769,19)),"/home/runner/work/credo-ts-docs/credo-ts-docs/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",3769],e5a09f30:[()=>Promise.all([n.e(532),n.e(2254)]).then(n.bind(n,3570)),"@site/versioned_docs/version-0.4/getting-started/set-up/anoncreds-rs.md",3570],e5f12b68:[()=>n.e(4656).then(n.bind(n,1971)),"@site/versioned_docs/version-0.3/updating/update-assistant.md",1971],ece13197:[()=>n.e(9852).then(n.bind(n,1920)),"@site/versioned_docs/version-0.4/concepts/agents.md",1920],ee7869b6:[()=>n.e(7240).then(n.bind(n,3944)),"@site/versioned_docs/version-0.4/getting-started/set-up/indy-sdk/macos-arm.md",3944],ee898636:[()=>Promise.all([n.e(532),n.e(9233)]).then(n.bind(n,2757)),"@site/versioned_docs/version-0.4/tutorials/create-a-connection.md",2757],eeecf87c:[()=>n.e(7547).then(n.bind(n,3076)),"@site/guides/concepts/platform-and-environment.md",3076],ef7acecf:[()=>Promise.all([n.e(532),n.e(2925)]).then(n.bind(n,2960)),"@site/guides/tutorials/create-a-connection.md",2960],f30d32a5:[()=>n.e(2637).then(n.bind(n,2736)),"@site/versioned_docs/version-0.4/tutorials/indy-sdk-postgres-database-nodejs/linux.md",2736],f3933b6b:[()=>n.e(911).then(n.bind(n,1033)),"@site/versioned_docs/version-0.3/tutorials/postgres-database-nodejs/windows.md",1033],f800d23c:[()=>Promise.all([n.e(532),n.e(8251)]).then(n.bind(n,440)),"@site/guides/getting-started/set-up/aries-askar.md",440],fd1a8f62:[()=>Promise.all([n.e(532),n.e(77)]).then(n.bind(n,9522)),"@site/versioned_docs/version-0.4/updating/versions/0.3-to-0.4.md",9522]};function u(e){let{error:t,retry:n,pastDelay:i}=e;return t?r.createElement("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"}},r.createElement("p",null,String(t)),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},"Retry"))):i?r.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"}},r.createElement("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb"},r.createElement("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2"},r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"8"},r.createElement("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}))))):null}var c=n(9670),d=n(226);function p(e,t){if("*"===e)return o()({loading:u,loader:()=>n.e(4972).then(n.bind(n,4972)),modules:["@theme/NotFound"],webpack:()=>[4972],render(e,t){const n=e.default;return r.createElement(d.z,{value:{plugin:{name:"native",id:"default"}}},r.createElement(n,t))}});const a=s[`${e}-${t}`],p={},f=[],m=[],g=(0,c.Z)(a);return Object.entries(g).forEach((e=>{let[t,n]=e;const r=l[n];r&&(p[t]=r[0],f.push(r[1]),m.push(r[2]))})),o().Map({loading:u,loader:p,modules:f,webpack:()=>m,render(t,n){const o=JSON.parse(JSON.stringify(a));Object.entries(t).forEach((t=>{let[n,r]=t;const i=r.default;if(!i)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof i&&"function"!=typeof i||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{i[e]=r[e]}));let a=o;const s=n.split(".");s.slice(0,-1).forEach((e=>{a=a[e]})),a[s[s.length-1]]=i}));const s=o.__comp;delete o.__comp;const l=o.__context;return delete o.__context,r.createElement(d.z,{value:l},r.createElement(s,(0,i.Z)({},o,n)))}})}const f=[{path:"/markdown-page",component:p("/markdown-page","ff5"),exact:!0},{path:"/guides/0.3",component:p("/guides/0.3","769"),routes:[{path:"/guides/0.3",component:p("/guides/0.3","c55"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/concepts",component:p("/guides/0.3/concepts","8ed"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/concepts/agents",component:p("/guides/0.3/concepts/agents","26a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/concepts/did-and-didcomm",component:p("/guides/0.3/concepts/did-and-didcomm","cae"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/concepts/platform-and-environment",component:p("/guides/0.3/concepts/platform-and-environment","c83"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/ecosystem",component:p("/guides/0.3/ecosystem","6e2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/extensions",component:p("/guides/0.3/extensions","89d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/extensions/push-notifications",component:p("/guides/0.3/extensions/push-notifications","83d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/extensions/push-notifications/setup",component:p("/guides/0.3/extensions/push-notifications/setup","4e7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/extensions/react-hooks",component:p("/guides/0.3/extensions/react-hooks","27a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/extensions/react-hooks/setup",component:p("/guides/0.3/extensions/react-hooks/setup","042"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/extensions/redux-store",component:p("/guides/0.3/extensions/redux-store","17e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/extensions/redux-store/setup",component:p("/guides/0.3/extensions/redux-store/setup","e20"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/extensions/rest",component:p("/guides/0.3/extensions/rest","f47"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/extensions/rest/setup",component:p("/guides/0.3/extensions/rest/setup","856"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/getting-started",component:p("/guides/0.3/getting-started","09e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/getting-started/installation",component:p("/guides/0.3/getting-started/installation","210"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/getting-started/installation/nodejs",component:p("/guides/0.3/getting-started/installation/nodejs","d46"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/getting-started/installation/nodejs/apple-arm",component:p("/guides/0.3/getting-started/installation/nodejs/apple-arm","fbf"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/getting-started/installation/nodejs/apple-intel",component:p("/guides/0.3/getting-started/installation/nodejs/apple-intel","c05"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/getting-started/installation/nodejs/linux",component:p("/guides/0.3/getting-started/installation/nodejs/linux","d0a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/getting-started/installation/nodejs/windows",component:p("/guides/0.3/getting-started/installation/nodejs/windows","834"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/getting-started/installation/react-native",component:p("/guides/0.3/getting-started/installation/react-native","839"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/getting-started/installation/react-native/android",component:p("/guides/0.3/getting-started/installation/react-native/android","550"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/getting-started/installation/react-native/ios",component:p("/guides/0.3/getting-started/installation/react-native/ios","655"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/getting-started/prerequisites",component:p("/guides/0.3/getting-started/prerequisites","840"),exact:!0},{path:"/guides/0.3/getting-started/set-up",component:p("/guides/0.3/getting-started/set-up","662"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/tutorials",component:p("/guides/0.3/tutorials","8f3"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/tutorials/agent-config",component:p("/guides/0.3/tutorials/agent-config","16e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/tutorials/agent-config/logging",component:p("/guides/0.3/tutorials/agent-config/logging","c89"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/tutorials/create-a-connection",component:p("/guides/0.3/tutorials/create-a-connection","14a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/tutorials/issue-a-credential",component:p("/guides/0.3/tutorials/issue-a-credential","b7f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/tutorials/postgres-database-nodejs",component:p("/guides/0.3/tutorials/postgres-database-nodejs","7e2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/tutorials/postgres-database-nodejs/linux",component:p("/guides/0.3/tutorials/postgres-database-nodejs/linux","33b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/tutorials/postgres-database-nodejs/macos",component:p("/guides/0.3/tutorials/postgres-database-nodejs/macos","af5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/tutorials/postgres-database-nodejs/windows",component:p("/guides/0.3/tutorials/postgres-database-nodejs/windows","b05"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/updating",component:p("/guides/0.3/updating","4bd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/updating/update-assistant",component:p("/guides/0.3/updating/update-assistant","33c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/updating/versions/0.1-to-0.2",component:p("/guides/0.3/updating/versions/0.1-to-0.2","714"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.3/updating/versions/0.2-to-0.3",component:p("/guides/0.3/updating/versions/0.2-to-0.3","0d2"),exact:!0,sidebar:"tutorialSidebar"}]},{path:"/guides/0.4",component:p("/guides/0.4","f07"),routes:[{path:"/guides/0.4",component:p("/guides/0.4","80d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/concepts",component:p("/guides/0.4/concepts","b21"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/concepts/agents",component:p("/guides/0.4/concepts/agents","58e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/concepts/did-and-didcomm",component:p("/guides/0.4/concepts/did-and-didcomm","596"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/concepts/platform-and-environment",component:p("/guides/0.4/concepts/platform-and-environment","8a6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/ecosystem",component:p("/guides/0.4/ecosystem","05b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/extensions",component:p("/guides/0.4/extensions","53e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/extensions/push-notifications",component:p("/guides/0.4/extensions/push-notifications","7c6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/extensions/react-hooks",component:p("/guides/0.4/extensions/react-hooks","24a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/extensions/redux-store",component:p("/guides/0.4/extensions/redux-store","808"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/extensions/rest",component:p("/guides/0.4/extensions/rest","df4"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/getting-started",component:p("/guides/0.4/getting-started","d5f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/getting-started/prerequisites",component:p("/guides/0.4/getting-started/prerequisites","508"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/getting-started/set-up",component:p("/guides/0.4/getting-started/set-up","46e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/getting-started/set-up/anoncreds-rs",component:p("/guides/0.4/getting-started/set-up/anoncreds-rs","4df"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/getting-started/set-up/aries-askar",component:p("/guides/0.4/getting-started/set-up/aries-askar","0ab"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/getting-started/set-up/cheqd",component:p("/guides/0.4/getting-started/set-up/cheqd","615"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/getting-started/set-up/indy-sdk",component:p("/guides/0.4/getting-started/set-up/indy-sdk","65a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/getting-started/set-up/indy-sdk/linux",component:p("/guides/0.4/getting-started/set-up/indy-sdk/linux","cda"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/getting-started/set-up/indy-sdk/macos-arm",component:p("/guides/0.4/getting-started/set-up/indy-sdk/macos-arm","219"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/getting-started/set-up/indy-sdk/macos-intel",component:p("/guides/0.4/getting-started/set-up/indy-sdk/macos-intel","5bd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/getting-started/set-up/indy-sdk/react-native",component:p("/guides/0.4/getting-started/set-up/indy-sdk/react-native","f6c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/getting-started/set-up/indy-sdk/windows",component:p("/guides/0.4/getting-started/set-up/indy-sdk/windows","714"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/getting-started/set-up/indy-vdr",component:p("/guides/0.4/getting-started/set-up/indy-vdr","670"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/tutorials",component:p("/guides/0.4/tutorials","c36"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/tutorials/agent-config",component:p("/guides/0.4/tutorials/agent-config","dfd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/tutorials/agent-config/logging",component:p("/guides/0.4/tutorials/agent-config/logging","854"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/tutorials/cheqd",component:p("/guides/0.4/tutorials/cheqd","8e1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/tutorials/create-a-connection",component:p("/guides/0.4/tutorials/create-a-connection","238"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs",component:p("/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs","8ea"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/linux",component:p("/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/linux","d2c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/macos",component:p("/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/macos","349"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/windows",component:p("/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/windows","4aa"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/tutorials/issue-a-credential",component:p("/guides/0.4/tutorials/issue-a-credential","445"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/tutorials/mediation",component:p("/guides/0.4/tutorials/mediation","0b4"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/tutorials/registering-schema-and-credential-definition",component:p("/guides/0.4/tutorials/registering-schema-and-credential-definition","ab0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/updating",component:p("/guides/0.4/updating","3fa"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/updating/update-assistant",component:p("/guides/0.4/updating/update-assistant","6d2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/updating/update-indy-sdk-to-askar",component:p("/guides/0.4/updating/update-indy-sdk-to-askar","92c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/updating/versions/0.1-to-0.2",component:p("/guides/0.4/updating/versions/0.1-to-0.2","df9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/updating/versions/0.2-to-0.3",component:p("/guides/0.4/updating/versions/0.2-to-0.3","e1b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/0.4/updating/versions/0.3-to-0.4",component:p("/guides/0.4/updating/versions/0.3-to-0.4","c5b"),exact:!0,sidebar:"tutorialSidebar"}]},{path:"/guides",component:p("/guides","bcb"),routes:[{path:"/guides",component:p("/guides","192"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/concepts",component:p("/guides/concepts","7cf"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/concepts/agents",component:p("/guides/concepts/agents","904"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/concepts/did-and-didcomm",component:p("/guides/concepts/did-and-didcomm","325"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/concepts/platform-and-environment",component:p("/guides/concepts/platform-and-environment","a71"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/ecosystem",component:p("/guides/ecosystem","390"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/extensions",component:p("/guides/extensions","09d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/extensions/push-notifications",component:p("/guides/extensions/push-notifications","cbe"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/extensions/react-hooks",component:p("/guides/extensions/react-hooks","5db"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/extensions/redux-store",component:p("/guides/extensions/redux-store","33c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/extensions/rest",component:p("/guides/extensions/rest","bcd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/features",component:p("/guides/features","d70"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/features/aries",component:p("/guides/features/aries","685"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/features/credentials",component:p("/guides/features/credentials","e84"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/features/dids",component:p("/guides/features/dids","447"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/features/openid4vc",component:p("/guides/features/openid4vc","4d5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/getting-started",component:p("/guides/getting-started","fa6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/getting-started/prerequisites",component:p("/guides/getting-started/prerequisites","3d8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/getting-started/set-up",component:p("/guides/getting-started/set-up","514"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/getting-started/set-up/anoncreds",component:p("/guides/getting-started/set-up/anoncreds","255"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/getting-started/set-up/aries-askar",component:p("/guides/getting-started/set-up/aries-askar","d82"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/getting-started/set-up/cheqd",component:p("/guides/getting-started/set-up/cheqd","371"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/getting-started/set-up/indy-vdr",component:p("/guides/getting-started/set-up/indy-vdr","f29"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/tutorials",component:p("/guides/tutorials","036"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/tutorials/agent-config",component:p("/guides/tutorials/agent-config","709"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/tutorials/agent-config/logging",component:p("/guides/tutorials/agent-config/logging","d7b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/tutorials/cheqd",component:p("/guides/tutorials/cheqd","b11"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/tutorials/create-a-connection",component:p("/guides/tutorials/create-a-connection","3a9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/tutorials/issue-a-credential",component:p("/guides/tutorials/issue-a-credential","968"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/tutorials/mediation",component:p("/guides/tutorials/mediation","308"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/tutorials/registering-schema-and-credential-definition",component:p("/guides/tutorials/registering-schema-and-credential-definition","97e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/updating",component:p("/guides/updating","a7f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/updating/update-assistant",component:p("/guides/updating/update-assistant","5e1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/updating/update-indy-sdk-to-askar",component:p("/guides/updating/update-indy-sdk-to-askar","0a8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/updating/versions/0.1-to-0.2",component:p("/guides/updating/versions/0.1-to-0.2","6c5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/updating/versions/0.2-to-0.3",component:p("/guides/updating/versions/0.2-to-0.3","4ae"),exact:!0,sidebar:"tutorialSidebar"},{path:"/guides/updating/versions/0.3-to-0.4",component:p("/guides/updating/versions/0.3-to-0.4","cf6"),exact:!0,sidebar:"tutorialSidebar"}]},{path:"/",component:p("/","3b7"),exact:!0},{path:"*",component:p("*")}]},8965:(e,t,n)=>{var r,i;!function(){var a,o,s,l,u,c,d,p,f,m,g,h,v,b,y,w,k,S,E,x,_,O,P,C,T,I,A,L,R,N,j=function(e){var t=new j.Builder;return t.pipeline.add(j.trimmer,j.stopWordFilter,j.stemmer),t.searchPipeline.add(j.stemmer),e.call(t,t),t.build()};j.version="2.3.9",j.utils={},j.utils.warn=(a=this,function(e){a.console&&console.warn&&console.warn(e)}),j.utils.asString=function(e){return null==e?"":e.toString()},j.utils.clone=function(e){if(null==e)return e;for(var t=Object.create(null),n=Object.keys(e),r=0;r0){var l=j.utils.clone(t)||{};l.position=[o,s],l.index=i.length,i.push(new j.Token(n.slice(o,a),l))}o=a+1}}return i},j.tokenizer.separator=/[\s\-]+/,j.Pipeline=function(){this._stack=[]},j.Pipeline.registeredFunctions=Object.create(null),j.Pipeline.registerFunction=function(e,t){t in this.registeredFunctions&&j.utils.warn("Overwriting existing registered function: "+t),e.label=t,j.Pipeline.registeredFunctions[e.label]=e},j.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||j.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},j.Pipeline.load=function(e){var t=new j.Pipeline;return e.forEach((function(e){var n=j.Pipeline.registeredFunctions[e];if(!n)throw new Error("Cannot load unregistered function: "+e);t.add(n)})),t},j.Pipeline.prototype.add=function(){Array.prototype.slice.call(arguments).forEach((function(e){j.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)}),this)},j.Pipeline.prototype.after=function(e,t){j.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");n+=1,this._stack.splice(n,0,t)},j.Pipeline.prototype.before=function(e,t){j.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");this._stack.splice(n,0,t)},j.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);-1!=t&&this._stack.splice(t,1)},j.Pipeline.prototype.run=function(e){for(var t=this._stack.length,n=0;n1&&(ae&&(n=i),a!=e);)r=n-t,i=t+Math.floor(r/2),a=this.elements[2*i];return a==e||a>e?2*i:as?u+=2:o==s&&(t+=n[l+1]*r[u+1],l+=2,u+=2);return t},j.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},j.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,n=0;t0){var a,o=i.str.charAt(0);o in i.node.edges?a=i.node.edges[o]:(a=new j.TokenSet,i.node.edges[o]=a),1==i.str.length&&(a.final=!0),r.push({node:a,editsRemaining:i.editsRemaining,str:i.str.slice(1)})}if(0!=i.editsRemaining){if("*"in i.node.edges)var s=i.node.edges["*"];else{s=new j.TokenSet;i.node.edges["*"]=s}if(0==i.str.length&&(s.final=!0),r.push({node:s,editsRemaining:i.editsRemaining-1,str:i.str}),i.str.length>1&&r.push({node:i.node,editsRemaining:i.editsRemaining-1,str:i.str.slice(1)}),1==i.str.length&&(i.node.final=!0),i.str.length>=1){if("*"in i.node.edges)var l=i.node.edges["*"];else{l=new j.TokenSet;i.node.edges["*"]=l}1==i.str.length&&(l.final=!0),r.push({node:l,editsRemaining:i.editsRemaining-1,str:i.str.slice(1)})}if(i.str.length>1){var u,c=i.str.charAt(0),d=i.str.charAt(1);d in i.node.edges?u=i.node.edges[d]:(u=new j.TokenSet,i.node.edges[d]=u),1==i.str.length&&(u.final=!0),r.push({node:u,editsRemaining:i.editsRemaining-1,str:c+i.str.slice(2)})}}}return n},j.TokenSet.fromString=function(e){for(var t=new j.TokenSet,n=t,r=0,i=e.length;r=e;t--){var n=this.uncheckedNodes[t],r=n.child.toString();r in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[r]:(n.child._str=r,this.minimizedNodes[r]=n.child),this.uncheckedNodes.pop()}},j.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},j.Index.prototype.search=function(e){return this.query((function(t){new j.QueryParser(e,t).parse()}))},j.Index.prototype.query=function(e){for(var t=new j.Query(this.fields),n=Object.create(null),r=Object.create(null),i=Object.create(null),a=Object.create(null),o=Object.create(null),s=0;s1?1:e},j.Builder.prototype.k1=function(e){this._k1=e},j.Builder.prototype.add=function(e,t){var n=e[this._ref],r=Object.keys(this._fields);this._documents[n]=t||{},this.documentCount+=1;for(var i=0;i=this.length)return j.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},j.QueryLexer.prototype.width=function(){return this.pos-this.start},j.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},j.QueryLexer.prototype.backup=function(){this.pos-=1},j.QueryLexer.prototype.acceptDigitRun=function(){var e,t;do{t=(e=this.next()).charCodeAt(0)}while(t>47&&t<58);e!=j.QueryLexer.EOS&&this.backup()},j.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(j.QueryLexer.TERM)),e.ignore(),e.more())return j.QueryLexer.lexText},j.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(j.QueryLexer.EDIT_DISTANCE),j.QueryLexer.lexText},j.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(j.QueryLexer.BOOST),j.QueryLexer.lexText},j.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(j.QueryLexer.TERM)},j.QueryLexer.termSeparator=j.tokenizer.separator,j.QueryLexer.lexText=function(e){for(;;){var t=e.next();if(t==j.QueryLexer.EOS)return j.QueryLexer.lexEOS;if(92!=t.charCodeAt(0)){if(":"==t)return j.QueryLexer.lexField;if("~"==t)return e.backup(),e.width()>0&&e.emit(j.QueryLexer.TERM),j.QueryLexer.lexEditDistance;if("^"==t)return e.backup(),e.width()>0&&e.emit(j.QueryLexer.TERM),j.QueryLexer.lexBoost;if("+"==t&&1===e.width())return e.emit(j.QueryLexer.PRESENCE),j.QueryLexer.lexText;if("-"==t&&1===e.width())return e.emit(j.QueryLexer.PRESENCE),j.QueryLexer.lexText;if(t.match(j.QueryLexer.termSeparator))return j.QueryLexer.lexTerm}else e.escapeCharacter()}},j.QueryParser=function(e,t){this.lexer=new j.QueryLexer(e),this.query=t,this.currentClause={},this.lexemeIdx=0},j.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=j.QueryParser.parseClause;e;)e=e(this);return this.query},j.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},j.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},j.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},j.QueryParser.parseClause=function(e){var t=e.peekLexeme();if(null!=t)switch(t.type){case j.QueryLexer.PRESENCE:return j.QueryParser.parsePresence;case j.QueryLexer.FIELD:return j.QueryParser.parseField;case j.QueryLexer.TERM:return j.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+t.type;throw t.str.length>=1&&(n+=" with value '"+t.str+"'"),new j.QueryParseError(n,t.start,t.end)}},j.QueryParser.parsePresence=function(e){var t=e.consumeLexeme();if(null!=t){switch(t.str){case"-":e.currentClause.presence=j.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=j.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+t.str+"'";throw new j.QueryParseError(n,t.start,t.end)}var r=e.peekLexeme();if(null==r){n="expecting term or field, found nothing";throw new j.QueryParseError(n,t.start,t.end)}switch(r.type){case j.QueryLexer.FIELD:return j.QueryParser.parseField;case j.QueryLexer.TERM:return j.QueryParser.parseTerm;default:n="expecting term or field, found '"+r.type+"'";throw new j.QueryParseError(n,r.start,r.end)}}},j.QueryParser.parseField=function(e){var t=e.consumeLexeme();if(null!=t){if(-1==e.query.allFields.indexOf(t.str)){var n=e.query.allFields.map((function(e){return"'"+e+"'"})).join(", "),r="unrecognised field '"+t.str+"', possible fields: "+n;throw new j.QueryParseError(r,t.start,t.end)}e.currentClause.fields=[t.str];var i=e.peekLexeme();if(null==i){r="expecting term, found nothing";throw new j.QueryParseError(r,t.start,t.end)}if(i.type===j.QueryLexer.TERM)return j.QueryParser.parseTerm;r="expecting term, found '"+i.type+"'";throw new j.QueryParseError(r,i.start,i.end)}},j.QueryParser.parseTerm=function(e){var t=e.consumeLexeme();if(null!=t){e.currentClause.term=t.str.toLowerCase(),-1!=t.str.indexOf("*")&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(null!=n)switch(n.type){case j.QueryLexer.TERM:return e.nextClause(),j.QueryParser.parseTerm;case j.QueryLexer.FIELD:return e.nextClause(),j.QueryParser.parseField;case j.QueryLexer.EDIT_DISTANCE:return j.QueryParser.parseEditDistance;case j.QueryLexer.BOOST:return j.QueryParser.parseBoost;case j.QueryLexer.PRESENCE:return e.nextClause(),j.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+n.type+"'";throw new j.QueryParseError(r,n.start,n.end)}else e.nextClause()}},j.QueryParser.parseEditDistance=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="edit distance must be numeric";throw new j.QueryParseError(r,t.start,t.end)}e.currentClause.editDistance=n;var i=e.peekLexeme();if(null!=i)switch(i.type){case j.QueryLexer.TERM:return e.nextClause(),j.QueryParser.parseTerm;case j.QueryLexer.FIELD:return e.nextClause(),j.QueryParser.parseField;case j.QueryLexer.EDIT_DISTANCE:return j.QueryParser.parseEditDistance;case j.QueryLexer.BOOST:return j.QueryParser.parseBoost;case j.QueryLexer.PRESENCE:return e.nextClause(),j.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+i.type+"'";throw new j.QueryParseError(r,i.start,i.end)}else e.nextClause()}},j.QueryParser.parseBoost=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="boost must be numeric";throw new j.QueryParseError(r,t.start,t.end)}e.currentClause.boost=n;var i=e.peekLexeme();if(null!=i)switch(i.type){case j.QueryLexer.TERM:return e.nextClause(),j.QueryParser.parseTerm;case j.QueryLexer.FIELD:return e.nextClause(),j.QueryParser.parseField;case j.QueryLexer.EDIT_DISTANCE:return j.QueryParser.parseEditDistance;case j.QueryLexer.BOOST:return j.QueryParser.parseBoost;case j.QueryLexer.PRESENCE:return e.nextClause(),j.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+i.type+"'";throw new j.QueryParseError(r,i.start,i.end)}else e.nextClause()}},void 0===(i="function"==typeof(r=function(){return j})?r.call(t,n,t,e):r)||(e.exports=i)}()},8934:(e,t,n)=>{"use strict";n.d(t,{_:()=>i,t:()=>a});var r=n(7294);const i=r.createContext(!1);function a(e){let{children:t}=e;const[n,a]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{a(!0)}),[]),r.createElement(i.Provider,{value:n},t)}},9383:(e,t,n)=>{"use strict";var r=n(7294),i=n(3935),a=n(3727),o=n(405),s=n(412);const l=[n(2497),n(3310),n(8320),n(2295)];var u=n(723),c=n(6550),d=n(8790);function p(e){let{children:t}=e;return r.createElement(r.Fragment,null,t)}var f=n(7462),m=n(5742),g=n(2263),h=n(4996),v=n(6668),b=n(1944),y=n(4711),w=n(9727),k=n(3320),S=n(197);function E(){const{i18n:{defaultLocale:e,localeConfigs:t}}=(0,g.Z)(),n=(0,y.l)();return r.createElement(m.Z,null,Object.entries(t).map((e=>{let[t,{htmlLang:i}]=e;return r.createElement("link",{key:t,rel:"alternate",href:n.createUrl({locale:t,fullyQualified:!0}),hrefLang:i})})),r.createElement("link",{rel:"alternate",href:n.createUrl({locale:e,fullyQualified:!0}),hrefLang:"x-default"}))}function x(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,g.Z)(),i=function(){const{siteConfig:{url:e}}=(0,g.Z)(),{pathname:t}=(0,c.TH)();return e+(0,h.Z)(t)}(),a=t?`${n}${t}`:i;return r.createElement(m.Z,null,r.createElement("meta",{property:"og:url",content:a}),r.createElement("link",{rel:"canonical",href:a}))}function _(){const{i18n:{currentLocale:e}}=(0,g.Z)(),{metadata:t,image:n}=(0,v.L)();return r.createElement(r.Fragment,null,r.createElement(m.Z,null,r.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),r.createElement("body",{className:w.h})),n&&r.createElement(b.d,{image:n}),r.createElement(x,null),r.createElement(E,null),r.createElement(S.Z,{tag:k.HX,locale:e}),r.createElement(m.Z,null,t.map(((e,t)=>r.createElement("meta",(0,f.Z)({key:t},e))))))}const O=new Map;function P(e){if(O.has(e.pathname))return{...e,pathname:O.get(e.pathname)};if((0,d.f)(u.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return O.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return O.set(e.pathname,t),{...e,pathname:t}}var C=n(8934),T=n(8940);function I(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>i.forEach((e=>e?.()))}const A=function(e){let{children:t,location:n,previousLocation:i}=e;return(0,r.useLayoutEffect)((()=>{i!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,i=t.hash===n.hash,a=t.search===n.search;if(r&&i&&!a)return;const{hash:o}=t;if(o){const e=decodeURIComponent(o.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:i}),I("onRouteDidUpdate",{previousLocation:i,location:n}))}),[i,n]),t};function L(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(u.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class R extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=s.Z.canUseDOM?I("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=I("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),L(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return r.createElement(A,{previousLocation:this.previousLocation,location:t},r.createElement(c.AW,{location:t,render:()=>e}))}}const N=R,j="docusaurus-base-url-issue-banner-container",D="docusaurus-base-url-issue-banner",M="docusaurus-base-url-issue-banner-suggestion-container",F="__DOCUSAURUS_INSERT_BASEURL_BANNER";function B(e){return`\nwindow['${F}'] = true;\n\ndocument.addEventListener('DOMContentLoaded', maybeInsertBanner);\n\nfunction maybeInsertBanner() {\n var shouldInsert = window['${F}'];\n shouldInsert && insertBanner();\n}\n\nfunction insertBanner() {\n var bannerContainer = document.getElementById('${j}');\n if (!bannerContainer) {\n return;\n }\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

\n

We suggest trying baseUrl =

\n
\n`}(e)).replace(/{window[F]=!1}),[]),r.createElement(r.Fragment,null,!s.Z.canUseDOM&&r.createElement(m.Z,null,r.createElement("script",null,B(e))),r.createElement("div",{id:j}))}function U(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,g.Z)(),{pathname:n}=(0,c.TH)();return t&&n===e?r.createElement(z,null):null}function q(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:i,localeConfigs:a}}=(0,g.Z)(),o=(0,h.Z)(e),{htmlLang:s,direction:l}=a[i];return r.createElement(m.Z,null,r.createElement("html",{lang:s,dir:l}),r.createElement("title",null,t),r.createElement("meta",{property:"og:title",content:t}),r.createElement("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&r.createElement("meta",{name:"robots",content:"noindex, nofollow"}),e&&r.createElement("link",{rel:"icon",href:o}))}var $=n(4763);function H(){const e=(0,d.H)(u.Z),t=(0,c.TH)();return r.createElement($.Z,null,r.createElement(T.M,null,r.createElement(C.t,null,r.createElement(p,null,r.createElement(q,null),r.createElement(_,null),r.createElement(U,null),r.createElement(N,{location:P(t)},e)))))}var G=n(6887);const Q=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const i=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;i?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var V=n(9670);const Z=new Set,W=new Set,K=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,Y={prefetch(e){if(!(e=>!K()&&!W.has(e)&&!Z.has(e))(e))return!1;Z.add(e);const t=(0,d.f)(u.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(G).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,V.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Q(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!K()&&!W.has(e))(e)&&(W.add(e),L(e))},X=Object.freeze(Y);if(s.Z.canUseDOM){window.docusaurus=X;const e=i.hydrate;L(window.location.pathname).then((()=>{e(r.createElement(o.B6,null,r.createElement(a.VK,null,r.createElement(H,null))),document.getElementById("__docusaurus"))}))}},8940:(e,t,n)=>{"use strict";n.d(t,{_:()=>c,M:()=>d});var r=n(7294),i=n(6809);const a=JSON.parse('{"@cmfcmf/docusaurus-search-local":{"default":{"titleBoost":10,"contentBoost":1,"parentCategoriesBoost":2,"indexDocSidebarParentCategories":3}},"docusaurus-plugin-content-docs":{"default":{"path":"/guides","versions":[{"name":"current","label":"v0.5.x","isLast":true,"path":"/guides","mainDocId":"index","docs":[{"id":"concepts/agents","path":"/guides/concepts/agents","sidebar":"tutorialSidebar"},{"id":"concepts/did-and-didcomm","path":"/guides/concepts/did-and-didcomm","sidebar":"tutorialSidebar"},{"id":"concepts/index","path":"/guides/concepts/","sidebar":"tutorialSidebar"},{"id":"concepts/platform-and-environment","path":"/guides/concepts/platform-and-environment","sidebar":"tutorialSidebar"},{"id":"ecosystem/index","path":"/guides/ecosystem/","sidebar":"tutorialSidebar"},{"id":"extensions/index","path":"/guides/extensions/","sidebar":"tutorialSidebar"},{"id":"extensions/push-notifications","path":"/guides/extensions/push-notifications","sidebar":"tutorialSidebar"},{"id":"extensions/react-hooks","path":"/guides/extensions/react-hooks","sidebar":"tutorialSidebar"},{"id":"extensions/redux-store","path":"/guides/extensions/redux-store","sidebar":"tutorialSidebar"},{"id":"extensions/rest","path":"/guides/extensions/rest","sidebar":"tutorialSidebar"},{"id":"features/aries","path":"/guides/features/aries","sidebar":"tutorialSidebar"},{"id":"features/credentials","path":"/guides/features/credentials","sidebar":"tutorialSidebar"},{"id":"features/dids","path":"/guides/features/dids","sidebar":"tutorialSidebar"},{"id":"features/index","path":"/guides/features/","sidebar":"tutorialSidebar"},{"id":"features/openid4vc","path":"/guides/features/openid4vc","sidebar":"tutorialSidebar"},{"id":"getting-started/index","path":"/guides/getting-started/","sidebar":"tutorialSidebar"},{"id":"getting-started/prerequisites","path":"/guides/getting-started/prerequisites","sidebar":"tutorialSidebar"},{"id":"getting-started/set-up/anoncreds","path":"/guides/getting-started/set-up/anoncreds","sidebar":"tutorialSidebar"},{"id":"getting-started/set-up/aries-askar","path":"/guides/getting-started/set-up/aries-askar","sidebar":"tutorialSidebar"},{"id":"getting-started/set-up/cheqd/index","path":"/guides/getting-started/set-up/cheqd/","sidebar":"tutorialSidebar"},{"id":"getting-started/set-up/index","path":"/guides/getting-started/set-up/","sidebar":"tutorialSidebar"},{"id":"getting-started/set-up/indy-vdr","path":"/guides/getting-started/set-up/indy-vdr","sidebar":"tutorialSidebar"},{"id":"index","path":"/guides/","sidebar":"tutorialSidebar"},{"id":"tutorials/agent-config/index","path":"/guides/tutorials/agent-config/","sidebar":"tutorialSidebar"},{"id":"tutorials/agent-config/logging","path":"/guides/tutorials/agent-config/logging","sidebar":"tutorialSidebar"},{"id":"tutorials/cheqd/index","path":"/guides/tutorials/cheqd/","sidebar":"tutorialSidebar"},{"id":"tutorials/create-a-connection","path":"/guides/tutorials/create-a-connection","sidebar":"tutorialSidebar"},{"id":"tutorials/index","path":"/guides/tutorials/","sidebar":"tutorialSidebar"},{"id":"tutorials/issue-a-credential","path":"/guides/tutorials/issue-a-credential","sidebar":"tutorialSidebar"},{"id":"tutorials/mediation","path":"/guides/tutorials/mediation","sidebar":"tutorialSidebar"},{"id":"tutorials/registering-schema-and-credential-definition","path":"/guides/tutorials/registering-schema-and-credential-definition","sidebar":"tutorialSidebar"},{"id":"updating/index","path":"/guides/updating/","sidebar":"tutorialSidebar"},{"id":"updating/update-assistant","path":"/guides/updating/update-assistant","sidebar":"tutorialSidebar"},{"id":"updating/update-indy-sdk-to-askar","path":"/guides/updating/update-indy-sdk-to-askar","sidebar":"tutorialSidebar"},{"id":"updating/versions/0.1-to-0.2","path":"/guides/updating/versions/0.1-to-0.2","sidebar":"tutorialSidebar"},{"id":"updating/versions/0.2-to-0.3","path":"/guides/updating/versions/0.2-to-0.3","sidebar":"tutorialSidebar"},{"id":"updating/versions/0.3-to-0.4","path":"/guides/updating/versions/0.3-to-0.4","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/guides/","label":"index"}}}},{"name":"0.4","label":"v0.4.x","isLast":false,"path":"/guides/0.4","mainDocId":"index","docs":[{"id":"concepts/agents","path":"/guides/0.4/concepts/agents","sidebar":"tutorialSidebar"},{"id":"concepts/did-and-didcomm","path":"/guides/0.4/concepts/did-and-didcomm","sidebar":"tutorialSidebar"},{"id":"concepts/index","path":"/guides/0.4/concepts/","sidebar":"tutorialSidebar"},{"id":"concepts/platform-and-environment","path":"/guides/0.4/concepts/platform-and-environment","sidebar":"tutorialSidebar"},{"id":"ecosystem/index","path":"/guides/0.4/ecosystem/","sidebar":"tutorialSidebar"},{"id":"extensions/index","path":"/guides/0.4/extensions/","sidebar":"tutorialSidebar"},{"id":"extensions/push-notifications","path":"/guides/0.4/extensions/push-notifications","sidebar":"tutorialSidebar"},{"id":"extensions/react-hooks","path":"/guides/0.4/extensions/react-hooks","sidebar":"tutorialSidebar"},{"id":"extensions/redux-store","path":"/guides/0.4/extensions/redux-store","sidebar":"tutorialSidebar"},{"id":"extensions/rest","path":"/guides/0.4/extensions/rest","sidebar":"tutorialSidebar"},{"id":"getting-started/index","path":"/guides/0.4/getting-started/","sidebar":"tutorialSidebar"},{"id":"getting-started/prerequisites","path":"/guides/0.4/getting-started/prerequisites","sidebar":"tutorialSidebar"},{"id":"getting-started/set-up/anoncreds-rs","path":"/guides/0.4/getting-started/set-up/anoncreds-rs","sidebar":"tutorialSidebar"},{"id":"getting-started/set-up/aries-askar","path":"/guides/0.4/getting-started/set-up/aries-askar","sidebar":"tutorialSidebar"},{"id":"getting-started/set-up/cheqd/index","path":"/guides/0.4/getting-started/set-up/cheqd/","sidebar":"tutorialSidebar"},{"id":"getting-started/set-up/index","path":"/guides/0.4/getting-started/set-up/","sidebar":"tutorialSidebar"},{"id":"getting-started/set-up/indy-sdk/index","path":"/guides/0.4/getting-started/set-up/indy-sdk/","sidebar":"tutorialSidebar"},{"id":"getting-started/set-up/indy-sdk/linux","path":"/guides/0.4/getting-started/set-up/indy-sdk/linux","sidebar":"tutorialSidebar"},{"id":"getting-started/set-up/indy-sdk/macos-arm","path":"/guides/0.4/getting-started/set-up/indy-sdk/macos-arm","sidebar":"tutorialSidebar"},{"id":"getting-started/set-up/indy-sdk/macos-intel","path":"/guides/0.4/getting-started/set-up/indy-sdk/macos-intel","sidebar":"tutorialSidebar"},{"id":"getting-started/set-up/indy-sdk/react-native","path":"/guides/0.4/getting-started/set-up/indy-sdk/react-native","sidebar":"tutorialSidebar"},{"id":"getting-started/set-up/indy-sdk/windows","path":"/guides/0.4/getting-started/set-up/indy-sdk/windows","sidebar":"tutorialSidebar"},{"id":"getting-started/set-up/indy-vdr","path":"/guides/0.4/getting-started/set-up/indy-vdr","sidebar":"tutorialSidebar"},{"id":"index","path":"/guides/0.4/","sidebar":"tutorialSidebar"},{"id":"tutorials/agent-config/index","path":"/guides/0.4/tutorials/agent-config/","sidebar":"tutorialSidebar"},{"id":"tutorials/agent-config/logging","path":"/guides/0.4/tutorials/agent-config/logging","sidebar":"tutorialSidebar"},{"id":"tutorials/cheqd/index","path":"/guides/0.4/tutorials/cheqd/","sidebar":"tutorialSidebar"},{"id":"tutorials/create-a-connection","path":"/guides/0.4/tutorials/create-a-connection","sidebar":"tutorialSidebar"},{"id":"tutorials/index","path":"/guides/0.4/tutorials/","sidebar":"tutorialSidebar"},{"id":"tutorials/indy-sdk-postgres-database-nodejs/index","path":"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/","sidebar":"tutorialSidebar"},{"id":"tutorials/indy-sdk-postgres-database-nodejs/linux","path":"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/linux","sidebar":"tutorialSidebar"},{"id":"tutorials/indy-sdk-postgres-database-nodejs/macos","path":"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/macos","sidebar":"tutorialSidebar"},{"id":"tutorials/indy-sdk-postgres-database-nodejs/windows","path":"/guides/0.4/tutorials/indy-sdk-postgres-database-nodejs/windows","sidebar":"tutorialSidebar"},{"id":"tutorials/issue-a-credential","path":"/guides/0.4/tutorials/issue-a-credential","sidebar":"tutorialSidebar"},{"id":"tutorials/mediation","path":"/guides/0.4/tutorials/mediation","sidebar":"tutorialSidebar"},{"id":"tutorials/registering-schema-and-credential-definition","path":"/guides/0.4/tutorials/registering-schema-and-credential-definition","sidebar":"tutorialSidebar"},{"id":"updating/index","path":"/guides/0.4/updating/","sidebar":"tutorialSidebar"},{"id":"updating/update-assistant","path":"/guides/0.4/updating/update-assistant","sidebar":"tutorialSidebar"},{"id":"updating/update-indy-sdk-to-askar","path":"/guides/0.4/updating/update-indy-sdk-to-askar","sidebar":"tutorialSidebar"},{"id":"updating/versions/0.1-to-0.2","path":"/guides/0.4/updating/versions/0.1-to-0.2","sidebar":"tutorialSidebar"},{"id":"updating/versions/0.2-to-0.3","path":"/guides/0.4/updating/versions/0.2-to-0.3","sidebar":"tutorialSidebar"},{"id":"updating/versions/0.3-to-0.4","path":"/guides/0.4/updating/versions/0.3-to-0.4","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/guides/0.4/","label":"index"}}}},{"name":"0.3","label":"v0.3.x","isLast":false,"path":"/guides/0.3","mainDocId":"index","docs":[{"id":"concepts/agents","path":"/guides/0.3/concepts/agents","sidebar":"tutorialSidebar"},{"id":"concepts/did-and-didcomm","path":"/guides/0.3/concepts/did-and-didcomm","sidebar":"tutorialSidebar"},{"id":"concepts/index","path":"/guides/0.3/concepts/","sidebar":"tutorialSidebar"},{"id":"concepts/platform-and-environment","path":"/guides/0.3/concepts/platform-and-environment","sidebar":"tutorialSidebar"},{"id":"ecosystem/index","path":"/guides/0.3/ecosystem/","sidebar":"tutorialSidebar"},{"id":"extensions/index","path":"/guides/0.3/extensions/","sidebar":"tutorialSidebar"},{"id":"extensions/push-notifications/index","path":"/guides/0.3/extensions/push-notifications/","sidebar":"tutorialSidebar"},{"id":"extensions/push-notifications/setup","path":"/guides/0.3/extensions/push-notifications/setup","sidebar":"tutorialSidebar"},{"id":"extensions/react-hooks/index","path":"/guides/0.3/extensions/react-hooks/","sidebar":"tutorialSidebar"},{"id":"extensions/react-hooks/setup","path":"/guides/0.3/extensions/react-hooks/setup","sidebar":"tutorialSidebar"},{"id":"extensions/redux-store/index","path":"/guides/0.3/extensions/redux-store/","sidebar":"tutorialSidebar"},{"id":"extensions/redux-store/setup","path":"/guides/0.3/extensions/redux-store/setup","sidebar":"tutorialSidebar"},{"id":"extensions/rest/index","path":"/guides/0.3/extensions/rest/","sidebar":"tutorialSidebar"},{"id":"extensions/rest/setup","path":"/guides/0.3/extensions/rest/setup","sidebar":"tutorialSidebar"},{"id":"getting-started/index","path":"/guides/0.3/getting-started/","sidebar":"tutorialSidebar"},{"id":"getting-started/installation/index","path":"/guides/0.3/getting-started/installation/","sidebar":"tutorialSidebar"},{"id":"getting-started/installation/nodejs/apple-arm","path":"/guides/0.3/getting-started/installation/nodejs/apple-arm","sidebar":"tutorialSidebar"},{"id":"getting-started/installation/nodejs/apple-intel","path":"/guides/0.3/getting-started/installation/nodejs/apple-intel","sidebar":"tutorialSidebar"},{"id":"getting-started/installation/nodejs/index","path":"/guides/0.3/getting-started/installation/nodejs/","sidebar":"tutorialSidebar"},{"id":"getting-started/installation/nodejs/linux","path":"/guides/0.3/getting-started/installation/nodejs/linux","sidebar":"tutorialSidebar"},{"id":"getting-started/installation/nodejs/windows","path":"/guides/0.3/getting-started/installation/nodejs/windows","sidebar":"tutorialSidebar"},{"id":"getting-started/installation/react-native/android","path":"/guides/0.3/getting-started/installation/react-native/android","sidebar":"tutorialSidebar"},{"id":"getting-started/installation/react-native/index","path":"/guides/0.3/getting-started/installation/react-native/","sidebar":"tutorialSidebar"},{"id":"getting-started/installation/react-native/ios","path":"/guides/0.3/getting-started/installation/react-native/ios","sidebar":"tutorialSidebar"},{"id":"getting-started/prerequisites/index","path":"/guides/0.3/getting-started/prerequisites/"},{"id":"getting-started/set-up/index","path":"/guides/0.3/getting-started/set-up/","sidebar":"tutorialSidebar"},{"id":"index","path":"/guides/0.3/","sidebar":"tutorialSidebar"},{"id":"tutorials/agent-config/index","path":"/guides/0.3/tutorials/agent-config/","sidebar":"tutorialSidebar"},{"id":"tutorials/agent-config/logging","path":"/guides/0.3/tutorials/agent-config/logging","sidebar":"tutorialSidebar"},{"id":"tutorials/create-a-connection","path":"/guides/0.3/tutorials/create-a-connection","sidebar":"tutorialSidebar"},{"id":"tutorials/index","path":"/guides/0.3/tutorials/","sidebar":"tutorialSidebar"},{"id":"tutorials/issue-a-credential","path":"/guides/0.3/tutorials/issue-a-credential","sidebar":"tutorialSidebar"},{"id":"tutorials/postgres-database-nodejs/index","path":"/guides/0.3/tutorials/postgres-database-nodejs/","sidebar":"tutorialSidebar"},{"id":"tutorials/postgres-database-nodejs/linux","path":"/guides/0.3/tutorials/postgres-database-nodejs/linux","sidebar":"tutorialSidebar"},{"id":"tutorials/postgres-database-nodejs/macos","path":"/guides/0.3/tutorials/postgres-database-nodejs/macos","sidebar":"tutorialSidebar"},{"id":"tutorials/postgres-database-nodejs/windows","path":"/guides/0.3/tutorials/postgres-database-nodejs/windows","sidebar":"tutorialSidebar"},{"id":"updating/index","path":"/guides/0.3/updating/","sidebar":"tutorialSidebar"},{"id":"updating/update-assistant","path":"/guides/0.3/updating/update-assistant","sidebar":"tutorialSidebar"},{"id":"updating/versions/0.1-to-0.2","path":"/guides/0.3/updating/versions/0.1-to-0.2","sidebar":"tutorialSidebar"},{"id":"updating/versions/0.2-to-0.3","path":"/guides/0.3/updating/versions/0.2-to-0.3","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/guides/0.3/","label":"index"}}}}],"breadcrumbs":true}}}'),o=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var s=n(7529);const l=JSON.parse('{"docusaurusVersion":"2.3.1","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"2.3.1"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"2.3.1"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.3.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.3.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.3.1"},"@cmfcmf/docusaurus-search-local":{"type":"package","name":"@cmfcmf/docusaurus-search-local","version":"0.10.0"},"docusaurus-theme-mermaid":{"type":"package","name":"@docusaurus/theme-mermaid","version":"2.3.1"}}}'),u={siteConfig:i.default,siteMetadata:l,globalData:a,i18n:o,codeTranslations:s},c=r.createContext(u);function d(e){let{children:t}=e;return r.createElement(c.Provider,{value:u},t)}},4763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var r=n(7294),i=n(412),a=n(5742),o=n(7003);function s(e){let{error:t,tryAgain:n}=e;return r.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center",height:"50vh",width:"100%",fontSize:"20px"}},r.createElement("h1",null,"This page crashed."),r.createElement("p",null,t.message),r.createElement("button",{type:"button",onClick:n},"Try again"))}function l(e){let{error:t,tryAgain:n}=e;return r.createElement(c,{fallback:()=>r.createElement(s,{error:t,tryAgain:n})},r.createElement(a.Z,null,r.createElement("title",null,"Page Error")),r.createElement(o.Z,null,r.createElement(s,{error:t,tryAgain:n})))}const u=e=>r.createElement(l,e);class c extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){i.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??u)(e)}return e??null}}},412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,i={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(7294),i=n(405);function a(e){return r.createElement(i.ql,e)}},9960:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7462),i=n(7294),a=n(3727),o=n(8780),s=n(2263),l=n(3919),u=n(412);const c=i.createContext({collectLink:()=>{}});var d=n(4996);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:m,isActive:g,"data-noBrokenLinkCheck":h,autoAddBaseUrl:v=!0,...b}=e;const{siteConfig:{trailingSlash:y,baseUrl:w}}=(0,s.Z)(),{withBaseUrl:k}=(0,d.C)(),S=(0,i.useContext)(c),E=(0,i.useRef)(null);(0,i.useImperativeHandle)(t,(()=>E.current));const x=p||f;const _=(0,l.Z)(x),O=x?.replace("pathname://","");let P=void 0!==O?(C=O,v&&(e=>e.startsWith("/"))(C)?k(C):C):void 0;var C;P&&_&&(P=(0,o.applyTrailingSlash)(P,{trailingSlash:y,baseUrl:w}));const T=(0,i.useRef)(!1),I=n?a.OL:a.rU,A=u.Z.canUseIntersectionObserver,L=(0,i.useRef)(),R=()=>{T.current||null==P||(window.docusaurus.preload(P),T.current=!0)};(0,i.useEffect)((()=>(!A&&_&&null!=P&&window.docusaurus.prefetch(P),()=>{A&&L.current&&L.current.disconnect()})),[L,P,A,_]);const N=P?.startsWith("#")??!1,j=!P||!_||N;return j||h||S.collectLink(P),j?i.createElement("a",(0,r.Z)({ref:E,href:P},x&&!_&&{target:"_blank",rel:"noopener noreferrer"},b)):i.createElement(I,(0,r.Z)({},b,{onMouseEnter:R,onTouchStart:R,innerRef:e=>{E.current=e,A&&e&&_&&(L.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(L.current.unobserve(e),L.current.disconnect(),null!=P&&window.docusaurus.prefetch(P))}))})),L.current.observe(e))},to:P},n&&{isActive:g,activeClassName:m}))}const f=i.forwardRef(p)},5999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>l,I:()=>s});var r=n(7294);function i(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var a=n(7529);function o(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return a[t??n]??n??t}function s(e,t){let{message:n,id:r}=e;return i(o({message:n,id:r}),t)}function l(e){let{children:t,id:n,values:a}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const s=o({message:t,id:n});return r.createElement(r.Fragment,null,i(s,a))}},9935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},3919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function i(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>i,b:()=>r})},4996:(e,t,n)=>{"use strict";n.d(t,{C:()=>o,Z:()=>s});var r=n(7294),i=n(2263),a=n(3919);function o(){const{siteConfig:{baseUrl:e,url:t}}=(0,i.Z)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:i=!1,absolute:o=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,a.b)(n))return n;if(i)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const s=n.startsWith(t)?n:t+n.replace(/^\//,"");return o?e+s:s}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function s(e,t){void 0===t&&(t={});const{withBaseUrl:n}=o();return n(e,t)}},2263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(7294),i=n(8940);function a(){return(0,r.useContext)(i._)}},8084:(e,t,n)=>{"use strict";n.d(t,{OD:()=>a,eZ:()=>o});var r=n(2263),i=n(9935);function a(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,r.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}function o(e,t,n){void 0===t&&(t=i.m),void 0===n&&(n={});const r=a(e),o=r?.[t];if(!o&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return o}},2389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(7294),i=n(8934);function a(){return(0,r.useContext)(i._)}},9670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function i(e){const t={};return function e(n,i){Object.entries(n).forEach((n=>{let[a,o]=n;const s=i?`${i}.${a}`:a;r(o)?e(o,s):t[s]=o}))}(e),t}},226:(e,t,n)=>{"use strict";n.d(t,{_:()=>i,z:()=>a});var r=n(7294);const i=r.createContext(null);function a(e){let{children:t,value:n}=e;const a=r.useContext(i),o=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:a,value:n})),[a,n]);return r.createElement(i.Provider,{value:o},t)}},4104:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>g,gA:()=>d,WS:()=>p,_r:()=>u,Jo:()=>h,zh:()=>c,yW:()=>m,gB:()=>f});var r=n(6550),i=n(8084);const a=e=>e.versions.find((e=>e.isLast));function o(e,t){const n=a(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}function s(e,t){const n=o(e,t),i=n?.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:i,alternateDocVersions:i?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(i.id):{}}}const l={},u=()=>(0,i.OD)("docusaurus-plugin-content-docs")??l,c=e=>(0,i.eZ)("docusaurus-plugin-content-docs",e,{failfast:!0});function d(e){void 0===e&&(e={});const t=u(),{pathname:n}=(0,r.TH)();return function(e,t,n){void 0===n&&(n={});const i=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),a=i?{pluginId:i[0],pluginData:i[1]}:void 0;if(!a&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return a}(t,n,e)}function p(e){void 0===e&&(e={});const t=d(e),{pathname:n}=(0,r.TH)();if(!t)return;return{activePlugin:t,activeVersion:o(t.pluginData,n)}}function f(e){return c(e).versions}function m(e){const t=c(e);return a(t)}function g(e){const t=c(e),{pathname:n}=(0,r.TH)();return s(t,n)}function h(e){const t=c(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=a(e);return{latestDocSuggestion:s(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},8320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(4865),i=n.n(r);i().configure({showSpinner:!1});const a={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{i().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){i().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r=n(7410),i=n(6809);!function(e){const{themeConfig:{prism:t}}=i.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{n(6726)(`./prism-${e}`)})),delete globalThis.Prism}(r.Z)},9471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(7294);const i={iconExternalLink:"iconExternalLink_nPIU"};function a(e){let{width:t=13.5,height:n=13.5}=e;return r.createElement("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:i.iconExternalLink},r.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}))}},7003:(e,t,n)=>{"use strict";n.d(t,{Z:()=>ua});var r=n(7294),i=n(6010),a=n(4763),o=n(1944),s=n(7462),l=n(6550),u=n(5999),c=n(5936);const d="docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,l.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&p(t)}),[]);return(0,c.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const m=(0,u.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function g(e){const t=e.children??m,{containerRef:n,onClick:i}=f();return r.createElement("div",{ref:n,role:"region","aria-label":m},r.createElement("a",(0,s.Z)({},e,{href:`#${d}`,onClick:i}),t))}var h=n(5281),v=n(9727);const b={skipToContent:"skipToContent_fXgn"};function y(){return r.createElement(g,{className:b.skipToContent})}var w=n(6668),k=n(9689);function S(e){let{width:t=21,height:n=21,color:i="currentColor",strokeWidth:a=1.2,className:o,...l}=e;return r.createElement("svg",(0,s.Z)({viewBox:"0 0 15 15",width:t,height:n},l),r.createElement("g",{stroke:i,strokeWidth:a},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const E={closeButton:"closeButton_CVFx"};function x(e){return r.createElement("button",(0,s.Z)({type:"button","aria-label":(0,u.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,i.Z)("clean-btn close",E.closeButton,e.className)}),r.createElement(S,{width:14,height:14,strokeWidth:3.1}))}const _={content:"content_knG7"};function O(e){const{announcementBar:t}=(0,w.L)(),{content:n}=t;return r.createElement("div",(0,s.Z)({},e,{className:(0,i.Z)(_.content,e.className),dangerouslySetInnerHTML:{__html:n}}))}const P={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function C(){const{announcementBar:e}=(0,w.L)(),{isActive:t,close:n}=(0,k.nT)();if(!t)return null;const{backgroundColor:i,textColor:a,isCloseable:o}=e;return r.createElement("div",{className:P.announcementBar,style:{backgroundColor:i,color:a},role:"banner"},o&&r.createElement("div",{className:P.announcementBarPlaceholder}),r.createElement(O,{className:P.announcementBarContent}),o&&r.createElement(x,{onClick:n,className:P.announcementBarClose}))}var T=n(3163),I=n(2466);var A=n(902),L=n(3102);const R=r.createContext(null);function N(e){let{children:t}=e;const n=function(){const e=(0,T.e)(),t=(0,L.HY)(),[n,i]=(0,r.useState)(!1),a=null!==t.component,o=(0,A.D9)(a);return(0,r.useEffect)((()=>{a&&!o&&i(!0)}),[a,o]),(0,r.useEffect)((()=>{a?e.shown||i(!0):i(!1)}),[e.shown,a]),(0,r.useMemo)((()=>[n,i]),[n])}();return r.createElement(R.Provider,{value:n},t)}function j(e){if(e.component){const t=e.component;return r.createElement(t,e.props)}}function D(){const e=(0,r.useContext)(R);if(!e)throw new A.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,i=(0,r.useCallback)((()=>n(!1)),[n]),a=(0,L.HY)();return(0,r.useMemo)((()=>({shown:t,hide:i,content:j(a)})),[i,a,t])}function M(e){let{header:t,primaryMenu:n,secondaryMenu:a}=e;const{shown:o}=D();return r.createElement("div",{className:"navbar-sidebar"},t,r.createElement("div",{className:(0,i.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":o})},r.createElement("div",{className:"navbar-sidebar__item menu"},n),r.createElement("div",{className:"navbar-sidebar__item menu"},a)))}var F=n(2949),B=n(2389);function z(e){return r.createElement("svg",(0,s.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"}))}function U(e){return r.createElement("svg",(0,s.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"}))}const q={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function $(e){let{className:t,value:n,onChange:a}=e;const o=(0,B.Z)(),s=(0,u.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===n?(0,u.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,u.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return r.createElement("div",{className:(0,i.Z)(q.toggle,t)},r.createElement("button",{className:(0,i.Z)("clean-btn",q.toggleButton,!o&&q.toggleButtonDisabled),type:"button",onClick:()=>a("dark"===n?"light":"dark"),disabled:!o,title:s,"aria-label":s,"aria-live":"polite"},r.createElement(z,{className:(0,i.Z)(q.toggleIcon,q.lightToggleIcon)}),r.createElement(U,{className:(0,i.Z)(q.toggleIcon,q.darkToggleIcon)})))}const H=r.memo($);function G(e){let{className:t}=e;const n=(0,w.L)().colorMode.disableSwitch,{colorMode:i,setColorMode:a}=(0,F.I)();return n?null:r.createElement(H,{className:t,value:i,onChange:a})}var Q=n(1327);function V(){return r.createElement(Q.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function Z(){const e=(0,T.e)();return r.createElement("button",{type:"button","aria-label":(0,u.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle()},r.createElement(S,{color:"var(--ifm-color-emphasis-600)"}))}function W(){return r.createElement("div",{className:"navbar-sidebar__brand"},r.createElement(V,null),r.createElement(G,{className:"margin-right--md"}),r.createElement(Z,null))}var K=n(9960),Y=n(4996),X=n(3919);function J(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var ee=n(9471);function te(e){let{activeBasePath:t,activeBaseRegex:n,to:i,href:a,label:o,html:l,isDropdownLink:u,prependBaseUrlToHref:c,...d}=e;const p=(0,Y.Z)(i),f=(0,Y.Z)(t),m=(0,Y.Z)(a,{forcePrependBaseUrl:!0}),g=o&&a&&!(0,X.Z)(a),h=l?{dangerouslySetInnerHTML:{__html:l}}:{children:r.createElement(r.Fragment,null,o,g&&r.createElement(ee.Z,u&&{width:12,height:12}))};return a?r.createElement(K.Z,(0,s.Z)({href:c?m:a},d,h)):r.createElement(K.Z,(0,s.Z)({to:p,isNavLink:!0},(t||n)&&{isActive:(e,t)=>n?J(n,t.pathname):t.pathname.startsWith(f)},d,h))}function ne(e){let{className:t,isDropdownItem:n=!1,...a}=e;const o=r.createElement(te,(0,s.Z)({className:(0,i.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n},a));return n?r.createElement("li",null,o):o}function re(e){let{className:t,isDropdownItem:n,...a}=e;return r.createElement("li",{className:"menu__list-item"},r.createElement(te,(0,s.Z)({className:(0,i.Z)("menu__link",t)},a)))}function ie(e){let{mobile:t=!1,position:n,...i}=e;const a=t?re:ne;return r.createElement(a,(0,s.Z)({},i,{activeClassName:i.activeClassName??(t?"menu__link--active":"navbar__link--active")}))}var ae=n(6043),oe=n(8596),se=n(2263);function le(e,t){return e.some((e=>function(e,t){return!!(0,oe.Mg)(e.to,t)||!!J(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function ue(e){let{items:t,position:n,className:a,onClick:o,...l}=e;const u=(0,r.useRef)(null),[c,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{u.current&&!u.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e)}}),[u]),r.createElement("div",{ref:u,className:(0,i.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":c})},r.createElement(te,(0,s.Z)({"aria-haspopup":"true","aria-expanded":c,role:"button",href:l.to?void 0:"#",className:(0,i.Z)("navbar__link",a)},l,{onClick:l.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!c))}}),l.children??l.label),r.createElement("ul",{className:"dropdown__menu"},t.map(((e,n)=>r.createElement(Pi,(0,s.Z)({isDropdownItem:!0,onKeyDown:e=>{if(n===t.length-1&&"Tab"===e.key){e.preventDefault(),d(!1);const t=u.current.nextElementSibling;if(t){(t instanceof HTMLAnchorElement?t:t.querySelector("a")).focus()}}},activeClassName:"dropdown__link--active"},e,{key:n}))))))}function ce(e){let{items:t,className:n,position:a,onClick:o,...u}=e;const c=function(){const{siteConfig:{baseUrl:e}}=(0,se.Z)(),{pathname:t}=(0,l.TH)();return t.replace(e,"/")}(),d=le(t,c),{collapsed:p,toggleCollapsed:f,setCollapsed:m}=(0,ae.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&m(!d)}),[c,d,m]),r.createElement("li",{className:(0,i.Z)("menu__list-item",{"menu__list-item--collapsed":p})},r.createElement(te,(0,s.Z)({role:"button",className:(0,i.Z)("menu__link menu__link--sublist menu__link--sublist-caret",n)},u,{onClick:e=>{e.preventDefault(),f()}}),u.children??u.label),r.createElement(ae.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:p},t.map(((e,t)=>r.createElement(Pi,(0,s.Z)({mobile:!0,isDropdownItem:!0,onClick:o,activeClassName:"menu__link--active"},e,{key:t}))))))}function de(e){let{mobile:t=!1,...n}=e;const i=t?ce:ue;return r.createElement(i,n)}var pe=n(4711);function fe(e){let{width:t=20,height:n=20,...i}=e;return r.createElement("svg",(0,s.Z)({viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0},i),r.createElement("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"}))}const me="iconLanguage_nlXk";var ge=n(3935);function he(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function ve(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function be(e,t,n){var r,i=t.initialState;return{getState:function(){return i},dispatch:function(r,a){var o=function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n0},reshape:function(e){return e.sources}},e),{},{id:null!==(n=e.id)&&void 0!==n?n:_e(),plugins:i,initialState:Re({activeItemId:null,query:"",completion:null,collections:[],isOpen:!1,status:"idle",context:{}},e.initialState),onStateChange:function(t){var n;null===(n=e.onStateChange)||void 0===n||n.call(e,t),i.forEach((function(e){var n;return null===(n=e.onStateChange)||void 0===n?void 0:n.call(e,t)}))},onSubmit:function(t){var n;null===(n=e.onSubmit)||void 0===n||n.call(e,t),i.forEach((function(e){var n;return null===(n=e.onSubmit)||void 0===n?void 0:n.call(e,t)}))},onReset:function(t){var n;null===(n=e.onReset)||void 0===n||n.call(e,t),i.forEach((function(e){var n;return null===(n=e.onReset)||void 0===n?void 0:n.call(e,t)}))},getSources:function(n){return Promise.all([].concat(Ie(i.map((function(e){return e.getSources}))),[e.getSources]).filter(Boolean).map((function(e){return function(e,t){var n=[];return Promise.resolve(e(t)).then((function(e){return Array.isArray(e),Promise.all(e.filter((function(e){return Boolean(e)})).map((function(e){if(e.sourceId,n.includes(e.sourceId))throw new Error("[Autocomplete] The `sourceId` ".concat(JSON.stringify(e.sourceId)," is not unique."));n.push(e.sourceId);var t={getItemInputValue:function(e){return e.state.query},getItemUrl:function(){},onSelect:function(e){(0,e.setIsOpen)(!1)},onActive:Oe,onResolve:Oe};Object.keys(t).forEach((function(e){t[e].__default=!0}));var r=Ce(Ce({},t),e);return Promise.resolve(r)})))}))}(e,n)}))).then((function(e){return ye(e)})).then((function(e){return e.map((function(e){return Re(Re({},e),{},{onSelect:function(n){e.onSelect(n),t.forEach((function(e){var t;return null===(t=e.onSelect)||void 0===t?void 0:t.call(e,n)}))},onActive:function(n){e.onActive(n),t.forEach((function(e){var t;return null===(t=e.onActive)||void 0===t?void 0:t.call(e,n)}))},onResolve:function(n){e.onResolve(n),t.forEach((function(e){var t;return null===(t=e.onResolve)||void 0===t?void 0:t.call(e,n)}))}})}))}))},navigator:Re({navigate:function(e){var t=e.itemUrl;r.location.assign(t)},navigateNewTab:function(e){var t=e.itemUrl,n=r.open(t,"_blank","noopener");null==n||n.focus()},navigateNewWindow:function(e){var t=e.itemUrl;r.open(t,"_blank","noopener")}},e.navigator)})}function De(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Me(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var st,lt,ut,ct=null,dt=(st=-1,lt=-1,ut=void 0,function(e){var t=++st;return Promise.resolve(e).then((function(e){return ut&&t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var bt=/((gt|sm)-|galaxy nexus)|samsung[- ]/i;var yt=["props","refresh","store"],wt=["inputElement","formElement","panelElement"],kt=["inputElement"],St=["inputElement","maxLength"],Et=["sourceIndex"],xt=["sourceIndex"],_t=["item","source","sourceIndex"];function Ot(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Pt(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function It(e){var t=e.props,n=e.refresh,r=e.store,i=Tt(e,yt),a=function(e,t){return void 0!==t?"".concat(e,"-").concat(t):e};return{getEnvironmentProps:function(e){var n=e.inputElement,i=e.formElement,a=e.panelElement;function o(e){!r.getState().isOpen&&r.pendingRequests.isEmpty()||e.target===n||!1===[i,a].some((function(t){return n=t,r=e.target,n===r||n.contains(r);var n,r}))&&(r.dispatch("blur",null),t.debug||r.pendingRequests.cancelAll())}return Pt({onTouchStart:o,onMouseDown:o,onTouchMove:function(e){!1!==r.getState().isOpen&&n===t.environment.document.activeElement&&e.target!==n&&n.blur()}},Tt(e,wt))},getRootProps:function(e){return Pt({role:"combobox","aria-expanded":r.getState().isOpen,"aria-haspopup":"listbox","aria-owns":r.getState().isOpen?"".concat(t.id,"-list"):void 0,"aria-labelledby":"".concat(t.id,"-label")},e)},getFormProps:function(e){e.inputElement;return Pt({action:"",noValidate:!0,role:"search",onSubmit:function(a){var o;a.preventDefault(),t.onSubmit(Pt({event:a,refresh:n,state:r.getState()},i)),r.dispatch("submit",null),null===(o=e.inputElement)||void 0===o||o.blur()},onReset:function(a){var o;a.preventDefault(),t.onReset(Pt({event:a,refresh:n,state:r.getState()},i)),r.dispatch("reset",null),null===(o=e.inputElement)||void 0===o||o.focus()}},Tt(e,kt))},getLabelProps:function(e){var n=e||{},r=n.sourceIndex,i=Tt(n,Et);return Pt({htmlFor:"".concat(a(t.id,r),"-input"),id:"".concat(a(t.id,r),"-label")},i)},getInputProps:function(e){var a;function o(e){(t.openOnFocus||Boolean(r.getState().query))&&pt(Pt({event:e,props:t,query:r.getState().completion||r.getState().query,refresh:n,store:r},i)),r.dispatch("focus",null)}var s=e||{},l=(s.inputElement,s.maxLength),u=void 0===l?512:l,c=Tt(s,St),d=tt(r.getState()),p=function(e){return Boolean(e&&e.match(bt))}((null===(a=t.environment.navigator)||void 0===a?void 0:a.userAgent)||""),f=null!=d&&d.itemUrl&&!p?"go":"search";return Pt({"aria-autocomplete":"both","aria-activedescendant":r.getState().isOpen&&null!==r.getState().activeItemId?"".concat(t.id,"-item-").concat(r.getState().activeItemId):void 0,"aria-controls":r.getState().isOpen?"".concat(t.id,"-list"):void 0,"aria-labelledby":"".concat(t.id,"-label"),value:r.getState().completion||r.getState().query,id:"".concat(t.id,"-input"),autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",enterKeyHint:f,spellCheck:"false",autoFocus:t.autoFocus,placeholder:t.placeholder,maxLength:u,type:"search",onChange:function(e){pt(Pt({event:e,props:t,query:e.currentTarget.value.slice(0,u),refresh:n,store:r},i))},onKeyDown:function(e){!function(e){var t=e.event,n=e.props,r=e.refresh,i=e.store,a=vt(e,ft);if("ArrowUp"===t.key||"ArrowDown"===t.key){var o=function(){var e=n.environment.document.getElementById("".concat(n.id,"-item-").concat(i.getState().activeItemId));e&&(e.scrollIntoViewIfNeeded?e.scrollIntoViewIfNeeded(!1):e.scrollIntoView(!1))},s=function(){var e=tt(i.getState());if(null!==i.getState().activeItemId&&e){var n=e.item,o=e.itemInputValue,s=e.itemUrl,l=e.source;l.onActive(gt({event:t,item:n,itemInputValue:o,itemUrl:s,refresh:r,source:l,state:i.getState()},a))}};t.preventDefault(),!1===i.getState().isOpen&&(n.openOnFocus||Boolean(i.getState().query))?pt(gt({event:t,props:n,query:i.getState().query,refresh:r,store:i},a)).then((function(){i.dispatch(t.key,{nextActiveItemId:n.defaultActiveItemId}),s(),setTimeout(o,0)})):(i.dispatch(t.key,{}),s(),o())}else if("Escape"===t.key)t.preventDefault(),i.dispatch(t.key,null),i.pendingRequests.cancelAll();else if("Tab"===t.key)i.dispatch("blur",null),i.pendingRequests.cancelAll();else if("Enter"===t.key){if(null===i.getState().activeItemId||i.getState().collections.every((function(e){return 0===e.items.length})))return void(n.debug||i.pendingRequests.cancelAll());t.preventDefault();var l=tt(i.getState()),u=l.item,c=l.itemInputValue,d=l.itemUrl,p=l.source;if(t.metaKey||t.ctrlKey)void 0!==d&&(p.onSelect(gt({event:t,item:u,itemInputValue:c,itemUrl:d,refresh:r,source:p,state:i.getState()},a)),n.navigator.navigateNewTab({itemUrl:d,item:u,state:i.getState()}));else if(t.shiftKey)void 0!==d&&(p.onSelect(gt({event:t,item:u,itemInputValue:c,itemUrl:d,refresh:r,source:p,state:i.getState()},a)),n.navigator.navigateNewWindow({itemUrl:d,item:u,state:i.getState()}));else if(t.altKey);else{if(void 0!==d)return p.onSelect(gt({event:t,item:u,itemInputValue:c,itemUrl:d,refresh:r,source:p,state:i.getState()},a)),void n.navigator.navigate({itemUrl:d,item:u,state:i.getState()});pt(gt({event:t,nextState:{isOpen:!1},props:n,query:c,refresh:r,store:i},a)).then((function(){p.onSelect(gt({event:t,item:u,itemInputValue:c,itemUrl:d,refresh:r,source:p,state:i.getState()},a))}))}}}(Pt({event:e,props:t,refresh:n,store:r},i))},onFocus:o,onBlur:Oe,onClick:function(n){e.inputElement!==t.environment.document.activeElement||r.getState().isOpen||o(n)}},c)},getPanelProps:function(e){return Pt({onMouseDown:function(e){e.preventDefault()},onMouseLeave:function(){r.dispatch("mouseleave",null)}},e)},getListProps:function(e){var n=e||{},r=n.sourceIndex,i=Tt(n,xt);return Pt({role:"listbox","aria-labelledby":"".concat(a(t.id,r),"-label"),id:"".concat(a(t.id,r),"-list")},i)},getItemProps:function(e){var o=e.item,s=e.source,l=e.sourceIndex,u=Tt(e,_t);return Pt({id:"".concat(a(t.id,l),"-item-").concat(o.__autocomplete_id),role:"option","aria-selected":r.getState().activeItemId===o.__autocomplete_id,onMouseMove:function(e){if(o.__autocomplete_id!==r.getState().activeItemId){r.dispatch("mousemove",o.__autocomplete_id);var t=tt(r.getState());if(null!==r.getState().activeItemId&&t){var a=t.item,s=t.itemInputValue,l=t.itemUrl,u=t.source;u.onActive(Pt({event:e,item:a,itemInputValue:s,itemUrl:l,refresh:n,source:u,state:r.getState()},i))}}},onMouseDown:function(e){e.preventDefault()},onClick:function(e){var a=s.getItemInputValue({item:o,state:r.getState()}),l=s.getItemUrl({item:o,state:r.getState()});(l?Promise.resolve():pt(Pt({event:e,nextState:{isOpen:!1},props:t,query:a,refresh:n,store:r},i))).then((function(){s.onSelect(Pt({event:e,item:o,itemInputValue:a,itemUrl:l,refresh:n,source:s,state:r.getState()},i))}))}},u)}}}var At="1.8.3",Lt=[{segment:"autocomplete-core",version:At}];function Rt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Nt(e){for(var t=1;t=n?null===r?null:0:i}function Bt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function zt(e){for(var t=1;t=5&&((i||!e&&5===r)&&(o.push(r,0,i,n),r=6),e&&(o.push(r,e,0,n),r=6)),i=""},l=0;l"===t?(r=1,i=""):i=t+i[0]:a?t===a?a="":i+=t:'"'===t||"'"===t?a=t:">"===t?(s(),r=1):r&&("="===t?(r=5,n=i,i=""):"/"===t&&(r<5||">"===e[l][u+1])?(s(),3===r&&(o=o[0]),r=o,(o=o[0]).push(2,0,r),r=0):" "===t||"\t"===t||"\n"===t||"\r"===t?(s(),r=2):i+=t),3===r&&"!--"===i&&(r=4,o=o[0])}return s(),o}(e)),t),arguments,[])).length>1?t:t[0]}var Xt=function(e){var t=e.environment,n=t.document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("class","aa-SubmitIcon"),n.setAttribute("viewBox","0 0 24 24"),n.setAttribute("width","20"),n.setAttribute("height","20"),n.setAttribute("fill","currentColor");var r=t.document.createElementNS("http://www.w3.org/2000/svg","path");return r.setAttribute("d","M16.041 15.856c-0.034 0.026-0.067 0.055-0.099 0.087s-0.060 0.064-0.087 0.099c-1.258 1.213-2.969 1.958-4.855 1.958-1.933 0-3.682-0.782-4.95-2.050s-2.050-3.017-2.050-4.95 0.782-3.682 2.050-4.95 3.017-2.050 4.95-2.050 3.682 0.782 4.95 2.050 2.050 3.017 2.050 4.95c0 1.886-0.745 3.597-1.959 4.856zM21.707 20.293l-3.675-3.675c1.231-1.54 1.968-3.493 1.968-5.618 0-2.485-1.008-4.736-2.636-6.364s-3.879-2.636-6.364-2.636-4.736 1.008-6.364 2.636-2.636 3.879-2.636 6.364 1.008 4.736 2.636 6.364 3.879 2.636 6.364 2.636c2.125 0 4.078-0.737 5.618-1.968l3.675 3.675c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414z"),n.appendChild(r),n},Jt=function(e){var t=e.environment,n=t.document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("class","aa-ClearIcon"),n.setAttribute("viewBox","0 0 24 24"),n.setAttribute("width","18"),n.setAttribute("height","18"),n.setAttribute("fill","currentColor");var r=t.document.createElementNS("http://www.w3.org/2000/svg","path");return r.setAttribute("d","M5.293 6.707l5.293 5.293-5.293 5.293c-0.391 0.391-0.391 1.024 0 1.414s1.024 0.391 1.414 0l5.293-5.293 5.293 5.293c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414l-5.293-5.293 5.293-5.293c0.391-0.391 0.391-1.024 0-1.414s-1.024-0.391-1.414 0l-5.293 5.293-5.293-5.293c-0.391-0.391-1.024-0.391-1.414 0s-0.391 1.024 0 1.414z"),n.appendChild(r),n},en=function(e){var t=e.environment.document.createElementNS("http://www.w3.org/2000/svg","svg");return t.setAttribute("class","aa-LoadingIcon"),t.setAttribute("viewBox","0 0 100 100"),t.setAttribute("width","20"),t.setAttribute("height","20"),t.innerHTML='\n \n',t},tn=["ontouchstart","ontouchend","ontouchmove","ontouchcancel"];function nn(e,t,n){e[t]=null===n?"":"number"!=typeof n?n:n+"px"}function rn(e){this._listeners[e.type](e)}function an(e,t,n){var r,i,a=e[t];if("style"===t)if("string"==typeof n)e.style=n;else if(null===n)e.style="";else for(t in n)a&&n[t]===a[t]||nn(e.style,t,n[t]);else"o"===t[0]&&"n"===t[1]?(r=t!==(t=t.replace(/Capture$/,"")),((i=t.toLowerCase())in e||tn.includes(i))&&(t=i),t=t.slice(2),e._listeners||(e._listeners={}),e._listeners[t]=n,n?a||e.addEventListener(t,rn,r):e.removeEventListener(t,rn,r)):"list"!==t&&"tagName"!==t&&"form"!==t&&"type"!==t&&"size"!==t&&"download"!==t&&"href"!==t&&t in e?e[t]=null==n?"":n:"function"!=typeof n&&"dangerouslySetInnerHTML"!==t&&(null==n||!1===n&&!/^ar/.test(t)?e.removeAttribute(t):e.setAttribute(t,n))}function on(e){return"onChange"===e?"onInput":e}function sn(e,t){for(var n in t)an(e,on(n),t[n])}function ln(e,t){for(var n in t)"o"===n[0]&&"n"===n[1]||an(e,on(n),t[n])}var un=["children"];function cn(e){return function(e){if(Array.isArray(e))return dn(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return dn(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return dn(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function dn(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function fn(e){return function(t,n){var r=n.children,i=void 0===r?[]:r,a=pn(n,un),o=e.document.createElement(t);return sn(o,a),o.append.apply(o,cn(i)),o}}var mn=["autocompleteScopeApi","environment","classNames","getInputProps","getInputPropsCore","isDetached","state"];function gn(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function hn(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var yn=function(e){var t=e.autocompleteScopeApi,n=e.environment,r=(e.classNames,e.getInputProps),i=e.getInputPropsCore,a=e.isDetached,o=e.state,s=bn(e,mn),l=fn(n)("input",s),u=r(hn({state:o,props:i({inputElement:l}),inputElement:l},t));return sn(l,hn(hn({},u),{},{onKeyDown:function(e){a&&"Tab"===e.key||u.onKeyDown(e)}})),l};function wn(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function kn(e){for(var t=1;t2&&(o.children=arguments.length>3?En.call(arguments,2):n),"function"==typeof e&&null!=e.defaultProps)for(a in e.defaultProps)void 0===o[a]&&(o[a]=e.defaultProps[a]);return Dn(e,o,r,i,null)}function Dn(e,t,n,r,i){var a={type:e,props:t,key:n,ref:r,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==i?++_n:i};return null==i&&null!=xn.vnode&&xn.vnode(a),a}function Mn(e){return e.children}function Fn(e,t){this.props=e,this.context=t}function Bn(e,t){if(null==t)return e.__?Bn(e.__,e.__.__k.indexOf(e)+1):null;for(var n;tt&&On.sort(Tn));qn.__r=0}function $n(e,t,n,r,i,a,o,s,l,u){var c,d,p,f,m,g,h,v=r&&r.__k||An,b=v.length;for(n.__k=[],c=0;c0?Dn(f.type,f.props,f.key,f.ref?f.ref:null,f.__v):f)){if(f.__=n,f.__b=n.__b+1,null===(p=v[c])||p&&f.key==p.key&&f.type===p.type)v[c]=void 0;else for(d=0;d=0;t--)if((n=e.__k[t])&&(r=Qn(n)))return r;return null}function Vn(e,t,n){"-"===t[0]?e.setProperty(t,null==n?"":n):e[t]=null==n?"":"number"!=typeof n||Ln.test(t)?n:n+"px"}function Zn(e,t,n,r,i){var a;e:if("style"===t)if("string"==typeof n)e.style.cssText=n;else{if("string"==typeof r&&(e.style.cssText=r=""),r)for(t in r)n&&t in n||Vn(e.style,t,"");if(n)for(t in n)r&&n[t]===r[t]||Vn(e.style,t,n[t])}else if("o"===t[0]&&"n"===t[1])a=t!==(t=t.replace(/Capture$/,"")),t=t.toLowerCase()in e?t.toLowerCase().slice(2):t.slice(2),e.l||(e.l={}),e.l[t+a]=n,n?r||e.addEventListener(t,a?Kn:Wn,a):e.removeEventListener(t,a?Kn:Wn,a);else if("dangerouslySetInnerHTML"!==t){if(i)t=t.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if("width"!==t&&"height"!==t&&"href"!==t&&"list"!==t&&"form"!==t&&"tabIndex"!==t&&"download"!==t&&t in e)try{e[t]=null==n?"":n;break e}catch(e){}"function"==typeof n||(null==n||!1===n&&"-"!==t[4]?e.removeAttribute(t):e.setAttribute(t,n))}}function Wn(e){return this.l[e.type+!1](xn.event?xn.event(e):e)}function Kn(e){return this.l[e.type+!0](xn.event?xn.event(e):e)}function Yn(e,t,n,r,i,a,o,s,l){var u,c,d,p,f,m,g,h,v,b,y,w,k,S,E,x=t.type;if(void 0!==t.constructor)return null;null!=n.__h&&(l=n.__h,s=t.__e=n.__e,t.__h=null,a=[s]),(u=xn.__b)&&u(t);try{e:if("function"==typeof x){if(h=t.props,v=(u=x.contextType)&&r[u.__c],b=u?v?v.props.value:u.__:r,n.__c?g=(c=t.__c=n.__c).__=c.__E:("prototype"in x&&x.prototype.render?t.__c=c=new x(h,b):(t.__c=c=new Fn(h,b),c.constructor=x,c.render=nr),v&&v.sub(c),c.props=h,c.state||(c.state={}),c.context=b,c.__n=r,d=c.__d=!0,c.__h=[],c._sb=[]),null==c.__s&&(c.__s=c.state),null!=x.getDerivedStateFromProps&&(c.__s==c.state&&(c.__s=Rn({},c.__s)),Rn(c.__s,x.getDerivedStateFromProps(h,c.__s))),p=c.props,f=c.state,c.__v=t,d)null==x.getDerivedStateFromProps&&null!=c.componentWillMount&&c.componentWillMount(),null!=c.componentDidMount&&c.__h.push(c.componentDidMount);else{if(null==x.getDerivedStateFromProps&&h!==p&&null!=c.componentWillReceiveProps&&c.componentWillReceiveProps(h,b),!c.__e&&null!=c.shouldComponentUpdate&&!1===c.shouldComponentUpdate(h,c.__s,b)||t.__v===n.__v){for(t.__v!==n.__v&&(c.props=h,c.state=c.__s,c.__d=!1),c.__e=!1,t.__e=n.__e,t.__k=n.__k,t.__k.forEach((function(e){e&&(e.__=t)})),y=0;y0&&void 0!==arguments[0]?arguments[0]:[];return{get:function(){return e},add:function(t){var n=e[e.length-1];(null==n?void 0:n.isHighlighted)===t.isHighlighted?e[e.length-1]={value:n.value+t.value,isHighlighted:n.isHighlighted}:e.push(t)}}}(n?[{value:n,isHighlighted:!1}]:[]);return t.forEach((function(e){var t=e.split(or);r.add({value:t[0],isHighlighted:!0}),""!==t[1]&&r.add({value:t[1],isHighlighted:!1})})),r.get()}function lr(e){return function(e){if(Array.isArray(e))return ur(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return ur(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return ur(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function ur(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n",""":'"',"'":"'"},fr=new RegExp(/\w/i),mr=/&(amp|quot|lt|gt|#39);/g,gr=RegExp(mr.source);function hr(e,t){var n,r,i,a=e[t],o=(null===(n=e[t+1])||void 0===n?void 0:n.isHighlighted)||!0,s=(null===(r=e[t-1])||void 0===r?void 0:r.isHighlighted)||!0;return fr.test((i=a.value)&&gr.test(i)?i.replace(mr,(function(e){return pr[e]})):i)||s!==o?a.isHighlighted:s}function vr(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function br(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var Nr={clearButton:"aa-ClearButton",detachedCancelButton:"aa-DetachedCancelButton",detachedContainer:"aa-DetachedContainer",detachedFormContainer:"aa-DetachedFormContainer",detachedOverlay:"aa-DetachedOverlay",detachedSearchButton:"aa-DetachedSearchButton",detachedSearchButtonIcon:"aa-DetachedSearchButtonIcon",detachedSearchButtonPlaceholder:"aa-DetachedSearchButtonPlaceholder",detachedSearchButtonQuery:"aa-DetachedSearchButtonQuery",form:"aa-Form",input:"aa-Input",inputWrapper:"aa-InputWrapper",inputWrapperPrefix:"aa-InputWrapperPrefix",inputWrapperSuffix:"aa-InputWrapperSuffix",item:"aa-Item",label:"aa-Label",list:"aa-List",loadingIndicator:"aa-LoadingIndicator",panel:"aa-Panel",panelLayout:"aa-PanelLayout aa-Panel--scrollable",root:"aa-Autocomplete",source:"aa-Source",sourceFooter:"aa-SourceFooter",sourceHeader:"aa-SourceHeader",sourceNoResults:"aa-SourceNoResults",submitButton:"aa-SubmitButton"},jr=function(e,t){var n=e.children;(0,e.render)(n,t)},Dr={createElement:jn,Fragment:Mn,render:rr};function Mr(e){var t=e.panelPlacement,n=e.container,r=e.form,i=e.environment,a=n.getBoundingClientRect(),o=(i.pageYOffset||i.document.documentElement.scrollTop||i.document.body.scrollTop||0)+a.top+a.height;switch(t){case"start":return{top:o,left:a.left};case"end":return{top:o,right:i.document.documentElement.clientWidth-(a.left+a.width)};case"full-width":return{top:o,left:0,right:0,width:"unset",maxWidth:"unset"};case"input-wrapper-width":var s=r.getBoundingClientRect();return{top:o,left:s.left,right:i.document.documentElement.clientWidth-(s.left+s.width),width:"unset",maxWidth:"unset"};default:throw new Error("[Autocomplete] The `panelPlacement` value ".concat(JSON.stringify(t)," is not valid."))}}function Fr(){return Fr=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function ti(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function ni(e){for(var t=1;t0;if(!p.value.core.openOnFocus&&!t.query)return n;var r=Boolean(u.current||p.value.renderer.renderNoResults);return!n&&r||n},__autocomplete_metadata:{userAgents:qr,options:e}}))})),g=Vt(ni({collections:[],completion:null,context:{},isOpen:!1,query:"",activeItemId:null,status:"idle"},p.value.core.initialState)),h={getEnvironmentProps:p.value.renderer.getEnvironmentProps,getFormProps:p.value.renderer.getFormProps,getInputProps:p.value.renderer.getInputProps,getItemProps:p.value.renderer.getItemProps,getLabelProps:p.value.renderer.getLabelProps,getListProps:p.value.renderer.getListProps,getPanelProps:p.value.renderer.getPanelProps,getRootProps:p.value.renderer.getRootProps},v={setActiveItemId:m.value.setActiveItemId,setQuery:m.value.setQuery,setCollections:m.value.setCollections,setIsOpen:m.value.setIsOpen,setStatus:m.value.setStatus,setContext:m.value.setContext,refresh:m.value.refresh,navigator:m.value.navigator},b=s((function(){return Yt.bind(p.value.renderer.renderer.createElement)})),y=s((function(){return function(e){var t=e.autocomplete,n=e.autocompleteScopeApi,r=e.classNames,i=e.environment,a=e.isDetached,o=e.placeholder,s=void 0===o?"Search":o,l=e.propGetters,u=e.setIsModalOpen,c=e.state,d=e.translations,p=fn(i),f=l.getRootProps(kn({state:c,props:t.getRootProps({})},n)),m=p("div",kn({class:r.root},f)),g=p("div",{class:r.detachedContainer,onMouseDown:function(e){e.stopPropagation()}}),h=p("div",{class:r.detachedOverlay,children:[g],onMouseDown:function(){u(!1),t.setIsOpen(!1)}}),v=l.getLabelProps(kn({state:c,props:t.getLabelProps({})},n)),b=p("button",{class:r.submitButton,type:"submit",title:d.submitButtonTitle,children:[Xt({environment:i})]}),y=p("label",kn({class:r.label,children:[b]},v)),w=p("button",{class:r.clearButton,type:"reset",title:d.clearButtonTitle,children:[Jt({environment:i})]}),k=p("div",{class:r.loadingIndicator,children:[en({environment:i})]}),S=yn({class:r.input,environment:i,state:c,getInputProps:l.getInputProps,getInputPropsCore:t.getInputProps,autocompleteScopeApi:n,isDetached:a}),E=p("div",{class:r.inputWrapperPrefix,children:[y,k]}),x=p("div",{class:r.inputWrapperSuffix,children:[w]}),_=p("div",{class:r.inputWrapper,children:[S]}),O=l.getFormProps(kn({state:c,props:t.getFormProps({inputElement:S})},n)),P=p("form",kn({class:r.form,children:[E,_,x]},O)),C=l.getPanelProps(kn({state:c,props:t.getPanelProps({})},n)),T=p("div",kn({class:r.panel},C)),I=p("div",{class:r.detachedSearchButtonQuery,textContent:c.query}),A=p("div",{class:r.detachedSearchButtonPlaceholder,hidden:Boolean(c.query),textContent:s});if(a){var L=p("div",{class:r.detachedSearchButtonIcon,children:[Xt({environment:i})]}),R=p("button",{type:"button",class:r.detachedSearchButton,onClick:function(){u(!0)},children:[L,A,I]}),N=p("button",{type:"button",class:r.detachedCancelButton,textContent:d.detachedCancelButtonText,onTouchStart:function(e){e.stopPropagation()},onClick:function(){t.setIsOpen(!1),u(!1)}}),j=p("div",{class:r.detachedFormContainer,children:[P,N]});g.appendChild(j),m.appendChild(R)}else m.appendChild(P);return{detachedContainer:g,detachedOverlay:h,detachedSearchButtonQuery:I,detachedSearchButtonPlaceholder:A,inputWrapper:_,input:S,root:m,form:P,label:y,submitButton:b,clearButton:w,loadingIndicator:k,panel:T}}({autocomplete:m.value,autocompleteScopeApi:v,classNames:p.value.renderer.classNames,environment:p.value.core.environment,isDetached:f.value,placeholder:p.value.core.placeholder,propGetters:h,setIsModalOpen:E,state:g.current,translations:p.value.renderer.translations})}));function w(){sn(y.value.panel,{style:f.value?{}:Mr({panelPlacement:p.value.renderer.panelPlacement,container:y.value.root,form:y.value.form,environment:p.value.core.environment})})}function k(e){g.current=e;var t={autocomplete:m.value,autocompleteScopeApi:v,classNames:p.value.renderer.classNames,components:p.value.renderer.components,container:p.value.renderer.container,html:b.value,dom:y.value,panelContainer:f.value?y.value.detachedContainer:p.value.renderer.panelContainer,propGetters:h,state:g.current,renderer:p.value.renderer.renderer},n=!Ee(e)&&!u.current&&p.value.renderer.renderNoResults||p.value.renderer.render;!function(e){var t=e.autocomplete,n=e.autocompleteScopeApi,r=e.dom,i=e.propGetters,a=e.state;ln(r.root,i.getRootProps(zr({state:a,props:t.getRootProps({})},n))),ln(r.input,i.getInputProps(zr({state:a,props:t.getInputProps({inputElement:r.input}),inputElement:r.input},n))),sn(r.label,{hidden:"stalled"===a.status}),sn(r.loadingIndicator,{hidden:"stalled"!==a.status}),sn(r.clearButton,{hidden:!a.query}),sn(r.detachedSearchButtonQuery,{textContent:a.query}),sn(r.detachedSearchButtonPlaceholder,{hidden:Boolean(a.query)})}(t),function(e,t){var n=t.autocomplete,r=t.autocompleteScopeApi,i=t.classNames,a=t.html,o=t.dom,s=t.panelContainer,l=t.propGetters,u=t.state,c=t.components,d=t.renderer;if(u.isOpen){s.contains(o.panel)||"loading"===u.status||s.appendChild(o.panel),o.panel.classList.toggle("aa-Panel--stalled","stalled"===u.status);var p=u.collections.filter((function(e){var t=e.source,n=e.items;return t.templates.noResults||n.length>0})).map((function(e,t){var o=e.source,s=e.items;return d.createElement("section",{key:t,className:i.source,"data-autocomplete-source-id":o.sourceId},o.templates.header&&d.createElement("div",{className:i.sourceHeader},o.templates.header({components:c,createElement:d.createElement,Fragment:d.Fragment,items:s,source:o,state:u,html:a})),o.templates.noResults&&0===s.length?d.createElement("div",{className:i.sourceNoResults},o.templates.noResults({components:c,createElement:d.createElement,Fragment:d.Fragment,source:o,state:u,html:a})):d.createElement("ul",Fr({className:i.list},l.getListProps(zr({state:u,props:n.getListProps({sourceIndex:t})},r))),s.map((function(e){var s=n.getItemProps({item:e,source:o,sourceIndex:t});return d.createElement("li",Fr({key:s.id,className:i.item},l.getItemProps(zr({state:u,props:s},r))),o.templates.item({components:c,createElement:d.createElement,Fragment:d.Fragment,item:e,state:u,html:a}))}))),o.templates.footer&&d.createElement("div",{className:i.sourceFooter},o.templates.footer({components:c,createElement:d.createElement,Fragment:d.Fragment,items:s,source:o,state:u,html:a})))})),f=d.createElement(d.Fragment,null,d.createElement("div",{className:i.panelLayout},p),d.createElement("div",{className:"aa-GradientBottom"})),m=p.reduce((function(e,t){return e[t.props["data-autocomplete-source-id"]]=t,e}),{});e(zr(zr({children:f,state:u,sections:p,elements:m},d),{},{components:c,html:a},r),o.panel)}else s.contains(o.panel)&&s.removeChild(o.panel)}(n,t)}function S(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};i();var t,n,r=p.value.renderer,o=r.components,s=ei(r,Jr);c.current=Vr(s,p.value.core,{components:(t=o,n=function(e){return!e.value.hasOwnProperty("__autocomplete_componentName")},Object.entries(t).reduce((function(e,t){var r=Yr(t,2),i=r[0],a=r[1];return n({key:i,value:a})?Wr(Wr({},e),{},Kr({},i,a)):e}),{})),initialState:g.current},e),l(),a(),m.value.refresh().then((function(){k(g.current)}))}function E(e){requestAnimationFrame((function(){var t=p.value.core.environment.document.body.contains(y.value.detachedOverlay);e!==t&&(e?(p.value.core.environment.document.body.appendChild(y.value.detachedOverlay),p.value.core.environment.document.body.classList.add("aa-Detached"),y.value.input.focus()):(p.value.core.environment.document.body.removeChild(y.value.detachedOverlay),p.value.core.environment.document.body.classList.remove("aa-Detached")))}))}return r((function(){var e=m.value.getEnvironmentProps({formElement:y.value.form,panelElement:y.value.panel,inputElement:y.value.input});return sn(p.value.core.environment,e),function(){sn(p.value.core.environment,Object.keys(e).reduce((function(e,t){return ni(ni({},e),{},ri({},t,void 0))}),{}))}})),r((function(){var e=f.value?p.value.core.environment.document.body:p.value.renderer.panelContainer,t=f.value?y.value.detachedOverlay:y.value.panel;return f.value&&g.current.isOpen&&E(!0),k(g.current),function(){e.contains(t)&&e.removeChild(t)}})),r((function(){var e=p.value.renderer.container;return e.appendChild(y.value.root),function(){e.removeChild(y.value.root)}})),r((function(){var e=Zt((function(e){k(e.state)}),0);return d.current=function(t){var n=t.state,r=t.prevState;(f.value&&r.isOpen!==n.isOpen&&E(n.isOpen),f.value||!n.isOpen||r.isOpen||w(),n.query!==r.query)&&p.value.core.environment.document.querySelectorAll(".aa-Panel--scrollable").forEach((function(e){0!==e.scrollTop&&(e.scrollTop=0)}));e({state:n})},function(){d.current=void 0}})),r((function(){var e=Zt((function(){var e=f.value;f.value=p.value.core.environment.matchMedia(p.value.renderer.detachedMediaQuery).matches,e!==f.value?S({}):requestAnimationFrame(w)}),20);return p.value.core.environment.addEventListener("resize",e),function(){p.value.core.environment.removeEventListener("resize",e)}})),r((function(){if(!f.value)return function(){};function e(e){y.value.detachedContainer.classList.toggle("aa-DetachedContainer--modal",e)}function t(t){e(t.matches)}var n=p.value.core.environment.matchMedia(getComputedStyle(p.value.core.environment.document.documentElement).getPropertyValue("--aa-detached-modal-media-query"));e(n.matches);var r=Boolean(n.addEventListener);return r?n.addEventListener("change",t):n.addListener(t),function(){r?n.removeEventListener("change",t):n.removeListener(t)}})),r((function(){return requestAnimationFrame(w),function(){}})),ni(ni({},v),{},{update:S,destroy:function(){i()}})}var ai=n(5742);n(9414);const oi=n(8965);oi.tokenizer.separator=/[\s\-]+/;const si=oi,li=(n(8965),e=>oi.tokenizer(e).map((e=>e.str))),ui=si;var ci=n(813),di=n.n(ci);function pi(){const e=(0,l.TH)(),t=(0,l.k6)(),{siteConfig:{baseUrl:n}}=(0,se.Z)(),[i,a]=(0,r.useState)({terms:[],isDocsOrBlog:!1});return(0,r.useEffect)((()=>{if(!e.state?.cmfcmfhighlight||0===e.state.cmfcmfhighlight.terms.length)return;a(e.state.cmfcmfhighlight);const{cmfcmfhighlight:n,...r}=e.state;t.replace({...e,state:r})}),[e.state?.cmfcmfhighlight,t,e]),(0,r.useEffect)((()=>{if(0===i.terms.length)return;const e=i.isDocsOrBlog?document.getElementsByTagName("article")[0]:document.getElementsByTagName("main")[0];if(!e)return;const t=new(di())(e),n={ignoreJoiners:!0};return t.mark(i.terms,n),()=>t.unmark(n)}),[i,n]),null}var fi=n(8084),mi=n(3320);const gi=!0;function hi(e){let{document:t}=e;const[n,r]=t.sectionRoute.split("#");let i=n;return r&&(i+="#"+r),i}const vi={documents:[],index:ui((function(){this.ref("id"),this.field("title"),this.field("content")}))};const bi=()=>{const e=(0,B.Z)(),[t,n]=(0,r.useState)((()=>!!e&&"dark"===document.documentElement.getAttribute("data-theme")));(0,r.useEffect)((()=>{const e=new MutationObserver((()=>{n("dark"===document.documentElement.getAttribute("data-theme"))}));return e.observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme"]}),()=>e.disconnect()}),[]);const{siteConfig:{baseUrl:i}}=(0,se.Z)(),{titleBoost:a,contentBoost:o,parentCategoriesBoost:s,indexDocSidebarParentCategories:c}=(0,fi.eZ)("@cmfcmf/docusaurus-search-local"),d=(0,l.k6)(),{tags:p}=(0,mi._q)(),f=(0,r.useRef)(p);(0,r.useEffect)((()=>{f.current=p}),[p]);const m=(0,r.useRef)({}),g=async e=>{const t=m.current[e];switch(t?.state){case"ready":return t;case void 0:{const t=[];m.current[e]={state:"loading",callbacks:t};const n=await async function(e,t){if(gi){let r;try{const n=await fetch(`${e}search-index-${t}.json`);if(!n.ok)return vi;r=await n.json()}catch(n){return vi}return{documents:r.documents,index:ui.Index.load(r.index)}}return Promise.resolve(vi)}(i,e);return t.forEach((e=>e(n))),m.current[e]={state:"ready",...n}}case"loading":return new Promise((e=>{t.callbacks.push(e)}))}},h=(0,u.I)({message:"cmfcmf/d-s-l.searchBar.placeholder",description:"Placeholder shown in the searchbar"}),v=(0,r.useRef)(null),b=(0,r.useRef)(null);return(0,r.useEffect)((()=>{if(v.current)return b.current=ii({container:v.current,placeholder:h,renderer:{createElement:r.createElement,Fragment:r.Fragment},render(e,t){let{children:n}=e;(0,ge.render)(n,t)},navigator:{navigate(e){let{item:t,itemUrl:n}=e;d.push(n,{cmfcmfhighlight:{terms:t.terms,isDocsOrBlog:"docs"===t.document.type||"blog"===t.document.type}})}},detachedMediaQuery:"",defaultActiveItemId:0,translations:{clearButtonTitle:(0,u.I)({message:"cmfcmf/d-s-l.searchBar.clearButtonTitle",description:"Title of the button to clear the current search input"}),detachedCancelButtonText:(0,u.I)({message:"cmfcmf/d-s-l.searchBar.detachedCancelButtonText",description:"Text of the button to close the detached search window"}),submitButtonTitle:(0,u.I)({message:"cmfcmf/d-s-l.searchBar.submitButtonTitle",description:"Title of the button to submit a new search"})},getSources(e){let{query:t}=e;return[{sourceId:"search-results",templates:{item(e){let{item:t}=e;const n=hi(t);return r.createElement("a",{href:n,className:"aa-ItemLink",onClick:e=>{e.preventDefault(),d.push(n,{cmfcmfhighlight:{terms:t.terms,isDocsOrBlog:"docs"===t.document.type||"blog"===t.document.type}})}},r.createElement("div",{className:"aa-ItemContent"},r.createElement("div",{className:"aa-ItemContentBody"},r.createElement("div",{className:"aa-ItemContentTitle"},t.document.sectionTitle),t.document.pageTitle!==t.document.sectionTitle&&r.createElement("div",{className:"aa-ItemContentDescription"},t.document.pageTitle))),r.createElement("div",{className:"aa-ItemActions"},r.createElement("button",{className:"aa-ItemActionButton aa-DesktopOnly aa-ActiveOnly",type:"button",title:"Select"},r.createElement("svg",{viewBox:"0 0 24 24",width:"20",height:"20",fill:"currentColor"},r.createElement("path",{d:"M18.984 6.984h2.016v6h-15.188l3.609 3.609-1.406 1.406-6-6 6-6 1.406 1.406-3.609 3.609h13.172v-4.031z"})))))},noResults:()=>r.createElement("div",{className:"aa-ItemContent"},r.createElement("div",{className:"aa-ItemContentBody"},gi?(0,u.I)({message:"cmfcmf/d-s-l.searchBar.noResults",description:"message shown if no results are found"}):"The search index is only available when you run docusaurus build!"))},getItemUrl(e){let{item:t}=e;return hi(t)},async getItems(){const e=f.current,n=await Promise.all(e.map((e=>g(e)))),r=li(t);return n.flatMap((e=>{let{index:t,documents:n}=e;return t.query((e=>{e.term(r,{fields:["title"],boost:a}),e.term(r,{fields:["title"],boost:a,wildcard:ui.Query.wildcard.TRAILING}),e.term(r,{fields:["content"],boost:o}),e.term(r,{fields:["content"],boost:o,wildcard:ui.Query.wildcard.TRAILING}),c&&(e.term(r,{fields:["sidebarParentCategories"],boost:s}),e.term(r,{fields:["sidebarParentCategories"],boost:s,wildcard:ui.Query.wildcard.TRAILING}))})).slice(0,8).map((e=>({document:n.find((t=>t.id.toString()===e.ref)),score:e.score,terms:r})))})).sort(((e,t)=>t.score-e.score)).slice(0,8)}}]}}),()=>b.current?.destroy()}),[]),r.createElement(r.Fragment,null,r.createElement(ai.Z,null,r.createElement("body",{"data-theme":t?"dark":"light"})),r.createElement(pi,null),r.createElement("div",{className:"dsla-search-wrapper"},r.createElement("div",{className:"dsla-search-field",ref:v,"data-tags":p.join(",")})))},yi={searchBox:"searchBox_ZlJk"};function wi(e){let{children:t,className:n}=e;return r.createElement("div",{className:(0,i.Z)(n,yi.searchBox)},t)}var ki=n(4104),Si=n(3438);var Ei=n(373);const xi=e=>e.docs.find((t=>t.id===e.mainDocId));const _i={default:ie,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:i,...a}=e;const{i18n:{currentLocale:o,locales:c,localeConfigs:d}}=(0,se.Z)(),p=(0,pe.l)(),{search:f,hash:m}=(0,l.TH)(),g=[...n,...c.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${m}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===o?t?"menu__link--active":"dropdown__link--active":""}})),...i],h=t?(0,u.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[o].label;return r.createElement(de,(0,s.Z)({},a,{mobile:t,label:r.createElement(r.Fragment,null,r.createElement(fe,{className:me}),h),items:g}))},search:function(e){let{mobile:t,className:n}=e;return t?null:r.createElement(wi,{className:n},r.createElement(bi,null))},dropdown:de,html:function(e){let{value:t,className:n,mobile:a=!1,isDropdownItem:o=!1}=e;const s=o?"li":"div";return r.createElement(s,{className:(0,i.Z)({navbar__item:!a&&!o,"menu__list-item":a},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:i,...a}=e;const{activeDoc:o}=(0,ki.Iw)(i),l=(0,Si.vY)(t,i);return null===l?null:r.createElement(ie,(0,s.Z)({exact:!0},a,{isActive:()=>o?.path===l.path||!!o?.sidebar&&o.sidebar===l.sidebar,label:n??l.id,to:l.path}))},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:i,...a}=e;const{activeDoc:o}=(0,ki.Iw)(i),l=(0,Si.oz)(t,i).link;if(!l)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return r.createElement(ie,(0,s.Z)({exact:!0},a,{isActive:()=>o?.sidebar===t,label:n??l.label,to:l.path}))},docsVersion:function(e){let{label:t,to:n,docsPluginId:i,...a}=e;const o=(0,Si.lO)(i)[0],l=t??o.label,u=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(o).path;return r.createElement(ie,(0,s.Z)({},a,{label:l,to:u}))},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:i,dropdownItemsBefore:a,dropdownItemsAfter:o,...c}=e;const{search:d,hash:p}=(0,l.TH)(),f=(0,ki.Iw)(n),m=(0,ki.gB)(n),{savePreferredVersionName:g}=(0,Ei.J)(n),h=m.map((e=>{const t=f.alternateDocVersions[e.name]??xi(e);return{label:e.label,to:`${t.path}${d}${p}`,isActive:()=>e===f.activeVersion,onClick:()=>g(e.name)}})),v=[...a,...h,...o],b=(0,Si.lO)(n)[0],y=t&&v.length>1?(0,u.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):b.label,w=t&&v.length>1?void 0:xi(b).path;return v.length<=1?r.createElement(ie,(0,s.Z)({},c,{mobile:t,label:y,to:w,isActive:i?()=>!1:void 0})):r.createElement(de,(0,s.Z)({},c,{mobile:t,label:y,to:w,items:v,isActive:i?()=>!1:void 0}))}},Oi=_i;function Pi(e){let{type:t,...n}=e;const i=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),a=Oi[i];if(!a)throw new Error(`No NavbarItem component found for type "${t}".`);return r.createElement(a,n)}function Ci(){const e=(0,T.e)(),t=(0,w.L)().navbar.items;return r.createElement("ul",{className:"menu__list"},t.map(((t,n)=>r.createElement(Pi,(0,s.Z)({mobile:!0},t,{onClick:()=>e.toggle(),key:n})))))}function Ti(e){return r.createElement("button",(0,s.Z)({},e,{type:"button",className:"clean-btn navbar-sidebar__back"}),r.createElement(u.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"},"\u2190 Back to main menu"))}function Ii(){const e=0===(0,w.L)().navbar.items.length,t=D();return r.createElement(r.Fragment,null,!e&&r.createElement(Ti,{onClick:()=>t.hide()}),t.content)}function Ai(){const e=(0,T.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?r.createElement(M,{header:r.createElement(W,null),primaryMenu:r.createElement(Ci,null),secondaryMenu:r.createElement(Ii,null)}):null}const Li={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Ri(e){return r.createElement("div",(0,s.Z)({role:"presentation"},e,{className:(0,i.Z)("navbar-sidebar__backdrop",e.className)}))}function Ni(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:a}}=(0,w.L)(),o=(0,T.e)(),{navbarRef:s,isNavbarVisible:l}=function(e){const[t,n]=(0,r.useState)(e),i=(0,r.useRef)(!1),a=(0,r.useRef)(0),o=(0,r.useCallback)((e=>{null!==e&&(a.current=e.getBoundingClientRect().height)}),[]);return(0,I.RF)(((t,r)=>{let{scrollY:o}=t;if(!e)return;if(o=s?n(!1):o+u{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return i.current=!0,void n(!1);n(!0)})),{navbarRef:o,isNavbarVisible:t}}(n);return r.createElement("nav",{ref:s,"aria-label":(0,u.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,i.Z)("navbar","navbar--fixed-top",n&&[Li.navbarHideable,!l&&Li.navbarHidden],{"navbar--dark":"dark"===a,"navbar--primary":"primary"===a,"navbar-sidebar--show":o.shown})},t,r.createElement(Ri,{onClick:o.toggle}),r.createElement(Ai,null))}const ji="right";function Di(e){let{width:t=30,height:n=30,className:i,...a}=e;return r.createElement("svg",(0,s.Z)({className:i,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true"},a),r.createElement("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"}))}function Mi(){const{toggle:e,shown:t}=(0,T.e)();return r.createElement("button",{onClick:e,"aria-label":(0,u.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button"},r.createElement(Di,null))}const Fi={colorModeToggle:"colorModeToggle_DEke"};function Bi(e){let{items:t}=e;return r.createElement(r.Fragment,null,t.map(((e,t)=>r.createElement(Pi,(0,s.Z)({},e,{key:t})))))}function zi(e){let{left:t,right:n}=e;return r.createElement("div",{className:"navbar__inner"},r.createElement("div",{className:"navbar__items"},t),r.createElement("div",{className:"navbar__items navbar__items--right"},n))}function Ui(){const e=(0,T.e)(),t=(0,w.L)().navbar.items,[n,i]=function(e){function t(e){return"left"===(e.position??ji)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),a=t.find((e=>"search"===e.type));return r.createElement(zi,{left:r.createElement(r.Fragment,null,!e.disabled&&r.createElement(Mi,null),r.createElement(V,null),r.createElement(Bi,{items:n})),right:r.createElement(r.Fragment,null,r.createElement(Bi,{items:i}),r.createElement(G,{className:Fi.colorModeToggle}),!a&&r.createElement(wi,null,r.createElement(bi,null)))})}function qi(){return r.createElement(Ni,null,r.createElement(Ui,null))}function $i(e){let{item:t}=e;const{to:n,href:i,label:a,prependBaseUrlToHref:o,...l}=t,u=(0,Y.Z)(n),c=(0,Y.Z)(i,{forcePrependBaseUrl:!0});return r.createElement(K.Z,(0,s.Z)({className:"footer__link-item"},i?{href:o?c:i}:{to:u},l),a,i&&!(0,X.Z)(i)&&r.createElement(ee.Z,null))}function Hi(e){let{item:t}=e;return t.html?r.createElement("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement("li",{key:t.href??t.to,className:"footer__item"},r.createElement($i,{item:t}))}function Gi(e){let{column:t}=e;return r.createElement("div",{className:"col footer__col"},r.createElement("div",{className:"footer__title"},t.title),r.createElement("ul",{className:"footer__items clean-list"},t.items.map(((e,t)=>r.createElement(Hi,{key:t,item:e})))))}function Qi(e){let{columns:t}=e;return r.createElement("div",{className:"row footer__links"},t.map(((e,t)=>r.createElement(Gi,{key:t,column:e}))))}function Vi(){return r.createElement("span",{className:"footer__link-separator"},"\xb7")}function Zi(e){let{item:t}=e;return t.html?r.createElement("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement($i,{item:t})}function Wi(e){let{links:t}=e;return r.createElement("div",{className:"footer__links text--center"},r.createElement("div",{className:"footer__links"},t.map(((e,n)=>r.createElement(r.Fragment,{key:n},r.createElement(Zi,{item:e}),t.length!==n+1&&r.createElement(Vi,null))))))}function Ki(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?r.createElement(Qi,{columns:t}):r.createElement(Wi,{links:t})}var Yi=n(941);const Xi={footerLogoLink:"footerLogoLink_BH7S"};function Ji(e){let{logo:t}=e;const{withBaseUrl:n}=(0,Y.C)(),a={light:n(t.src),dark:n(t.srcDark??t.src)};return r.createElement(Yi.Z,{className:(0,i.Z)("footer__logo",t.className),alt:t.alt,sources:a,width:t.width,height:t.height,style:t.style})}function ea(e){let{logo:t}=e;return t.href?r.createElement(K.Z,{href:t.href,className:Xi.footerLogoLink,target:t.target},r.createElement(Ji,{logo:t})):r.createElement(Ji,{logo:t})}function ta(e){let{copyright:t}=e;return r.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function na(e){let{style:t,links:n,logo:a,copyright:o}=e;return r.createElement("footer",{className:(0,i.Z)("footer",{"footer--dark":"dark"===t})},r.createElement("div",{className:"container container-fluid"},n,(a||o)&&r.createElement("div",{className:"footer__bottom text--center"},a&&r.createElement("div",{className:"margin-bottom--sm"},a),o)))}function ra(){const{footer:e}=(0,w.L)();if(!e)return null;const{copyright:t,links:n,logo:i,style:a}=e;return r.createElement(na,{style:a,links:n&&n.length>0&&r.createElement(Ki,{links:n}),logo:i&&r.createElement(ea,{logo:i}),copyright:t&&r.createElement(ta,{copyright:t})})}const ia=r.memo(ra),aa=(0,A.Qc)([F.S,k.pl,I.OC,Ei.L5,o.VC,function(e){let{children:t}=e;return r.createElement(L.n2,null,r.createElement(T.M,null,r.createElement(N,null,t)))}]);function oa(e){let{children:t}=e;return r.createElement(aa,null,t)}function sa(e){let{error:t,tryAgain:n}=e;return r.createElement("main",{className:"container margin-vert--xl"},r.createElement("div",{className:"row"},r.createElement("div",{className:"col col--6 col--offset-3"},r.createElement("h1",{className:"hero__title"},r.createElement(u.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),r.createElement("p",null,t.message),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},r.createElement(u.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again when the page crashed"},"Try again"))))))}const la={mainWrapper:"mainWrapper_z2l0"};function ua(e){const{children:t,noFooter:n,wrapperClassName:s,title:l,description:u}=e;return(0,v.t)(),r.createElement(oa,null,r.createElement(o.d,{title:l,description:u}),r.createElement(y,null),r.createElement(C,null),r.createElement(qi,null),r.createElement("div",{id:d,className:(0,i.Z)(h.k.wrapper.main,la.mainWrapper,s)},r.createElement(a.Z,{fallback:e=>r.createElement(sa,e)},t)),!n&&r.createElement(ia,null))}},1327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(7462),i=n(7294),a=n(9960),o=n(4996),s=n(2263),l=n(6668),u=n(941);function c(e){let{logo:t,alt:n,imageClassName:r}=e;const a={light:(0,o.Z)(t.src),dark:(0,o.Z)(t.srcDark||t.src)},s=i.createElement(u.Z,{className:t.className,sources:a,height:t.height,width:t.width,alt:n,style:t.style});return r?i.createElement("div",{className:r},s):s}function d(e){const{siteConfig:{title:t}}=(0,s.Z)(),{navbar:{title:n,logo:u}}=(0,l.L)(),{imageClassName:d,titleClassName:p,...f}=e,m=(0,o.Z)(u?.href||"/"),g=n?"":t,h=u?.alt??g;return i.createElement(a.Z,(0,r.Z)({to:m},f,u?.target&&{target:u.target}),u&&i.createElement(c,{logo:u,alt:h,imageClassName:d}),null!=n&&i.createElement("b",{className:p},n))}},197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(7294),i=n(5742);function a(e){let{locale:t,version:n,tag:a}=e;const o=t;return r.createElement(i.Z,null,t&&r.createElement("meta",{name:"docusaurus_locale",content:t}),n&&r.createElement("meta",{name:"docusaurus_version",content:n}),a&&r.createElement("meta",{name:"docusaurus_tag",content:a}),o&&r.createElement("meta",{name:"docsearch:language",content:o}),n&&r.createElement("meta",{name:"docsearch:version",content:n}),a&&r.createElement("meta",{name:"docsearch:docusaurus_tag",content:a}))}},941:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(7462),i=n(7294),a=n(6010),o=n(2389),s=n(2949);const l={themedImage:"themedImage_ToTc","themedImage--light":"themedImage--light_HNdA","themedImage--dark":"themedImage--dark_i4oU"};function u(e){const t=(0,o.Z)(),{colorMode:n}=(0,s.I)(),{sources:u,className:c,alt:d,...p}=e,f=t?"dark"===n?["dark"]:["light"]:["light","dark"];return i.createElement(i.Fragment,null,f.map((e=>i.createElement("img",(0,r.Z)({key:e,src:u[e],alt:d,className:(0,a.Z)(l.themedImage,l[`themedImage--${e}`],c)},p)))))}},6043:(e,t,n)=>{"use strict";n.d(t,{u:()=>s,z:()=>g});var r=n(7462),i=n(7294),a=n(412);const o="ease-in-out";function s(e){let{initialState:t}=e;const[n,r]=(0,i.useState)(t??!1),a=(0,i.useCallback)((()=>{r((e=>!e))}),[]);return{collapsed:n,setCollapsed:r,toggleCollapsed:a}}const l={display:"none",overflow:"hidden",height:"0px"},u={display:"block",overflow:"visible",height:"auto"};function c(e,t){const n=t?l:u;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function d(e){let{collapsibleRef:t,collapsed:n,animation:r}=e;const a=(0,i.useRef)(!1);(0,i.useEffect)((()=>{const e=t.current;function i(){const t=e.scrollHeight,n=r?.duration??function(e){const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${r?.easing??o}`,height:`${t}px`}}function s(){const t=i();e.style.transition=t.transition,e.style.height=t.height}if(!a.current)return c(e,n),void(a.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(s(),requestAnimationFrame((()=>{e.style.height=l.height,e.style.overflow=l.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{s()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,r])}function p(e){if(!a.Z.canUseDOM)return e?l:u}function f(e){let{as:t="div",collapsed:n,children:r,animation:a,onCollapseTransitionEnd:o,className:s,disableSSRStyle:l}=e;const u=(0,i.useRef)(null);return d({collapsibleRef:u,collapsed:n,animation:a}),i.createElement(t,{ref:u,style:l?void 0:p(n),onTransitionEnd:e=>{"height"===e.propertyName&&(c(u.current,n),o?.(n))},className:s},r)}function m(e){let{collapsed:t,...n}=e;const[a,o]=(0,i.useState)(!t),[s,l]=(0,i.useState)(t);return(0,i.useLayoutEffect)((()=>{t||o(!0)}),[t]),(0,i.useLayoutEffect)((()=>{a&&l(t)}),[a,t]),a?i.createElement(f,(0,r.Z)({},n,{collapsed:s})):null}function g(e){let{lazy:t,...n}=e;const r=t?m:f;return i.createElement(r,n)}},9689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>m,pl:()=>f});var r=n(7294),i=n(2389),a=n(12),o=n(902),s=n(6668);const l=(0,a.WA)("docusaurus.announcement.dismiss"),u=(0,a.WA)("docusaurus.announcement.id"),c=()=>"true"===l.get(),d=e=>l.set(String(e)),p=r.createContext(null);function f(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,s.L)(),t=(0,i.Z)(),[n,a]=(0,r.useState)((()=>!!t&&c()));(0,r.useEffect)((()=>{a(c())}),[]);const o=(0,r.useCallback)((()=>{d(!0),a(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;u.set(t),r&&d(!1),!r&&c()||a(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:o})),[e,n,o])}();return r.createElement(p.Provider,{value:n},t)}function m(){const e=(0,r.useContext)(p);if(!e)throw new o.i6("AnnouncementBarProvider");return e}},2949:(e,t,n)=>{"use strict";n.d(t,{I:()=>h,S:()=>g});var r=n(7294),i=n(412),a=n(902),o=n(12),s=n(6668);const l=r.createContext(void 0),u="theme",c=(0,o.WA)(u),d={light:"light",dark:"dark"},p=e=>e===d.dark?d.dark:d.light,f=e=>i.Z.canUseDOM?p(document.documentElement.getAttribute("data-theme")):p(e),m=e=>{c.set(p(e))};function g(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,s.L)(),[i,a]=(0,r.useState)(f(e));(0,r.useEffect)((()=>{t&&c.del()}),[t]);const o=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:i=!0}=r;t?(a(t),i&&m(t)):(a(n?window.matchMedia("(prefers-color-scheme: dark)").matches?d.dark:d.light:e),c.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",p(i))}),[i]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==u)return;const t=c.get();null!==t&&o(p(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,o]);const l=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||l.current?l.current=window.matchMedia("print").matches:o(null)};return e.addListener(r),()=>e.removeListener(r)}),[o,t,n]),(0,r.useMemo)((()=>({colorMode:i,setColorMode:o,get isDarkTheme(){return i===d.dark},setLightTheme(){o(d.light)},setDarkTheme(){o(d.dark)}})),[i,o])}();return r.createElement(l.Provider,{value:n},t)}function h(){const e=(0,r.useContext)(l);if(null==e)throw new a.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},373:(e,t,n)=>{"use strict";n.d(t,{J:()=>b,L5:()=>h,Oh:()=>y});var r=n(7294),i=n(4104),a=n(9935),o=n(6668),s=n(3438),l=n(902),u=n(12);const c=e=>`docs-preferred-version-${e}`,d={save:(e,t,n)=>{(0,u.WA)(c(e),{persistence:t}).set(n)},read:(e,t)=>(0,u.WA)(c(e),{persistence:t}).get(),clear:(e,t)=>{(0,u.WA)(c(e),{persistence:t}).del()}},p=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const f=r.createContext(null);function m(){const e=(0,i._r)(),t=(0,o.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[a,s]=(0,r.useState)((()=>p(n)));(0,r.useEffect)((()=>{s(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function i(e){const t=d.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(d.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,i(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[a,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){d.save(e,t,n),s((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function g(e){let{children:t}=e;const n=m();return r.createElement(f.Provider,{value:n},t)}function h(e){let{children:t}=e;return s.cE?r.createElement(g,null,t):r.createElement(r.Fragment,null,t)}function v(){const e=(0,r.useContext)(f);if(!e)throw new l.i6("DocsPreferredVersionContextProvider");return e}function b(e){void 0===e&&(e=a.m);const t=(0,i.zh)(e),[n,o]=v(),{preferredVersionName:s}=n[e];return{preferredVersion:t.versions.find((e=>e.name===s))??null,savePreferredVersionName:(0,r.useCallback)((t=>{o.savePreferredVersion(e,t)}),[o,e])}}function y(){const e=(0,i._r)(),[t]=v();function n(n){const r=e[n],{preferredVersionName:i}=t[n];return r.versions.find((e=>e.name===i))??null}const r=Object.keys(e);return Object.fromEntries(r.map((e=>[e,n(e)])))}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>l,b:()=>s});var r=n(7294),i=n(902);const a=Symbol("EmptyContext"),o=r.createContext(a);function s(e){let{children:t,name:n,items:i}=e;const a=(0,r.useMemo)((()=>n&&i?{name:n,items:i}:null),[n,i]);return r.createElement(o.Provider,{value:a},t)}function l(){const e=(0,r.useContext)(o);if(e===a)throw new i.i6("DocsSidebarProvider");return e}},4477:(e,t,n)=>{"use strict";n.d(t,{E:()=>s,q:()=>o});var r=n(7294),i=n(902);const a=r.createContext(null);function o(e){let{children:t,version:n}=e;return r.createElement(a.Provider,{value:n},t)}function s(){const e=(0,r.useContext)(a);if(null===e)throw new i.i6("DocsVersionProvider");return e}},3163:(e,t,n)=>{"use strict";n.d(t,{M:()=>d,e:()=>p});var r=n(7294),i=n(3102),a=n(7524),o=n(1980),s=n(6668),l=n(902);const u=r.createContext(void 0);function c(){const e=function(){const e=(0,i.HY)(),{items:t}=(0,s.L)().navbar;return 0===t.length&&!e.component}(),t=(0,a.i)(),n=!e&&"mobile"===t,[l,u]=(0,r.useState)(!1);(0,o.Rb)((()=>{if(l)return u(!1),!1}));const c=(0,r.useCallback)((()=>{u((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&u(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:c,shown:l})),[e,n,c,l])}function d(e){let{children:t}=e;const n=c();return r.createElement(u.Provider,{value:n},t)}function p(){const e=r.useContext(u);if(void 0===e)throw new l.i6("NavbarMobileSidebarProvider");return e}},3102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>s,Zo:()=>l,n2:()=>o});var r=n(7294),i=n(902);const a=r.createContext(null);function o(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return r.createElement(a.Provider,{value:n},t)}function s(){const e=(0,r.useContext)(a);if(!e)throw new i.i6("NavbarSecondaryMenuContentProvider");return e[0]}function l(e){let{component:t,props:n}=e;const o=(0,r.useContext)(a);if(!o)throw new i.i6("NavbarSecondaryMenuContentProvider");const[,s]=o,l=(0,i.Ql)(n);return(0,r.useEffect)((()=>{s({component:t,props:l})}),[s,t,l]),(0,r.useEffect)((()=>()=>s({component:null,props:null})),[s]),null}},9727:(e,t,n)=>{"use strict";n.d(t,{h:()=>i,t:()=>a});var r=n(7294);const i="navigation-with-keyboard";function a(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(i),"mousedown"===e.type&&document.body.classList.remove(i)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(i),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},7524:(e,t,n)=>{"use strict";n.d(t,{i:()=>u});var r=n(7294),i=n(412);const a={desktop:"desktop",mobile:"mobile",ssr:"ssr"},o=996;function s(){return i.Z.canUseDOM?window.innerWidth>o?a.desktop:a.mobile:a.ssr}const l=!1;function u(){const[e,t]=(0,r.useState)((()=>l?"ssr":s()));return(0,r.useEffect)((()=>{function e(){t(s())}const n=l?window.setTimeout(e,1e3):void 0;return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e),clearTimeout(n)}}),[]),e}},5281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},3438:(e,t,n)=>{"use strict";n.d(t,{MN:()=>_,Wl:()=>m,_F:()=>b,cE:()=>p,hI:()=>x,jA:()=>g,lO:()=>k,oz:()=>S,s1:()=>w,vY:()=>E,xz:()=>f});var r=n(7294),i=n(6550),a=n(8790),o=n(4104),s=n(373),l=n(4477),u=n(1116),c=n(7392),d=n(8596);const p=!!o._r;function f(e){const t=(0,l.E)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function m(e){if(e.href)return e.href;for(const t of e.items){if("link"===t.type)return t.href;if("category"===t.type){const e=m(t);if(e)return e}}}function g(){const{pathname:e}=(0,i.TH)(),t=(0,u.V)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=y({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}const h=(e,t)=>void 0!==e&&(0,d.Mg)(e,t),v=(e,t)=>e.some((e=>b(e,t)));function b(e,t){return"link"===e.type?h(e.href,t):"category"===e.type&&(h(e.href,t)||v(e.items,t))}function y(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const i=[];return function e(t){for(const a of t)if("category"===a.type&&((0,d.Mg)(a.href,n)||e(a.items))||"link"===a.type&&(0,d.Mg)(a.href,n)){return r&&"category"!==a.type||i.unshift(a),!0}return!1}(t),i}function w(){const e=(0,u.V)(),{pathname:t}=(0,i.TH)(),n=(0,o.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?y({sidebarItems:e.items,pathname:t}):null}function k(e){const{activeVersion:t}=(0,o.Iw)(e),{preferredVersion:n}=(0,s.J)(e),i=(0,o.yW)(e);return(0,r.useMemo)((()=>(0,c.j)([t,n,i].filter(Boolean))),[t,n,i])}function S(e,t){const n=k(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\n Available sidebar ids are:\n - ${Object.keys(t).join("\n- ")}`);return r[1]}),[e,n])}function E(e,t){const n=k(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`DocNavbarItem: couldn't find any doc with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,c.j)(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function x(e){let{route:t,versionMetadata:n}=e;const r=(0,i.TH)(),o=t.routes,s=o.find((e=>(0,i.LX)(r.pathname,e)));if(!s)return null;const l=s.sidebar,u=l?n.docsSidebars[l]:void 0;return{docElement:(0,a.H)(o),sidebarName:l,sidebarItems:u}}function _(e){return e.filter((e=>"category"!==e.type||!!m(e)))}},1980:(e,t,n)=>{"use strict";n.d(t,{Rb:()=>s,_X:()=>l});var r=n(7294),i=n(6550),a=n(1688),o=n(902);function s(e){!function(e){const t=(0,i.k6)(),n=(0,o.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}function l(e){return function(e){const t=(0,i.k6)();return(0,a.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}},7392:(e,t,n)=>{"use strict";function r(e,t){return void 0===t&&(t=(e,t)=>e===t),e.filter(((n,r)=>e.findIndex((e=>t(e,n)))!==r))}function i(e){return Array.from(new Set(e))}n.d(t,{j:()=>i,l:()=>r})},1944:(e,t,n)=>{"use strict";n.d(t,{FG:()=>p,d:()=>c,VC:()=>f});var r=n(7294),i=n(6010),a=n(5742),o=n(226);function s(){const e=r.useContext(o._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var l=n(4996),u=n(2263);function c(e){let{title:t,description:n,keywords:i,image:o,children:s}=e;const c=function(e){const{siteConfig:t}=(0,u.Z)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,l.C)(),p=o?d(o,{absolute:!0}):void 0;return r.createElement(a.Z,null,t&&r.createElement("title",null,c),t&&r.createElement("meta",{property:"og:title",content:c}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),i&&r.createElement("meta",{name:"keywords",content:Array.isArray(i)?i.join(","):i}),p&&r.createElement("meta",{property:"og:image",content:p}),p&&r.createElement("meta",{name:"twitter:image",content:p}),s)}const d=r.createContext(void 0);function p(e){let{className:t,children:n}=e;const o=r.useContext(d),s=(0,i.Z)(o,t);return r.createElement(d.Provider,{value:s},r.createElement(a.Z,null,r.createElement("html",{className:s})),n)}function f(e){let{children:t}=e;const n=s(),a=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const o=`plugin-id-${n.plugin.id}`;return r.createElement(p,{className:(0,i.Z)(a,o)},t)}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>o,Qc:()=>u,Ql:()=>l,i6:()=>s,zX:()=>a});var r=n(7294);const i=n(412).Z.canUseDOM?r.useLayoutEffect:r.useEffect;function a(e){const t=(0,r.useRef)(e);return i((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function o(e){const t=(0,r.useRef)();return i((()=>{t.current=e})),t.current}class s extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function l(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function u(e){return t=>{let{children:n}=t;return r.createElement(r.Fragment,null,e.reduceRight(((e,t)=>r.createElement(t,null,e)),n))}}},8596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>o,Ns:()=>s});var r=n(7294),i=n(723),a=n(2263);function o(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function s(){const{baseUrl:e}=(0,a.Z)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function i(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(i).flatMap((e=>e.routes??[])))}(n)}({routes:i.Z,baseUrl:e})),[e])}},2466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>f,OC:()=>l,RF:()=>d,o5:()=>p});var r=n(7294),i=n(412),a=n(2389),o=n(902);const s=r.createContext(void 0);function l(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return r.createElement(s.Provider,{value:n},t)}function u(){const e=(0,r.useContext)(s);if(null==e)throw new o.i6("ScrollControllerProvider");return e}const c=()=>i.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function d(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=u(),i=(0,r.useRef)(c()),a=(0,o.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=c();a(e,i.current),i.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[a,n,...t])}function p(){const e=u(),t=function(){const e=(0,r.useRef)({elem:null,top:0}),t=(0,r.useCallback)((t=>{e.current={elem:t,top:t.getBoundingClientRect().top}}),[]),n=(0,r.useCallback)((()=>{const{current:{elem:t,top:n}}=e;if(!t)return{restored:!1};const r=t.getBoundingClientRect().top-n;return r&&window.scrollBy({left:0,top:r}),e.current={elem:null,top:0},{restored:0!==r}}),[]);return(0,r.useMemo)((()=>({save:t,restore:n})),[n,t])}(),n=(0,r.useRef)(void 0),i=(0,r.useCallback)((r=>{t.save(r),e.disableScrollEvents(),n.current=()=>{const{restored:r}=t.restore();if(n.current=void 0,r){const t=()=>{e.enableScrollEvents(),window.removeEventListener("scroll",t)};window.addEventListener("scroll",t)}else e.enableScrollEvents()}}),[e,t]);return(0,r.useLayoutEffect)((()=>{queueMicrotask((()=>n.current?.()))})),{blockElementScrollPositionUntilNextRender:i}}function f(){const e=(0,r.useRef)(null),t=(0,a.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const i=document.documentElement.scrollTop;(n&&i>e||!n&&it&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},3320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>o,_q:()=>l,os:()=>s});var r=n(4104),i=n(2263),a=n(373);const o="default";function s(e,t){return`docs-${e}-${t}`}function l(){const{i18n:e}=(0,i.Z)(),t=(0,r._r)(),n=(0,r.WS)(),l=(0,a.Oh)();const u=[o,...Object.keys(t).map((function(e){const r=n?.activePlugin.pluginId===e?n.activeVersion:void 0,i=l[e],a=t[e].versions.find((e=>e.isLast));return s(e,(r??i??a).name)}))];return{locale:e.currentLocale,tags:u}}},12:(e,t,n)=>{"use strict";n.d(t,{Nk:()=>d,WA:()=>c});var r=n(7294),i=n(1688);const a="localStorage";function o(e){let{key:t,oldValue:n,newValue:r,storage:i}=e;if(n===r)return;const a=document.createEvent("StorageEvent");a.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,i),window.dispatchEvent(a)}function s(e){if(void 0===e&&(e=a),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,l||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),l=!0),null}var t}let l=!1;const u={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function c(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=s(t?.persistence);return null===n?u:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const r=n.getItem(e);n.setItem(e,t),o({key:e,oldValue:r,newValue:t,storage:n})}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),o({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const r=r=>{r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}catch(r){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,r),()=>{}}}}}function d(e,t){const n=(0,r.useRef)((()=>null===e?u:c(e,t))).current(),a=(0,r.useCallback)((e=>"undefined"==typeof window?()=>{}:n.listen(e)),[n]);return[(0,i.useSyncExternalStore)(a,(()=>"undefined"==typeof window?null:n.get()),(()=>null)),n]}},4711:(e,t,n)=>{"use strict";n.d(t,{l:()=>a});var r=n(2263),i=n(6550);function a(){const{siteConfig:{baseUrl:e,url:t},i18n:{defaultLocale:n,currentLocale:a}}=(0,r.Z)(),{pathname:o}=(0,i.TH)(),s=a===n?e:e.replace(`/${a}/`,"/"),l=o.replace(e,"");return{createUrl:function(e){let{locale:r,fullyQualified:i}=e;return`${i?t:""}${function(e){return e===n?`${s}`:`${s}${e}/`}(r)}${l}`}}}},5936:(e,t,n)=>{"use strict";n.d(t,{S:()=>o});var r=n(7294),i=n(6550),a=n(902);function o(e){const t=(0,i.TH)(),n=(0,a.D9)(t),o=(0,a.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&o({location:t,previousLocation:n})}),[o,t,n])}},6668:(e,t,n)=>{"use strict";n.d(t,{L:()=>i});var r=n(2263);function i(){return(0,r.Z)().siteConfig.themeConfig}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[i]=e.split(/[#?]/),a="/"===i||i===r?i:(o=i,n?function(e){return e.endsWith("/")?e:`${e}/`}(o):function(e){return e.endsWith("/")?e.slice(0,-1):e}(o));var o;return e.replace(i,a)}},8780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="post-content";var i=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(i).default}})},6010:(e,t,n)=>{"use strict";function r(e){var t,n,i="";if("string"==typeof e||"number"==typeof e)i+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;ti});const i=function(){for(var e,t,n=0,i="";n{"use strict";n.d(t,{lX:()=>w,q_:()=>O,ob:()=>f,PP:()=>C,Ep:()=>p});var r=n(7462);function i(e){return"/"===e.charAt(0)}function a(e,t){for(var n=t,r=n+1,i=e.length;r=0;p--){var f=o[p];"."===f?a(o,p):".."===f?(a(o,p),d++):d&&(a(o,p),d--)}if(!u)for(;d--;d)o.unshift("..");!u||""===o[0]||o[0]&&i(o[0])||o.unshift("");var m=o.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var s=n(8776);function l(e){return"/"===e.charAt(0)?e:"/"+e}function u(e){return"/"===e.charAt(0)?e.substr(1):e}function c(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,r=e.hash,i=t||"/";return n&&"?"!==n&&(i+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(i+="#"===r.charAt(0)?r:"#"+r),i}function f(e,t,n,i){var a;"string"==typeof e?(a=function(e){var t=e||"/",n="",r="",i=t.indexOf("#");-1!==i&&(r=t.substr(i),t=t.substr(0,i));var a=t.indexOf("?");return-1!==a&&(n=t.substr(a),t=t.substr(0,a)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),a.state=t):(void 0===(a=(0,r.Z)({},e)).pathname&&(a.pathname=""),a.search?"?"!==a.search.charAt(0)&&(a.search="?"+a.search):a.search="",a.hash?"#"!==a.hash.charAt(0)&&(a.hash="#"+a.hash):a.hash="",void 0!==t&&void 0===a.state&&(a.state=t));try{a.pathname=decodeURI(a.pathname)}catch(s){throw s instanceof URIError?new URIError('Pathname "'+a.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):s}return n&&(a.key=n),i?a.pathname?"/"!==a.pathname.charAt(0)&&(a.pathname=o(a.pathname,i.pathname)):a.pathname=i.pathname:a.pathname||(a.pathname="/"),a}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,i){if(null!=e){var a="function"==typeof e?e(t,n):e;"string"==typeof a?"function"==typeof r?r(a,i):i(!0):i(!1!==a)}else i(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,i):n.push(i),d({action:r,location:i,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",i=f(e,t,g(),w.location);c.confirmTransitionTo(i,r,n,(function(e){e&&(w.entries[w.index]=i,d({action:r,location:i}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t{"use strict";var r=n(9864),i={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},a={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},o={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function l(e){return r.isMemo(e)?o:s[e.$$typeof]||i}s[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[r.Memo]=o;var u=Object.defineProperty,c=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var i=f(n);i&&i!==m&&e(t,i,r)}var o=c(n);d&&(o=o.concat(d(n)));for(var s=l(t),g=l(n),h=0;h{"use strict";e.exports=function(e,t,n,r,i,a,o,s){if(!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var u=[n,r,i,a,o,s],c=0;(l=new Error(t.replace(/%s/g,(function(){return u[c++]})))).name="Invariant Violation"}throw l.framesToPop=1,l}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},813:function(e){e.exports=function(){"use strict";var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},t=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},n=function(){function e(e,t){for(var n=0;n1&&void 0!==arguments[1])||arguments[1],i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:5e3;t(this,e),this.ctx=n,this.iframes=r,this.exclude=i,this.iframesTimeout=a}return n(e,[{key:"getContexts",value:function(){var e=[];return(void 0!==this.ctx&&this.ctx?NodeList.prototype.isPrototypeOf(this.ctx)?Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?this.ctx:"string"==typeof this.ctx?Array.prototype.slice.call(document.querySelectorAll(this.ctx)):[this.ctx]:[]).forEach((function(t){var n=e.filter((function(e){return e.contains(t)})).length>0;-1!==e.indexOf(t)||n||e.push(t)})),e}},{key:"getIframeContents",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){},r=void 0;try{var i=e.contentWindow;if(r=i.document,!i||!r)throw new Error("iframe inaccessible")}catch(a){n()}r&&t(r)}},{key:"isIframeBlank",value:function(e){var t="about:blank",n=e.getAttribute("src").trim();return e.contentWindow.location.href===t&&n!==t&&n}},{key:"observeIframeLoad",value:function(e,t,n){var r=this,i=!1,a=null,o=function o(){if(!i){i=!0,clearTimeout(a);try{r.isIframeBlank(e)||(e.removeEventListener("load",o),r.getIframeContents(e,t,n))}catch(s){n()}}};e.addEventListener("load",o),a=setTimeout(o,this.iframesTimeout)}},{key:"onIframeReady",value:function(e,t,n){try{"complete"===e.contentWindow.document.readyState?this.isIframeBlank(e)?this.observeIframeLoad(e,t,n):this.getIframeContents(e,t,n):this.observeIframeLoad(e,t,n)}catch(r){n()}}},{key:"waitForIframes",value:function(e,t){var n=this,r=0;this.forEachIframe(e,(function(){return!0}),(function(e){r++,n.waitForIframes(e.querySelector("html"),(function(){--r||t()}))}),(function(e){e||t()}))}},{key:"forEachIframe",value:function(t,n,r){var i=this,a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},o=t.querySelectorAll("iframe"),s=o.length,l=0;o=Array.prototype.slice.call(o);var u=function(){--s<=0&&a(l)};s||u(),o.forEach((function(t){e.matches(t,i.exclude)?u():i.onIframeReady(t,(function(e){n(t)&&(l++,r(e)),u()}),u)}))}},{key:"createIterator",value:function(e,t,n){return document.createNodeIterator(e,t,n,!1)}},{key:"createInstanceOnIframe",value:function(t){return new e(t.querySelector("html"),this.iframes)}},{key:"compareNodeIframe",value:function(e,t,n){if(e.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_PRECEDING){if(null===t)return!0;if(t.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_FOLLOWING)return!0}return!1}},{key:"getIteratorNode",value:function(e){var t=e.previousNode();return{prevNode:t,node:(null===t||e.nextNode())&&e.nextNode()}}},{key:"checkIframeFilter",value:function(e,t,n,r){var i=!1,a=!1;return r.forEach((function(e,t){e.val===n&&(i=t,a=e.handled)})),this.compareNodeIframe(e,t,n)?(!1!==i||a?!1===i||a||(r[i].handled=!0):r.push({val:n,handled:!0}),!0):(!1===i&&r.push({val:n,handled:!1}),!1)}},{key:"handleOpenIframes",value:function(e,t,n,r){var i=this;e.forEach((function(e){e.handled||i.getIframeContents(e.val,(function(e){i.createInstanceOnIframe(e).forEachNode(t,n,r)}))}))}},{key:"iterateThroughNodes",value:function(e,t,n,r,i){for(var a=this,o=this.createIterator(t,e,r),s=[],l=[],u=void 0,c=void 0,d=function(){var e=a.getIteratorNode(o);return c=e.prevNode,u=e.node};d();)this.iframes&&this.forEachIframe(t,(function(e){return a.checkIframeFilter(u,c,e,s)}),(function(t){a.createInstanceOnIframe(t).forEachNode(e,(function(e){return l.push(e)}),r)})),l.push(u);l.forEach((function(e){n(e)})),this.iframes&&this.handleOpenIframes(s,e,n,r),i()}},{key:"forEachNode",value:function(e,t,n){var r=this,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},a=this.getContexts(),o=a.length;o||i(),a.forEach((function(a){var s=function(){r.iterateThroughNodes(e,a,t,n,(function(){--o<=0&&i()}))};r.iframes?r.waitForIframes(a,s):s()}))}}],[{key:"matches",value:function(e,t){var n="string"==typeof t?[t]:t,r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(r){var i=!1;return n.every((function(t){return!r.call(e,t)||(i=!0,!1)})),i}return!1}}]),e}(),a=function(){function a(e){t(this,a),this.ctx=e,this.ie=!1;var n=window.navigator.userAgent;(n.indexOf("MSIE")>-1||n.indexOf("Trident")>-1)&&(this.ie=!0)}return n(a,[{key:"log",value:function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"debug",r=this.opt.log;this.opt.debug&&"object"===(void 0===r?"undefined":e(r))&&"function"==typeof r[n]&&r[n]("mark.js: "+t)}},{key:"escapeStr",value:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}},{key:"createRegExp",value:function(e){return"disabled"!==this.opt.wildcards&&(e=this.setupWildcardsRegExp(e)),e=this.escapeStr(e),Object.keys(this.opt.synonyms).length&&(e=this.createSynonymsRegExp(e)),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),this.opt.diacritics&&(e=this.createDiacriticsRegExp(e)),e=this.createMergedBlanksRegExp(e),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.createJoinersRegExp(e)),"disabled"!==this.opt.wildcards&&(e=this.createWildcardsRegExp(e)),e=this.createAccuracyRegExp(e)}},{key:"createSynonymsRegExp",value:function(e){var t=this.opt.synonyms,n=this.opt.caseSensitive?"":"i",r=this.opt.ignoreJoiners||this.opt.ignorePunctuation.length?"\0":"";for(var i in t)if(t.hasOwnProperty(i)){var a=t[i],o="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(i):this.escapeStr(i),s="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(a):this.escapeStr(a);""!==o&&""!==s&&(e=e.replace(new RegExp("("+this.escapeStr(o)+"|"+this.escapeStr(s)+")","gm"+n),r+"("+this.processSynomyms(o)+"|"+this.processSynomyms(s)+")"+r))}return e}},{key:"processSynomyms",value:function(e){return(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),e}},{key:"setupWildcardsRegExp",value:function(e){return(e=e.replace(/(?:\\)*\?/g,(function(e){return"\\"===e.charAt(0)?"?":"\x01"}))).replace(/(?:\\)*\*/g,(function(e){return"\\"===e.charAt(0)?"*":"\x02"}))}},{key:"createWildcardsRegExp",value:function(e){var t="withSpaces"===this.opt.wildcards;return e.replace(/\u0001/g,t?"[\\S\\s]?":"\\S?").replace(/\u0002/g,t?"[\\S\\s]*?":"\\S*")}},{key:"setupIgnoreJoinersRegExp",value:function(e){return e.replace(/[^(|)\\]/g,(function(e,t,n){var r=n.charAt(t+1);return/[(|)\\]/.test(r)||""===r?e:e+"\0"}))}},{key:"createJoinersRegExp",value:function(e){var t=[],n=this.opt.ignorePunctuation;return Array.isArray(n)&&n.length&&t.push(this.escapeStr(n.join(""))),this.opt.ignoreJoiners&&t.push("\\u00ad\\u200b\\u200c\\u200d"),t.length?e.split(/\u0000+/).join("["+t.join("")+"]*"):e}},{key:"createDiacriticsRegExp",value:function(e){var t=this.opt.caseSensitive?"":"i",n=this.opt.caseSensitive?["a\xe0\xe1\u1ea3\xe3\u1ea1\u0103\u1eb1\u1eaf\u1eb3\u1eb5\u1eb7\xe2\u1ea7\u1ea5\u1ea9\u1eab\u1ead\xe4\xe5\u0101\u0105","A\xc0\xc1\u1ea2\xc3\u1ea0\u0102\u1eb0\u1eae\u1eb2\u1eb4\u1eb6\xc2\u1ea6\u1ea4\u1ea8\u1eaa\u1eac\xc4\xc5\u0100\u0104","c\xe7\u0107\u010d","C\xc7\u0106\u010c","d\u0111\u010f","D\u0110\u010e","e\xe8\xe9\u1ebb\u1ebd\u1eb9\xea\u1ec1\u1ebf\u1ec3\u1ec5\u1ec7\xeb\u011b\u0113\u0119","E\xc8\xc9\u1eba\u1ebc\u1eb8\xca\u1ec0\u1ebe\u1ec2\u1ec4\u1ec6\xcb\u011a\u0112\u0118","i\xec\xed\u1ec9\u0129\u1ecb\xee\xef\u012b","I\xcc\xcd\u1ec8\u0128\u1eca\xce\xcf\u012a","l\u0142","L\u0141","n\xf1\u0148\u0144","N\xd1\u0147\u0143","o\xf2\xf3\u1ecf\xf5\u1ecd\xf4\u1ed3\u1ed1\u1ed5\u1ed7\u1ed9\u01a1\u1edf\u1ee1\u1edb\u1edd\u1ee3\xf6\xf8\u014d","O\xd2\xd3\u1ece\xd5\u1ecc\xd4\u1ed2\u1ed0\u1ed4\u1ed6\u1ed8\u01a0\u1ede\u1ee0\u1eda\u1edc\u1ee2\xd6\xd8\u014c","r\u0159","R\u0158","s\u0161\u015b\u0219\u015f","S\u0160\u015a\u0218\u015e","t\u0165\u021b\u0163","T\u0164\u021a\u0162","u\xf9\xfa\u1ee7\u0169\u1ee5\u01b0\u1eeb\u1ee9\u1eed\u1eef\u1ef1\xfb\xfc\u016f\u016b","U\xd9\xda\u1ee6\u0168\u1ee4\u01af\u1eea\u1ee8\u1eec\u1eee\u1ef0\xdb\xdc\u016e\u016a","y\xfd\u1ef3\u1ef7\u1ef9\u1ef5\xff","Y\xdd\u1ef2\u1ef6\u1ef8\u1ef4\u0178","z\u017e\u017c\u017a","Z\u017d\u017b\u0179"]:["a\xe0\xe1\u1ea3\xe3\u1ea1\u0103\u1eb1\u1eaf\u1eb3\u1eb5\u1eb7\xe2\u1ea7\u1ea5\u1ea9\u1eab\u1ead\xe4\xe5\u0101\u0105A\xc0\xc1\u1ea2\xc3\u1ea0\u0102\u1eb0\u1eae\u1eb2\u1eb4\u1eb6\xc2\u1ea6\u1ea4\u1ea8\u1eaa\u1eac\xc4\xc5\u0100\u0104","c\xe7\u0107\u010dC\xc7\u0106\u010c","d\u0111\u010fD\u0110\u010e","e\xe8\xe9\u1ebb\u1ebd\u1eb9\xea\u1ec1\u1ebf\u1ec3\u1ec5\u1ec7\xeb\u011b\u0113\u0119E\xc8\xc9\u1eba\u1ebc\u1eb8\xca\u1ec0\u1ebe\u1ec2\u1ec4\u1ec6\xcb\u011a\u0112\u0118","i\xec\xed\u1ec9\u0129\u1ecb\xee\xef\u012bI\xcc\xcd\u1ec8\u0128\u1eca\xce\xcf\u012a","l\u0142L\u0141","n\xf1\u0148\u0144N\xd1\u0147\u0143","o\xf2\xf3\u1ecf\xf5\u1ecd\xf4\u1ed3\u1ed1\u1ed5\u1ed7\u1ed9\u01a1\u1edf\u1ee1\u1edb\u1edd\u1ee3\xf6\xf8\u014dO\xd2\xd3\u1ece\xd5\u1ecc\xd4\u1ed2\u1ed0\u1ed4\u1ed6\u1ed8\u01a0\u1ede\u1ee0\u1eda\u1edc\u1ee2\xd6\xd8\u014c","r\u0159R\u0158","s\u0161\u015b\u0219\u015fS\u0160\u015a\u0218\u015e","t\u0165\u021b\u0163T\u0164\u021a\u0162","u\xf9\xfa\u1ee7\u0169\u1ee5\u01b0\u1eeb\u1ee9\u1eed\u1eef\u1ef1\xfb\xfc\u016f\u016bU\xd9\xda\u1ee6\u0168\u1ee4\u01af\u1eea\u1ee8\u1eec\u1eee\u1ef0\xdb\xdc\u016e\u016a","y\xfd\u1ef3\u1ef7\u1ef9\u1ef5\xffY\xdd\u1ef2\u1ef6\u1ef8\u1ef4\u0178","z\u017e\u017c\u017aZ\u017d\u017b\u0179"],r=[];return e.split("").forEach((function(i){n.every((function(n){if(-1!==n.indexOf(i)){if(r.indexOf(n)>-1)return!1;e=e.replace(new RegExp("["+n+"]","gm"+t),"["+n+"]"),r.push(n)}return!0}))})),e}},{key:"createMergedBlanksRegExp",value:function(e){return e.replace(/[\s]+/gim,"[\\s]+")}},{key:"createAccuracyRegExp",value:function(e){var t=this,n="!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~\xa1\xbf",r=this.opt.accuracy,i="string"==typeof r?r:r.value,a="string"==typeof r?[]:r.limiters,o="";switch(a.forEach((function(e){o+="|"+t.escapeStr(e)})),i){case"partially":default:return"()("+e+")";case"complementary":return"()([^"+(o="\\s"+(o||this.escapeStr(n)))+"]*"+e+"[^"+o+"]*)";case"exactly":return"(^|\\s"+o+")("+e+")(?=$|\\s"+o+")"}}},{key:"getSeparatedKeywords",value:function(e){var t=this,n=[];return e.forEach((function(e){t.opt.separateWordSearch?e.split(" ").forEach((function(e){e.trim()&&-1===n.indexOf(e)&&n.push(e)})):e.trim()&&-1===n.indexOf(e)&&n.push(e)})),{keywords:n.sort((function(e,t){return t.length-e.length})),length:n.length}}},{key:"isNumeric",value:function(e){return Number(parseFloat(e))==e}},{key:"checkRanges",value:function(e){var t=this;if(!Array.isArray(e)||"[object Object]"!==Object.prototype.toString.call(e[0]))return this.log("markRanges() will only accept an array of objects"),this.opt.noMatch(e),[];var n=[],r=0;return e.sort((function(e,t){return e.start-t.start})).forEach((function(e){var i=t.callNoMatchOnInvalidRanges(e,r),a=i.start,o=i.end;i.valid&&(e.start=a,e.length=o-a,n.push(e),r=o)})),n}},{key:"callNoMatchOnInvalidRanges",value:function(e,t){var n=void 0,r=void 0,i=!1;return e&&void 0!==e.start?(r=(n=parseInt(e.start,10))+parseInt(e.length,10),this.isNumeric(e.start)&&this.isNumeric(e.length)&&r-t>0&&r-n>0?i=!0:(this.log("Ignoring invalid or overlapping range: "+JSON.stringify(e)),this.opt.noMatch(e))):(this.log("Ignoring invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:n,end:r,valid:i}}},{key:"checkWhitespaceRanges",value:function(e,t,n){var r=void 0,i=!0,a=n.length,o=t-a,s=parseInt(e.start,10)-o;return(r=(s=s>a?a:s)+parseInt(e.length,10))>a&&(r=a,this.log("End range automatically set to the max value of "+a)),s<0||r-s<0||s>a||r>a?(i=!1,this.log("Invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)):""===n.substring(s,r).replace(/\s+/g,"")&&(i=!1,this.log("Skipping whitespace only range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:s,end:r,valid:i}}},{key:"getTextNodes",value:function(e){var t=this,n="",r=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,(function(e){r.push({start:n.length,end:(n+=e.textContent).length,node:e})}),(function(e){return t.matchesExclude(e.parentNode)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}),(function(){e({value:n,nodes:r})}))}},{key:"matchesExclude",value:function(e){return i.matches(e,this.opt.exclude.concat(["script","style","title","head","html"]))}},{key:"wrapRangeInTextNode",value:function(e,t,n){var r=this.opt.element?this.opt.element:"mark",i=e.splitText(t),a=i.splitText(n-t),o=document.createElement(r);return o.setAttribute("data-markjs","true"),this.opt.className&&o.setAttribute("class",this.opt.className),o.textContent=i.textContent,i.parentNode.replaceChild(o,i),a}},{key:"wrapRangeInMappedTextNode",value:function(e,t,n,r,i){var a=this;e.nodes.every((function(o,s){var l=e.nodes[s+1];if(void 0===l||l.start>t){if(!r(o.node))return!1;var u=t-o.start,c=(n>o.end?o.end:n)-o.start,d=e.value.substr(0,o.start),p=e.value.substr(c+o.start);if(o.node=a.wrapRangeInTextNode(o.node,u,c),e.value=d+p,e.nodes.forEach((function(t,n){n>=s&&(e.nodes[n].start>0&&n!==s&&(e.nodes[n].start-=c),e.nodes[n].end-=c)})),n-=c,i(o.node.previousSibling,o.start),!(n>o.end))return!1;t=o.end}return!0}))}},{key:"wrapMatches",value:function(e,t,n,r,i){var a=this,o=0===t?0:t+1;this.getTextNodes((function(t){t.nodes.forEach((function(t){t=t.node;for(var i=void 0;null!==(i=e.exec(t.textContent))&&""!==i[o];)if(n(i[o],t)){var s=i.index;if(0!==o)for(var l=1;l{"use strict";n.r(t)},2497:(e,t,n)=>{"use strict";n.r(t)},2295:(e,t,n)=>{"use strict";n.r(t)},4865:function(e,t,n){var r,i;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function i(e,t,n){return en?n:e}function a(e){return 100*(-1+e)}function o(e,t,n){var i;return(i="translate3d"===r.positionUsing?{transform:"translate3d("+a(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+a(e)+"%,0)"}:{"margin-left":a(e)+"%"}).transition="all "+t+"ms "+n,i}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=i(e,r.minimum,1),n.status=1===e?null:e;var a=n.render(!t),u=a.querySelector(r.barSelector),c=r.speed,d=r.easing;return a.offsetWidth,s((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),l(u,o(e,c,d)),1===e?(l(a,{transition:"none",opacity:1}),a.offsetWidth,setTimeout((function(){l(a,{transition:"all "+c+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),c)}),c)):setTimeout(t,c)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*i(Math.random()*t,.1,.95)),t=i(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");c(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var i,o=t.querySelector(r.barSelector),s=e?"-100":a(n.status||0),u=document.querySelector(r.parent);return l(o,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),r.showSpinner||(i=t.querySelector(r.spinnerSelector))&&f(i),u!=document.body&&c(u,"nprogress-custom-parent"),u.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var s=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),l=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,i=e.length,a=t.charAt(0).toUpperCase()+t.slice(1);i--;)if((r=e[i]+a)in n)return r;return t}function i(e){return e=n(e),t[e]||(t[e]=r(e))}function a(e,t,n){t=i(t),e.style[t]=n}return function(e,t){var n,r,i=arguments;if(2==i.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&a(e,n,r);else a(e,i[1],i[2])}}();function u(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function c(e,t){var n=p(e),r=n+t;u(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=p(e);u(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(i="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=i)},7418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(i){return!1}}()?Object.assign:function(e,i){for(var a,o,s=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),l=1;l{"use strict";n.d(t,{Z:()=>a});var r=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof i?new i(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=d.reach);E+=S.value.length,S=S.next){var x=S.value;if(t.length>e.length)return;if(!(x instanceof i)){var _,O=1;if(b){if(!(_=a(k,E,e,v))||_.index>=e.length)break;var P=_.index,C=_.index+_[0].length,T=E;for(T+=S.value.length;P>=T;)T+=(S=S.next).value.length;if(E=T-=S.value.length,S.value instanceof i)continue;for(var I=S;I!==t.tail&&(Td.reach&&(d.reach=N);var j=S.prev;if(L&&(j=l(t,j,L),E+=L.length),u(t,j,O),S=l(t,j,new i(p,h?r.tokenize(A,h):A,y,A)),R&&l(t,S,R),O>1){var D={cause:p+","+m,reach:N};o(e,t,n,S.prev,E,D),d&&D.reach>d.reach&&(d.reach=D.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function l(e,t,n){var r=t.next,i={value:n,prev:t,next:r};return t.next=i,r.prev=i,e.length++,i}function u(e,t,n){for(var r=t.next,i=0;i"+a.content+""},r}(),i=r;r.default=r,i.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},i.languages.markup.tag.inside["attr-value"].inside.entity=i.languages.markup.entity,i.languages.markup.doctype.inside["internal-subset"].inside=i.languages.markup,i.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(i.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:i.languages[t]},n.cdata=/^$/i;var r={"included-cdata":{pattern://i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:i.languages[t]};var a={};a[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},i.languages.insertBefore("markup","cdata",a)}}),Object.defineProperty(i.languages.markup.tag,"addAttribute",{value:function(e,t){i.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:i.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),i.languages.html=i.languages.markup,i.languages.mathml=i.languages.markup,i.languages.svg=i.languages.markup,i.languages.xml=i.languages.extend("markup",{}),i.languages.ssml=i.languages.xml,i.languages.atom=i.languages.xml,i.languages.rss=i.languages.xml,function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var i=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],a=r.variable[1].inside,o=0;o]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},i.languages.c=i.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),i.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),i.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},i.languages.c.string],char:i.languages.c.char,comment:i.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:i.languages.c}}}}),i.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete i.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(i),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(i),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+n.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[n,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}});var r={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},i={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:r,number:i,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:i})}(i),i.languages.javascript=i.languages.extend("clike",{"class-name":[i.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),i.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,i.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:i.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:i.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:i.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:i.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:i.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),i.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:i.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),i.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),i.languages.markup&&(i.languages.markup.tag.addInlined("script","javascript"),i.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),i.languages.js=i.languages.javascript,function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(i),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",i=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),a=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function o(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return"(?:"+i+"|"+a+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:o(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:o(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:o(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:o(a),lookbehind:!0,greedy:!0},number:{pattern:o(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(i),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(//g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,i=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),a=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+i+a+"(?:"+i+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+i+a+")(?:"+i+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+i+")"+a+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+i+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~))+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n",quot:'"'},l=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(i),i.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:i.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},i.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n0)){var s=p(/^\{$/,/^\}$/);if(-1===s)continue;for(var l=n;l=0&&f(u,"variable-input")}}}}function c(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,i=r.inside["interpolation-punctuation"],a=r.pattern.source;function o(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function s(e,t){return"___"+t.toUpperCase()+"_"+e+"___"}function l(t,n,r){var i={code:t,grammar:n,language:r};return e.hooks.run("before-tokenize",i),i.tokens=e.tokenize(i.code,i.grammar),e.hooks.run("after-tokenize",i),i.tokens}function u(t){var n={};n["interpolation-punctuation"]=i;var a=e.tokenize(t,n);if(3===a.length){var o=[1,1];o.push.apply(o,l(a[1],e.languages.javascript,"javascript")),a.splice.apply(a,o)}return new e.Token("interpolation",a,r.alias,t)}function c(t,n,r){var i=e.tokenize(t,{interpolation:{pattern:RegExp(a),lookbehind:!0}}),o=0,c={},d=l(i.map((function(e){if("string"==typeof e)return e;for(var n,i=e.content;-1!==t.indexOf(n=s(o++,r)););return c[n]=i,n})).join(""),n,r),p=Object.keys(c);return o=0,function e(t){for(var n=0;n=p.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var i=p[o],a="string"==typeof r?r:r.content,s=a.indexOf(i);if(-1!==s){++o;var l=a.substring(0,s),d=u(c[i]),f=a.substring(s+i.length),m=[];if(l&&m.push(l),m.push(d),f){var g=[f];e(g),m.push.apply(m,g)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(m)),n+=m.length-1):r.content=m}}else{var h=r.content;Array.isArray(h)?e(h):e([h])}}}(d),new e.Token(r,d,"language-"+r,t)}e.languages.javascript["template-string"]=[o("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),o("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),o("svg",/\bsvg/.source),o("markdown",/\b(?:markdown|md)/.source),o("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),o("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function p(e){return"string"==typeof e?e:Array.isArray(e)?e.map(p).join(""):p(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var r=0,i=n.length;r]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(i),function(e){function t(e,t){return RegExp(e.replace(//g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:(?:\s*,\s*(?:\*\s*as\s+|\{[^{}]*\}))?|\*\s*as\s+|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r*\.{3}(?:[^{}]|)*\})/.source;function a(e,t){return e=e.replace(//g,(function(){return n})).replace(//g,(function(){return r})).replace(//g,(function(){return i})),RegExp(e,t)}i=a(i).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=a(/<\/?(?:[\w.:-]+(?:+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|))?|))**\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:a(//.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:a(/=/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var o=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(o).join(""):""},s=function(t){for(var n=[],r=0;r0&&n[n.length-1].tagName===o(i.content[0].content[1])&&n.pop():"/>"===i.content[i.content.length-1].content||n.push({tagName:o(i.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===i.type&&"{"===i.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===i.type&&"}"===i.content?n[n.length-1].openedBraces--:a=!0),(a||"string"==typeof i)&&n.length>0&&0===n[n.length-1].openedBraces){var l=o(i);r0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(l=o(t[r-1])+l,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",l,null,l)}i.content&&"string"!=typeof i.content&&s(i.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||s(e.tokens)}))}(i),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],i=[];/^\w+$/.test(n)||i.push(/\w+/.exec(n)[0]),"diff"===n&&i.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:i,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(i),i.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},i.languages.go=i.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),i.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete i.languages.go["class-name"],function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,i,a){if(n.language===r){var o=n.tokenStack=[];n.code=n.code.replace(i,(function(e){if("function"==typeof a&&!a(e))return e;for(var i,s=o.length;-1!==n.code.indexOf(i=t(r,s));)++s;return o[s]=e,i})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var i=0,a=Object.keys(n.tokenStack);!function o(s){for(var l=0;l=a.length);l++){var u=s[l];if("string"==typeof u||u.content&&"string"==typeof u.content){var c=a[i],d=n.tokenStack[c],p="string"==typeof u?u:u.content,f=t(r,c),m=p.indexOf(f);if(m>-1){++i;var g=p.substring(0,m),h=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),v=p.substring(m+f.length),b=[];g&&b.push.apply(b,o([g])),b.push(h),v&&b.push.apply(b,o([v])),"string"==typeof u?s.splice.apply(s,[l,1].concat(b)):u.content=b}}else u.content&&o(u.content)}return s}(n.tokens)}}}})}(i),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(t){e.languages["markup-templating"].buildPlaceholders(t,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"handlebars")})),e.languages.hbs=e.languages.handlebars}(i),i.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},i.languages.webmanifest=i.languages.json,i.languages.less=i.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),i.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),i.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},i.languages.objectivec=i.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete i.languages.objectivec["class-name"],i.languages.objc=i.languages.objectivec,i.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},i.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},i.languages.python["string-interpolation"].inside.interpolation.inside.rest=i.languages.python,i.languages.py=i.languages.python,i.languages.reason=i.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),i.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete i.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(i),i.languages.scss=i.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),i.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),i.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),i.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),i.languages.scss.atrule.inside.rest=i.languages.scss,function(e){var t={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},n={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},r={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:n,punctuation:/[{}()\[\];:,]/};r.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:r}},r.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:r}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:r}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:r}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:r}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:r.interpolation}},rest:r}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:r.interpolation,comment:r.comment,punctuation:/[{},]/}},func:r.func,string:r.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:r.interpolation,punctuation:/[{}()\[\];:.]/}}(i),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(i),i.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/};const a=i},9901:e=>{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to WebPlatform.org documentation. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (.comment can become .namespace--comment) or replace them with your defined ones (like .editor__comment). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the highlightAll and highlightAllUnder methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},2885:(e,t,n)=>{const r=n(9901),i=n(9642),a=new Set;function o(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...a,...Object.keys(Prism.languages)];i(r,e,t).load((e=>{if(!(e in r.languages))return void(o.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(6500).resolve(t)],delete Prism.languages[e],n(6500)(t),a.add(e)}))}o.silent=!1,e.exports=o},6726:(e,t,n)=>{var r={"./":2885};function i(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}i.keys=function(){return Object.keys(r)},i.resolve=a,e.exports=i,i.id=6726},6500:(e,t,n)=>{var r={"./":2885};function i(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}i.keys=function(){return Object.keys(r)},i.resolve=a,e.exports=i,i.id=6500},9642:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n "));var s={},l=e[r];if(l){function u(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in s))for(var o in i(t,a),s[t]=!0,n[t])s[o]=!0}t(l.require,u),t(l.optional,u),t(l.modify,u)}n[r]=s,a.pop()}}return function(e){var t=n[e];return t||(i(e,r),t=n[e]),t}}function i(e){for(var t in e)return!0;return!1}return function(a,o,s){var l=function(e){var t={};for(var n in e){var r=e[n];for(var i in r)if("meta"!=i){var a=r[i];t[i]="string"==typeof a?{title:a}:a}}return t}(a),u=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var i in n={},e){var a=e[i];t(a&&a.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+i+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+i+" because it is a component.");n[t]=i}))}return n[r]||r}}(l);o=o.map(u),s=(s||[]).map(u);var c=n(o),d=n(s);o.forEach((function e(n){var r=l[n];t(r&&r.require,(function(t){t in d||(c[t]=!0,e(t))}))}));for(var p,f=r(l),m=c;i(m);){for(var g in p={},m){var h=l[g];t(h&&h.modify,(function(e){e in d&&(p[e]=!0)}))}for(var v in d)if(!(v in c))for(var b in f(v))if(b in c){p[v]=!0;break}for(var y in m=p)c[y]=!0}var w={getIds:function(){var e=[];return w.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,i){var a=i?i.series:void 0,o=i?i.parallel:e,s={},l={};function u(e){if(e in s)return s[e];l[e]=!0;var i,c=[];for(var d in t(e))d in n&&c.push(d);if(0===c.length)i=r(e);else{var p=o(c.map((function(e){var t=u(e);return delete l[e],t})));a?i=a(p,(function(){return r(e)})):r(e)}return s[e]=i}for(var c in n)u(c);var d=[];for(var p in l)d.push(s[p]);return o(d)}(f,c,t,n)}};return w}}();e.exports=t},2703:(e,t,n)=>{"use strict";var r=n(414);function i(){}function a(){}a.resetWarningCache=i,e.exports=function(){function e(e,t,n,i,a,o){if(o!==r){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:a,resetWarningCache:i};return n.PropTypes=n,n}},5697:(e,t,n)=>{e.exports=n(2703)()},414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:(e,t,n)=>{"use strict";var r=n(7294),i=n(7418),a=n(3840);function o(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n