diff --git a/src/iden3comm/types/protocol/auth.ts b/src/iden3comm/types/protocol/auth.ts index 48080219..c3085734 100644 --- a/src/iden3comm/types/protocol/auth.ts +++ b/src/iden3comm/types/protocol/auth.ts @@ -7,7 +7,7 @@ import { DIDDocument as DidResolverDidDocument, VerificationMethod as DidResolverVerificationMethod } from 'did-resolver'; -import { RootInfo, StateInfo } from '../../../storage'; +import { RootInfoWithProof, StateInfo } from '../../../storage'; /** AuthorizationResponseMessage is struct the represents iden3message authorization response */ export type AuthorizationResponseMessage = BasicMessage & { @@ -89,5 +89,5 @@ export type DIDDocument = DidResolverDidDocument & { export type VerificationMethod = DidResolverVerificationMethod & { published?: boolean; info?: StateInfo; - global?: RootInfo; + global?: RootInfoWithProof; }; diff --git a/src/storage/blockchain/did-resolver-readonly-storage.ts b/src/storage/blockchain/did-resolver-readonly-storage.ts index 4c87308b..9a8ccfd2 100644 --- a/src/storage/blockchain/did-resolver-readonly-storage.ts +++ b/src/storage/blockchain/did-resolver-readonly-storage.ts @@ -6,7 +6,7 @@ import { IStateStorage } from '../interfaces'; import { DID, Id } from '@iden3/js-iden3-core'; import { JsonRpcProvider } from 'ethers'; -export class DidResolverReadonlyStorage implements IStateStorage { +export class DidResolverStateReadonlyStorage implements IStateStorage { constructor(private readonly resolverUrl: string) {} async getLatestStateById(id: bigint): Promise { return this.getStateInfo(id); @@ -15,6 +15,34 @@ export class DidResolverReadonlyStorage implements IStateStorage { return this.getStateInfo(id, state); } + async getGISTProof(id: bigint): Promise { + const { didDocument } = await resolveDidDocument( + DID.parseFromId(Id.fromBigInt(id)), + this.resolverUrl + ); + const vm = (didDocument as DIDDocument).verificationMethod?.find( + (i) => i.type === 'Iden3StateInfo2023' + ); + if (!vm) { + throw new Error('Iden3StateInfo2023 verification method not found'); + } + const { global } = vm as VerificationMethod; + if (!global) { + throw new Error('GIST root not found'); + } + const { proof } = global; + return { + root: BigInt(proof.root), + existence: proof.existence, + siblings: proof.siblings?.map((sibling) => BigInt(sibling)), + index: BigInt(proof.index), + value: BigInt(proof.value), + auxExistence: proof.auxExistence, + auxIndex: BigInt(proof.auxIndex), + auxValue: BigInt(proof.auxValue) + }; + } + async getGISTRootInfo(root: bigint, userId: bigint): Promise { const { didDocument } = await resolveDidDocument( DID.parseFromId(Id.fromBigInt(userId)), @@ -36,9 +64,6 @@ export class DidResolverReadonlyStorage implements IStateStorage { return global; } - async getGISTProof(): Promise { - throw new Error('Method not implemented.'); - } getRpcProvider(): JsonRpcProvider { throw new Error('Method not implemented.'); } diff --git a/src/storage/entities/state.ts b/src/storage/entities/state.ts index a6661d25..947513f5 100644 --- a/src/storage/entities/state.ts +++ b/src/storage/entities/state.ts @@ -46,6 +46,16 @@ export interface RootInfo { replacedAtBlock: bigint; } +/** + * global identity state root info from DID resolver document + * + * @public + * @interface RootInfoWithProof + */ +export interface RootInfoWithProof extends RootInfo { + proof: StateProof; +} + /** * identity state message * diff --git a/tests/handlers/readonly-storage.test.ts b/tests/handlers/readonly-storage.test.ts index 042c4656..aebfe41e 100644 --- a/tests/handlers/readonly-storage.test.ts +++ b/tests/handlers/readonly-storage.test.ts @@ -1,14 +1,14 @@ import { expect } from 'chai'; -import { DidResolverReadonlyStorage, IStateStorage } from '../../src'; +import { DidResolverStateReadonlyStorage, IStateStorage } from '../../src'; import { DID } from '@iden3/js-iden3-core'; import { Hash } from '@iden3/js-merkletree'; -describe('resolver readonly storage', () => { +describe.skip('resolver readonly storage', () => { let stateStorage: IStateStorage; const did = DID.parse('did:polygonid:polygon:amoy:2qV7YACbSYpvuXySSqhBd6E4XAxzLE5kYmPqwxuvwD'); const id = DID.idFromDID(did); beforeEach(async () => { - stateStorage = new DidResolverReadonlyStorage('https://resolver-dev.privado.id/'); + stateStorage = new DidResolverStateReadonlyStorage('http://127.0.0.1:8080'); }); it('getLatestStateById', async () => { @@ -24,6 +24,12 @@ describe('resolver readonly storage', () => { expect(info).to.have.property('id'); }); + it('getGISTProof', async () => { + const proof = await stateStorage.getGISTProof(id.bigInt()); + expect(proof).to.be.an('object'); + expect(proof).to.have.property('root'); + }); + it('getGISTRootInfo', async () => { const root = Hash.fromHex('44f40dd34c5b840ef1c55e3805febef589069dab35f8684857ba118778826d1b'); const rootInfo = await stateStorage.getGISTRootInfo(root.bigInt(), id.bigInt());