@iden3/js-iden3-auth
Version:
iden3-auth implementation in JavaScript
109 lines (108 loc) • 4.04 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.isGenesisStateId = exports.EthStateResolver = void 0;
const js_iden3_core_1 = require("@iden3/js-iden3-core");
const ethers_1 = require("ethers");
const ethers_contracts_1 = require("./types/ethers-contracts");
const zeroInt = BigInt(0);
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_1.ethers.providers.JsonRpcProvider({
url: url.href,
user: url.username,
password: url.password
});
const contract = ethers_contracts_1.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_1.ethers.providers.JsonRpcProvider({
url: url.href,
user: url.username,
password: url.password
});
const contract = ethers_contracts_1.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
};
}
}
exports.EthStateResolver = EthStateResolver;
function isGenesisStateId(id, state) {
const userID = js_iden3_core_1.Id.fromBigInt(id);
const identifier = js_iden3_core_1.Id.idGenesisFromIdenState(userID.type(), state);
return userID.equal(identifier);
}
exports.isGenesisStateId = isGenesisStateId;
;