Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ability to replace auth bjj with another status #264

Merged
merged 7 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@0xpolygonid/js-sdk",
"version": "1.18.3",
"version": "1.18.4",
"description": "SDK to work with Polygon ID",
"main": "dist/node/cjs/index.js",
"module": "dist/node/esm/index.js",
Expand Down
68 changes: 38 additions & 30 deletions src/identity/identity-wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,19 @@ export type IdentityCreationOptions = {
/**
* Options for creating Auth BJJ credential
* seed - seed to generate BJJ key pair
* revocationOpts -
* revocationOpts
* nonce - explicit revocation nonce to use
* onChain - onchain status related option
* txCallback - defines how the TransactionReceipt is handled
* publishMode - specifies the work of transaction polling type: sync / async / callback
* genesisPublishingDisabled - genesis is publishing by default. Set `true` to prevent genesis publishing
*/
export type AuthBJJCredentialCreationOptions = {
revocationOpts: {
id: string;
type: CredentialStatusType;
nonce?: number;
genesisPublishingDisabled?: boolean;
onChain?: {
txCallback?: (tx: TransactionReceipt) => Promise<void>;
publishMode?: PublishMode;
Expand Down Expand Up @@ -661,13 +667,24 @@ export class IdentityWallet implements IIdentityWallet {
allowedIssuers: [did.string()]
});

if (credentials.length) {
// if credential exists with the same credential status type we return this credential
if (
credentials.length === 1 &&
credentials[0].credentialStatus.type === opts.revocationOpts.type
) {
return {
did,
credential: credentials[0]
};
}

// otherwise something is already wrong with storage as it has more than 1 credential in it or credential status type of existing credential is different from what user provides - We should remove everything and create new credential.
// in this way credential status of auth credential can be upgraded
for (let i = 0; i < credentials.length; i++) {
await this._credentialWallet.remove(credentials[i].id);
}

// otherwise we create a new credential
const credential = await this.createAuthBJJCredential(
did,
pubKey,
Expand Down Expand Up @@ -695,10 +712,13 @@ export class IdentityWallet implements IIdentityWallet {

credential.proof = [mtpProof];

await this.publishRevocationInfoByCredentialStatusType(did, opts.revocationOpts.type, {
rhsUrl: opts.revocationOpts.id,
onChain: opts.revocationOpts.onChain
});
// only if user specified that genesis state publishing is not needed we won't do this.
if (!opts.revocationOpts.genesisPublishingDisabled) {
await this.publishRevocationInfoByCredentialStatusType(did, opts.revocationOpts.type, {
rhsUrl: opts.revocationOpts.id,
onChain: opts.revocationOpts.onChain
});
}

await this._credentialWallet.save(credential);

Expand Down Expand Up @@ -1248,30 +1268,18 @@ export class IdentityWallet implements IIdentityWallet {
}

let nodes: ProofNode[] = [];
if (opts?.treeModel) {
nodes = await getNodesRepresentation(
opts.revokedNonces,
{
revocationTree: opts.treeModel.revocationTree,
claimsTree: opts.treeModel.claimsTree,
state: opts.treeModel.state,
rootsTree: opts.treeModel.rootsTree
},
opts.treeModel.state
);
} else {
const treeState = await this.getDIDTreeModel(issuerDID);
nodes = await getNodesRepresentation(
opts?.revokedNonces,
{
revocationTree: treeState.revocationTree,
claimsTree: treeState.claimsTree,
state: treeState.state,
rootsTree: treeState.rootsTree
},
treeState.state
);
}

const tree = opts?.treeModel ?? (await this.getDIDTreeModel(issuerDID));
nodes = await getNodesRepresentation(
opts?.revokedNonces ?? [],
{
revocationTree: tree.revocationTree,
claimsTree: tree.claimsTree,
state: tree.state,
rootsTree: tree.rootsTree
},
tree.state
);

if (!nodes.length) {
return;
Expand Down
56 changes: 54 additions & 2 deletions tests/identity/id.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
NativeProver,
Iden3SparseMerkleTreeProof,
BJJSignatureProof2021,
TreeState
TreeState,
IdentityCreationOptions
} from '../../src';
import {
MOCK_STATE_STORAGE,
Expand All @@ -26,7 +27,8 @@ import {
registerKeyProvidersInMemoryKMS,
WALLET_KEY,
createEthereumBasedIdentity,
SEED_ISSUER
SEED_ISSUER,
RHS_CONTRACT_ADDRESS
} from '../helpers';
import { expect } from 'chai';
import { Wallet } from 'ethers';
Expand Down Expand Up @@ -397,4 +399,54 @@ describe('identity', () => {
expect(credential).to.be.deep.eq(restoredCredential);
expect(did.string()).to.be.eq(restoredDid.string());
});

it('replace auth bjj credential', async () => {
const idRequest: IdentityCreationOptions = {
method: DidMethod.Iden3,
blockchain: Blockchain.Polygon,
networkId: NetworkId.Amoy,
seed: SEED_ISSUER,
revocationOpts: {
type: CredentialStatusType.Iden3ReverseSparseMerkleTreeProof,
id: RHS_URL
}
};
const { did, credential } = await idWallet.createIdentity(idRequest);
expect(did.string()).to.equal(expectedDID);

let credentials = await credWallet.findByQuery({
credentialSubject: {
x: {
$eq: credential.credentialSubject['x']
},
y: {
$eq: credential.credentialSubject['y']
}
}
});
expect(credentials.length).to.be.equal(1);

idRequest.revocationOpts.type = CredentialStatusType.Iden3OnchainSparseMerkleTreeProof2023;
idRequest.revocationOpts.id = RHS_CONTRACT_ADDRESS;
idRequest.revocationOpts.genesisPublishingDisabled = true;

const { did: did2, credential: credential2 } = await idWallet.createIdentity(idRequest);
expect(did2.string()).to.equal(expectedDID);
expect(credential2.credentialStatus.type).to.be.equal(
CredentialStatusType.Iden3OnchainSparseMerkleTreeProof2023
);
expect(credential2.credentialStatus.id).to.contain('state');

credentials = await credWallet.findByQuery({
credentialSubject: {
x: {
$eq: credential2.credentialSubject['x']
},
y: {
$eq: credential2.credentialSubject['y']
}
}
});
expect(credentials.length).to.be.equal(1);
});
});