Skip to content

Commit 3768bda

Browse files
authored
ability to replace auth bjj with another status (#264)
* add logic for removal of the credential with another status * add possibility to disable publishing of the genesis state
1 parent 39187cc commit 3768bda

File tree

4 files changed

+95
-35
lines changed

4 files changed

+95
-35
lines changed

package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@0xpolygonid/js-sdk",
3-
"version": "1.18.3",
3+
"version": "1.18.4",
44
"description": "SDK to work with Polygon ID",
55
"main": "dist/node/cjs/index.js",
66
"module": "dist/node/esm/index.js",

src/identity/identity-wallet.ts

+38-30
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,19 @@ export type IdentityCreationOptions = {
7676
/**
7777
* Options for creating Auth BJJ credential
7878
* seed - seed to generate BJJ key pair
79-
* revocationOpts -
79+
* revocationOpts
80+
* nonce - explicit revocation nonce to use
81+
* onChain - onchain status related option
82+
* txCallback - defines how the TransactionReceipt is handled
83+
* publishMode - specifies the work of transaction polling type: sync / async / callback
84+
* genesisPublishingDisabled - genesis is publishing by default. Set `true` to prevent genesis publishing
8085
*/
8186
export type AuthBJJCredentialCreationOptions = {
8287
revocationOpts: {
8388
id: string;
8489
type: CredentialStatusType;
8590
nonce?: number;
91+
genesisPublishingDisabled?: boolean;
8692
onChain?: {
8793
txCallback?: (tx: TransactionReceipt) => Promise<void>;
8894
publishMode?: PublishMode;
@@ -661,13 +667,24 @@ export class IdentityWallet implements IIdentityWallet {
661667
allowedIssuers: [did.string()]
662668
});
663669

664-
if (credentials.length) {
670+
// if credential exists with the same credential status type we return this credential
671+
if (
672+
credentials.length === 1 &&
673+
credentials[0].credentialStatus.type === opts.revocationOpts.type
674+
) {
665675
return {
666676
did,
667677
credential: credentials[0]
668678
};
669679
}
670680

681+
// 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.
682+
// in this way credential status of auth credential can be upgraded
683+
for (let i = 0; i < credentials.length; i++) {
684+
await this._credentialWallet.remove(credentials[i].id);
685+
}
686+
687+
// otherwise we create a new credential
671688
const credential = await this.createAuthBJJCredential(
672689
did,
673690
pubKey,
@@ -695,10 +712,13 @@ export class IdentityWallet implements IIdentityWallet {
695712

696713
credential.proof = [mtpProof];
697714

698-
await this.publishRevocationInfoByCredentialStatusType(did, opts.revocationOpts.type, {
699-
rhsUrl: opts.revocationOpts.id,
700-
onChain: opts.revocationOpts.onChain
701-
});
715+
// only if user specified that genesis state publishing is not needed we won't do this.
716+
if (!opts.revocationOpts.genesisPublishingDisabled) {
717+
await this.publishRevocationInfoByCredentialStatusType(did, opts.revocationOpts.type, {
718+
rhsUrl: opts.revocationOpts.id,
719+
onChain: opts.revocationOpts.onChain
720+
});
721+
}
702722

703723
await this._credentialWallet.save(credential);
704724

@@ -1248,30 +1268,18 @@ export class IdentityWallet implements IIdentityWallet {
12481268
}
12491269

12501270
let nodes: ProofNode[] = [];
1251-
if (opts?.treeModel) {
1252-
nodes = await getNodesRepresentation(
1253-
opts.revokedNonces,
1254-
{
1255-
revocationTree: opts.treeModel.revocationTree,
1256-
claimsTree: opts.treeModel.claimsTree,
1257-
state: opts.treeModel.state,
1258-
rootsTree: opts.treeModel.rootsTree
1259-
},
1260-
opts.treeModel.state
1261-
);
1262-
} else {
1263-
const treeState = await this.getDIDTreeModel(issuerDID);
1264-
nodes = await getNodesRepresentation(
1265-
opts?.revokedNonces,
1266-
{
1267-
revocationTree: treeState.revocationTree,
1268-
claimsTree: treeState.claimsTree,
1269-
state: treeState.state,
1270-
rootsTree: treeState.rootsTree
1271-
},
1272-
treeState.state
1273-
);
1274-
}
1271+
1272+
const tree = opts?.treeModel ?? (await this.getDIDTreeModel(issuerDID));
1273+
nodes = await getNodesRepresentation(
1274+
opts?.revokedNonces ?? [],
1275+
{
1276+
revocationTree: tree.revocationTree,
1277+
claimsTree: tree.claimsTree,
1278+
state: tree.state,
1279+
rootsTree: tree.rootsTree
1280+
},
1281+
tree.state
1282+
);
12751283

12761284
if (!nodes.length) {
12771285
return;

tests/identity/id.test.ts

+54-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import {
1515
NativeProver,
1616
Iden3SparseMerkleTreeProof,
1717
BJJSignatureProof2021,
18-
TreeState
18+
TreeState,
19+
IdentityCreationOptions
1920
} from '../../src';
2021
import {
2122
MOCK_STATE_STORAGE,
@@ -26,7 +27,8 @@ import {
2627
registerKeyProvidersInMemoryKMS,
2728
WALLET_KEY,
2829
createEthereumBasedIdentity,
29-
SEED_ISSUER
30+
SEED_ISSUER,
31+
RHS_CONTRACT_ADDRESS
3032
} from '../helpers';
3133
import { expect } from 'chai';
3234
import { Wallet } from 'ethers';
@@ -397,4 +399,54 @@ describe('identity', () => {
397399
expect(credential).to.be.deep.eq(restoredCredential);
398400
expect(did.string()).to.be.eq(restoredDid.string());
399401
});
402+
403+
it('replace auth bjj credential', async () => {
404+
const idRequest: IdentityCreationOptions = {
405+
method: DidMethod.Iden3,
406+
blockchain: Blockchain.Polygon,
407+
networkId: NetworkId.Amoy,
408+
seed: SEED_ISSUER,
409+
revocationOpts: {
410+
type: CredentialStatusType.Iden3ReverseSparseMerkleTreeProof,
411+
id: RHS_URL
412+
}
413+
};
414+
const { did, credential } = await idWallet.createIdentity(idRequest);
415+
expect(did.string()).to.equal(expectedDID);
416+
417+
let credentials = await credWallet.findByQuery({
418+
credentialSubject: {
419+
x: {
420+
$eq: credential.credentialSubject['x']
421+
},
422+
y: {
423+
$eq: credential.credentialSubject['y']
424+
}
425+
}
426+
});
427+
expect(credentials.length).to.be.equal(1);
428+
429+
idRequest.revocationOpts.type = CredentialStatusType.Iden3OnchainSparseMerkleTreeProof2023;
430+
idRequest.revocationOpts.id = RHS_CONTRACT_ADDRESS;
431+
idRequest.revocationOpts.genesisPublishingDisabled = true;
432+
433+
const { did: did2, credential: credential2 } = await idWallet.createIdentity(idRequest);
434+
expect(did2.string()).to.equal(expectedDID);
435+
expect(credential2.credentialStatus.type).to.be.equal(
436+
CredentialStatusType.Iden3OnchainSparseMerkleTreeProof2023
437+
);
438+
expect(credential2.credentialStatus.id).to.contain('state');
439+
440+
credentials = await credWallet.findByQuery({
441+
credentialSubject: {
442+
x: {
443+
$eq: credential2.credentialSubject['x']
444+
},
445+
y: {
446+
$eq: credential2.credentialSubject['y']
447+
}
448+
}
449+
});
450+
expect(credentials.length).to.be.equal(1);
451+
});
400452
});

0 commit comments

Comments
 (0)