UNPKG

@0xpolygonid/js-sdk

Version:
141 lines (128 loc) 4.68 kB
import { createStore, UseStore, get, set, del } from 'idb-keyval'; import { IndexedDBStorage, Merkletree, str2Bytes } from '@iden3/js-merkletree'; import { IdentityMerkleTreeMetaInformation, MerkleTreeType } from '../entities/mt'; import * as uuid from 'uuid'; import { IMerkleTreeStorage } from '../interfaces/merkletree'; import { createMerkleTreeMetaInfo } from '../utils'; /** * Merkle tree storage that uses browser indexed db storage * * @public * @class MerkleTreeIndexedDBStorage * @implements implements IMerkleTreeStorage interface */ export class MerkleTreeIndexedDBStorage implements IMerkleTreeStorage { /** * key for the storage key metadata * * @static */ static readonly storageKeyMeta = 'merkle-tree-meta'; static readonly storageBindingKeyMeta = 'binding-did'; private readonly _merkleTreeMetaStore: UseStore; private readonly _bindingStore: UseStore; /** * Creates an instance of MerkleTreeIndexedDBStorage. * @param {number} _mtDepth */ constructor(private readonly _mtDepth: number) { this._merkleTreeMetaStore = createStore( `${MerkleTreeIndexedDBStorage.storageKeyMeta}-db`, MerkleTreeIndexedDBStorage.storageKeyMeta ); this._bindingStore = createStore( `${MerkleTreeIndexedDBStorage.storageBindingKeyMeta}-db`, MerkleTreeIndexedDBStorage.storageBindingKeyMeta ); } /** creates a tree in the indexed db storage */ async createIdentityMerkleTrees( identifier: string ): Promise<IdentityMerkleTreeMetaInformation[]> { if (!identifier) { identifier = `${uuid.v4()}`; } const existingBinging = await get(identifier, this._bindingStore); if (existingBinging) { throw new Error( `Present merkle tree meta information in the store for current identifier ${identifier}` ); } const treesMeta = createMerkleTreeMetaInfo(identifier); await set(identifier, treesMeta, this._merkleTreeMetaStore); return treesMeta; } /** * * getIdentityMerkleTreesInfo from the indexed db storage * @param {string} identifier * @returns `{Promise<IdentityMerkleTreeMetaInformation[]>}` */ async getIdentityMerkleTreesInfo( identifier: string ): Promise<IdentityMerkleTreeMetaInformation[]> { const meta = await get(identifier, this._merkleTreeMetaStore); if (meta) { return meta; } throw new Error(`Merkle tree meta not found for identifier ${identifier}`); } /** get merkle tree from the indexed db storage */ async getMerkleTreeByIdentifierAndType( identifier: string, mtType: MerkleTreeType ): Promise<Merkletree> { const meta = await get(identifier, this._merkleTreeMetaStore); const err = new Error(`Merkle tree not found for identifier ${identifier} and type ${mtType}`); if (!meta) { throw err; } const resultMeta = meta.find( (m: { identifier: string; type: MerkleTreeType }) => m.identifier === identifier && m.type === mtType ); if (!resultMeta) { throw err; } return new Merkletree(new IndexedDBStorage(str2Bytes(resultMeta.treeId)), true, this._mtDepth); } /** adds to merkle tree in the indexed db storage */ async addToMerkleTree( identifier: string, mtType: MerkleTreeType, hindex: bigint, hvalue: bigint ): Promise<void> { const meta = await get(identifier, this._merkleTreeMetaStore); if (!meta) { throw new Error(`Merkle tree meta not found for identifier ${identifier}`); } const resultMeta = meta.find( (m: { identifier: string; type: MerkleTreeType }) => m.identifier === identifier && m.type === mtType ); if (!resultMeta) { throw new Error(`Merkle tree not found for identifier ${identifier} and type ${mtType}`); } const tree = new Merkletree( new IndexedDBStorage(str2Bytes(resultMeta.treeId)), true, this._mtDepth ); await tree.add(hindex, hvalue); } /** binds merkle tree in the indexed db storage to the new identifiers */ async bindMerkleTreeToNewIdentifier(oldIdentifier: string, newIdentifier: string): Promise<void> { const meta = await get(oldIdentifier, this._merkleTreeMetaStore); if (!meta || !meta?.length) { throw new Error(`Merkle tree meta not found for identifier ${oldIdentifier}`); } const treesMeta = meta.map((m: { identifier: string; type: MerkleTreeType }) => ({ ...m, identifier: newIdentifier })); await del(oldIdentifier, this._merkleTreeMetaStore); await set(newIdentifier, treesMeta, this._merkleTreeMetaStore); await set(oldIdentifier, newIdentifier, this._bindingStore); } }