PageSourceSearch

https://elastos-wiki.netlify.app/assets/js/a4306619.ce84c812.js

js elastos-wiki.netlify.app collected 2026-10-03 10:41:36 UTC 15,275 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[300],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>v});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 o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,i,r=function(e,t){if(null==e)return{};var n,i,r={},a=Object.keys(e);for(i=0;i<a.length;i++)n=a[i],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i<a.length;i++)n=a[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=i.createContext({}),l=function(e){var t=i.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return i.createElement(c.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},h=i.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(n),h=r,v=d["".concat(c,".").concat(h)]||d[h]||u[h]||a;return n?i.createElement(v,o(o({ref:t},p),{},{components:n})):i.createElement(v,o({ref:t},p))}));function v(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,o=new Array(a);o[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:r,o[1]=s;for(var l=2;l<a;l++)o[l]=n[l];return i.createElement.apply(null,o)}return i.createElement.apply(null,n)}h.displayName="MDXCreateElement"},1591:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>c,default:()=>v,frontMatter:()=>s,metadata:()=>l,toc:()=>d});var i=n(7462),r=n(3366),a=(n(7294),n(3905)),o=["components"],s={title:"Connect"},c=void 0,l={unversionedId:"develop/hive/connect",id:"develop/hive/connect",title:"Connect",description:"This guide is meant only as an introduction. For an exhaustive list of Hive methods, please visit the SDK documentation.",source:"@site/../docs/3.develop/hive/connect.md",sourceDirName:"3.develop/hive",slug:"/develop/hive/connect",permalink:"/develop/hive/connect",draft:!1,editUrl:"https://github.com/elastos/Elastos.Wiki/edit/master/website/../docs/3.develop/hive/connect.md",tags:[],version:"current",lastUpdatedBy:"racollette",lastUpdatedAt:1678819255,formattedLastUpdatedAt:"Mar 14, 2023",frontMatter:{title:"Connect"},sidebar:"developSidebar",previous:{title:"Working with DIDs in Other Wallets",permalink:"/develop/dids/metamask"},next:{title:"Write",permalink:"/develop/hive/write"}},p={},d=[{value:"Setup",id:"setup",level:2},{value:"Connect to Service",id:"connect-to-service",level:2},{value:"An Example Authenticiation Setup",id:"an-example-authenticiation-setup",level:3}],u={toc:d},h="wrapper";function v(e){var t=e.components,n=(0,r.Z)(e,o);return(0,a.kt)(h,(0,i.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"This guide is meant only as an introduction. For an exhaustive list of Hive methods, please visit the ",(0,a.kt)("a",{parentName:"p",href:"/sdk/hive/js/introduction"},"SDK documentation"),".")),(0,a.kt)("h2",{id:"setup"},"Setup"),(0,a.kt)("p",null,"To add the Hive JS SDK dependency to your project, run the following command from your source folder:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"npm i --save @elastosfoundation/hive-js-sdk\n")),(0,a.kt)("h2",{id:"connect-to-service"},"Connect to Service"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},'import {\n  AppContext,\n  AppContextProvider,\n  DIDResolverAlreadySetupException,\n  Vault as VaultServices,\n} from "@elastosfoundation/hive-js-sdk";\n\nlet vaultSubscriptionService: VaultSubscriptionService =\n  new VaultSubscriptionService(appContext, "[hiveNode address]");\nlet vaultInfo = await vaultSubscriptionService.subscribe();\n')),(0,a.kt)("p",null,"The same mechanics is used by VaultService, which provides all services to interact with Hive vaults."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},'let vaultServices = new VaultServices(appContext, "[hiveNode address]");\nlet scriptingService = vaultServices.getScriptingService();\nlet filesService = vaultServices.getFilesService();\nlet databaseService = vaultServices.getDatabaseService();\n')),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"There is also an HTTP API available to interact with Hive nodes. Find it ",(0,a.kt)("a",{parentName:"p",href:"https://apidocs.trinity-tech.io/hive-node-https-apis/"},"here"),".")),(0,a.kt)("h3",{id:"an-example-authenticiation-setup"},"An Example Authenticiation Setup"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"}
1,"import {\n  Claims, DIDDocument, JWTHeader, JWTParserBuilder, VerifiableCredential, VerifiablePresentation, Logger,\n} from '@elastosfoundation/did-js-sdk';\nimport { DID as ConnDID, DID } from '@elastosfoundation/elastos-connectivity-sdk-js';\nimport {\n  AppContext, AppContextProvider, DIDResolverAlreadySetupException, Vault as VaultServices,\n} from '@elastosfoundation/hive-js-sdk';\nimport dayjs from 'dayjs';\n\n/**\n * This is a sample hive auth helper that makes everything automatic for apps using hive to\n * authenticate on hive vaults.\n *\n * This authentication flow is for the connectivity SDK.\n */\nexport class BrowserConnectivitySDKHiveAuthHelper {\n  private didAccess: DID.DIDAccess;\n\n  private logger = new Logger('hiveauthhelper');\n\n  private dataDir = '/data/userDir/data/store/user'\n\n  constructor(didResolverUrl: string, protected appDid: string) {\n    try {\n      AppContext.setupResolver(didResolverUrl, this.dataDir);\n    } catch (e) {\n      if (e instanceof DIDResolverAlreadySetupException) {\n        // silent error, it's ok\n      } else {\n        this.logger.error('AppContext.setupResolver() exception:', e);\n      }\n    }\n\n    this.didAccess = new ConnDID.DIDAccess();\n  }\n\n  use(didAccess: ConnDID.DIDAccess): BrowserConnectivitySDKHiveAuthHelper {\n    this.didAccess = didAccess;\n\n    return this;\n  }\n\n  public async getAppContext(userDid: string, onAuthError?: (e: Error) => void): Promise<AppContext> {\n    const appInstanceDIDInfo = await this.didAccess.getOrCreateAppInstanceDID();\n\n    this.logger.log('hiveauthhelper', 'Getting app instance DID document');\n    const didDocument = await appInstanceDIDInfo.didStore.loadDid(appInstanceDIDInfo.did.toString());\n    this.logger.log('hiveauthhelper', 'Got app instance DID document. Now creating the Hive client', didDocument.toJSON());\n\n    const appContextProvider: AppContextProvider = {\n      getLocalDataDir: (): string => this.dataDir,\n      getAppInstanceDocument: (): Promise<DIDDocument> => Promise.resolve(didDocument),\n      getAuthorization: (authenticationChallengeJWtCode: string): Promise<string> => {\n        /**\n         * Called by the Hive plugin when a hive backend needs to authenticate the user and app.\n         * The returned data must be a verifiable presentation, signed by the app instance DID, and\n         * including a appid certification credential provided by the identity application.\n         */\n        this.logger.log('hiveauthhelper', 'Hive client authentication challenge callback is being called with token:', authenticationChallengeJWtCode);\n        try {\n          return this.handleVaultAuthenticationChallenge(authenticationChallengeJWtCode);\n        } catch (e) {\n          this.logger.error('hiveauthhelper', 'Exception in authentication handler:', e);\n          if (onAuthError) onAuthError(e);\n          return null;\n        }\n      },\n    };\n\n    const appContext = await AppContext.build(appContextProvider, userDid, this.appDid);\n    return appContext;\n  }\n\n  public async getVaultServices(userDid: string, providerAddress: string = null, onAuthError?: (e: Error) => void): Promise<VaultServices> {\n    const appContext = await this.getAppContext(userDid, onAuthError);\n    if (!providerAddress) { providerAddress = await AppContext.getProviderAddressByUserDid(userDid); } // TODO: cache, don't resolve every time\n    return new VaultServices(appContext, providerAddress);\n  }\n\n  /*\n  - auth challenge: JWT (iss, nonce)\n  - hive sdk:\n    - verify jwt\n    - extract iss and nonce\n  - consumer dapp:\n    - generate app instance presentation including nonce=nonce, realm=iss, app id credential\n    - embed presentation as JWT and return to the hive auth handler\n  - server side:\n    - verify jwt (using local app instance did public key provided before)\n    - generate access token\n  */\n  public handleVaultAuthenticationChallenge(jwtToken: string): Promise<string> {\n    return this.generateAuthPresentationJWT(jwtToken);\n  }\n\n  /**\n   * Generates a JWT token needed by hive vaults to authenticate users and app.\n   * That JWT contains a verifiable presentation that contains server challenge info, and the app id credential\n   * issued by the end user earlier.\n   */\n  private generateAuthPresentationJWT(authChallengeJwttoken: string): Promise<string> {\n    this.logger.log('hiveauthhelper', 'Starting process to generate hive auth presentation JWT');\n\n    return new Promise(async (resolve, reject) => {\n      // Parse, but verify on chain that this JWT is valid first\n      tr
1y {\n        const claims: Claims = (await new JWTParserBuilder().setAllowedClockSkewSeconds(300).build().parse(authChallengeJwttoken)).getBody();\n        if (claims == null) throw new Error('Invalid jwt token as authorization.');\n\n        // The request JWT must contain iss and nonce fields\n        if (!claims.getIssuer() || !claims.get('nonce')) {\n          reject('The received authentication JWT token does not contain iss or nonce');\n          return;\n        }\n\n        // Generate a hive authentication presentation and put the credential + back-end info such as nonce inside\n        const nonce = claims.get('nonce') as string;\n        const realm = claims.getIssuer() as string;\n\n        this.logger.log('hiveauthhelper', 'Getting app instance DID');\n        const appInstanceDIDResult = await this.didAccess.getOrCreateAppInstanceDID();\n        const appInstanceDID = appInstanceDIDResult.did;\n\n        const appInstanceDIDInfo = await this.didAccess.getExistingAppInstanceDIDInfo();\n\n        this.logger.log('hiveauthhelper', 'Getting app identity credential');\n        let appIdCredential = await this.didAccess.getExistingAppIdentityCredential();\n\n        if (!appIdCredential) {\n          this.logger.log('hiveauthhelper', 'Empty app id credential. Trying to generate a new one');\n\n          appIdCredential = await this.generateAppIdCredential();\n          if (!appIdCredential) {\n            this.logger.warn('hiveauthhelper', 'Failed to generate a new App ID credential');\n            resolve(null);\n            return;\n          }\n        }\n\n        // Create the presentation that includes hive back end challenge (nonce) and the app id credential.\n        this.logger.log('hiveauthhelper', 'Creating DID presentation response for Hive authentication challenge');\n        const builder = await VerifiablePresentation.createFor(appInstanceDID.toString(), null, appInstanceDIDResult.didStore);\n        const presentation = await builder\n          .credentials(appIdCredential)\n          .realm(realm)\n          .nonce(nonce)\n          .seal(appInstanceDIDInfo.storePassword);\n\n        if (presentation) {\n          // Generate the hive back end authentication JWT\n          this.logger.log('hiveauthhelper', 'Opening DID store to create a JWT for presentation:', presentation.toJSON());\n          const didStore = await DID.DIDHelper.openDidStore(appInstanceDIDInfo.storeId);\n\n          this.logger.log('hiveauthhelper', 'Loading DID document');\n          try {\n            const didDocument = await didStore.loadDid(appInstanceDIDInfo.didString);\n            this.logger.log('hiveauthhelper', 'App instance DID document', didDocument.toJSON());\n            this.logger.log('hiveauthhelper', 'Creating JWT');\n\n            try {\n              // Create JWT token with presentation.\n              // let info = await new ConDID.DIDAccess().getExistingAppInstanceDIDInfo();\n              const jwtToken = await didDocument.jwtBuilder().addHeader(JWTHeader.TYPE, JWTHeader.JWT_TYPE)\n                .addHeader('version', '1.0')\n                .setSubject('DIDAuthResponse')\n                .setAudience(claims.getIssuer())\n                .setIssuedAt(dayjs().unix())\n                .setExpiration(dayjs().add(3, 'month').unix())\n                .setNotBefore(dayjs().unix())\n                .claimsWithJson('presentation', presentation.toString(true))\n                .sign(appInstanceDIDInfo.storePassword);\n\n              this.logger.log('hiveauthhelper', 'JWT created for presentation:', jwtToken);\n              resolve(jwtToken);\n            } catch (err) {\n              reject(err);\n            }\n          } catch (err) {\n            reject(err);\n          }\n        } else {\n          reject('No presentation generated');\n        }\n      } catch (e) {\n        // Verification error?\n        // Could not verify the received JWT as valid - reject the authentication request by returning a null token\n        reject(`The received authentication JWT token signature cannot be verified or failed to verify: ${e.message}. Is the hive back-end DID published? Are you on the right network?`);\n      }\n    });\n  }\n\n  private generateAppIdCredential(): Promise<VerifiableCredential> {\n    // eslint-disable-next-line no-async-promise-executor, @typescript-eslint/no-misused-promises\n    return new Promise(async (resolve) => {\n      const storedAppInstanceDID = await this.didAccess.getOrCreateAppInstanceDID();\n      if (!storedAppInstanceDID) {\n        resolve(null);\n        return;\n      }\n\n      // No such credential, so we have to create one. Send an intent to get that from the did app\n      this.logger.log('hiveauthhelper', 'Starting to generate a new App ID credential.');\n\n      // Ask the identity wallet (eg: Essentials) to generate an app id credential.\n      const didAccess = new ConnDID.DIDAccess();\n      const appIdCredential = await didAccess.generateAppIdCredential();\n\n      // Save this issued credential for later use.\n      await storedAppInstanceDID.didStore.storeCredential(appIdCredential);\n\n      resolve(appIdCredential);\n    });\n  }\n}\n")))}v.isMDXComponent=!0}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.