UNPKG

@elysium-onchain-id/identity-sdk

Version:
336 lines (232 loc) 10.1 kB
# IDENTITY SDK > This package facilitates the interaction with Identities stored in the BlockChain. ## Specifications ### Features - Deploy identities - List and Manage keys on an Identity - List and manage Claims on an Identity. - Issue claims for an Identity. - Fetch claim data using their URI. --- ## Usage ### Installation **Install with `npm install @onchain-id/identity-sdk`** Then require with: ```javascript const { IdentitySDK } = require('@onchain-id/identity-sdk'); ``` ### Tutorials - [Tutorial Homepage](./docs/tutorials/README.md) - [Implement a Claim Issuer service](./docs/tutorials/implement%20a%20claim%20issuer.md) - [Restrict access to compliant Identities](./docs/tutorials/restrict%20to%20compliant%20identities.md) - [Connect with Identity](./docs/tutorials/connect%20with%20identity.md) ### BlockChain Provider To interact with the BlockChain, you will need to instantiate a Provider. The SDK is using [Ethers](https://github.com/ethers-io/ethers.js) to connect with Ethereum network. Thus, any provider supported by Ethers can be used with the SDK. This means any standard web3 provider should by supported. Connect to a default provider: ```javascript // You can use any standard network name // - "homestead" // - "rinkeby" // - "ropsten" // - "kovan" const ethers = require('ethers'); const provider = ethers.getDefaultProvider('ropsten'); const identity = await Identity.at('0x...', { provider }); ``` Connect to JSON RPC: ```javascript // When using the JSON-RPC API, the network will be automatically detected // Default: http://localhost:8545 let httpProvider = new ethers.providers.JsonRpcProvider(); ``` Connect to any Web3 Provider: ```javascript // When using a Web3 provider, the network will be automatically detected // e.g. HTTP provider let currentProvider = new web3.providers.HttpProvider('http://localhost:8545'); let web3Provider = new ethers.providers.Web3Provider(currentProvider); ``` Connect to metamask: ```javascript // The network will be automatically detected; if the network is // changed in MetaMask, it causes a page refresh. let provider = new ethers.providers.Web3Provider(web3.currentProvider); ``` To use a signer instead of a provider (required to sign transactions): ```javascript const signer = new ethers.Wallet('PRIVATE_KEY', provider); // Or other signers from EthersJS. const identity = await Identity.at('0x...', { signer }); ``` > Please refer to the [Ethers Providers Documentation](https://docs.ethers.io/ethers.js/html/api-providers.html) for more information. #### Overriding provider or signer for operation Every methods that connects to the Blockchain (write or read) accept last `options` arguments to specify the signer or provider to use for the operation, and for write operation, to override transaction parameters: ```javascript const ethers = require('ethers'); const identity = new IdentitySDK.Identity('0xadD92F8Ef0729E969c5a98Ea5740c9b644B362e3', provider); await identity.addKey('0x..', 1, 3, { signer: someSigner, overrides: { gasPrice: ethers.parseUnits('2.0', 'gwei') } }); ``` ### Configuration #### Providers By default, unsecured providers are not allowed. The SDK will refuse to fetch data on these endpoints. A claim that has an uri which is not an HTTPS endpoint won't be retrieved. Allow unsecured endpoints with: ``` const IdentitySDK = require('@onchain-id/identity-sdk'); IdentitySDK.Config.config({ allowUnsecuredProviders: true }); ``` ### SignerModule Many interaction with identities, and especially claims, require to sign a challenge message. Functions requiring these signatures expect a SignerModule as argument. A SignerModule must expose a .getPublicKey() and a .signMessage(message: string) functions. This is, for instance, a valid SignerModule: ```javascript const jsrasign = require('jsrasign'); const signer = new SignerModule({ getPublicKey: async () => ({ key: "-----BEGIN CERTIFICATE----- my_super_public_key -----END CERTIFICATE-----", type: "X.509", signingMethod: "SHA-256", }), signMessage: async (message) => { const signer = new jsrsasign.Signature({ alg: 'SHA256withRSA' }); signer.init("-----BEGIN CERTIFICATE----- my_super_PRIVATE_no_really_super_secret_PRIVATE_key -----END CERTIFICATE-----"); signer.updateString(message); return signer.sign(); }, }); ``` As a convenient method, a SignerModule can be created from an ethers Wallet: ```javascript const wallet = new IdentitySDK.Providers.Wallet('PRIVATE_KEY', provider); const signer = new IdentitySDK.SignerModule(wallet); ``` ### Examples Find examples in the [Example folder](./examples). #### Load a contract ```javascript const { IdentitySDK } = require('@onchain-id/identity-sdk'); const provider = new ethers.providers.JsonRpcProvider(); (async () => { const identity = new IdentitySDK.Identity(); // Create the Identity Object console.log(identity.instantiateAtAddress('0xadD92F8Ef0729E969c5a98Ea5740c9b644B362e3', provider)); // Get the instance of the Identity console.log(await identity.instance.getClaimIdsByTopic(1)); // Call directly a function from the Contract. })(); ``` #### Get claims of an Identity ```javascript const { IdentitySDK } = require('@onchain-id/identity-sdk'); const provider = new ethers.providers.JsonRpcProvider(); (async () => { const identity = new IdentitySDK.Identity('0xadD92F8Ef0729E969c5a98Ea5740c9b644B362e3', provider); const claims = await identity.getClaimsByTopic(1); console.log(claims); })(); ``` #### Get keys of an Identity ```javascript const { IdentitySDK } = require('@onchain-id/identity-sdk'); const provider = new ethers.providers.JsonRpcProvider(); (async () => { const identity = new IdentitySDK.Identity('0xadD92F8Ef0729E969c5a98Ea5740c9b644B362e3', provider); const keys = await identity.getKeysByPurpose(IdentitySDK.utils.enums.KeyPurpose.CLAIM); console.log(keys); console.log(await identity.getKeyPurposes(keys[0].key)); })(); ``` #### Deploy an identity ```javascript const { IdentitySDK } = require('@onchain-id/identity-sdk'); const provider = new ethers.providers.JsonRpcProvider(); const CLAIM_ISSUER_PRIVATE_KEY = 'issuer_private_key'; const claimIssuerWallet = new IdentitySDK.Providers.Wallet(CLAIM_ISSUER_PRIVATE_KEY, provider); const DEPLOY_PRIVATE_KEY = 'deploy_private_key'; const deployWallet = new IdentitySDK.Providers.Wallet(DEPLOY_PRIVATE_KEY, provider); (async () => { // Deploy a new Identity const identity = await IdentitySDK.Identity.deployNew( { managementKey: deployWallet.address, implementationAuthority: IdentitySDK.constants.implementationAuthorities.kovan, }, { signer: deployWallet } ); await identity.deployed(); await identity.addKey(IdentitySDK.utils.crypto.keccak256(claimIssuerWallet.address), IdentitySDK.utils.enums.KeyPurpose.CLAIM, IdentitySDK.utils.enums.KeyType.ECDSA); identity.useProvider(claimIssuerWallet); await identity.addClaim(IdentitySDK.utils.enums.ClaimTopic.KYC, IdentitySDK.utils.enums.ClaimScheme.SOME, claimIssuerWallet.address, "a signature", "what a lot of data", "http://localhost:8080/claims/666"); })(); ``` #### Deploy an implementation ```javascript const ethers = require('ethers'); const OnchainID = require('@onchain-id/solidity'); (async () => { const provider = ethers.getDefaultProvider('kovan'); const signer = new ethers.Wallet('<private key>', provider); const implementation = await new ethers.ContractFactory( OnchainID.contracts.Identity.abi, OnchainID.contracts.Identity.bytecode, signer ).deploy( signer.address, true, ); await implementation.deployed(); console.log(implementation.address); })(); ``` #### Deploy an implementation authority ```javascript const ethers = require('ethers'); const OnchainID = require('@onchain-id/solidity'); (async () => { const provider = ethers.getDefaultProvider('kovan'); const signer = new ethers.Wallet('<private key>', provider); const implementationAddress = '<implementation address>'; const implementationAuthority = await new ethers.ContractFactory( OnchainID.contracts.ImplementationAuthority.abi, OnchainID.contracts.ImplementationAuthority.bytecode, signer ).deploy(implementationAddress); await implementationAuthority.deployed(); console.log(implementationAuthority.address); })(); ``` --- #### Get details of a claim ```javascript const { IdentitySDK } = require('@onchain-id/identity-sdk'); const provider = new ethers.providers.JsonRpcProvider(); (async () => { IdentitySDK.config({ allowUnsecuredProviders: true }); const identity = new IdentitySDK.Identity('0xadD92F8Ef0729E969c5a98Ea5740c9b644B362e3', provider); const claims = await identity.getClaimsByTopic(IdentitySDK.utils.enums.ClaimTopic.KYC); const claim = new IdentitySDK.Claim(claims[0]); await claim.populate(); console.log(claim); /* Claim { data: '0x65773261724950755a302f626e5a744e327961676676376139462f6a3672744a4e3761666a52414c6871493d', id: '0x3c6532cc1f4d1a44de8f58d4bde617bef8e744168bf92d783a0e1b66e7c6a44a', issuer: '0x8c78fF753c63ea0e8CA1FcA9997A132bC3e6a8F1', scheme: 1, topic: 1, uri: 'http://localhost:8080/claims/b701e350-2a08-11e9-ac7e-517ddf10b60e', issuanceDate: 2019-02-06T12:14:12.996Z, emissionDate: 2019-02-06T12:15:02.039Z, status: 'PENDING', publicData: { result: 'clear' } } */ })(); ``` ## Development - Install dependencies: `yarn`. - Lint code with `yarn lint`. - Run unit tests: `yarn test:unit`. You can run unit tests each time you modify a file with `yarn test:unit:watch`. - Build project with `yarn build`. This will build package into the `dist/` folder from the TypeScript sources. - Run end to end tests against a builded package: `yarn test:e2e`. - You can generate type documentation with `yarn build:docs`. This will build the TypeDoc website into `docs/type_doc`.