UNPKG

@elysium-onchain-id/identity-sdk

Version:
191 lines 8.87 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Claim = void 0; const utils_1 = require("ethers/lib/utils"); const OnchainID = __importStar(require("@onchain-id/solidity")); const SignerModule_1 = require("../core/SignerModule"); const ethers_1 = require("ethers"); const Utils_1 = require("../core/utils/Utils"); const Errors_1 = require("../core/errors/Errors"); class Claim { /** * Generate the hash of a claim using the provided data, use this method when using a JSON scheme with public and private data. * This hash should be put in the `data` field of the claim. * @param topic * @param emissionDate * @param publicData * @param privateData */ static generateHash(topic, emissionDate, publicData, privateData) { if (publicData && privateData && emissionDate && topic) { return (0, utils_1.sha256)((0, utils_1.toUtf8Bytes)(JSON.stringify({ topic, emissionDate, privateData, publicData }))); } else { throw new Error("Can't generate the Claim Hash because some data is missing."); } } /** * Generate the blockchain hash of the claim. This is the hash that has to be sign by the claim issuer. * @param address * @param topic * @param data */ static generateBlockchainHash(address, topic, data) { return (0, Utils_1.encodeAndHash)(['address', 'uint256', 'bytes'], [address, topic, data]); } static generateClaimID(issuer, topic) { return (0, Utils_1.encodeAndHash)(['address', 'uint256'], [issuer, topic]); } /** * Generate the blockchain hash of a claim and signs it with the provided signer or the default signer of the SDK. * @param topic * @param address * @param data * @param [signer] * @returns Claim signature. */ static sign(topic, address, data, signer) { return __awaiter(this, void 0, void 0, function* () { if (!SignerModule_1.SignerModule.isSignerModule(signer)) { throw new Errors_1.InvalidProviderError('A signer is required to generate a claim signature.'); } if (!(0, Utils_1.isHexString)(data)) { throw new Error('Claim data to sign must be a valid hex string.'); } const claimHash = Claim.generateBlockchainHash(address, topic, data); return signer.signMessage((0, utils_1.arrayify)(claimHash)); }); } /** * Verify the signature of a claim. * The standard signature of a claim is the keccak256 hash of (identityAddress, topic, data) prefixed and signed. * The data argument is exactly the content of the data claim field stored in blockchain (caution to hex padding). * Data is expected to be an hexString. * Using the IdentitySDK, call `IdentitySDK.utils.toHex('data')`. * Using web3utils, call `web3utils.asciiToHex('data')`. * Using ethersjs, call `Ethers.utils.hexlify(Ethers.utils.toUtf8Bytes('data'))` * @param signingKey * @param topic * @param address Address of identity contract. * @param data * @param signature */ static verifySignature(signingKey, topic, address, data, signature) { return __awaiter(this, void 0, void 0, function* () { if (!(0, Utils_1.isHexString)(data)) { throw new Error('Claim data to sign must be a valid hex string.'); } const claimHash = Claim.generateBlockchainHash(address, topic, data); try { const signerAddress = yield (0, utils_1.verifyMessage)((0, utils_1.arrayify)(claimHash), signature); return signerAddress === signingKey; } catch (err) { return false; } }); } /** * Create a new Claim Object from a ClaimData (got from BlockChain Identity Contract). * Use #.createFromURI() to fetch from an URI. * @param claim */ constructor(claim) { if (claim) { Object.assign(this, claim); } } /** * Generate the hash of the claim data if it was populated with private data. * If all data are not provided as arguments, data fromm the Claim object will be used. * Note that to verify a claim complete data, you will need to have access to its private data. * Use the .populate() method to fetch all the public and private data if available. * @param topic * @param emissionDate * @param publicData * @param privateData */ generateHash(topic, emissionDate, publicData, privateData) { if (publicData && privateData && emissionDate && topic) { return Claim.generateHash(topic, emissionDate, publicData, privateData); } else { if (!this.publicData || !this.privateData || !this.emissionDate) { throw new Error("Can't generate the Claim Hash because some data is missing. Call .populate() first to retrieve data from the Claim Issuer."); } return this.generateHash(this.topic, this.emissionDate, this.publicData, this.privateData); } } /** * Sign the claim. * It will update the signature property of the claim. The signature can only be generated for a claim that as a topic, an address and data. * @param signer Signer module to use. If null, use default signer of SDK. */ sign(signer) { return __awaiter(this, void 0, void 0, function* () { if (!this.topic) { throw new Error('Claim has no topic defined, thus it cannot be signed.'); } if (!this.address) { throw new Error('Claim has no address defined, thus it cannot be signed.'); } if (!this.data) { throw new Error('Claim has no data defined, thus it cannot be signed.'); } const signature = yield Claim.sign(this.topic, this.address, this.data, signer); this.signature = signature; return signature; }); } /** * Verify the validity of a claim against the Claim Issuer Contract. * @param provider Provider instance to fetch blockchain data. * @return true if the claim is declared valid by the Claim Issuer, false otherwise. */ verifyValidity(provider) { return __awaiter(this, void 0, void 0, function* () { if (!this.topic || !this.address || !this.signature) { throw new Error(`Claim is not complete and thus cannot be verified.`); } if (!this.issuer) { throw new Error('A claim that has no issuer address cannot be verified.'); } const claimIssuerInstance = new ethers_1.Contract(this.issuer, OnchainID.interfaces.IClaimIssuer.abi, provider); return claimIssuerInstance.isClaimValid(this.address, this.topic, this.signature, this.data); }); } } exports.Claim = Claim; //# sourceMappingURL=Claim.js.map