UNPKG

@iden3/js-iden3-auth

Version:

iden3-auth implementation in JavaScript

104 lines (103 loc) 3.72 kB
import { Id } from '@iden3/js-iden3-core'; import { ethers } from 'ethers'; import { Abi__factory } from './types/ethers-contracts/index.js'; const zeroInt = BigInt(0); export class EthStateResolver { constructor(rpcUrl, contractAddress) { this.rpcUrl = rpcUrl; this.contractAddress = contractAddress; } async resolve(id, state) { const url = new URL(this.rpcUrl); const ethersProvider = new ethers.providers.JsonRpcProvider({ url: url.href, user: url.username, password: url.password }); const contract = Abi__factory.connect(this.contractAddress, ethersProvider); // check if id is genesis const isGenesis = isGenesisStateId(id, state); let contractState; try { contractState = await contract.getStateInfoByIdAndState(id, state); } catch (e) { if (e.errorArgs[0] === 'State does not exist') { if (isGenesis) { return { latest: true, genesis: isGenesis, state: state, transitionTimestamp: 0 }; } throw new Error('State is not genesis and not registered in the smart contract'); } throw e; } if (!contractState.id.eq(id)) { throw new Error(`state was recorded for another identity`); } if (!contractState.state.eq(state)) { if (contractState.replacedAtTimestamp.eq(zeroInt)) { throw new Error(`no information about state transition`); } return { latest: false, genesis: false, state: state, transitionTimestamp: contractState.replacedAtTimestamp.toNumber() }; } return { latest: contractState.replacedAtTimestamp.isZero(), genesis: isGenesis, state, transitionTimestamp: contractState.replacedAtTimestamp.toNumber() }; } async rootResolve(state) { const url = new URL(this.rpcUrl); const ethersProvider = new ethers.providers.JsonRpcProvider({ url: url.href, user: url.username, password: url.password }); const contract = Abi__factory.connect(this.contractAddress, ethersProvider); let globalStateInfo; try { globalStateInfo = await contract.getGISTRootInfo(state); } catch (e) { if (e.errorArgs[0] === 'Root does not exist') { throw new Error('GIST root does not exist in the smart contract'); } throw e; } if (!globalStateInfo.root.eq(state)) { throw new Error(`gist info contains invalid state`); } if (!globalStateInfo.replacedByRoot.eq(zeroInt)) { if (globalStateInfo.replacedAtTimestamp.eq(zeroInt)) { throw new Error(`state was replaced, but replaced time unknown`); } return { latest: false, state: state, transitionTimestamp: globalStateInfo.replacedAtTimestamp.toString(), genesis: false }; } return { latest: true, state: state, transitionTimestamp: 0, genesis: false }; } } export function isGenesisStateId(id, state) { const userID = Id.fromBigInt(id); const identifier = Id.idGenesisFromIdenState(userID.type(), state); return userID.equal(identifier); }