Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.DS_Store
**/**/node_modules/
**/.env
2 changes: 2 additions & 0 deletions verifier-integration/js/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
VIDOS_RESOLVER_URL=
VIDOS_API_KEY=
2 changes: 2 additions & 0 deletions verifier-integration/js/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
VIDOS_RESOLVER_URL=https://ugly-aqua-hummingbird-120.resolver.service.eu.vidos.dev
VIDOS_API_KEY=24b500499e7c2f0a8634831d1b9894b74d656d3e7cd6de238d706c20a5db6d41
117 changes: 117 additions & 0 deletions verifier-integration/js/VidosResolver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
const { Id } = require("@iden3/js-iden3-core");
const { resolver } = require("@iden3/js-iden3-auth");

/**
* Implementation of {@link resolver.IStateResolver} that uses Vidos resolver service to resolve states.
* It can serve as drop-in replacement for {@link resolver.EthStateResolver}.
*
* @implements {resolver.IStateResolver}
*/
class VidosResolver {
/**
* @param {string} resolverUrl
* @param {string} apiKey
*/
constructor(resolverUrl, apiKey) {
this.resolverUrl = resolverUrl;
this.apiKey = apiKey;
}

/**
* @param {bigint} state
* @returns {Promise<resolver.ResolvedState>}
*/
async rootResolve(state) {
const stateHex = state.toString("16");

const zeroAddress = "11111111111111111111"; // 1 is 0 in base58
const did = `did:polygonid:polygon:amoy:${zeroAddress}?gist=${stateHex}`;

const response = await fetch(`${this.resolverUrl}/${encodeURIComponent(did)}`, {
method: "GET",
headers: {
Authorization: `Bearer ${this.apiKey}`,
},
});
const result = await response.json();

const globalInfo = result.didDocument.verificationMethod[0].global;
if (globalInfo == null) throw new Error('gist info not found')

if (globalInfo.root !== stateHex) {
throw new Error('gist info contains invalid state');
}

if (globalInfo.replacedByRoot !== "0") {
if (globalInfo.replacedAtTimestamp === "0") {
throw new Error('state was replaced, but replaced time unknown');
}
return {
latest: false,
state: state,
transitionTimestamp: globalInfo.replacedAtTimestamp,
genesis: false,
};
}

return {
latest: true,
state: state,
transitionTimestamp: 0,
genesis: false,
};
}

/**
* @param {bigint} id
* @param {bigint} state
* @returns {Promise<resolver.ResolvedState>}
*/
async resolve(id, state) {
const iden3Id = Id.fromBigInt(id);
const stateHex = state.toString("16");

const did = `did:polygonid:polygon:amoy:${iden3Id.string()}`;

const didWithState = `${did}?state=${stateHex}`;
const response = await fetch(
`${this.resolverUrl}/${encodeURIComponent(didWithState)}`,
{
method: "GET",
headers: {
Authorization: `Bearer ${this.apiKey}`,
},
}
);
const result = await response.json();
const isGenesis = resolver.isGenesisStateId(id, state);

const stateInfo = result.didDocument.verificationMethod[0].info;
if (stateInfo == null) throw new Error('state info not found');

if (stateInfo.id !== did) {
throw new Error(`state was recorded for another identity`);
}

if (stateInfo.state !== stateHex) {
if (stateInfo.replacedAtTimestamp === "0") {
throw new Error(`no information about state transition`);
}
return {
latest: false,
genesis: false,
state: state,
transitionTimestamp: Number.parseInt(stateInfo.replacedAtTimestamp),
};
}

return {
latest: stateInfo.replacedAtTimestamp === "0",
genesis: isGenesis,
state,
transitionTimestamp: Number.parseInt(stateInfo.replacedAtTimestamp),
};
}
}

module.exports = VidosResolver;
13 changes: 11 additions & 2 deletions verifier-integration/js/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
require("dotenv").config();
const path = require("path");
const express = require("express");
const { auth, resolver, protocol } = require("@iden3/js-iden3-auth");
const { auth, resolver } = require("@iden3/js-iden3-auth");
const getRawBody = require("raw-body");
const VidosResolver = require("./VidosResolver");

const app = express();
const port = 8080;
Expand Down Expand Up @@ -85,9 +87,16 @@ async function callback(req, res) {
ethURL,
contractAddress
);
const vidosResolver =
process.env.VIDOS_RESOLVER_URL && process.env.VIDOS_API_KEY
? new VidosResolver(
process.env.VIDOS_RESOLVER_URL,
process.env.VIDOS_API_KEY
)
: undefined;

const resolvers = {
["polygon:amoy"]: ethStateResolver,
["polygon:amoy"]: vidosResolver ?? ethStateResolver,
};

// fetch authRequest from sessionID
Expand Down
36 changes: 36 additions & 0 deletions verifier-integration/js/interceptStateResolver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const { resolver } = require("@iden3/js-iden3-auth");

/**
* Wrapper around a state resolver that logs the state resolution process. Useful for debugging and learning how state resolution works.
*
* @param {resolver.IStateResolver} resolver
* @returns {resolver.IStateResolver}
*/
function interceptStateResolver(resolver) {
return {
async resolve(id, state) {
try {
console.log("Resolving state", id, state);
const result = await resolver.resolve(id, state);
console.log("Resolved state", id, state, result);
return result;
} catch (e) {
console.error("Error resolving state", id, state, e);
throw e;
}
},
async rootResolve(state) {
try {
console.log("Resolving root state", state);
const result = await resolver.rootResolve(state);
console.log("Resolved root state", state, result);
return result;
} catch (e) {
console.error("Error resolving root state", state, e);
throw e;
}
},
};
}

module.exports = interceptStateResolver;
13 changes: 13 additions & 0 deletions verifier-integration/js/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion verifier-integration/js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{
"dependencies": {
"@iden3/js-iden3-auth": "1.3.2",
"express": "^4.18.2"
"@iden3/js-iden3-core": "^1.3.1",
"express": "^4.18.2",
"dotenv": "^16.4.5"
}
}