diff --git a/.github/workflows/integrations-tests.yml b/.github/workflows/integrations-tests.yml index 530a38c93..33ee7fa82 100644 --- a/.github/workflows/integrations-tests.yml +++ b/.github/workflows/integrations-tests.yml @@ -22,6 +22,7 @@ jobs: mainnet: runs-on: ubuntu-latest env: + DisableTrustRegistryTests: true CONFIG_DOCK_NODE_IMAGE_TAG: 'mainnet' steps: - uses: actions/checkout@v2 @@ -39,6 +40,7 @@ jobs: testnet: runs-on: ubuntu-latest env: + DisableTrustRegistryTests: true CONFIG_DOCK_NODE_IMAGE_TAG: 'testnet' steps: - uses: actions/checkout@v2 diff --git a/example/blob.js b/example/blob.js index 5bd1b39fa..31514fbc6 100644 --- a/example/blob.js +++ b/example/blob.js @@ -3,8 +3,7 @@ import { u8aToString } from '@polkadot/util'; import { DockAPI } from '../src/index'; import { DockBlobIdByteSize } from '../src/modules/blob'; -import { createNewDockDID } from '../src/utils/did'; -import { getPublicKeyFromKeyringPair } from '../src/utils/misc'; +import { createNewDockDID, DidKeypair } from '../src/utils/did'; // The following can be tweaked depending on where the node is running and what // account is to be used for sending the transaction. @@ -20,7 +19,7 @@ async function writeAndReadBlob(dock, blobValue, dockDID, pair) { blob: blobValue, }; - await dock.blob.new(blob, dockDID, pair, 1, { didModule: dock.did }, false); + await dock.blob.new(blob, dockDID, pair, { didModule: dock.did }, false); console.log('Blob written, reading from chain...'); @@ -33,7 +32,7 @@ async function createAuthorDID(dock, pair) { console.log('Creating new author DID', dockDID); // Create an author DID to write with - const publicKey = getPublicKeyFromKeyringPair(pair); + const publicKey = pair.publicKey(); const didKey = new DidKey(publicKey, new VerificationRelationship()); await dock.did.new(dockDID, [didKey], [], false); return dockDID; @@ -57,7 +56,7 @@ async function main() { const dock = await connectToNode(); // Generate keypair for DID - const pair = dock.keyring.addFromUri(randomAsHex(32)); + const pair = DidKeypair.fromApi(dock); // Generate a DID to be used as author const dockDID = await createAuthorDID(dock, pair); diff --git a/example/dock-did.js b/example/dock-did.js index b2c5c4c8f..d114a4041 100644 --- a/example/dock-did.js +++ b/example/dock-did.js @@ -8,8 +8,8 @@ import dock, { } from '../src/index'; import { createNewDockDID, + DidKeypair, } from '../src/utils/did'; -import { getPublicKeyFromKeyringPair } from '../src/utils/misc'; // The following can be tweaked depending on where the node is running and what // account is to be used for sending the transaction. @@ -31,9 +31,9 @@ async function removeDID() { console.log('Removing DID now.'); // Sign the DID removal with this key pair as this is the current key of the DID - const pair = dock.keyring.addFromUri(firstKeySeed, null, 'sr25519'); + const pair = new DidKeypair(dock.keyring.addFromUri(firstKeySeed, null, 'sr25519'), 1); - return dock.did.remove(dockDID, dockDID, pair, 1, undefined, false); + return dock.did.remove(dockDID, dockDID, pair, undefined, false); } // This function assumes the DID has been written. @@ -41,7 +41,7 @@ async function addServiceEndpoint() { console.log('Add new service endpoint now.'); // Sign key update with this key pair as this is the current key of the DID - const pair = dock.keyring.addFromUri(firstKeySeed, null, 'sr25519'); + const pair = new DidKeypair(dock.keyring.addFromUri(firstKeySeed, null, 'sr25519'), 1); const spType = new ServiceEndpointType(); spType.setLinkedDomains(); @@ -50,7 +50,7 @@ async function addServiceEndpoint() { const spId = u8aToHex(encoder.encode(spIdText)); const originsText = ['https://foo.example.com']; const origins = originsText.map((u) => u8aToHex(encoder.encode(u))); - return dock.did.addServiceEndpoint(spId, spType, origins, dockDID, dockDID, pair, 1, undefined, false); + return dock.did.addServiceEndpoint(spId, spType, origins, dockDID, dockDID, pair, undefined, false); } // This function assumes the DID has been written. @@ -58,11 +58,11 @@ async function addController() { console.log('Add new controller now.'); // Sign key update with this key pair as this is the current key of the DID - const pair = dock.keyring.addFromUri(firstKeySeed, null, 'sr25519'); + const pair = new DidKeypair(dock.keyring.addFromUri(firstKeySeed, null, 'sr25519'), 1); const newController = createNewDockDID(); - return dock.did.addControllers([newController], dockDID, dockDID, pair, 1, undefined, false); + return dock.did.addControllers([newController], dockDID, dockDID, pair, undefined, false); } // This function assumes the DID has been written. @@ -70,18 +70,18 @@ async function addKey() { console.log('Add new key now.'); // Sign key update with this key pair as this is the current key of the DID - const pair = dock.keyring.addFromUri(firstKeySeed, null, 'sr25519'); + const pair = new DidKeypair(dock.keyring.addFromUri(firstKeySeed, null, 'sr25519'), 1); // Update DID key to the following - const newPair = dock.keyring.addFromUri(secondKeySeed, null, 'ed25519'); + const newPair = new DidKeypair(dock.keyring.addFromUri(secondKeySeed, null, 'ed25519'), 1); // the following function will figure out the correct PublicKey type from the `type` property of `newPair` - const newPk = getPublicKeyFromKeyringPair(newPair); + const newPk = newPair.publicKey(); const vr = new VerificationRelationship(); vr.setAuthentication(); const newDidKey = new DidKey(newPk, vr); - return dock.did.addKeys([newDidKey], dockDID, dockDID, pair, 1, undefined, false); + return dock.did.addKeys([newDidKey], dockDID, dockDID, pair, undefined, false); } async function getDIDDoc() { diff --git a/example/resolver.js b/example/resolver.js index 5da83bf89..036706bff 100644 --- a/example/resolver.js +++ b/example/resolver.js @@ -2,7 +2,7 @@ import { randomAsHex } from '@polkadot/util-crypto'; import ethr from 'ethr-did-resolver'; import { DockAPI } from '../src/index'; -import { createNewDockDID, NoDIDError } from '../src/utils/did'; +import { createNewDockDID, NoDIDError, DidKeypair } from '../src/utils/did'; import { DIDResolver, DIDKeyResolver, UniversalResolver, WILDCARD, DockDIDResolver, } from '../src/resolver'; @@ -54,7 +54,7 @@ async function createDockDID() { dock.setAccount(account); const dockDID = createNewDockDID(); - const pair = dock.keyring.addFromUri(randomAsHex(32), null, 'sr25519'); + const pair = new DidKeypair(dock.keyring.addFromUri(randomAsHex(32), null, 'sr25519'), 1); await registerNewDIDUsingPair(dock, dockDID, pair); return dockDID; } diff --git a/example/revocation.js b/example/revocation.js index 13390d85c..587d33d20 100644 --- a/example/revocation.js +++ b/example/revocation.js @@ -1,8 +1,7 @@ import { randomAsHex } from '@polkadot/util-crypto'; import dock from '../src/index'; -import { createNewDockDID } from '../src/utils/did'; -import { getPublicKeyFromKeyringPair } from '../src/utils/misc'; +import { createNewDockDID, DidKeypair, typedHexDID } from '../src/utils/did'; import { OneOfPolicy, @@ -21,17 +20,17 @@ const registryId = createRandomRegistryId(); const controllerDID = createNewDockDID(); const controllerSeed = randomAsHex(32); -// Create a list of controllers -const controllers = new Set(); -controllers.add(controllerDID); - -// Create a registry policy -const policy = new OneOfPolicy(controllers); - // Create revoke IDs const revokeId = randomAsHex(32); async function createRegistry() { + // Create a list of controllers + const controllers = new Set(); + + controllers.add(typedHexDID(dock.api, controllerDID)); + + // Create a registry policy + const policy = new OneOfPolicy(controllers); console.log(`Creating a registry with owner DID (${controllerDID}) with policy type:`, policy.constructor.name); await dock.revocation.newRegistry(registryId, policy, false, false); console.log('Created registry'); @@ -40,20 +39,20 @@ async function createRegistry() { async function removeRegistry(pair) { console.log('Removing registry...'); - await dock.revocation.removeRegistryWithOneOfPolicy(registryId, controllerDID, pair, 1, { didModule: dock.did }, false); + await dock.revocation.removeRegistryWithOneOfPolicy(registryId, controllerDID, pair, { didModule: dock.did }, false); console.log('Registry removed. All done.'); } async function unrevoke(pair) { console.log('Trying to undo the revocation (unrevoke) of id:', revokeId); - const extrinsic = await dock.revocation.unrevokeCredentialWithOneOfPolicy(registryId, revokeId, controllerDID, pair, 1, { didModule: dock.did }, false); + const extrinsic = await dock.revocation.unrevokeCredentialWithOneOfPolicy(registryId, revokeId, controllerDID, pair, { didModule: dock.did }, false); await extrinsic; } async function revoke(pair) { console.log('Trying to revoke id:', revokeId); - const extrinsic = await dock.revocation.revokeCredentialWithOneOfPolicy(registryId, revokeId, controllerDID, pair, 1, { didModule: dock.did }, false); + const extrinsic = await dock.revocation.revokeCredentialWithOneOfPolicy(registryId, revokeId, controllerDID, pair, { didModule: dock.did }, false); await extrinsic; } @@ -65,13 +64,13 @@ async function main() { dock.setAccount(account); // The DID should be written before creating a registry - const pair = dock.keyring.addFromUri(controllerSeed, null, 'sr25519'); + const pair = new DidKeypair(dock.keyring.addFromUri(controllerSeed, null, 'sr25519'), 1); // Set our controller DID and associated keypair to be used for generating proof console.log(`Creating controller DID (${controllerDID}) using sr25519 pair from seed (${controllerSeed})...`); // The controller is same as the DID - const publicKey = getPublicKeyFromKeyringPair(pair); + const publicKey = pair.publicKey(); const didKey = new DidKey(publicKey, new VerificationRelationship()); await dock.did.new(controllerDID, [didKey], [], false); diff --git a/example/schema.js b/example/schema.js index a5e7c0792..49f0fdf08 100644 --- a/example/schema.js +++ b/example/schema.js @@ -2,8 +2,7 @@ import { randomAsHex } from '@polkadot/util-crypto'; import Schema from '../src/modules/schema'; import { DockAPI } from '../src/index'; -import { createNewDockDID } from '../src/utils/did'; -import { getPublicKeyFromKeyringPair } from '../src/utils/misc'; +import { createNewDockDID, DidKeypair } from '../src/utils/did'; import VerifiableCredential from '../src/verifiable-credential'; import { Ed25519VerKeyName } from '../src/utils/vc/crypto/constants'; import { getKeyDoc } from '../src/utils/vc/helpers'; @@ -27,7 +26,7 @@ async function createAuthorDID(dock, pair) { console.log('Creating new author DID', dockDID); // Create an author DID to write with - const publicKey = getPublicKeyFromKeyringPair(pair); + const publicKey = pair.publicKey(); const didKey = new DidKey(publicKey, new VerificationRelationship()); await dock.did.new(dockDID, [didKey], [], false); return dockDID; @@ -47,7 +46,7 @@ async function main() { const subjectKeySeed = randomAsHex(32); // Generate first key with this seed. The key type is Sr25519 - const pair = dock.keyring.addFromUri(keySeed, null, 'ed25519'); + const pair = new DidKeypair(dock.keyring.addFromUri(keySeed, null, 'ed25519'), 1); // Generate a DID to be used as author const dockDID = await createAuthorDID(dock, pair); @@ -59,7 +58,7 @@ async function main() { Ed25519VerKeyName, ); - const subjectPair = dock.keyring.addFromUri(subjectKeySeed); + const subjectPair = new DidKeypair(dock.keyring.addFromUri(subjectKeySeed), 1); const subjectDID = createNewDockDID(); await registerNewDIDUsingPair(dock, subjectDID, subjectPair); @@ -88,7 +87,7 @@ async function main() { console.log('The schema is:', JSON.stringify(schema.toJSON(), null, 2)); console.log('Writing schema to the chain with blob id of', schema.id, '...'); - await schema.writeToChain(dock, dockDID, pair, 1, undefined, false); + await schema.writeToChain(dock, dockDID, pair, undefined, false); console.log(`Schema written, reading from chain (${schema.id})...`); diff --git a/example/vcdm.js b/example/vcdm.js index ebb81985e..6368d6c39 100644 --- a/example/vcdm.js +++ b/example/vcdm.js @@ -3,7 +3,7 @@ import { randomAsHex } from '@polkadot/util-crypto'; import dock from '../src/index'; import VerifiableCredential from '../src/verifiable-credential'; import VerifiablePresentation from '../src/verifiable-presentation'; -import { createNewDockDID } from '../src/utils/did'; +import { createNewDockDID, DidKeypair, typedHexDID } from '../src/utils/did'; import { registerNewDIDUsingPair } from '../tests/integration/helpers'; import { createRandomRegistryId, OneOfPolicy, buildDockCredentialStatus } from '../src/utils/revocation'; import { FullNodeEndpoint, TestAccountURI } from '../tests/test-constants'; @@ -44,17 +44,17 @@ async function setup() { // Register issuer DID console.log('Registering issuer DID...'); - const pair = dock.keyring.addFromUri(issuerSeed, null, 'ed25519'); + const pair = new DidKeypair(dock.keyring.addFromUri(issuerSeed, null, 'ed25519'), 1); await registerNewDIDUsingPair(dock, issuerDID, pair); // Register holder DID console.log('Registering holder DID...'); - const pair1 = dock.keyring.addFromUri(holderSeed, null, 'ed25519'); + const pair1 = new DidKeypair(dock.keyring.addFromUri(holderSeed, null, 'ed25519'), 1); await registerNewDIDUsingPair(dock, holderDID, pair1); // Create a new policy const policy = new OneOfPolicy(); - policy.addOwner(issuerDID); + policy.addOwner(typedHexDID(dock.api, issuerDID)); // Add a new revocation registry with above policy console.log('Creating registry...'); diff --git a/scripts/hit_1.js b/scripts/hit_1.js index 70f57558f..17735e81e 100644 --- a/scripts/hit_1.js +++ b/scripts/hit_1.js @@ -1,7 +1,7 @@ import { randomAsHex } from '@polkadot/util-crypto'; import dock, { DockAPI } from '../src/index'; import { - createNewDockDID, + createNewDockDID, DidKeypair, } from '../src/utils/did'; import { getPublicKeyFromKeyringPair } from '../src/utils/misc'; import { sendBatch } from './helpers'; @@ -47,7 +47,7 @@ async function sendOnChainDIDTxns(count, waitForFinalization = true) { const didKey = new DidKey(publicKey, new VerificationRelationship()); const tx = dock.did.createNewOnchainTx(did, [didKey], []); txs.push(tx); - didPairs.push([did, pair]); + didPairs.push([did, new DidKeypair(pair, 1)]); } await sendBatch(dock, txs, account.address, waitForFinalization); @@ -77,7 +77,7 @@ async function sendAddKeyTxns(count, didPairs) { const newPair = dock.keyring.addFromUri(seed, null, 'sr25519'); const publicKey = getPublicKeyFromKeyringPair(newPair); const didKey = new DidKey(publicKey, new VerificationRelationship()); - const tx = await dock.did.createAddKeysTx([didKey], did, did, currentPair, 1); + const tx = await dock.did.createAddKeysTx([didKey], did, did, currentPair); txs.push(tx); j++; } @@ -105,7 +105,7 @@ async function sendAddControllerTxns(count, didPairs) { while (txs.length < count) { const did = didPairs[j][0]; const currentPair = didPairs[j][1]; - const tx = await dock.did.createAddControllersTx([createNewDockDID()], did, did, currentPair, 1); + const tx = await dock.did.createAddControllersTx([createNewDockDID()], did, did, currentPair); txs.push(tx); j++; } @@ -133,7 +133,7 @@ async function sendRemoveTxns(count, didPairs, waitForFinalization = true) { while (txs.length < count) { const did = didPairs[j][0]; const currentPair = didPairs[j][1]; - const tx = await dock.did.createRemoveTx(did, did, currentPair, 1); + const tx = await dock.did.createRemoveTx(did, did, currentPair); txs.push(tx); j++; } @@ -166,7 +166,7 @@ async function sendBlobTxns(count, didPairs) { id: blobId, blob: randomAsHex(995), }; - const tx = await dock.blob.createNewTx(blob, did, pair, 1, { didModule: dock.did }); + const tx = await dock.blob.createNewTx(blob, did, pair, { didModule: dock.did }); txs.push(tx); blobIds.push(blobId); j++; @@ -207,15 +207,16 @@ async function sendAnchorTxns(count) { } async function runOnce() { - let didPairs = await sendOnChainDIDTxns(1950); + const count = 1000; + let didPairs = await sendOnChainDIDTxns(count); console.log(''); - didPairs = await sendAddKeyTxns(1950, didPairs); + didPairs = await sendAddKeyTxns(count, didPairs); console.log(''); - await sendAddControllerTxns(1950, didPairs); + await sendAddControllerTxns(count, didPairs); console.log(''); - await sendBlobTxns(1500, didPairs); + await sendBlobTxns(800, didPairs); console.log(''); - await sendRemoveTxns(1950, didPairs); + await sendRemoveTxns(count, didPairs); } async function runInLoop(limit) { diff --git a/scripts/master_voting/vote.js b/scripts/master_voting/vote.js index de2954af4..dbcf3eec7 100644 --- a/scripts/master_voting/vote.js +++ b/scripts/master_voting/vote.js @@ -2,7 +2,7 @@ import { u8aToHex } from '@polkadot/util'; import { connect, keypair } from '../helpers'; -import { getHexIdentifierFromDID } from '../../src/utils/did'; +import { typedHexDID } from '../../src/utils/did'; import { getStateChange } from '../../src/utils/misc'; require('dotenv').config(); @@ -45,7 +45,7 @@ async function main() { const round_no = parseIntChecked(process.argv[2]); - const did = getHexIdentifierFromDID(did); + const did = typedHexDID(did); const proposal_filename = process.argv[3]; const proposal_unparsed = await fsp.readFile(proposal_filename); @@ -86,7 +86,7 @@ async function main() { console.log(''); const encodedProposal = [...nc.api.createType('Call', proposal).toU8a()]; - const nonce = await nc.didModule.getNextNonceForDID(did); + const nonce = await nc.didModule.getNextNonceForDid(did); const vote = { nonce, proposal: encodedProposal, round_no: actual_round_no }; const encodedStateChange = getStateChange(nc.api, 'MasterVote', vote); diff --git a/scripts/txn-pricing.js b/scripts/txn-pricing.js index 4e746c940..ef4537a8e 100755 --- a/scripts/txn-pricing.js +++ b/scripts/txn-pricing.js @@ -5,7 +5,7 @@ import { BTreeSet } from '@polkadot/types'; import { randomAsHex } from '@polkadot/util-crypto'; import dock from '../src/index'; import { - createNewDockDID, + createNewDockDID, DidKeypair, typedHexDID, } from '../src/utils/did'; import { getPublicKeyFromKeyringPair } from '../src/utils/misc'; import { createRandomRegistryId, OneOfPolicy } from '../src/utils/revocation'; @@ -34,7 +34,7 @@ function getDidPair() { const pair = dock.keyring.addFromUri(seed, null, 'sr25519'); const publicKey = getPublicKeyFromKeyringPair(pair); const didKey = new DidKey(publicKey, new VerificationRelationship()); - return [did, pair, didKey]; + return [did, new DidKeypair(pair, 1), didKey]; } async function printFeePaid(dockApi, address, fn) { @@ -59,7 +59,7 @@ async function dids() { const [, , dk1] = getDidPair(); await printFeePaid(dock.api, account.address, async () => { console.info('Adding DID key with all verification relationships'); - await dock.did.addKeys([dk1], did, did, pair, 1, undefined, false); + await dock.did.addKeys([dk1], did, did, pair, undefined, false); }); // Add DID key with only 1 verification relationship @@ -67,7 +67,7 @@ async function dids() { dk2.verRels.setAuthentication(); await printFeePaid(dock.api, account.address, async () => { console.info('Adding DID key with only 1 verification relationship'); - await dock.did.addKeys([dk2], did, did, pair, 1, undefined, false); + await dock.did.addKeys([dk2], did, did, pair, undefined, false); }); // Add DID key with only 2 verification relationships @@ -76,7 +76,7 @@ async function dids() { dk3.verRels.setAssertion(); await printFeePaid(dock.api, account.address, async () => { console.info('Adding DID key with only 2 verification relationships'); - await dock.did.addKeys([dk3], did, did, pair, 1, undefined, false); + await dock.did.addKeys([dk3], did, did, pair, undefined, false); }); // Add DID key with 3 verification relationships @@ -86,7 +86,7 @@ async function dids() { dk4.verRels.setCapabilityInvocation(); await printFeePaid(dock.api, account.address, async () => { console.info('Adding DID key with 3 verification relationships'); - await dock.did.addKeys([dk4], did, did, pair, 1, undefined, false); + await dock.did.addKeys([dk4], did, did, pair, undefined, false); }); // Add 2 DID keys with only 1 verification relationship @@ -96,7 +96,7 @@ async function dids() { dk6.verRels.setCapabilityInvocation(); await printFeePaid(dock.api, account.address, async () => { console.info('Adding 2 DID keys with only 1 verification relationship'); - await dock.did.addKeys([dk5, dk6], did, did, pair, 1, undefined, false); + await dock.did.addKeys([dk5, dk6], did, did, pair, undefined, false); }); // Add 3 DID keys with only 1 verification relationship @@ -108,20 +108,20 @@ async function dids() { dk9.verRels.setAssertion(); await printFeePaid(dock.api, account.address, async () => { console.info('Adding 3 DID keys with only 1 verification relationship'); - await dock.did.addKeys([dk7, dk8, dk9], did, did, pair, 1, undefined, false); + await dock.did.addKeys([dk7, dk8, dk9], did, did, pair, undefined, false); }); const newControllers = [createNewDockDID(), createNewDockDID(), createNewDockDID()]; // Add 1 controller await printFeePaid(dock.api, account.address, async () => { console.info('Adding 1 controller'); - await dock.did.addControllers([newControllers[0]], did, did, pair, 1, undefined, false); + await dock.did.addControllers([newControllers[0]], did, did, pair, undefined, false); }); // Add 2 controllers await printFeePaid(dock.api, account.address, async () => { console.info('Adding 2 controllers'); - await dock.did.addControllers([newControllers[1], newControllers[2]], did, did, pair, 1, undefined, false); + await dock.did.addControllers([newControllers[1], newControllers[2]], did, did, pair, undefined, false); }); const spType = new ServiceEndpointType(); @@ -133,13 +133,13 @@ async function dids() { // Add 1 service endpoint with 1 origin await printFeePaid(dock.api, account.address, async () => { console.info('Adding 1 service endpoint with 1 origin'); - await dock.did.addServiceEndpoint(spId1, spType, origins1, did, did, pair, 1, undefined, false); + await dock.did.addServiceEndpoint(spId1, spType, origins1, did, did, pair, undefined, false); }); // Add 1 service endpoint with 2 origins await printFeePaid(dock.api, account.address, async () => { console.info('Adding 1 service endpoint with 2 origins'); - await dock.did.addServiceEndpoint(spId2, spType, origins2, did, did, pair, 1, undefined, false); + await dock.did.addServiceEndpoint(spId2, spType, origins2, did, did, pair, undefined, false); }); // Adding a new DID which doesn't control itself but controlled by one other controller @@ -167,43 +167,43 @@ async function dids() { const [, , dk__] = getDidPair(); await printFeePaid(dock.api, account.address, async () => { console.info('Adding DID key with all verification relationships to a DID that doesnt control itself'); - await dock.did.addKeys([dk__], did1, did, pair, 1, undefined, false); + await dock.did.addKeys([dk__], did1, did, pair, undefined, false); }); // Removing 1 key await printFeePaid(dock.api, account.address, async () => { console.info('Removing 1 key'); - await dock.did.removeKeys([2], did, did, pair, 1, undefined, false); + await dock.did.removeKeys([2], did, did, pair, undefined, false); }); // Removing 2 keys await printFeePaid(dock.api, account.address, async () => { console.info('Removing 2 keys'); - await dock.did.removeKeys([3, 4], did, did, pair, 1, undefined, false); + await dock.did.removeKeys([3, 4], did, did, pair, undefined, false); }); // Removing 1 controller await printFeePaid(dock.api, account.address, async () => { console.info('Removing 1 controller'); - await dock.did.removeControllers([newControllers[0]], did, did, pair, 1, undefined, false); + await dock.did.removeControllers([newControllers[0]], did, did, pair, undefined, false); }); // Removing 2 controllers await printFeePaid(dock.api, account.address, async () => { console.info('Removing 2 controllers'); - await dock.did.removeControllers([newControllers[1], newControllers[2]], did, did, pair, 1, undefined, false); + await dock.did.removeControllers([newControllers[1], newControllers[2]], did, did, pair, undefined, false); }); // Removing 1 service endpoint await printFeePaid(dock.api, account.address, async () => { console.info('Removing service endpoint'); - await dock.did.removeServiceEndpoint(spId1, did, did, pair, 1, undefined, false); + await dock.did.removeServiceEndpoint(spId1, did, did, pair, undefined, false); }); // Remove DID await printFeePaid(dock.api, account.address, async () => { console.info('Removing DID'); - await dock.did.remove(did, did, pair, 1, undefined, false); + await dock.did.remove(did, did, pair, undefined, false); }); } @@ -217,7 +217,7 @@ async function revocation() { const registryId = createRandomRegistryId(); // Create owners const owners = new Set(); - owners.add(did); + owners.add(typedHexDID(dock.api, did)); const policy = new OneOfPolicy(owners); await printFeePaid(dock.api, account.address, async () => { @@ -232,16 +232,16 @@ async function revocation() { revokeIds.add(randomAsHex(32)); } - const [update, sig, nonce] = await dock.revocation.createSignedRevoke(registryId, revokeIds, did, pair, 1, { didModule: dock.did }); - const revTx = dock.revocation.createRevokeTx(update, [[sig, nonce]]); + const [update, sig, nonce] = await dock.revocation.createSignedRevoke(registryId, revokeIds, did, pair, { didModule: dock.did }); + const revTx = dock.revocation.createRevokeTx(update, [{ nonce, sig }]); console.info(`Payment info of ${count} revocation is ${(await revTx.paymentInfo(account.address))}`); await printFeePaid(dock.api, account.address, async () => { await dock.signAndSend(revTx, false); }); } - const [update, sig, nonce] = await dock.revocation.createSignedRemove(registryId, did, pair, 1, { didModule: dock.did }); - const revTx = dock.revocation.createRemoveRegistryTx(update, [[sig, nonce]]); + const [update, sig, nonce] = await dock.revocation.createSignedRemove(registryId, did, pair, { didModule: dock.did }); + const revTx = dock.revocation.createRemoveRegistryTx(update, [{ nonce, sig }]); console.info(`Payment info of removing registry is ${(await revTx.paymentInfo(account.address))}`); await printFeePaid(dock.api, account.address, async () => { @@ -274,7 +274,7 @@ async function blobs() { }; await printFeePaid(dock.api, account.address, async () => { console.info('Blob write'); - await dock.blob.new(blob, did, pair, 1, { didModule: dock.did }, false); + await dock.blob.new(blob, did, pair, { didModule: dock.did }, false); }); } @@ -295,28 +295,28 @@ async function bbsPlus() { const params = BBSPlusModule.prepareAddParameters(bytes, undefined, label); await printFeePaid(dock.api, account.address, async () => { console.info(`Add BBS+ params with ${attributeCount} attributes`); - await dock.bbsPlusModule.addParams(params, did, pair, 1, { didModule: dock.did }, false); + await dock.bbsPlusModule.addParams(params, did, pair, { didModule: dock.did }, false); }); } // Add a public key const kp = BBSPlusKeypairG2.generate(BBSPlusSignatureParamsG1.generate(10, hexToU8a(label))); - const pk = BBSPlusModule.prepareAddPublicKey(u8aToHex(kp.publicKey.bytes), undefined, [did, 1]); + const pk = BBSPlusModule.prepareAddPublicKey(dock.api, u8aToHex(kp.publicKey.bytes), undefined, [did, 1]); await printFeePaid(dock.api, account.address, async () => { console.info('Add a BBS+ key'); - await dock.bbsPlusModule.addPublicKey(pk, did, did, pair, 1, { didModule: dock.did }, false); + await dock.bbsPlusModule.addPublicKey(pk, did, did, pair, { didModule: dock.did }, false); }); // Remove public key await printFeePaid(dock.api, account.address, async () => { console.info('Remove BBS+ key'); - await dock.bbsPlusModule.removePublicKey(2, did, did, pair, 1, { didModule: dock.did }, false); + await dock.bbsPlusModule.removePublicKey(2, did, did, pair, { didModule: dock.did }, false); }); // Remove params await printFeePaid(dock.api, account.address, async () => { console.info('Remove BBS+ params'); - await dock.bbsPlusModule.removeParams(1, did, pair, 1, { didModule: dock.did }, false); + await dock.bbsPlusModule.removeParams(1, did, pair, { didModule: dock.did }, false); }); } @@ -334,15 +334,15 @@ async function accumulator() { const params = AccumulatorModule.prepareAddParameters(bytes, undefined, label); await printFeePaid(dock.api, account.address, async () => { console.info('Accumulator params write'); - await dock.accumulatorModule.addParams(params, did, pair, 1, { didModule: dock.did }, false); + await dock.accumulatorModule.addParams(params, did, pair, { didModule: dock.did }, false); }); const kp = Accumulator.generateKeypair(new AccumulatorParams(hexToU8a(params.bytes))); - const pk = AccumulatorModule.prepareAddPublicKey(u8aToHex(kp.publicKey.bytes), undefined, [did, 1]); + const pk = AccumulatorModule.prepareAddPublicKey(dock.api, u8aToHex(kp.publicKey.bytes), undefined, [did, 1]); await printFeePaid(dock.api, account.address, async () => { console.info('Accumulator key write'); - await dock.accumulatorModule.addPublicKey(pk, did, pair, 1, { didModule: dock.did }, false); + await dock.accumulatorModule.addPublicKey(pk, did, pair, { didModule: dock.did }, false); }); const accumulatorPos = PositiveAccumulator.initialize(new AccumulatorParams(hexToU8a(params.bytes)), kp.secretKey); @@ -350,14 +350,14 @@ async function accumulator() { const accumulatedPos = u8aToHex(accumulatorPos.accumulated); await printFeePaid(dock.api, account.address, async () => { console.info('Adding a positive accumulator'); - await dock.accumulatorModule.addPositiveAccumulator(accumulatorIdPos, accumulatedPos, [did, 1], did, pair, 1, { didModule: dock.did }, false); + await dock.accumulatorModule.addPositiveAccumulator(accumulatorIdPos, accumulatedPos, [did, 1], did, pair, { didModule: dock.did }, false); }); const accumulatorIdUni = randomAsHex(32); const accumulatedUni = u8aToHex(accumulatorPos.accumulated); await printFeePaid(dock.api, account.address, async () => { console.info('Adding a universal accumulator'); - await dock.accumulatorModule.addUniversalAccumulator(accumulatorIdUni, accumulatedUni, [did, 1], 10000, did, pair, 1, { didModule: dock.did }, false); + await dock.accumulatorModule.addUniversalAccumulator(accumulatorIdUni, accumulatedUni, [did, 1], 10000, did, pair, { didModule: dock.did }, false); }); const start = 10; @@ -372,20 +372,20 @@ async function accumulator() { let witUpd = u8aToHex(WitnessUpdatePublicInfo.new(hexToU8a(accumulated), members, [], kp.secretKey).value); await printFeePaid(dock.api, account.address, async () => { console.info(`Updating a positive accumulator with ${members.length} additions`); - await dock.accumulatorModule.updateAccumulator(accumulatorIdPos, accumulated, { additions: members.map((m) => u8aToHex(m)), witnessUpdateInfo: witUpd }, did, pair, 1, { didModule: dock.did }, false); + await dock.accumulatorModule.updateAccumulator(accumulatorIdPos, accumulated, { additions: members.map((m) => u8aToHex(m)), witnessUpdateInfo: witUpd }, did, pair, { didModule: dock.did }, false); }); witUpd = u8aToHex(WitnessUpdatePublicInfo.new(hexToU8a(accumulated), [], members, kp.secretKey).value); await printFeePaid(dock.api, account.address, async () => { console.info(`Updating a positive accumulator with ${members.length} removals`); - await dock.accumulatorModule.updateAccumulator(accumulatorIdPos, accumulated, { removals: members.map((m) => u8aToHex(m)), witnessUpdateInfo: witUpd }, did, pair, 1, { didModule: dock.did }, false); + await dock.accumulatorModule.updateAccumulator(accumulatorIdPos, accumulated, { removals: members.map((m) => u8aToHex(m)), witnessUpdateInfo: witUpd }, did, pair, { didModule: dock.did }, false); }); } await printFeePaid(dock.api, account.address, async () => { console.info('Removing a positive accumulator'); - await dock.accumulatorModule.removeAccumulator(accumulatorIdPos, did, pair, 1, { didModule: dock.did }, false); + await dock.accumulatorModule.removeAccumulator(accumulatorIdPos, did, pair, { didModule: dock.did }, false); }); } diff --git a/src/dock-api.js b/src/dock-api.js index 8e2291251..be2daba90 100644 --- a/src/dock-api.js +++ b/src/dock-api.js @@ -22,6 +22,7 @@ import PriceFeedRpcDefs from './rpc-defs/price-feed-rpc-defs'; import CoreModsRpcDefs from './rpc-defs/core-mods-rpc-defs'; import ExtrinsicError from './errors/extrinsic-error'; +import TrustRegistryModule from './modules/trust-registry'; function getExtrinsicError(data, api) { // Loop through each of the parameters @@ -133,6 +134,15 @@ export default class DockAPI { this.api = await ApiPromise.create(apiOptions); + const runtimeVersion = await this.api.rpc.state.getRuntimeVersion(); + const specVersion = runtimeVersion.specVersion.toNumber(); + + if (specVersion < 50) { + apiOptions.types = { ...(apiOptions.types || {}), DidOrDidMethodKey: 'Did' }; + this.api = await ApiPromise.create(apiOptions); + } + this.api.specVersion = specVersion; + await this.initKeyring(keyring); this.anchorModule.setApi(this.api, this.signAndSend.bind(this)); @@ -142,6 +152,10 @@ export default class DockAPI { this.api, this.signAndSend.bind(this), ); + this.trustRegistryModule = new TrustRegistryModule( + this.api, + this.signAndSend.bind(this), + ); this.statusListCredentialModule = new StatusListCredentialModule( this.api, this.signAndSend.bind(this), @@ -201,6 +215,7 @@ export default class DockAPI { delete this.migrationModule; delete this.legacyBBSPlus; delete this.statusListCredentialModule; + delete this.trustRegistryModule; } } @@ -369,6 +384,19 @@ export default class DockAPI { return this.statusListCredentialModule; } + /** + * Gets the SDK's TrustRegistryModule module + * @return {TrustRegistryModule} The module to use + */ + get trustRegistry() { + if (!this.trustRegistryModule) { + throw new Error( + 'Unable to get TrustRegistryModule module, SDK is not initialised', + ); + } + return this.trustRegistryModule; + } + /** * Gets the SDK's OffchainSignaturesModule module * @return {OffchainSignaturesModule} The module to use diff --git a/src/modules/WithParamsAndPublicKeys.js b/src/modules/WithParamsAndPublicKeys.js index 2289607ef..8fc13e300 100644 --- a/src/modules/WithParamsAndPublicKeys.js +++ b/src/modules/WithParamsAndPublicKeys.js @@ -1,15 +1,17 @@ /* eslint-disable camelcase */ import { u8aToHex } from '@polkadot/util'; -import { createDidSig, getHexIdentifierFromDID } from '../utils/did'; -import { getNonce } from '../utils/misc'; +import { createDidSig, typedHexDID, typedHexDIDFromSubstrate } from '../utils/did'; +import { getDidNonce } from '../utils/misc'; /** * Class with logic for public keys and corresponding setup parameters. * This logic is common in offchain signatures modules and accumulator */ export default class WithParamsAndPublicKeys { - /// Builds module-specific params from the provided value. + /** + * Builds module-specific params from the provided value. + */ static buildParams(params) { return params; } @@ -47,6 +49,7 @@ export default class WithParamsAndPublicKeys { * @returns {{}} */ static prepareAddPublicKey( + api, bytes, curveType = undefined, paramsRef = undefined, @@ -65,7 +68,7 @@ export default class WithParamsAndPublicKeys { throw new Error(`Invalid curve type ${curveType}`); } publicKey.paramsRef = paramsRef !== undefined - ? WithParamsAndPublicKeys.parseRef(paramsRef) + ? WithParamsAndPublicKeys.parseRef(api, paramsRef) : undefined; return publicKey; } @@ -76,7 +79,7 @@ export default class WithParamsAndPublicKeys { * @param ref * @returns {any[]} */ - static parseRef(ref) { + static parseRef(api, ref) { const parsed = new Array(2); if ( !(typeof ref === 'object' && ref instanceof Array && ref.length === 2) @@ -84,7 +87,7 @@ export default class WithParamsAndPublicKeys { throw new Error('Reference should be an array of 2 items'); } try { - parsed[0] = getHexIdentifierFromDID(ref[0]); + parsed[0] = typedHexDID(api, ref[0]); } catch (e) { throw new Error( `First item of reference should be a DID but was ${ref[0]}`, @@ -105,7 +108,7 @@ export default class WithParamsAndPublicKeys { * @param params - The BBS+ params to add. * @param signerDid - Signer of the payload * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Reference to the keypair used by the signer. This will be used by the verifier (node) to fetch the public key for verification * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this @@ -114,17 +117,15 @@ export default class WithParamsAndPublicKeys { async createAddParamsTx( params, signerDid, - keyPair, - keyId, + signingKeyRef, { nonce = undefined, didModule = undefined }, ) { const offchainParams = this.constructor.buildParams(params); - const hexDid = getHexIdentifierFromDID(signerDid); + const hexDid = typedHexDID(this.api, signerDid); const [addParams, signature] = await this.createSignedAddParams( offchainParams, hexDid, - keyPair, - keyId, + signingKeyRef, { nonce, didModule }, ); return this.module.addParams(addParams, signature); @@ -135,7 +136,7 @@ export default class WithParamsAndPublicKeys { * @param index - Index to uniquely identify BBS+ params * @param signerDid - Signer of the payload * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Reference to the keypair used by the signer. This will be used by the verifier (node) to fetch the public key for verification * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this @@ -144,16 +145,14 @@ export default class WithParamsAndPublicKeys { async removeParamsTx( index, signerDid, - keyPair, - keyId, + signingKeyRef, { nonce = undefined, didModule = undefined }, ) { - const hexDid = getHexIdentifierFromDID(signerDid); + const hexDid = typedHexDID(this.api, signerDid); const [removeParams, signature] = await this.createSignedRemoveParams( index, hexDid, - keyPair, - keyId, + signingKeyRef, { nonce, didModule }, ); return this.module.removeParams(removeParams, signature); @@ -164,7 +163,7 @@ export default class WithParamsAndPublicKeys { * @param param - The signature params to add. * @param signerDid - Signer of the payload * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Reference to the keypair used by the signer. This will be used by the verifier (node) to fetch the public key for verification * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this @@ -175,13 +174,12 @@ export default class WithParamsAndPublicKeys { async addParams( param, signerDid, - keyPair, - keyId, + signingKeyRef, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}, ) { - const tx = await this.createAddParamsTx(param, signerDid, keyPair, keyId, { + const tx = await this.createAddParamsTx(param, signerDid, signingKeyRef, { nonce, didModule, }); @@ -193,7 +191,7 @@ export default class WithParamsAndPublicKeys { * @param index - Index to uniquely identify BBS+ params * @param signerDid - Signer of the blob * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Reference to the keypair used by the signer. This will be used by the verifier (node) to fetch the public key for verification * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this @@ -204,13 +202,12 @@ export default class WithParamsAndPublicKeys { async removeParams( index, signerDid, - keyPair, - keyId, + signingKeyRef, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}, ) { - const tx = await this.removeParamsTx(index, signerDid, keyPair, keyId, { + const tx = await this.removeParamsTx(index, signerDid, signingKeyRef, { nonce, didModule, }); @@ -220,30 +217,28 @@ export default class WithParamsAndPublicKeys { async createSignedAddParams( params, hexDid, - keyPair, - keyId, + signingKeyRef, { nonce = undefined, didModule = undefined }, ) { // eslint-disable-next-line no-param-reassign - nonce = await getNonce(hexDid, nonce, didModule); + nonce = await getDidNonce(hexDid, nonce, didModule); const addParams = { params, nonce }; - const signature = this.signAddParams(keyPair, addParams); - const didSig = createDidSig(hexDid, keyId, signature); + const signature = this.signAddParams(signingKeyRef, addParams); + const didSig = createDidSig(hexDid, signingKeyRef, signature); return [addParams, didSig]; } async createSignedRemoveParams( index, hexDid, - keyPair, - keyId, + signingKeyRef, { nonce = undefined, didModule = undefined }, ) { // eslint-disable-next-line no-param-reassign - nonce = await getNonce(hexDid, nonce, didModule); + nonce = await getDidNonce(hexDid, nonce, didModule); const removeParams = { paramsRef: [hexDid, index], nonce }; - const signature = this.signRemoveParams(keyPair, removeParams); - const didSig = createDidSig(hexDid, keyId, signature); + const signature = this.signRemoveParams(signingKeyRef, removeParams); + const didSig = createDidSig(hexDid, signingKeyRef, signature); return [removeParams, didSig]; } @@ -258,7 +253,7 @@ export default class WithParamsAndPublicKeys { } async getParams(did, counter) { - const hexId = getHexIdentifierFromDID(did); + const hexId = typedHexDID(this.api, did); return this.getParamsByHexDid(hexId, counter); } @@ -271,7 +266,7 @@ export default class WithParamsAndPublicKeys { * @returns {Promise<{bytes: string}|null>} */ async getPublicKey(did, keyId, withParams = false) { - const hexId = getHexIdentifierFromDID(did); + const hexId = typedHexDID(this.api, did); return this.getPublicKeyByHexDid(hexId, keyId, withParams); } @@ -286,7 +281,7 @@ export default class WithParamsAndPublicKeys { async getPublicKeyByHexDid(hexDid, keyId, withParams = false) { const resp = await this.queryPublicKeyFromChain(hexDid, keyId); if (resp) { - const pkObj = WithParamsAndPublicKeys.createPublicKeyObjFromChainResponse(resp); + const pkObj = WithParamsAndPublicKeys.createPublicKeyObjFromChainResponse(this.api, resp); if (withParams) { if (pkObj.paramsRef === null) { throw new Error('No reference to parameters for the public key'); @@ -333,7 +328,7 @@ export default class WithParamsAndPublicKeys { * @param pk * @returns {{bytes: string}} */ - static createPublicKeyObjFromChainResponse(pk) { + static createPublicKeyObjFromChainResponse(api, pk) { const pkObj = { bytes: u8aToHex(pk.bytes), }; @@ -342,7 +337,7 @@ export default class WithParamsAndPublicKeys { } if (pk.paramsRef.isSome) { const pr = pk.paramsRef.unwrap(); - pkObj.paramsRef = [u8aToHex(pr[0]), pr[1].toNumber()]; + pkObj.paramsRef = [typedHexDIDFromSubstrate(api, pr[0]), pr[1].toNumber()]; } else { pkObj.paramsRef = null; } diff --git a/src/modules/accumulator.js b/src/modules/accumulator.js index 45e492f29..f636b4db6 100644 --- a/src/modules/accumulator.js +++ b/src/modules/accumulator.js @@ -1,10 +1,10 @@ /* eslint-disable camelcase */ import { isHex, u8aToHex } from '@polkadot/util'; -import { getNonce, getSignatureFromKeyringPair, getStateChange } from '../utils/misc'; +import { getDidNonce, getStateChange } from '../utils/misc'; import WithParamsAndPublicKeys from './WithParamsAndPublicKeys'; import { getAllExtrinsicsFromBlock } from '../utils/chain-ops'; -import { createDidSig, getHexIdentifierFromDID } from '../utils/did'; +import { createDidSig, typedHexDID, typedHexDIDFromSubstrate } from '../utils/did'; /** Class to manage accumulators on chain */ export default class AccumulatorModule extends WithParamsAndPublicKeys { @@ -16,28 +16,28 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { this.signAndSend = signAndSend; } - static prepareAddPositiveAccumulator(id, accumulated, publicKeyRef) { - const vals = AccumulatorModule.parseRef(publicKeyRef); + static prepareAddPositiveAccumulator(api, id, accumulated, publicKeyRef) { + const keyRef = AccumulatorModule.parseRef(api, publicKeyRef); return { id, accumulator: { Positive: { accumulated, - keyRef: vals, + keyRef, }, }, }; } - static prepareAddUniversalAccumulator(id, accumulated, publicKeyRef, maxSize) { - const vals = AccumulatorModule.parseRef(publicKeyRef); + static prepareAddUniversalAccumulator(api, id, accumulated, publicKeyRef, maxSize) { + const keyRef = AccumulatorModule.parseRef(api, publicKeyRef); return { id, accumulator: { Universal: { common: { accumulated, - keyRef: vals, + keyRef, }, maxSize, }, @@ -77,16 +77,15 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { * Create transaction to add accumulator public key * @param publicKey - Accumulator public key * @param signerDid - Signer of the transaction payload - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this * @returns {Promise<*>} */ - async createAddPublicKeyTx(publicKey, signerDid, keyPair, keyId, { nonce = undefined, didModule = undefined }) { - const signerHexDid = getHexIdentifierFromDID(signerDid); - const [addPk, signature] = await this.createSignedAddPublicKey(publicKey, signerHexDid, keyPair, keyId, { nonce, didModule }); + async createAddPublicKeyTx(publicKey, signerDid, signingKeyRef, { nonce = undefined, didModule = undefined }) { + const signerHexDid = typedHexDID(this.api, signerDid); + const [addPk, signature] = await this.createSignedAddPublicKey(publicKey, signerHexDid, signingKeyRef, { nonce, didModule }); return this.module.addPublicKey(addPk, signature); } @@ -94,16 +93,15 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { * Create transaction to remove accumulator public key * @param removeKeyId - Index of the accumulator public key * @param signerDid - Signer of the transaction payload - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this * @returns {Promise<*>} */ - async createRemovePublicKeyTx(removeKeyId, signerDid, keyPair, keyId, { nonce = undefined, didModule = undefined }) { - const signerHexDid = getHexIdentifierFromDID(signerDid); - const [remPk, signature] = await this.createSignedRemovePublicKey(removeKeyId, signerHexDid, keyPair, keyId, { nonce, didModule }); + async createRemovePublicKeyTx(removeKeyId, signerDid, signingKeyRef, { nonce = undefined, didModule = undefined }) { + const signerHexDid = typedHexDID(this.api, signerDid); + const [remPk, signature] = await this.createSignedRemovePublicKey(removeKeyId, signerHexDid, signingKeyRef, { nonce, didModule }); return this.module.removePublicKey(remPk, signature); } @@ -113,16 +111,15 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { * @param accumulated - Current accumulated value. * @param publicKeyRef - Reference to accumulator public key * @param signerDid - Signer of the transaction payload - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this * @returns {Promise<*>} */ - async createAddPositiveAccumulatorTx(id, accumulated, publicKeyRef, signerDid, keyPair, keyId, { nonce = undefined, didModule = undefined }) { - const signerHexDid = getHexIdentifierFromDID(signerDid); - const [addAccumulator, signature] = await this.createSignedAddPositiveAccumulator(id, accumulated, publicKeyRef, signerHexDid, keyPair, keyId, { nonce, didModule }); + async createAddPositiveAccumulatorTx(id, accumulated, publicKeyRef, signerDid, signingKeyRef, { nonce = undefined, didModule = undefined }) { + const signerHexDid = typedHexDID(this.api, signerDid); + const [addAccumulator, signature] = await this.createSignedAddPositiveAccumulator(id, accumulated, publicKeyRef, signerHexDid, signingKeyRef, { nonce, didModule }); return this.module.addAccumulator(addAccumulator, signature); } @@ -133,16 +130,15 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { * @param publicKeyRef - Reference to accumulator public key * @param maxSize - Maximum size of the accumulator * @param signerDid - Signer of the transaction payload - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this * @returns {Promise<*>} */ - async createAddUniversalAccumulatorTx(id, accumulated, publicKeyRef, maxSize, signerDid, keyPair, keyId, { nonce = undefined, didModule = undefined }) { - const signerHexDid = getHexIdentifierFromDID(signerDid); - const [addAccumulator, signature] = await this.createSignedAddUniversalAccumulator(id, accumulated, publicKeyRef, maxSize, signerHexDid, keyPair, keyId, { nonce, didModule }); + async createAddUniversalAccumulatorTx(id, accumulated, publicKeyRef, maxSize, signerDid, signingKeyRef, { nonce = undefined, didModule = undefined }) { + const signerHexDid = typedHexDID(this.api, signerDid); + const [addAccumulator, signature] = await this.createSignedAddUniversalAccumulator(id, accumulated, publicKeyRef, maxSize, signerHexDid, signingKeyRef, { nonce, didModule }); return this.module.addAccumulator(addAccumulator, signature); } @@ -154,8 +150,7 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { * @param removals * @param witnessUpdateInfo * @param signerDid - Signer of the transaction payload - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this @@ -163,11 +158,11 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { */ async updateAccumulatorTx( id, newAccumulated, - { additions = undefined, removals = undefined, witnessUpdateInfo = undefined }, signerDid, keyPair, keyId, { nonce = undefined, didModule = undefined }, + { additions = undefined, removals = undefined, witnessUpdateInfo = undefined }, signerDid, signingKeyRef, { nonce = undefined, didModule = undefined }, ) { - const signerHexDid = getHexIdentifierFromDID(signerDid); + const signerHexDid = typedHexDID(this.api, signerDid); const [update, signature] = await this.createSignedUpdateAccumulator(id, newAccumulated, - { additions, removals, witnessUpdateInfo }, signerHexDid, keyPair, keyId, { nonce, didModule }); + { additions, removals, witnessUpdateInfo }, signerHexDid, signingKeyRef, { nonce, didModule }); return this.module.updateAccumulator(update, signature); } @@ -175,16 +170,15 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { * Create transaction to remove accumulator * @param id - id to remove * @param signerDid - Signer of the transaction payload - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this * @returns {Promise} */ - async removeAccumulatorTx(id, signerDid, keyPair, keyId, { nonce = undefined, didModule = undefined }) { - const signerHexDid = getHexIdentifierFromDID(signerDid); - const [removal, signature] = await this.createSignedRemoveAccumulator(id, signerHexDid, keyPair, keyId, { nonce, didModule }); + async removeAccumulatorTx(id, signerDid, signingKeyRef, { nonce = undefined, didModule = undefined }) { + const signerHexDid = typedHexDID(this.api, signerDid); + const [removal, signature] = await this.createSignedRemoveAccumulator(id, signerHexDid, signingKeyRef, { nonce, didModule }); return this.module.removeAccumulator(removal, signature); } @@ -192,8 +186,7 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { * Add accumulator public key * @param publicKey - Accumulator public key * @param signerDid - Signer of the transaction payload - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this @@ -201,8 +194,8 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { * @param params * @returns {Promise<*>} */ - async addPublicKey(publicKey, signerDid, keyPair, keyId, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}) { - const tx = await this.createAddPublicKeyTx(publicKey, signerDid, keyPair, keyId, { nonce, didModule }); + async addPublicKey(publicKey, signerDid, signingKeyRef, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}) { + const tx = await this.createAddPublicKeyTx(publicKey, signerDid, signingKeyRef, { nonce, didModule }); return this.signAndSend(tx, waitForFinalization, params); } @@ -210,8 +203,7 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { * Remove a public key * @param removeKeyId - Index of the accumulator public key * @param signerDid - Signer of the transaction payload - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this @@ -219,8 +211,8 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { * @param params * @returns {Promise<*>} */ - async removePublicKey(removeKeyId, signerDid, keyPair, keyId, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}) { - const tx = await this.createRemovePublicKeyTx(removeKeyId, signerDid, keyPair, keyId, { nonce, didModule }); + async removePublicKey(removeKeyId, signerDid, signingKeyRef, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}) { + const tx = await this.createRemovePublicKeyTx(removeKeyId, signerDid, signingKeyRef, { nonce, didModule }); return this.signAndSend(tx, waitForFinalization, params); } @@ -230,8 +222,7 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { * @param accumulated - Current accumulated value. * @param publicKeyRef - Reference to accumulator public key * @param signerDid - Signer of the transaction payload - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this @@ -239,8 +230,8 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { * @param params * @returns {Promise<*>} */ - async addPositiveAccumulator(id, accumulated, publicKeyRef, signerDid, keyPair, keyId, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}) { - const tx = await this.createAddPositiveAccumulatorTx(id, accumulated, publicKeyRef, signerDid, keyPair, keyId, { nonce, didModule }); + async addPositiveAccumulator(id, accumulated, publicKeyRef, signerDid, signingKeyRef, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}) { + const tx = await this.createAddPositiveAccumulatorTx(id, accumulated, publicKeyRef, signerDid, signingKeyRef, { nonce, didModule }); return this.signAndSend(tx, waitForFinalization, params); } @@ -251,8 +242,7 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { * @param publicKeyRef - Reference to accumulator public key * @param maxSize - Maximum size of the accumulator * @param signerDid - Signer of the transaction payload - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this @@ -260,8 +250,8 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { * @param params * @returns {Promise<*>} */ - async addUniversalAccumulator(id, accumulated, publicKeyRef, maxSize, signerDid, keyPair, keyId, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}) { - const tx = await this.createAddUniversalAccumulatorTx(id, accumulated, publicKeyRef, maxSize, signerDid, keyPair, keyId, { nonce, didModule }); + async addUniversalAccumulator(id, accumulated, publicKeyRef, maxSize, signerDid, signingKeyRef, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}) { + const tx = await this.createAddUniversalAccumulatorTx(id, accumulated, publicKeyRef, maxSize, signerDid, signingKeyRef, { nonce, didModule }); return this.signAndSend(tx, waitForFinalization, params); } @@ -273,8 +263,7 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { * @param removals * @param witnessUpdateInfo * @param signerDid - Signer of the transaction payload - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this @@ -283,19 +272,17 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { * @returns {Promise< object>} */ async updateAccumulator(id, newAccumulated, - { additions = undefined, removals = undefined, witnessUpdateInfo = undefined }, signerDid, keyPair, keyId, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}) { + { additions = undefined, removals = undefined, witnessUpdateInfo = undefined }, signerDid, signingKeyRef, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}) { const tx = await this.updateAccumulatorTx(id, newAccumulated, - { additions, removals, witnessUpdateInfo }, signerDid, keyPair, keyId, { nonce, didModule }); + { additions, removals, witnessUpdateInfo }, signerDid, signingKeyRef, { nonce, didModule }); return this.signAndSend(tx, waitForFinalization, params); } /** * Remove the accumulator from chain. This frees up the id for reuse. - * @param id * @param id - id to remove * @param signerDid - Signer of the transaction payload - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this @@ -303,53 +290,53 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { * @param params * @returns {Promise<*>} */ - async removeAccumulator(id, signerDid, keyPair, keyId, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}) { - const tx = await this.removeAccumulatorTx(id, signerDid, keyPair, keyId, { nonce, didModule }); + async removeAccumulator(id, signerDid, signingKeyRef, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}) { + const tx = await this.removeAccumulatorTx(id, signerDid, signingKeyRef, { nonce, didModule }); return this.signAndSend(tx, waitForFinalization, params); } - async createSignedAddPublicKey(publicKey, signerHexDid, keyPair, keyId, { nonce = undefined, didModule = undefined }) { + async createSignedAddPublicKey(publicKey, signerHexDid, signingKeyRef, { nonce = undefined, didModule = undefined }) { // eslint-disable-next-line no-param-reassign - nonce = await getNonce(signerHexDid, nonce, didModule); + nonce = await getDidNonce(signerHexDid, nonce, didModule); const addPk = { publicKey, nonce }; - const signature = this.signAddPublicKey(keyPair, addPk); - const didSig = createDidSig(signerHexDid, keyId, signature); + const signature = this.signAddPublicKey(signingKeyRef, addPk); + const didSig = createDidSig(signerHexDid, signingKeyRef, signature); return [addPk, didSig]; } - async createSignedRemovePublicKey(removeKeyId, signerHexDid, keyPair, keyId, { nonce = undefined, didModule = undefined }) { + async createSignedRemovePublicKey(removeKeyId, signerHexDid, signingKeyRef, { nonce = undefined, didModule = undefined }) { // eslint-disable-next-line no-param-reassign - nonce = await getNonce(signerHexDid, nonce, didModule); + nonce = await getDidNonce(signerHexDid, nonce, didModule); const removeKey = { keyRef: [signerHexDid, removeKeyId], nonce }; - const signature = this.signRemovePublicKey(keyPair, removeKey); - const didSig = createDidSig(signerHexDid, keyId, signature); + const signature = this.signRemovePublicKey(signingKeyRef, removeKey); + const didSig = createDidSig(signerHexDid, signingKeyRef, signature); return [removeKey, didSig]; } - async createSignedAddPositiveAccumulator(id, accumulated, publicKeyRef, signerHexDid, keyPair, keyId, { nonce = undefined, didModule = undefined }) { + async createSignedAddPositiveAccumulator(id, accumulated, publicKeyRef, signerHexDid, signingKeyRef, { nonce = undefined, didModule = undefined }) { // eslint-disable-next-line no-param-reassign - nonce = await getNonce(signerHexDid, nonce, didModule); - const accum = AccumulatorModule.prepareAddPositiveAccumulator(id, accumulated, publicKeyRef); + nonce = await getDidNonce(signerHexDid, nonce, didModule); + const accum = AccumulatorModule.prepareAddPositiveAccumulator(this.api, id, accumulated, publicKeyRef); const addAccum = { ...accum, nonce }; - const signature = this.signAddAccumulator(keyPair, addAccum); - const didSig = createDidSig(signerHexDid, keyId, signature); + const signature = this.signAddAccumulator(signingKeyRef, addAccum); + const didSig = createDidSig(signerHexDid, signingKeyRef, signature); return [addAccum, didSig]; } - async createSignedAddUniversalAccumulator(id, accumulated, publicKeyRef, maxSize, signerHexDid, keyPair, keyId, { nonce = undefined, didModule = undefined }) { + async createSignedAddUniversalAccumulator(id, accumulated, publicKeyRef, maxSize, signerHexDid, signingKeyRef, { nonce = undefined, didModule = undefined }) { // eslint-disable-next-line no-param-reassign - nonce = await getNonce(signerHexDid, nonce, didModule); - const accum = AccumulatorModule.prepareAddUniversalAccumulator(id, accumulated, publicKeyRef, maxSize); + nonce = await getDidNonce(signerHexDid, nonce, didModule); + const accum = AccumulatorModule.prepareAddUniversalAccumulator(this.api, id, accumulated, publicKeyRef, maxSize); const addAccum = { ...accum, nonce }; - const signature = this.signAddAccumulator(keyPair, addAccum); - const didSig = createDidSig(signerHexDid, keyId, signature); + const signature = this.signAddAccumulator(signingKeyRef, addAccum); + const didSig = createDidSig(signerHexDid, signingKeyRef, signature); return [addAccum, didSig]; } async createSignedUpdateAccumulator(id, newAccumulated, - { additions = undefined, removals = undefined, witnessUpdateInfo = undefined }, signerHexDid, keyPair, keyId, { nonce = undefined, didModule = undefined }) { + { additions = undefined, removals = undefined, witnessUpdateInfo = undefined }, signerHexDid, signingKeyRef, { nonce = undefined, didModule = undefined }) { // eslint-disable-next-line no-param-reassign - nonce = await getNonce(signerHexDid, nonce, didModule); + nonce = await getDidNonce(signerHexDid, nonce, didModule); if (additions !== undefined) { AccumulatorModule.ensureArrayOfBytearrays(additions); } @@ -367,17 +354,17 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { witness_update_info: witnessUpdateInfo, nonce, }; - const signature = this.signUpdateAccumulator(keyPair, updateAccum); - const didSig = createDidSig(signerHexDid, keyId, signature); + const signature = this.signUpdateAccumulator(signingKeyRef, updateAccum); + const didSig = createDidSig(signerHexDid, signingKeyRef, signature); return [updateAccum, didSig]; } - async createSignedRemoveAccumulator(id, signerHexDid, keyPair, keyId, { nonce = undefined, didModule = undefined }) { + async createSignedRemoveAccumulator(id, signerHexDid, signingKeyRef, { nonce = undefined, didModule = undefined }) { // eslint-disable-next-line no-param-reassign - nonce = await getNonce(signerHexDid, nonce, didModule); + nonce = await getDidNonce(signerHexDid, nonce, didModule); const remAccum = { id, nonce }; - const signature = this.signRemoveAccumulator(keyPair, remAccum); - const didSig = createDidSig(signerHexDid, keyId, signature); + const signature = this.signRemoveAccumulator(signingKeyRef, remAccum); + const didSig = createDidSig(signerHexDid, signingKeyRef, signature); return [remAccum, didSig]; } @@ -409,9 +396,9 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { accumulatorObj.maxSize = accumInfo.accumulator.asUniversal.maxSize.toNumber(); } accumulatorObj.accumulated = u8aToHex(common.accumulated); - const owner = u8aToHex(common.keyRef[0]); + const owner = common.keyRef[0]; const keyId = common.keyRef[1].toNumber(); - accumulatorObj.keyRef = [owner, keyId]; + accumulatorObj.keyRef = [typedHexDIDFromSubstrate(this.api, owner), keyId]; if (withKeyAndParams) { const pk = await this.getPublicKeyByHexDid(owner, keyId, true); @@ -473,7 +460,8 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { * @returns {Promise<{bytes: string}|null>} */ async getLastParamsWritten(did) { - const hexId = getHexIdentifierFromDID(did); + const hexId = typedHexDID(this.api, did); + const counters = await this.api.query[this.moduleName].accumulatorOwnerCounters(hexId); const counter = counters.paramsCounter.toNumber(); if (counter > 0) { @@ -491,7 +479,7 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { * @returns {Promise} */ async getAllParamsByDid(did) { - const hexId = getHexIdentifierFromDID(did); + const hexId = typedHexDID(this.api, did); const params = []; const counters = await this.api.query[this.moduleName].accumulatorOwnerCounters(hexId); @@ -515,7 +503,7 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { * @returns {Promise< object[]>} */ async getAllPublicKeysByDid(did, withParams = false) { - const hexId = getHexIdentifierFromDID(did); + const hexId = typedHexDID(this.api, did); const pks = []; const counters = await this.api.query[this.moduleName].accumulatorOwnerCounters(hexId); @@ -558,46 +546,46 @@ export default class AccumulatorModule extends WithParamsAndPublicKeys { } } - signAddParams(keyPair, params) { + signAddParams(signingKeyRef, params) { const serialized = getStateChange(this.api, 'AddAccumulatorParams', params); - return getSignatureFromKeyringPair(keyPair, serialized); + return signingKeyRef.sign(serialized); } - signAddPublicKey(keyPair, pk) { + signAddPublicKey(signingKeyRef, pk) { const serialized = getStateChange(this.api, 'AddAccumulatorPublicKey', pk); - return getSignatureFromKeyringPair(keyPair, serialized); + return signingKeyRef.sign(serialized); } - signRemoveParams(keyPair, ref) { + signRemoveParams(signingKeyRef, ref) { const serialized = getStateChange(this.api, 'RemoveAccumulatorParams', ref); - return getSignatureFromKeyringPair(keyPair, serialized); + return signingKeyRef.sign(serialized); } - signRemovePublicKey(keyPair, ref) { + signRemovePublicKey(signingKeyRef, ref) { const serialized = getStateChange( this.api, 'RemoveAccumulatorPublicKey', ref, ); - return getSignatureFromKeyringPair(keyPair, serialized); + return signingKeyRef.sign(serialized); } - signAddAccumulator(keyPair, addAccumulator) { + signAddAccumulator(signingKeyRef, addAccumulator) { const serialized = getStateChange( this.api, 'AddAccumulator', addAccumulator, ); - return getSignatureFromKeyringPair(keyPair, serialized); + return signingKeyRef.sign(serialized); } - signUpdateAccumulator(keyPair, update) { + signUpdateAccumulator(signingKeyRef, update) { const serialized = getStateChange(this.api, 'UpdateAccumulator', update); - return getSignatureFromKeyringPair(keyPair, serialized); + return signingKeyRef.sign(serialized); } - signRemoveAccumulator(keyPair, removal) { + signRemoveAccumulator(signingKeyRef, removal) { const serialized = getStateChange(this.api, 'RemoveAccumulator', removal); - return getSignatureFromKeyringPair(keyPair, serialized); + return signingKeyRef.sign(serialized); } } diff --git a/src/modules/bbs-plus.js b/src/modules/bbs-plus.js index 35c13a35d..e4435af7e 100644 --- a/src/modules/bbs-plus.js +++ b/src/modules/bbs-plus.js @@ -6,12 +6,16 @@ import BBSPlusParams from '../offchain-signatures/params/bbs-plus'; /** Class to write `BBS+` parameters and keys on chain */ export default class BBSPlusModule extends OffchainSignaturesModule { - /// Builds `BBS+` params from the provided value. + /** + * Builds `BBS+` params from the provided value. + */ static buildParams(params) { return new BBSPlusParams(params); } - /// Builds `BBS+` public key from the provided value. + /** + * Builds `BBS+` public key from the provided value. + */ static buildPublicKey(publicKey) { return new BBSPlusPublicKey(publicKey); } diff --git a/src/modules/bbs.js b/src/modules/bbs.js index b90062b5c..f823486a7 100644 --- a/src/modules/bbs.js +++ b/src/modules/bbs.js @@ -6,12 +6,16 @@ import BBSParams from '../offchain-signatures/params/bbs'; /** Class to write `BBS` parameters and keys on chain */ export default class BBSModule extends OffchainSignaturesModule { - /// Builds `BBS` params from the provided value. + /** + * Builds `BBS` params from the provided value. + */ static buildParams(params) { return new BBSParams(params); } - /// Builds `BBS` public key from the provided value. + /** + * Builds `BBS` public key from the provided value. + */ static buildPublicKey(publicKey) { return new BBSPublicKey(publicKey); } diff --git a/src/modules/blob.js b/src/modules/blob.js index 8fd87803a..05d05b33c 100644 --- a/src/modules/blob.js +++ b/src/modules/blob.js @@ -1,12 +1,13 @@ import { encodeAddress, randomAsHex } from '@polkadot/util-crypto'; import { - u8aToString, stringToHex, bufferToU8a, u8aToHex, + u8aToHex, + u8aToString, stringToHex, bufferToU8a, } from '@polkadot/util'; -import { getNonce, getSignatureFromKeyringPair, getStateChange } from '../utils/misc'; +import { getDidNonce, getStateChange } from '../utils/misc'; import { isHexWithGivenByteSize, getHexIdentifier } from '../utils/codec'; import NoBlobError from '../utils/errors/no-blob-error'; -import { createDidSig, getHexIdentifierFromDID } from '../utils/did'; +import { typedHexDIDFromSubstrate, createDidSig, typedHexDID } from '../utils/did'; export const DockBlobQualifier = 'blob:dock:'; export const DockBlobIdByteSize = 32; @@ -33,7 +34,10 @@ export function validateBlobIDHexIdentifier(identifier) { * @return {string} Returns the hexadecimal representation of the ID. */ export function getHexIdentifierFromBlobID(id) { - return getHexIdentifier(id, DockBlobQualifier, validateBlobIDHexIdentifier, DockBlobIdByteSize); + const hexId = getHexIdentifier(id, DockBlobQualifier, DockBlobIdByteSize); + validateBlobIDHexIdentifier(hexId); + + return hexId; } /** @@ -73,16 +77,15 @@ class BlobModule { * Create a signed transaction for adding a new blob * @param blob * @param signerDid - Signer of the blob - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this * @returns {Promise<*>} */ - async createNewTx(blob, signerDid, keyPair, keyId, { nonce = undefined, didModule = undefined }) { - const hexDid = getHexIdentifierFromDID(signerDid); - const [addBlob, didSig] = await this.createSignedAddBlob(blob, hexDid, keyPair, keyId, { nonce, didModule }); + async createNewTx(blob, signerDid, signingKeyRef, { nonce = undefined, didModule = undefined }) { + const signerHexDid = typedHexDID(this.api, signerDid); + const [addBlob, didSig] = await this.createSignedAddBlob(blob, signerHexDid, signingKeyRef, { nonce, didModule }); return this.module.new(addBlob, didSig); } @@ -90,8 +93,7 @@ class BlobModule { * Write a new blob on chain. * @param blob * @param signerDid - Signer of the blob - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this @@ -99,9 +101,9 @@ class BlobModule { * @param params * @returns {Promise<*>} */ - async new(blob, signerDid, keyPair, keyId, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}) { + async new(blob, signerDid, signingKeyRef, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}) { return this.signAndSend( - (await this.createNewTx(blob, signerDid, keyPair, keyId, { nonce, didModule })), waitForFinalization, params, + (await this.createNewTx(blob, signerDid, signingKeyRef, { nonce, didModule })), waitForFinalization, params, ); } @@ -131,7 +133,7 @@ class BlobModule { // no-op, just use default Uint8 array value } - return [u8aToHex(respTuple[0]), value]; + return [typedHexDIDFromSubstrate(this.api, respTuple[0]), value]; } throw new Error(`Needed 2 items in response but got${respTuple.length}`); } @@ -139,20 +141,19 @@ class BlobModule { /** * Create an `AddBlob` struct as expected by node and return along with signature. * @param blob - * @param hexDid - Signer DID in hex form - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param {DockDidOrDidMethodKey} signerDid - Signer DID + * @param signingKeyRef - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this * @returns {Promise} */ - async createSignedAddBlob(blob, hexDid, keyPair, keyId, { nonce = undefined, didModule = undefined }) { + async createSignedAddBlob(blob, signerDid, signingKeyRef, { nonce = undefined, didModule = undefined }) { if (!blob.blob) { throw new Error('Blob must have a value!'); } // eslint-disable-next-line no-param-reassign - nonce = await getNonce(hexDid, nonce, didModule); + nonce = await getDidNonce(signerDid, nonce, didModule); const blobObj = { ...blob, @@ -163,14 +164,14 @@ class BlobModule { nonce, }; const serializedAddBlob = this.getSerializedBlob(addBlob); - const signature = getSignatureFromKeyringPair(keyPair, serializedAddBlob); - const didSig = createDidSig(hexDid, keyId, signature); + const signature = signingKeyRef.sign(serializedAddBlob); + const didSig = createDidSig(signerDid, signingKeyRef, signature); return [addBlob, didSig]; } getSerializedBlobValue(blobValue) { if (blobValue instanceof Uint8Array) { - return [...blobValue]; + return u8aToHex(blobValue); } else if (typeof blobValue === 'object') { return stringToHex(JSON.stringify(blobValue)); } else if (typeof blobValue === 'string' && !isHexWithGivenByteSize(blobValue)) { diff --git a/src/modules/did/did.js b/src/modules/did/did.js index 71f17a6ae..8b5dc969e 100644 --- a/src/modules/did/did.js +++ b/src/modules/did/did.js @@ -3,15 +3,16 @@ import { u8aToString, hexToU8a, u8aToHex } from '@polkadot/util'; import { BTreeSet } from '@polkadot/types'; import b58 from 'bs58'; import { - getHexIdentifierFromDID, + typedHexDID, DockDIDQualifier, NoDIDError, validateDockDIDHexIdentifier, NoOnchainDIDError, NoOffchainDIDError, createDidSig, + DockDIDMethodKeyQualifier, } from '../../utils/did'; -import { getSignatureFromKeyringPair, getStateChange } from '../../utils/misc'; +import { getStateChange } from '../../utils/misc'; import OffChainDidDocRef from './offchain-did-doc-ref'; import { @@ -35,6 +36,7 @@ class DIDModule { * Creates a new instance of DIDModule and sets the api * @constructor * @param {object} api - PolkadotJS API Reference + * @param signAndSend - Function to sign and send transaction */ constructor(api, signAndSend) { this.api = api; @@ -49,7 +51,7 @@ class DIDModule { * @returns {*} */ createNewOffchainTx(did, didDocRef) { - const hexId = getHexIdentifierFromDID(did); + const hexId = typedHexDID(this.api, did).asDid; return this.module.newOffchain(hexId, didDocRef); } @@ -76,7 +78,7 @@ class DIDModule { * @returns {*} */ createSetOffchainDidRefTx(did, didDocRef) { - const hexId = getHexIdentifierFromDID(did); + const hexId = typedHexDID(this.api, did).asDid; return this.module.setOffchainDidDocRef(hexId, didDocRef); } @@ -107,7 +109,7 @@ class DIDModule { * @returns {Promise<*>} */ createRemoveOffchainDidTx(did) { - const hexId = getHexIdentifierFromDID(did); + const hexId = typedHexDID(this.api, did).asDid; return this.module.removeOffchainDid(hexId); } @@ -137,10 +139,10 @@ class DIDModule { const cnts = new BTreeSet(); if (controllers !== undefined) { controllers.forEach((c) => { - cnts.add(getHexIdentifierFromDID(c)); + cnts.add(typedHexDID(this.api, c)); }); } - const hexId = getHexIdentifierFromDID(did); + const hexId = typedHexDID(this.api, did).asDid; return this.module.newOnchain( hexId, didKeys.map((d) => d.toJSON()), @@ -171,13 +173,31 @@ class DIDModule { ); } + /** + * Creates a new `did:key:` on the Dock chain. + * @param {string} did - The new DID. Can be a full DID or hex identifier + * @param waitForFinalization + * @param params + * @return {Promise} Promise to the pending transaction + */ + async newDidMethodKey( + didMethodKey, + waitForFinalization = true, + params = {}, + ) { + return this.signAndSend( + this.module.newDidMethodKey(didMethodKey), + waitForFinalization, + params, + ); + } + /** * Create transaction to add keys to an on-chain DID. * @param {DidKey[]} didKeys - Array of `DidKey`s as expected by the Substrate node * @param targetDid - The DID to which keys are being added * @param signerDid - The DID that is adding the keys by signing the payload because it controls `targetDid` - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then an appropriate nonce will be * fetched from chain before creating the transaction * @returns {Promise<*>} @@ -186,18 +206,16 @@ class DIDModule { didKeys, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, nonce = undefined, ) { - const targetHexDid = getHexIdentifierFromDID(targetDid); - const signerHexDid = getHexIdentifierFromDID(signerDid); + const targetHexDid = typedHexDID(this.api, targetDid).asDid; + const signerHexDid = typedHexDID(this.api, signerDid); const [addKeys, signature] = await this.createSignedAddKeys( didKeys, targetHexDid, signerHexDid, - keyPair, - keyId, + signingKeyRef, nonce, ); return this.module.addKeys(addKeys, signature); @@ -208,8 +226,7 @@ class DIDModule { * @param {DidKey[]} didKeys - Array of `DidKey`s as expected by the Substrate node * @param targetDid - The DID to which keys are being added * @param signerDid - The DID that is adding the keys by signing the payload because it controls `targetDid` - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then an appropriate nonce will be * fetched from chain before creating the transaction * @param waitForFinalization @@ -220,8 +237,7 @@ class DIDModule { didKeys, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, nonce = undefined, waitForFinalization = true, params = {}, @@ -231,8 +247,7 @@ class DIDModule { didKeys, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, nonce, ), waitForFinalization, @@ -245,8 +260,7 @@ class DIDModule { * @param controllers - The DIDs that will control the `targetDid` * @param targetDid - The DID to which keys are being added * @param signerDid - The DID that is adding the controllers by signing the payload because it controls `targetDid` - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then an appropriate nonce will be * fetched from chain before creating the transaction * @returns {Promise<*>} @@ -255,18 +269,16 @@ class DIDModule { controllers, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, nonce = undefined, ) { - const targetHexDid = getHexIdentifierFromDID(targetDid); - const signerHexDid = getHexIdentifierFromDID(signerDid); + const targetHexDid = typedHexDID(this.api, targetDid).asDid; + const signerHexDid = typedHexDID(this.api, signerDid); const [addControllers, signature] = await this.createSignedAddControllers( controllers, targetHexDid, signerHexDid, - keyPair, - keyId, + signingKeyRef, nonce, ); return this.module.addControllers(addControllers, signature); @@ -277,8 +289,7 @@ class DIDModule { * @param controllers - The DIDs that will control the `targetDid` * @param targetDid - The DID to which controllers are being added * @param signerDid - The DID that is adding the controllers by signing the payload because it controls `targetDid` - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then an appropriate nonce will be * fetched from chain before creating the transaction * @param waitForFinalization @@ -289,8 +300,7 @@ class DIDModule { controllers, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, nonce = undefined, waitForFinalization = true, params = {}, @@ -299,8 +309,7 @@ class DIDModule { controllers, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, nonce, ); return this.signAndSend(tx, waitForFinalization, params); @@ -313,8 +322,7 @@ class DIDModule { * @param {Array} origins - An array of one of URIs encoded as hex. * @param targetDid - The DID to which service endpoint is being added * @param signerDid - The DID that is adding the service endpoint by signing the payload because it controls `targetDid` - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then an appropriate nonce will be * fetched from chain before creating the transaction * @returns {Promise<*>} @@ -325,20 +333,18 @@ class DIDModule { origins, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, nonce = undefined, ) { - const targetHexDid = getHexIdentifierFromDID(targetDid); - const signerHexDid = getHexIdentifierFromDID(signerDid); + const targetHexDid = typedHexDID(this.api, targetDid).asDid; + const signerHexDid = typedHexDID(this.api, signerDid); const [addServiceEndpoint, signature] = await this.createSignedAddServiceEndpoint( endpointId, endpointType, origins, targetHexDid, signerHexDid, - keyPair, - keyId, + signingKeyRef, nonce, ); return this.module.addServiceEndpoint(addServiceEndpoint, signature); @@ -351,8 +357,7 @@ class DIDModule { * @param {Array} origins - An array of one of URIs encoded as hex. * @param targetDid - The DID to which service endpoint is being added * @param signerDid - The DID that is adding the service endpoint by signing the payload because it controls `targetDid` - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then an appropriate nonce will be * fetched from chain before creating the transaction * @param waitForFinalization @@ -365,8 +370,7 @@ class DIDModule { origins, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, nonce = undefined, waitForFinalization = true, params = {}, @@ -377,8 +381,7 @@ class DIDModule { origins, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, nonce, ); return this.signAndSend(tx, waitForFinalization, params); @@ -389,8 +392,7 @@ class DIDModule { * @param keyIds - Key indices to remove * @param targetDid - The DID from which keys are being removed * @param signerDid - The DID that is removing the keys by signing the payload because it controls `targetDid` - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then an appropriate nonce will be * fetched from chain before creating the transaction * @returns {Promise<*>} @@ -399,18 +401,16 @@ class DIDModule { keyIds, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, nonce = undefined, ) { - const targetHexDid = getHexIdentifierFromDID(targetDid); - const signerHexDid = getHexIdentifierFromDID(signerDid); + const targetHexDid = typedHexDID(this.api, targetDid).asDid; + const signerHexDid = typedHexDID(this.api, signerDid); const [removeKeys, signature] = await this.createSignedRemoveKeys( keyIds, targetHexDid, signerHexDid, - keyPair, - keyId, + signingKeyRef, nonce, ); return this.module.removeKeys(removeKeys, signature); @@ -421,8 +421,7 @@ class DIDModule { * @param keyIds - Key indices to remove * @param targetDid - The DID from which keys are being removed * @param signerDid - The DID that is removing the keys by signing the payload because it controls `targetDid` - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then an appropriate nonce will be * fetched from chain before creating the transaction * @param waitForFinalization @@ -433,8 +432,7 @@ class DIDModule { keyIds, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, nonce = undefined, waitForFinalization = true, params = {}, @@ -443,8 +441,7 @@ class DIDModule { keyIds, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, nonce, ); return this.signAndSend(tx, waitForFinalization, params); @@ -455,8 +452,7 @@ class DIDModule { * @param controllers - Controller DIDs to remove. * @param targetDid - The DID from which controllers are being removed * @param signerDid - The DID that is removing the controllers by signing the payload because it controls `targetDid` - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then an appropriate nonce will be * fetched from chain before creating the transaction * @returns {Promise<*>} @@ -465,18 +461,16 @@ class DIDModule { controllers, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, nonce = undefined, ) { - const targetHexDid = getHexIdentifierFromDID(targetDid); - const signerHexDid = getHexIdentifierFromDID(signerDid); + const targetHexDid = typedHexDID(this.api, targetDid).asDid; + const signerHexDid = typedHexDID(this.api, signerDid); const [removeControllers, signature] = await this.createSignedRemoveControllers( controllers, targetHexDid, signerHexDid, - keyPair, - keyId, + signingKeyRef, nonce, ); return this.module.removeControllers(removeControllers, signature); @@ -487,8 +481,7 @@ class DIDModule { * @param controllers - Controller DIDs to remove. * @param targetDid - The DID from which controllers are being removed * @param signerDid - The DID that is removing the controllers by signing the payload because it controls `targetDid` - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then an appropriate nonce will be * fetched from chain before creating the transaction * @param waitForFinalization @@ -499,8 +492,7 @@ class DIDModule { controllers, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, nonce = undefined, waitForFinalization = true, params = {}, @@ -509,8 +501,7 @@ class DIDModule { controllers, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, nonce, ); return this.signAndSend(tx, waitForFinalization, params); @@ -521,8 +512,7 @@ class DIDModule { * @param endpointId - The endpoint to remove * @param targetDid - The DID from which endpoint is being removed * @param signerDid - The DID that is removing the endpoint by signing the payload because it controls `targetDid` - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then an appropriate nonce will be * fetched from chain before creating the transaction * @returns {Promise<*>} @@ -531,18 +521,16 @@ class DIDModule { endpointId, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, nonce = undefined, ) { - const targetHexDid = getHexIdentifierFromDID(targetDid); - const signerHexDid = getHexIdentifierFromDID(signerDid); + const targetHexDid = typedHexDID(this.api, targetDid).asDid; + const signerHexDid = typedHexDID(this.api, signerDid); const [removeServiceEndpoint, signature] = await this.createSignedRemoveServiceEndpoint( endpointId, targetHexDid, signerHexDid, - keyPair, - keyId, + signingKeyRef, nonce, ); return this.module.removeServiceEndpoint(removeServiceEndpoint, signature); @@ -553,8 +541,7 @@ class DIDModule { * @param endpointId - The endpoint to remove * @param targetDid - The DID from which endpoint is being removed * @param signerDid - The DID that is removing the endpoint by signing the payload because it controls `targetDid` - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then an appropriate nonce will be * fetched from chain before creating the transaction * @param waitForFinalization @@ -565,8 +552,7 @@ class DIDModule { endpointId, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, nonce = undefined, waitForFinalization = true, params = {}, @@ -575,8 +561,7 @@ class DIDModule { endpointId, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, nonce, ); return this.signAndSend(tx, waitForFinalization, params); @@ -586,26 +571,18 @@ class DIDModule { * Create a transaction to remove an on-chain DID * @param targetDid - The DID being removed * @param signerDid - The DID that is removing `targetDid` by signing the payload because it controls `targetDid` - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then an appropriate nonce will be * fetched from chain before creating the transaction * @return {Promise} The extrinsic to sign and send. */ - async createRemoveTx( - targetDid, - signerDid, - keyPair, - keyId, - nonce = undefined, - ) { - const hexDid = getHexIdentifierFromDID(targetDid); - const signerHexDid = getHexIdentifierFromDID(signerDid); + async createRemoveTx(targetDid, signerDid, signingKeyRef, nonce = undefined) { + const hexDid = typedHexDID(this.api, targetDid).asDid; + const signerHexDid = typedHexDID(this.api, signerDid); const [didRemoval, signature] = await this.createSignedDidRemoval( hexDid, signerHexDid, - keyPair, - keyId, + signingKeyRef, nonce, ); return this.module.removeOnchainDid(didRemoval, signature); @@ -615,8 +592,7 @@ class DIDModule { * Removes an on-chain DID. * @param targetDid - The DID being removed * @param signerDid - The DID that is removing `targetDid` by signing the payload because it controls `targetDid` - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's keypair reference * @param nonce - The nonce to be used for sending this transaction. If not provided then an appropriate nonce will be * fetched from chain before creating the transaction * @param waitForFinalization @@ -626,8 +602,7 @@ class DIDModule { async remove( targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, nonce = undefined, waitForFinalization = true, params = {}, @@ -635,8 +610,7 @@ class DIDModule { const tx = await this.createRemoveTx( targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, nonce, ); return this.signAndSend(tx, waitForFinalization, params); @@ -647,26 +621,17 @@ class DIDModule { * @param priority * @param iri * @param did - * @param keyPair - * @param keyId + * @param signingKeyRef * @param nonce * @returns {Promise>} */ - async createSetClaimTx( - priority, - iri, - did, - keyPair, - keyId, - nonce = undefined, - ) { - const hexDid = getHexIdentifierFromDID(did); + async createSetClaimTx(priority, iri, did, signingKeyRef, nonce = undefined) { + const hexDid = typedHexDID(this.api, did); const [setAttestation, signature] = await this.createSignedAttestation( priority, iri, hexDid, - keyPair, - keyId, + signingKeyRef, nonce, ); return this.api.tx.attest.setClaim(setAttestation, signature); @@ -677,8 +642,7 @@ class DIDModule { * @param priority * @param iri * @param did - * @param keyPair - * @param keyId + * @param signingKeyRef * @param nonce * @param waitForFinalization * @param params @@ -687,8 +651,7 @@ class DIDModule { priority, iri, did, - keyPair, - keyId, + signingKeyRef, nonce = undefined, waitForFinalization = true, params = {}, @@ -697,8 +660,7 @@ class DIDModule { priority, iri, did, - keyPair, - keyId, + signingKeyRef, nonce, ); return this.signAndSend(attestTx, waitForFinalization, params); @@ -713,6 +675,15 @@ class DIDModule { return `${DockDIDQualifier}${did}`; } + /** + * Create the fully qualified DID like "did:dock:..." + * @param {string} didMethodKey - DID + * @return {string} The DID identifier. + */ + getFullyQualifiedDIDMethodKey(didMethodKey) { + return `${DockDIDMethodKeyQualifier}${didMethodKey}`; + } + /** * Fetches the DIDs attestations IRI from the chain * @param {string} hexId - DID in hex format @@ -730,29 +701,35 @@ class DIDModule { * Throws NoDID if the DID does not exist on chain. * @param {string} did - The DID can be passed as fully qualified DID like `did:dock:` or * a 32 byte hex string + * @param getOffchainSigKeys * @return {Promise} The DID document. */ // eslint-disable-next-line sonarjs/cognitive-complexity async getDocument(did, { getOffchainSigKeys = true } = {}) { - const hexId = getHexIdentifierFromDID(did); - let didDetails = await this.getOnchainDidDetail(hexId); + const typedDid = typedHexDID(this.api, did); + const hexDid = typedDid.asDid; + let didDetails = await this.getOnchainDidDetail(hexDid); didDetails = didDetails.data || didDetails; // Get DIDs attestations - const attests = await this.getAttests(hexId); + const attests = await this.getAttests(typedDid); // If given DID was in hex, encode to SS58 and then construct fully qualified DID else the DID was already fully qualified - const id = (did === hexId) ? this.getFullyQualifiedDID(encodeAddress(hexId)) : did; + const id = did === hexDid ? this.getFullyQualifiedDID(encodeAddress(hexDid)) : did; // Get controllers const controllers = []; if (didDetails.activeControllers > 0) { - const cnts = await this.api.query.didModule.didControllers.entries(hexId); + const cnts = await this.api.query.didModule.didControllers.entries( + hexDid, + ); cnts.forEach(([key, value]) => { if (value.isSome) { const [controlled, controller] = key.toHuman(); - if (controlled !== hexId) { - throw new Error(`Controlled DID ${controlled[0]} was found to be different than queried DID ${hexId}`); + if (controlled !== hexDid) { + throw new Error( + `Controlled DID ${controlled[0]} was found to be different than queried DID ${hexDid}`, + ); } controllers.push(controller); } @@ -761,7 +738,9 @@ class DIDModule { // Get service endpoints const serviceEndpoints = []; - const sps = await this.api.query.didModule.didServiceEndpoints.entries(hexId); + const sps = await this.api.query.didModule.didServiceEndpoints.entries( + hexDid, + ); sps.forEach(([key, value]) => { if (value.isSome) { const sp = value.unwrap(); @@ -769,8 +748,10 @@ class DIDModule { const [d, spId] = key.args; // eslint-disable-next-line no-underscore-dangle const d_ = u8aToHex(d); - if (d_ !== hexId) { - throw new Error(`DID ${d_} was found to be different than queried DID ${hexId}`); + if (d_ !== hexDid) { + throw new Error( + `DID ${d_} was found to be different than queried DID ${hexDid}`, + ); } serviceEndpoints.push([spId, sp]); } @@ -783,7 +764,7 @@ class DIDModule { const capInv = []; const keyAgr = []; if (didDetails.lastKeyId > 0) { - const dks = await this.api.query.didModule.didKeys.entries(hexId); + const dks = await this.api.query.didModule.didKeys.entries(hexDid); dks.forEach(([key, value]) => { if (value.isSome) { const dk = value.unwrap(); @@ -791,8 +772,10 @@ class DIDModule { const [d, i] = key.args; // eslint-disable-next-line no-underscore-dangle const d_ = u8aToHex(d); - if (d_ !== hexId) { - throw new Error(`DID ${d_} was found to be different than queried DID ${hexId}`); + if (d_ !== hexDid) { + throw new Error( + `DID ${d_} was found to be different than queried DID ${hexDid}`, + ); } const index = i.toNumber(); const pk = dk.publicKey; @@ -849,16 +832,18 @@ class DIDModule { // Query all BBS+ keys in a single RPC call to the node. const queryKeys = []; for (const k of possibleKeyIds) { - queryKeys.push([hexId, k]); + queryKeys.push([hexDid, k]); } if (this.api.query.offchainSignatures != null) { - const resp = await this.api.query.offchainSignatures.publicKeys.multi(queryKeys); + const resp = await this.api.query.offchainSignatures.publicKeys.multi( + queryKeys, + ); let currentIter = 0; for (let r of resp) { // The gaps in `keyId` might correspond to removed keys if (r.isSome) { - let rawKey; let - keyType; + let rawKey; + let keyType; r = r.unwrap(); if (r.isBbs) { @@ -872,9 +857,14 @@ class DIDModule { rawKey = r.asPs; } // Don't care about signature params for now - const pkObj = WithParamsAndPublicKeys.createPublicKeyObjFromChainResponse(rawKey); + const pkObj = WithParamsAndPublicKeys.createPublicKeyObjFromChainResponse( + this.api, + rawKey, + ); if (pkObj.curveType !== 'Bls12381') { - throw new Error(`Curve type should have been Bls12381 but was ${pkObj.curveType}`); + throw new Error( + `Curve type should have been Bls12381 but was ${pkObj.curveType}`, + ); } const keyIndex = queryKeys[currentIter][1]; keys.push([keyIndex, keyType, hexToU8a(pkObj.bytes)]); @@ -883,7 +873,9 @@ class DIDModule { currentIter++; } } else { - const resp = await this.api.query.bbsPlus.bbsPlusKeys.multi(queryKeys); + const resp = await this.api.query.bbsPlus.bbsPlusKeys.multi( + queryKeys, + ); let currentIter = 0; for (const r of resp) { // The gaps in `keyId` might correspond to removed keys @@ -892,9 +884,14 @@ class DIDModule { const rawKey = r.unwrap(); // Don't care about signature params for now - const pkObj = WithParamsAndPublicKeys.createPublicKeyObjFromChainResponse(rawKey); + const pkObj = WithParamsAndPublicKeys.createPublicKeyObjFromChainResponse( + this.api, + rawKey, + ); if (pkObj.curveType !== 'Bls12381') { - throw new Error(`Curve type should have been Bls12381 but was ${pkObj.curveType}`); + throw new Error( + `Curve type should have been Bls12381 but was ${pkObj.curveType}`, + ); } const keyIndex = queryKeys[currentIter][1]; keys.push([keyIndex, keyType, hexToU8a(pkObj.bytes)]); @@ -927,7 +924,15 @@ class DIDModule { const document = { '@context': ['https://www.w3.org/ns/did/v1'], id, - controller: [...controllers].map((c) => this.getFullyQualifiedDID(encodeAddress(c))), + controller: [...controllers].map((c) => { + if (c.Did) { + return this.getFullyQualifiedDID(encodeAddress(c.Did)); + } else if (c.DidMethodKey) { + return this.getFullyQualifiedDIDMethodKey(encodeAddress(c.DidMethodKey)); + } else { + return this.getFullyQualifiedDID(encodeAddress(c)); + } + }), publicKey: verificationMethod, }; @@ -998,6 +1003,18 @@ class DIDModule { }; } + async getDidMethodKeyDetail(did) { + let resp = await this.api.query.didModule.didMethodKeys(did); + if (resp.isNone) { + throw new NoDIDError(`did:key:dock:${did}`); + } + resp = resp.unwrap(); + + return { + nonce: resp.nonce.toNumber(), + }; + } + /** * Gets the DID detail of an on chain DID * @param didIdentifier @@ -1031,21 +1048,27 @@ class DIDModule { /** * Gets the current nonce for the DID. It will throw error if the DID does not exist on * chain or chain returns null response. - * @param {string} didIdentifier - DID identifier as hex. Not accepting full DID intentionally for efficiency as these + * @param {DockDidOrDidMethodKey} did - DID identifier as hex. Not accepting full DID intentionally for efficiency as these * methods are used internally * @return {Promise} */ - async getNonceForDID(didIdentifier) { - return (await this.getOnchainDidDetail(didIdentifier)).nonce; + async getNonceForDid(did) { + if (did.isDid) { + return (await this.getOnchainDidDetail(did.asDid)).nonce; + } else if (did.isDidMethodKey) { + return (await this.getDidMethodKeyDetail(did.asDidMethodKey)).nonce; + } else { + return (await this.getOnchainDidDetail(did)).nonce; + } } /** * Gets the nonce that should be used for sending the next transaction by this DID. Its 1 more than the current nonce. - * @param didIdentifier + * @param {DockDidOrDidMethodKey} did * @returns {Promise<*>} */ - async getNextNonceForDID(didIdentifier) { - return (await this.getNonceForDID(didIdentifier)) + 1; + async getNextNonceForDid(did) { + return (await this.getNonceForDid(did)) + 1; } /** @@ -1055,7 +1078,7 @@ class DIDModule { * @returns {Promise} */ async getDidKey(did, keyIndex) { - const hexId = getHexIdentifierFromDID(did); + const hexId = typedHexDID(this.api, did).asDid; let resp = await this.api.query.didModule.didKeys(hexId, keyIndex); if (resp.isNone) { throw new Error(`No key for found did ${did} and key index ${keyIndex}`); @@ -1066,13 +1089,21 @@ class DIDModule { let publicKey; if (pk.isSr25519) { - publicKey = new PublicKeySr25519(u8aToHex(valuePropOrIdentity(pk.asSr25519))); + publicKey = new PublicKeySr25519( + u8aToHex(valuePropOrIdentity(pk.asSr25519)), + ); } else if (pk.isEd25519) { - publicKey = new PublicKeyEd25519(u8aToHex(valuePropOrIdentity(pk.asEd25519))); + publicKey = new PublicKeyEd25519( + u8aToHex(valuePropOrIdentity(pk.asEd25519)), + ); } else if (pk.isSecp256k1) { - publicKey = new PublicKeySecp256k1(u8aToHex(valuePropOrIdentity(pk.asSecp256k1))); + publicKey = new PublicKeySecp256k1( + u8aToHex(valuePropOrIdentity(pk.asSecp256k1)), + ); } else if (pk.isX25519) { - publicKey = new PublicKeyX25519(u8aToHex(valuePropOrIdentity(pk.asX25519))); + publicKey = new PublicKeyX25519( + u8aToHex(valuePropOrIdentity(pk.asX25519)), + ); } else { throw new Error(`Cannot parse public key ${pk}`); } @@ -1089,11 +1120,11 @@ class DIDModule { * @returns {Promise} */ async isController(controlled, controller) { - const controlledHexId = getHexIdentifierFromDID(controlled); - const controllerHexId = getHexIdentifierFromDID(controller); + const controlledDid = typedHexDID(this.api, controlled).asDid; + const controllerDid = typedHexDID(this.api, controller); const resp = await this.api.query.didModule.didControllers( - controlledHexId, - controllerHexId, + controlledDid, + controllerDid, ); return resp.isSome; } @@ -1105,7 +1136,7 @@ class DIDModule { * @returns {Promise} */ async getServiceEndpoint(did, endpointId) { - const hexId = getHexIdentifierFromDID(did); + const hexId = typedHexDID(this.api, did).asDid; let resp = await this.api.query.didModule.didServiceEndpoints( hexId, endpointId, @@ -1124,22 +1155,21 @@ class DIDModule { async createSignedAddKeys( didKeys, - hexDid, - controllerHexDid, - keyPair, - keyId, + did, + controllerDid, + signingKeyRef, nonce = undefined, ) { if (nonce === undefined) { // eslint-disable-next-line no-param-reassign - nonce = await this.getNextNonceForDID(controllerHexDid); + nonce = await this.getNextNonceForDid(controllerDid); } const keys = didKeys.map((d) => d.toJSON()); - const addKeys = { did: hexDid, keys, nonce }; + const addKeys = { did, keys, nonce }; const serializedAddKeys = this.getSerializedAddKeys(addKeys); - const signature = getSignatureFromKeyringPair(keyPair, serializedAddKeys); - const didSig = createDidSig(controllerHexDid, keyId, signature); + const signature = signingKeyRef.sign(serializedAddKeys); + const didSig = createDidSig(controllerDid, signingKeyRef, signature); return [addKeys, didSig]; } @@ -1147,26 +1177,22 @@ class DIDModule { controllers, hexDid, controllerHexDid, - keyPair, - keyId, + signingKeyRef, nonce = undefined, ) { if (nonce === undefined) { // eslint-disable-next-line no-param-reassign - nonce = await this.getNextNonceForDID(controllerHexDid); + nonce = await this.getNextNonceForDid(controllerHexDid); } const cnts = new BTreeSet(); controllers.forEach((c) => { - cnts.add(getHexIdentifierFromDID(c)); + cnts.add(typedHexDID(this.api, c)); }); const addControllers = { did: hexDid, controllers: cnts, nonce }; const serializedAddControllers = this.getSerializedAddControllers(addControllers); - const signature = getSignatureFromKeyringPair( - keyPair, - serializedAddControllers, - ); - const didSig = createDidSig(controllerHexDid, keyId, signature); + const signature = signingKeyRef.sign(serializedAddControllers); + const didSig = createDidSig(controllerHexDid, signingKeyRef, signature); return [addControllers, didSig]; } @@ -1176,13 +1202,12 @@ class DIDModule { origins, hexDid, controllerHexDid, - keyPair, - keyId, + signingKeyRef, nonce = undefined, ) { if (nonce === undefined) { // eslint-disable-next-line no-param-reassign - nonce = await this.getNextNonceForDID(controllerHexDid); + nonce = await this.getNextNonceForDid(controllerHexDid); } const endpoint = { types: endpointType.value, origins }; @@ -1193,72 +1218,55 @@ class DIDModule { nonce, }; const serializedServiceEndpoint = this.getSerializedAddServiceEndpoint(addServiceEndpoint); - const signature = getSignatureFromKeyringPair( - keyPair, - serializedServiceEndpoint, - ); - const didSig = createDidSig(controllerHexDid, keyId, signature); + const signature = signingKeyRef.sign(serializedServiceEndpoint); + const didSig = createDidSig(controllerHexDid, signingKeyRef, signature); return [addServiceEndpoint, didSig]; } async createSignedRemoveKeys( keyIds, did, - controllerDid, - keyPair, - keyId, + controllerHexDid, + signingKeyRef, nonce = undefined, ) { - const hexDid = getHexIdentifierFromDID(did); - const controllerHexDid = getHexIdentifierFromDID(controllerDid); - if (nonce === undefined) { // eslint-disable-next-line no-param-reassign - nonce = await this.getNextNonceForDID(controllerHexDid); + nonce = await this.getNextNonceForDid(controllerHexDid); } const keys = new BTreeSet(); keyIds.forEach((k) => { keys.add(k); }); - const removeKeys = { did: hexDid, keys, nonce }; + const removeKeys = { did, keys, nonce }; const serializedRemoveKeys = this.getSerializedRemoveKeys(removeKeys); - const signature = getSignatureFromKeyringPair( - keyPair, - serializedRemoveKeys, - ); - const didSig = createDidSig(controllerHexDid, keyId, signature); + const signature = signingKeyRef.sign(serializedRemoveKeys); + const didSig = createDidSig(controllerHexDid, signingKeyRef, signature); return [removeKeys, didSig]; } async createSignedRemoveControllers( controllers, - did, - controllerDid, - keyPair, - keyId, + hexDid, + controllerHexDid, + signingKeyRef, nonce = undefined, ) { - const hexDid = getHexIdentifierFromDID(did); - const controllerHexDid = getHexIdentifierFromDID(controllerDid); - if (nonce === undefined) { // eslint-disable-next-line no-param-reassign - nonce = await this.getNextNonceForDID(controllerHexDid); + nonce = await this.getNextNonceForDid(controllerHexDid); } const cnts = new BTreeSet(); controllers.forEach((c) => { - cnts.add(getHexIdentifierFromDID(c)); + cnts.add(typedHexDID(this.api, c)); }); const removeControllers = { did: hexDid, controllers: cnts, nonce }; const serializedRemoveControllers = this.getSerializedRemoveControllers(removeControllers); - const signature = getSignatureFromKeyringPair( - keyPair, - serializedRemoveControllers, - ); - const didSig = createDidSig(controllerHexDid, keyId, signature); + const signature = signingKeyRef.sign(serializedRemoveControllers); + const didSig = createDidSig(controllerHexDid, signingKeyRef, signature); return [removeControllers, didSig]; } @@ -1266,41 +1274,36 @@ class DIDModule { endpointId, hexDid, controllerHexDid, - keyPair, - keyId, + signingKeyRef, nonce = undefined, ) { if (nonce === undefined) { // eslint-disable-next-line no-param-reassign - nonce = await this.getNextNonceForDID(controllerHexDid); + nonce = await this.getNextNonceForDid(controllerHexDid); } const removeServiceEndpoint = { did: hexDid, id: endpointId, nonce }; const serializedRemoveServiceEndpoint = this.getSerializedRemoveServiceEndpoint(removeServiceEndpoint); - const signature = getSignatureFromKeyringPair( - keyPair, - serializedRemoveServiceEndpoint, - ); - const didSig = createDidSig(controllerHexDid, keyId, signature); + const signature = signingKeyRef.sign(serializedRemoveServiceEndpoint); + const didSig = createDidSig(controllerHexDid, signingKeyRef, signature); return [removeServiceEndpoint, didSig]; } async createSignedDidRemoval( - hexDid, - controllerHexDid, - keyPair, - keyId, + did, + controllerDid, + signingKeyRef, nonce = undefined, ) { if (nonce === undefined) { // eslint-disable-next-line no-param-reassign - nonce = await this.getNextNonceForDID(controllerHexDid); + nonce = await this.getNextNonceForDid(controllerDid); } - const removal = { did: hexDid, nonce }; + const removal = { did, nonce }; const serializedRemoval = this.getSerializedDidRemoval(removal); - const signature = getSignatureFromKeyringPair(keyPair, serializedRemoval); - const didSig = createDidSig(controllerHexDid, keyId, signature); + const signature = signingKeyRef.sign(serializedRemoval); + const didSig = createDidSig(controllerDid, signingKeyRef, signature); return [removal, didSig]; } @@ -1308,13 +1311,12 @@ class DIDModule { priority, iri, hexDid, - keyPair, - keyId, + signingKeyRef, nonce = undefined, ) { if (nonce === undefined) { // eslint-disable-next-line no-param-reassign - nonce = await this.getNextNonceForDID(hexDid); + nonce = await this.getNextNonceForDid(hexDid); } const setAttestation = { attest: { @@ -1324,11 +1326,8 @@ class DIDModule { nonce, }; const serializedAttestation = this.getSerializedAttestation(setAttestation); - const signature = getSignatureFromKeyringPair( - keyPair, - serializedAttestation, - ); - const didSig = createDidSig(hexDid, keyId, signature); + const signature = signingKeyRef.sign(serializedAttestation); + const didSig = createDidSig(hexDid, signingKeyRef, signature); return [setAttestation, didSig]; } diff --git a/src/modules/did/offchain-did-doc-ref.js b/src/modules/did/offchain-did-doc-ref.js index 60e4b469e..0b42fad47 100644 --- a/src/modules/did/offchain-did-doc-ref.js +++ b/src/modules/did/offchain-did-doc-ref.js @@ -1,4 +1,4 @@ -import { bytesToWrappedBytes } from '../../utils/misc'; +export const FORMATS = new Set(['CID', 'URL', 'Custom']); /** * An off-chain DID Doc reference stored on chain. The reference may be @@ -7,21 +7,23 @@ import { bytesToWrappedBytes } from '../../utils/misc'; * - any other format */ export default class OffChainDidDocRef { + constructor(type, bytes) { + if (!FORMATS.has(type)) { + throw new Error(`Unsupported type: ${type}`); + } + + this[type] = bytes; + } + static cid(bytes) { - return { - CID: bytesToWrappedBytes(bytes), - }; + return new this('CID', bytes); } static url(bytes) { - return { - URL: bytesToWrappedBytes(bytes), - }; + return new this('URL', bytes); } static custom(bytes) { - return { - Custom: bytesToWrappedBytes(bytes), - }; + return new this('Custom', bytes); } } diff --git a/src/modules/offchain-signatures.js b/src/modules/offchain-signatures.js index dea0c68dd..d0739f551 100644 --- a/src/modules/offchain-signatures.js +++ b/src/modules/offchain-signatures.js @@ -1,12 +1,11 @@ /* eslint-disable camelcase */ import { - getNonce, - getSignatureFromKeyringPair, + getDidNonce, getStateChange, } from '../utils/misc'; import WithParamsAndPublicKeys from './WithParamsAndPublicKeys'; -import { createDidSig, getHexIdentifierFromDID } from '../utils/did'; +import { createDidSig, typedHexDID } from '../utils/did'; const STATE_CHANGES = { AddParams: 'AddOffchainSignatureParams', @@ -38,7 +37,9 @@ export default class OffchainSignaturesModule extends WithParamsAndPublicKeys { this.signAndSend = signAndSend; } - /// Builds module-specific public key from the provided value. + /** + * Builds module-specific public key from the provided value. + */ static buildPublicKey(publicKey) { return publicKey; } @@ -49,7 +50,7 @@ export default class OffchainSignaturesModule extends WithParamsAndPublicKeys { * @returns {Promise<{bytes: string}|null>} */ async getLastParamsWritten(did) { - const hexId = getHexIdentifierFromDID(did); + const hexId = typedHexDID(this.api, did); const counter = await this.api.query[this.moduleName].paramsCounter(hexId); if (counter > 0) { const resp = await this.queryParamsFromChain(hexId, counter); @@ -66,7 +67,7 @@ export default class OffchainSignaturesModule extends WithParamsAndPublicKeys { * @returns {Promise} */ async getAllParamsByDid(did) { - const hexId = getHexIdentifierFromDID(did); + const hexId = typedHexDID(this.api, did); const params = []; const counter = await this.api.query[this.moduleName].paramsCounter(hexId); @@ -97,7 +98,7 @@ export default class OffchainSignaturesModule extends WithParamsAndPublicKeys { async queryPublicKeyFromChain(hexDid, keyId) { const key = await this.api.query[this.moduleName][this.methods.PublicKeys]( - hexDid, + hexDid.asDid, keyId, ); @@ -113,8 +114,7 @@ export default class OffchainSignaturesModule extends WithParamsAndPublicKeys { * @param publicKey - public key to add. * @param targetDid - The DID to which key is being added * @param signerDid - The DID that is adding the key by signing the payload because it controls `targetDid` - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's signingKeyRef * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this @@ -124,19 +124,17 @@ export default class OffchainSignaturesModule extends WithParamsAndPublicKeys { publicKey, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, { nonce = undefined, didModule = undefined }, ) { const offchainPublicKey = this.constructor.buildPublicKey(publicKey); - const targetHexDid = getHexIdentifierFromDID(targetDid); - const signerHexDid = getHexIdentifierFromDID(signerDid); + const targetHexDid = typedHexDID(this.api, targetDid).asDid; + const signerHexDid = typedHexDID(this.api, signerDid); const [addPk, signature] = await this.createSignedAddPublicKey( offchainPublicKey, targetHexDid, signerHexDid, - keyPair, - keyId, + signingKeyRef, { nonce, didModule }, ); return this.module.addPublicKey(addPk, signature); @@ -147,8 +145,7 @@ export default class OffchainSignaturesModule extends WithParamsAndPublicKeys { * @param removeKeyId - The key index for key to remove. * @param targetDid - The DID from which key is being removed * @param signerDid - The DID that is removing the key by signing the payload because it controls `targetDid` - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's signingKeyRef * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this @@ -158,18 +155,16 @@ export default class OffchainSignaturesModule extends WithParamsAndPublicKeys { removeKeyId, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, { nonce = undefined, didModule = undefined }, ) { - const targetHexDid = getHexIdentifierFromDID(targetDid); - const signerHexDid = getHexIdentifierFromDID(signerDid); + const targetHexDid = typedHexDID(this.api, targetDid).asDid; + const signerHexDid = typedHexDID(this.api, signerDid); const [removePk, signature] = await this.createSignedRemovePublicKey( removeKeyId, targetHexDid, signerHexDid, - keyPair, - keyId, + signingKeyRef, { nonce, didModule }, ); return this.module.removePublicKey(removePk, signature); @@ -180,8 +175,7 @@ export default class OffchainSignaturesModule extends WithParamsAndPublicKeys { * @param publicKey - public key to add. * @param targetDid - The DID to which key is being added * @param signerDid - The DID that is adding the key by signing the payload because it controls `targetDid` - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's signingKeyRef * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this @@ -193,8 +187,7 @@ export default class OffchainSignaturesModule extends WithParamsAndPublicKeys { publicKey, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}, @@ -203,8 +196,7 @@ export default class OffchainSignaturesModule extends WithParamsAndPublicKeys { publicKey, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, { nonce, didModule }, ); return this.signAndSend(tx, waitForFinalization, params); @@ -215,8 +207,7 @@ export default class OffchainSignaturesModule extends WithParamsAndPublicKeys { * @param removeKeyId - The key index for key to remove. * @param targetDid - The DID from which key is being removed * @param signerDid - The DID that is removing the key by signing the payload because it controls `targetDid` - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's signing key reference * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this @@ -228,8 +219,7 @@ export default class OffchainSignaturesModule extends WithParamsAndPublicKeys { removeKeyId, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}, @@ -238,8 +228,7 @@ export default class OffchainSignaturesModule extends WithParamsAndPublicKeys { removeKeyId, targetDid, signerDid, - keyPair, - keyId, + signingKeyRef, { nonce, didModule }, ); return this.signAndSend(tx, waitForFinalization, params); @@ -249,15 +238,14 @@ export default class OffchainSignaturesModule extends WithParamsAndPublicKeys { publicKey, targetHexDid, signerHexDid, - keyPair, - keyId, + signingKeyRef, { nonce = undefined, didModule = undefined }, ) { // eslint-disable-next-line no-param-reassign - nonce = await getNonce(signerHexDid, nonce, didModule); + nonce = await getDidNonce(signerHexDid, nonce, didModule); const addPk = { key: publicKey, did: targetHexDid, nonce }; - const signature = this.signAddPublicKey(keyPair, addPk); - const didSig = createDidSig(signerHexDid, keyId, signature); + const signature = this.signAddPublicKey(signingKeyRef, addPk); + const didSig = createDidSig(signerHexDid, signingKeyRef, signature); return [addPk, didSig]; } @@ -265,79 +253,78 @@ export default class OffchainSignaturesModule extends WithParamsAndPublicKeys { removeKeyId, targetHexDid, signerHexDid, - keyPair, - keyId, + signingKeyRef, { nonce = undefined, didModule = undefined }, ) { // eslint-disable-next-line no-param-reassign - nonce = await getNonce(signerHexDid, nonce, didModule); + nonce = await getDidNonce(signerHexDid, nonce, didModule); const removeKey = { keyRef: [targetHexDid, removeKeyId], did: targetHexDid, nonce, }; - const signature = this.signRemovePublicKey(keyPair, removeKey); - const didSig = createDidSig(signerHexDid, keyId, signature); + const signature = this.signRemovePublicKey(signingKeyRef, removeKey); + const didSig = createDidSig(signerHexDid, signingKeyRef, signature); return [removeKey, didSig]; } /** * - * @param keyPair + * @param signingKeyRef * @param params * @returns {Signature} */ - signAddParams(keyPair, params) { + signAddParams(signingKeyRef, params) { const serialized = getStateChange( this.api, this.stateChanges.AddParams, params, ); - return getSignatureFromKeyringPair(keyPair, serialized); + return signingKeyRef.sign(serialized); } /** * - * @param keyPair + * @param signingKeyRef * @param pk * @returns {Signature} */ - signAddPublicKey(keyPair, pk) { + signAddPublicKey(signingKeyRef, pk) { const serialized = getStateChange( this.api, this.stateChanges.AddPublicKey, pk, ); - return getSignatureFromKeyringPair(keyPair, serialized); + return signingKeyRef.sign(serialized); } /** * - * @param keyPair + * @param signingKeyRef * @param ref * @returns {Signature} */ - signRemoveParams(keyPair, ref) { + signRemoveParams(signingKeyRef, ref) { const serialized = getStateChange( this.api, this.stateChanges.RemoveParams, ref, ); - return getSignatureFromKeyringPair(keyPair, serialized); + return signingKeyRef.sign(serialized); } /** * - * @param keyPair + * @param signingKeyRef * @param ref * @returns {Signature} */ - signRemovePublicKey(keyPair, ref) { + signRemovePublicKey(signingKeyRef, ref) { const serialized = getStateChange( this.api, this.stateChanges.RemovePublicKey, ref, ); - return getSignatureFromKeyringPair(keyPair, serialized); + return signingKeyRef.sign(serialized); } } diff --git a/src/modules/ps.js b/src/modules/ps.js index 83a0c06ea..7ec4da97f 100644 --- a/src/modules/ps.js +++ b/src/modules/ps.js @@ -6,12 +6,16 @@ import PSParams from '../offchain-signatures/params/ps'; /** Class to write `Pointcheval-Sanders` parameters and keys on chain */ export default class PSModule extends OffchainSignaturesModule { - /// Builds `Pointcheval-Sanders` params from the provided value. + /** + * Builds `Pointcheval-Sanders` params from the provided value. + */ static buildParams(params) { return new PSParams(params); } - /// Builds `Pointcheval-Sanders` public key from the provided value. + /** + * Builds `Pointcheval-Sanders` public key from the provided value. + */ static buildPublicKey(publicKey) { return new PSPublicKey(publicKey); } diff --git a/src/modules/revocation.js b/src/modules/revocation.js index acebd31cc..86786100b 100644 --- a/src/modules/revocation.js +++ b/src/modules/revocation.js @@ -1,10 +1,9 @@ import { - getNonce, - getSignatureFromKeyringPair, + getDidNonce, getStateChange, } from '../utils/misc'; -import { createDidSig, getHexIdentifierFromDID } from '../utils/did'; // eslint-disable-line +import { createDidSig, typedHexDID } from '../utils/did'; // eslint-disable-line /** Class to create, update and destroy revocations */ class RevocationModule { @@ -179,17 +178,16 @@ class RevocationModule { * @param registryId - The registry id being updated * @param revId - The revocation id that is being revoked * @param did - * @param keyPair - * @param keyId + * @param signingKeyRef * @param nonce * @param didModule * @param waitForFinalization * @param params * @returns {Promise} */ - async revokeCredentialWithOneOfPolicy(registryId, revId, did, keyPair, keyId, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}) { - const [revoke, sig, sigNonce] = await this.createSignedRevoke(registryId, [revId], did, keyPair, keyId, { nonce, didModule }); - return this.revoke(revoke, [[sig, sigNonce]], waitForFinalization, params); + async revokeCredentialWithOneOfPolicy(registryId, revId, did, signingKeyRef, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}) { + const [revoke, sig, sigNonce] = await this.createSignedRevoke(registryId, [revId], did, signingKeyRef, { nonce, didModule }); + return this.revoke(revoke, [{ sig, nonce: sigNonce }], waitForFinalization, params); } /** @@ -197,28 +195,27 @@ class RevocationModule { * @param registryId * @param revId * @param did - * @param keyPair - * @param keyId + * @param signingKeyRef * @param nonce * @param didModule * @param waitForFinalization * @param params * @returns {Promise} */ - async unrevokeCredentialWithOneOfPolicy(registryId, revId, did, keyPair, keyId, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}) { - const [revoke, sig, sigNonce] = await this.createSignedUnRevoke(registryId, [revId], did, keyPair, keyId, { nonce, didModule }); - return this.unrevoke(revoke, [[sig, sigNonce]], waitForFinalization, params); + async unrevokeCredentialWithOneOfPolicy(registryId, revId, did, signingKeyRef, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}) { + const [revoke, sig, sigNonce] = await this.createSignedUnRevoke(registryId, [revId], did, signingKeyRef, { nonce, didModule }); + return this.unrevoke(revoke, [{ sig, nonce: sigNonce }], waitForFinalization, params); } - async removeRegistryWithOneOfPolicy(registryId, did, keyPair, keyId, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}) { - const [removal, sig, sigNonce] = await this.createSignedRemove(registryId, did, keyPair, keyId, { nonce, didModule }); - return this.removeRegistry(removal, [[sig, sigNonce]], waitForFinalization, params); + async removeRegistryWithOneOfPolicy(registryId, did, signingKeyRef, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}) { + const [removal, sig, sigNonce] = await this.createSignedRemove(registryId, did, signingKeyRef, { nonce, didModule }); + return this.removeRegistry(removal, [{ sig, nonce: sigNonce }], waitForFinalization, params); } - async createSignedUpdate(updateFunc, registryId, [...revokeIds], did, keyPair, keyId, { nonce = undefined, didModule = undefined }) { - const hexDid = getHexIdentifierFromDID(did); + async createSignedUpdate(updateFunc, registryId, [...revokeIds], did, signingKeyRef, { nonce = undefined, didModule = undefined }) { + const hexDid = typedHexDID(this.api, did); // eslint-disable-next-line no-param-reassign - nonce = await getNonce(hexDid, nonce, didModule); + nonce = await getDidNonce(hexDid, nonce, didModule); const update = { data: { @@ -227,32 +224,32 @@ class RevocationModule { }, nonce, }; - const serializedRevoke = updateFunc.bind(this)(update); - const signature = getSignatureFromKeyringPair(keyPair, serializedRevoke); - const didSig = createDidSig(hexDid, keyId, signature); + const serializedRevoke = updateFunc.call(this, update); + const signature = signingKeyRef.sign(serializedRevoke); + const didSig = createDidSig(hexDid, signingKeyRef, signature); return [{ registryId, revokeIds }, didSig, nonce]; } - async createSignedRevoke(registryId, revokeIds, did, keyPair, keyId, { nonce = undefined, didModule = undefined }) { - return this.createSignedUpdate(this.getSerializedRevoke, registryId, revokeIds, did, keyPair, keyId, { nonce, didModule }); + async createSignedRevoke(registryId, revokeIds, did, signingKeyRef, { nonce = undefined, didModule = undefined }) { + return this.createSignedUpdate(this.getSerializedRevoke, registryId, revokeIds, did, signingKeyRef, { nonce, didModule }); } - async createSignedUnRevoke(registryId, revokeIds, did, keyPair, keyId, { nonce = undefined, didModule = undefined }) { - return this.createSignedUpdate(this.getSerializedUnrevoke, registryId, revokeIds, did, keyPair, keyId, { nonce, didModule }); + async createSignedUnRevoke(registryId, revokeIds, did, signingKeyRef, { nonce = undefined, didModule = undefined }) { + return this.createSignedUpdate(this.getSerializedUnrevoke, registryId, revokeIds, did, signingKeyRef, { nonce, didModule }); } - async createSignedRemove(registryId, did, keyPair, keyId, { nonce = undefined, didModule = undefined }) { - const hexDid = getHexIdentifierFromDID(did); + async createSignedRemove(registryId, did, signingKeyRef, { nonce = undefined, didModule = undefined }) { + const hexDid = typedHexDID(this.api, did); // eslint-disable-next-line no-param-reassign - nonce = await getNonce(hexDid, nonce, didModule); + nonce = await getDidNonce(hexDid, nonce, didModule); const remove = { data: { registryId }, nonce, }; const serializedRemove = this.getSerializedRemoveRegistry(remove); - const signature = getSignatureFromKeyringPair(keyPair, serializedRemove); - const didSig = createDidSig(hexDid, keyId, signature); + const signature = signingKeyRef.sign(serializedRemove); + const didSig = createDidSig(hexDid, signingKeyRef, signature); return [{ registryId }, didSig, nonce]; } diff --git a/src/modules/schema.js b/src/modules/schema.js index 6470fadf5..84a624fa3 100644 --- a/src/modules/schema.js +++ b/src/modules/schema.js @@ -2,7 +2,6 @@ import { canonicalize } from 'json-canonicalize'; import { validate } from 'jsonschema'; import { hexDIDToQualified } from '../utils/did'; -import { getSignatureFromKeyringPair } from '../utils/misc'; import { createNewDockBlobId, @@ -56,7 +55,7 @@ export default class Schema { */ sign(pair, blobModule) { const serializedBlob = blobModule.getSerializedBlob(this.toBlob()); - this.signature = getSignatureFromKeyringPair(pair, serializedBlob); + this.signature = pair.sign(serializedBlob); return this; } @@ -95,20 +94,19 @@ export default class Schema { * @param {object} dock - The dock API * @param signerDid * @param keyPair - * @param keyId * @param nonce * @param waitForFinalization * @param params * @return {Promise} The extrinsic to sign and send. */ - async writeToChain(dock, signerDid, keyPair, keyId, nonce = undefined, waitForFinalization, params = {}) { + async writeToChain(dock, signerDid, keyPair, nonce = undefined, waitForFinalization, params = {}) { let arg; if (nonce === undefined) { arg = { didModule: dock.did }; } else { arg = { nonce }; } - return dock.blob.new(this.toBlob(), signerDid, keyPair, keyId, arg, waitForFinalization, params); + return dock.blob.new(this.toBlob(), signerDid, keyPair, arg, waitForFinalization, params); } /** diff --git a/src/modules/status-list-credential.js b/src/modules/status-list-credential.js index c3b3024df..038b7de9c 100644 --- a/src/modules/status-list-credential.js +++ b/src/modules/status-list-credential.js @@ -1,11 +1,10 @@ import StatusList2021Credential from '../status-list-credential/status-list2021-credential'; import { - getNonce, - getSignatureFromKeyringPair, + getDidNonce, getStateChange, } from '../utils/misc'; -import { createDidSig, getHexIdentifierFromDID } from '../utils/did'; +import { createDidSig, typedHexDID } from '../utils/did'; /** * Module supporting `StatusList2021Credential` and `RevocationList2020Credential`. @@ -114,8 +113,7 @@ export default class StatusListCredentialModule { * @param id - Unique identifier of the status list credential. * @param statusListCredential - Status list credential. * @param did - Signer of the transaction payload - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's signing key reference * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this @@ -127,8 +125,7 @@ export default class StatusListCredentialModule { id, statusListCredential, did, - keyPair, - keyId, + signingKeyRef, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}, @@ -137,13 +134,12 @@ export default class StatusListCredentialModule { id, statusListCredential, did, - keyPair, - keyId, + signingKeyRef, { nonce, didModule }, ); return this.updateStatusListCredential( payload, - [[sig, sigNonce]], + [{ nonce: sigNonce, sig }], waitForFinalization, params, ); @@ -153,8 +149,7 @@ export default class StatusListCredentialModule { * Remove a single `StatusListCredential`. Works only with credentials having `OneOf` policy * @param id - Unique identifier of the status list credential. * @param did - Signer of the transaction payload - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's signing key reference * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this @@ -165,8 +160,7 @@ export default class StatusListCredentialModule { async removeStatusListCredentialWithOneOfPolicy( id, did, - keyPair, - keyId, + signingKeyRef, { nonce = undefined, didModule = undefined }, waitForFinalization = true, params = {}, @@ -174,13 +168,12 @@ export default class StatusListCredentialModule { const [payload, sig, sigNonce] = await this.createSignedRemoveStatusListCredential( id, did, - keyPair, - keyId, + signingKeyRef, { nonce, didModule }, ); return this.removeStatusListCredential( payload, - [[sig, sigNonce]], + [{ nonce: sigNonce, sig }], waitForFinalization, params, ); @@ -239,8 +232,7 @@ export default class StatusListCredentialModule { * @param createSerializedTx - Function to create a serialized transaction using supplied payload. * @param data - Payload data. * @param did - Signer of the transaction payload - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's signing key reference * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * @param params - parameters to be used @@ -249,21 +241,20 @@ export default class StatusListCredentialModule { createSerializedTx, data, did, - keyPair, - keyId, + signingKeyRef, { nonce = undefined, didModule = undefined }, ) { - const hexDid = getHexIdentifierFromDID(did); + const hexDid = typedHexDID(this.api, did); // eslint-disable-next-line no-param-reassign - nonce = await getNonce(hexDid, nonce, didModule); + nonce = await getDidNonce(hexDid, nonce, didModule); const update = { data, nonce, }; const serializedTx = createSerializedTx.call(this, update); - const signature = getSignatureFromKeyringPair(keyPair, serializedTx); - const didSig = createDidSig(hexDid, keyId, signature); + const signature = signingKeyRef.sign(serializedTx); + const didSig = createDidSig(hexDid, signingKeyRef, signature); return [data, didSig, nonce]; } @@ -273,8 +264,7 @@ export default class StatusListCredentialModule { * @param id - Unique identifier of the status list credential. * @param statusListCredential - Status list credential. * @param did - Signer of the transaction payload - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's signing key ref key reference * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * @param params - parameters to be used @@ -283,16 +273,14 @@ export default class StatusListCredentialModule { id, statusListCredential, did, - keyPair, - keyId, + signingKeyRef, { nonce = undefined, didModule = undefined }, ) { return this.createDidSignature( this.getSerializedUpdateStatusListCredential, { id, credential: statusListCredential.toSubstrate() }, did, - keyPair, - keyId, + signingKeyRef, { nonce, didModule }, ); } @@ -302,24 +290,21 @@ export default class StatusListCredentialModule { * * @param id - Unique identifier of the status list credential. * @param did - Signer of the transaction payload - * @param keyPair - Signer's keypair - * @param keyId - The key id used by the signer. This will be used by the verifier (node) to fetch the public key for verification + * @param signingKeyRef - Signer's signing key reference * @param nonce - The nonce to be used for sending this transaction. If not provided then `didModule` must be provided. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by */ async createSignedRemoveStatusListCredential( id, did, - keyPair, - keyId, + signingKeyRef, { nonce = undefined, didModule = undefined }, ) { return this.createDidSignature( this.getSerializedRemoveStatusListCredential, { id }, did, - keyPair, - keyId, + signingKeyRef, { nonce, didModule }, ); } diff --git a/src/modules/trust-registry.js b/src/modules/trust-registry.js new file mode 100644 index 000000000..1596312b4 --- /dev/null +++ b/src/modules/trust-registry.js @@ -0,0 +1,271 @@ +import { BTreeSet } from '@polkadot/types'; +import { typedHexDID } from '../utils/did'; +import { getDidNonce } from '../utils/misc'; + +/** + * `Trust Registry` module. + */ +export default class TrustRegistryModule { + /** + * Creates a new instance of `StatusListCredentialModule` and sets the api + * @constructor + * @param {object} api - PolkadotJS API Reference + * @param signAndSend + */ + constructor(api, signAndSend) { + this.api = api; + this.module = api.tx.trustRegistry; + this.signAndSend = signAndSend; + } + + /** + * Initializes Trust Registry with the supplied parameters. + * @param convenerDid + * @param registryId + * @param name + * @param govFramework + * @param signingKeyRef + * @param nonce + * @param didModule + * @param params + * @param waitForFinalization + * @param params + * @returns {Promise} + */ + async init( + convenerDid, + registryId, + name, + govFramework, + signingKeyRef, + { nonce = undefined, didModule = undefined } = {}, + waitForFinalization = true, + params = {}, + ) { + const [convenerHexDid, lastNonce] = await this.getActorDidAndNonce(convenerDid, { nonce, didModule }); + + return this.signAndSend( + convenerHexDid.changeState( + this.api, + this.module.initOrUpdateTrustRegistry.bind(this.module), + 'InitOrUpdateTrustRegistry', + { + registryId, + name, + govFramework, + nonce: lastNonce, + }, + signingKeyRef, + ), + waitForFinalization, + params, + ); + } + + /** + * Appends new schemas to the registry. + * @param convenerDid + * @param registryId + * @param schemas + * @param signingKeyRef + * @param nonce + * @param didModule + * @param params + * @param waitForFinalization + * @param params + * @returns {Promise} + */ + async addSchemaMetadata( + convenerDid, + registryId, + schemas, + signingKeyRef, + { nonce = undefined, didModule = undefined } = {}, + waitForFinalization = true, + params = {}, + ) { + const [convenerHexDid, lastNonce] = await this.getActorDidAndNonce(convenerDid, { nonce, didModule }); + + return this.signAndSend( + convenerHexDid.changeState( + this.api, + this.module.addSchemaMetadata, + 'AddSchemaMetadata', + { registryId, schemas, nonce: lastNonce }, + signingKeyRef, + ), + waitForFinalization, + params, + ); + } + + /** + * Updates schemas metadatas in the registry. + * @param convenerOrIssuerOrVerifierDid + * @param registryId + * @param schemas + * @param signingKeyRef + * @param nonce + * @param didModule + * @param params + * @param waitForFinalization + * @param params + * @returns {Promise} + */ + async updateSchemaMetadata( + convenerOrIssuerOrVerifierDid, + registryId, + schemas, + signingKeyRef, + { nonce = undefined, didModule = undefined } = {}, + waitForFinalization = true, + params = {}, + ) { + const [convenerOrIssuerOrVerifierHexDid, lastNonce] = await this.getActorDidAndNonce(convenerOrIssuerOrVerifierDid, { nonce, didModule }); + + return this.signAndSend( + convenerOrIssuerOrVerifierHexDid.changeState( + this.api, + this.module.updateSchemaMetadata, + 'UpdateSchemaMetadata', + { registryId, schemas, nonce: lastNonce }, + signingKeyRef, + ), + waitForFinalization, + params, + ); + } + + /** + * Suspends issuers in the registry. + * @param convenerDid + * @param registryId + * @param issuers + * @param signingKeyRef + * @param nonce + * @param didModule + * @param params + * @param waitForFinalization + * @param params + * @returns {Promise} + */ + async suspendIssuers( + convenerDid, + registryId, + issuers, + signingKeyRef, + { nonce = undefined, didModule = undefined } = {}, + waitForFinalization = true, + params = {}, + ) { + const [convenerHexDid, lastNonce] = await this.getActorDidAndNonce(convenerDid, { nonce, didModule }); + + const hexIssuers = new BTreeSet(); + for (const issuer of issuers) { + hexIssuers.add(typedHexDID(this.api, issuer)); + } + + return this.signAndSend( + convenerHexDid.changeState( + this.api, + this.module.suspendIssuers, + 'SuspendIssuers', + { registryId, issuers: hexIssuers, nonce: lastNonce }, + signingKeyRef, + ), + waitForFinalization, + params, + ); + } + + /** + * Unsuspends issuers in the registry. + * @param convenerDid + * @param registryId + * @param issuers + * @param signingKeyRef + * @param nonce + * @param didModule + * @param params + * @param waitForFinalization + * @param params + * @returns {Promise} + */ + async unsuspendIssuers( + convenerDid, + registryId, + issuers, + signingKeyRef, + { nonce = undefined, didModule = undefined } = {}, + waitForFinalization = true, + params = {}, + ) { + const [convenerHexDid, lastNonce] = await this.getActorDidAndNonce(convenerDid, { nonce, didModule }); + + const hexIssuers = new BTreeSet(); + for (const issuer of issuers) { + hexIssuers.add(typedHexDID(this.api, issuer)); + } + + return this.signAndSend( + convenerHexDid.changeState( + this.api, + this.module.unsuspendIssuers, + 'UnsuspendIssuers', + { registryId, issuers: hexIssuers, nonce: lastNonce }, + signingKeyRef, + ), + waitForFinalization, + params, + ); + } + + /** + * Unsuspends issuers in the registry. + * @param issuerDid + * @param registryId + * @param issuers + * @param delegated + * @param signingKeyRef + * @param params + * @param waitForFinalization + * @param params + * @returns {Promise} + */ + async updateDelegatedIssuers( + issuerDid, + registryId, + delegated, + signingKeyRef, + { nonce = undefined, didModule = undefined } = {}, + waitForFinalization = true, + params = {}, + ) { + const [issuerHexDid, lastNonce] = await this.getActorDidAndNonce(issuerDid, { nonce, didModule }); + + return this.signAndSend( + issuerHexDid.changeState( + this.api, + this.module.updateDelegatedIssuers, + 'UpdateDelegatedIssuers', + { registryId, delegated, nonce: lastNonce }, + signingKeyRef, + ), + waitForFinalization, + params, + ); + } + + /** + * Get the DID doing the action and its corresponding nonce. + * @param actorDid + * @param nonce + * @param didModule + * @returns {Promise} + */ + async getActorDidAndNonce(actorDid, { nonce = undefined, didModule = undefined } = {}) { + const convenerHexDid = typedHexDID(this.api, actorDid); + const lastNonce = nonce ?? (await getDidNonce(convenerHexDid, nonce, didModule)); + return [convenerHexDid, lastNonce]; + } +} diff --git a/src/rpc-defs/core-mods-rpc-defs.js b/src/rpc-defs/core-mods-rpc-defs.js index 91c3188f1..4a7a052da 100644 --- a/src/rpc-defs/core-mods-rpc-defs.js +++ b/src/rpc-defs/core-mods-rpc-defs.js @@ -17,7 +17,7 @@ export default { params: [ { name: 'did', - type: 'Did', + type: 'DidOrDidMethodKey', }, ], type: 'BTreeMap', @@ -47,7 +47,7 @@ export default { params: [ { name: 'did', - type: 'Did', + type: 'DidOrDidMethodKey', }, ], type: 'BTreeMap', @@ -77,7 +77,7 @@ export default { params: [ { name: 'did', - type: 'Did', + type: 'DidOrDidMethodKey', }, ], type: 'BTreeMap', diff --git a/src/status-list-credential/status-list2021-credential.js b/src/status-list-credential/status-list2021-credential.js index e6e9c5689..0e9c7d2f8 100644 --- a/src/status-list-credential/status-list2021-credential.js +++ b/src/status-list-credential/status-list2021-credential.js @@ -64,6 +64,7 @@ export default class StatusList2021Credential extends VerifiableCredential { * Can be either `revocation` or `suspension`. * @param {number} [params.length=1e4] - length of the underlying `StatusList`. * @param {Iterable} [params.revokeIndices=[]] - iterable producing indices to be revoked or suspended initially + * @returns {Promise} */ static async create( keyDoc, @@ -94,7 +95,7 @@ export default class StatusList2021Credential extends VerifiableCredential { * @param {object} [update={}] * @param {Iterable} update.revokeIndices - indices to be revoked or suspended * @param {Iterable} update.unsuspendIndices - indices to be unsuspended - * @returns {this} + * @returns {Promise} */ async update(keyDoc, { revokeIndices = [], unsuspendIndices = [] }) { const statusList = new StatusList({ @@ -121,7 +122,7 @@ export default class StatusList2021Credential extends VerifiableCredential { * Throws an error if the underlying status list can't be decoded or supplied index is out of range. * * @param {number} index - * @returns {boolean} + * @returns {Promise} */ async revoked(index) { const decodedStatusList = await this.decodedStatusList(); @@ -135,7 +136,7 @@ export default class StatusList2021Credential extends VerifiableCredential { * Throws an error if the underlying status list can't be decoded or any of supplied indices is out of range. * * @param {Iterable} indices - * @returns {Array} + * @returns {Promise>} */ async revokedBatch(indices) { const decodedStatusList = await this.decodedStatusList(); diff --git a/src/utils/codec.js b/src/utils/codec.js index dcc30a038..8108dbf67 100644 --- a/src/utils/codec.js +++ b/src/utils/codec.js @@ -16,10 +16,10 @@ export function isHexWithGivenByteSize(value, byteSize = undefined) { if (byteSize !== undefined) { // If `byteSize` is not a positive integer type, then check will fail // 2 hex digits make a byte - return match[1].length === (2 * byteSize); + return match[1].length === 2 * byteSize; } // Don't care about byte size of the match but it must be full byte - return (match[1].length % 2) === 0; + return match[1].length % 2 === 0; } return false; } @@ -28,29 +28,35 @@ export function isHexWithGivenByteSize(value, byteSize = undefined) { * Gets the hexadecimal value of the given string. * @return {string} Returns the hexadecimal representation of the ID. */ -export function getHexIdentifier(id, qualifier, validate, byteSize) { - if (id.startsWith(qualifier)) { - // Fully qualified ID. Remove the qualifier - const ss58Did = id.slice(qualifier.length); - try { - const hex = u8aToHex(decodeAddress(ss58Did)); - // 2 characters for `0x` and 2*byte size of ID - if (hex.length !== (2 + 2 * byteSize)) { - throw new Error('Unexpected byte size'); +export function getHexIdentifier(id, qualifiers, byteSize) { + const strId = String(id); + for (const qualifier of [].concat(qualifiers)) { + if (strId.startsWith(qualifier)) { + // Fully qualified ID. Remove the qualifier + const ss58Did = strId.slice(qualifier.length); + try { + const hex = u8aToHex(decodeAddress(ss58Did)); + // 2 characters for `0x` and 2*byte size of ID + if (hex.length !== 2 + 2 * byteSize) { + throw new Error('Unexpected byte size'); + } + return hex; + } catch (e) { + throw new Error(`Invalid SS58 ID ${strId}. ${e}`); } - return hex; - } catch (e) { - throw new Error(`Invalid SS58 ID ${id}. ${e}`); } - } else { - try { - // Check if hex and of correct size and return the hex value if successful. - validate(id); - return id; - } catch (e) { - // Cannot parse as hex - throw new Error(`Invalid hexadecimal ID ${id}. ${e}`); + } + + try { + // Check if hex and of correct size and return the hex value if successful. + if (!isHexWithGivenByteSize(strId, byteSize)) { + throw new Error(`Expected ${byteSize}-byte sequence`); } + + return strId; + } catch (error) { + // Cannot parse as hex + throw new Error(`Invalid hex Did \`${id}\`, stringified \`${strId}\`: ${error}`); } } @@ -68,7 +74,9 @@ export function asDockAddress(addr, network = 'test') { case 'main': return encodeAddress(addr, 22); default: - throw new Error(`Network can be either test or main or dev but was passed as ${network}`); + throw new Error( + `Network can be either test or main or dev but was passed as ${network}`, + ); } } diff --git a/src/utils/did.js b/src/utils/did.js index 99621f7d5..9f3a6bea9 100644 --- a/src/utils/did.js +++ b/src/utils/did.js @@ -3,14 +3,183 @@ // Import some utils from Polkadot JS // eslint-disable-next-line max-classes-per-file import { randomAsHex, encodeAddress } from '@polkadot/util-crypto'; +import { u8aToHex } from '@polkadot/util'; import { isHexWithGivenByteSize, getHexIdentifier } from './codec'; +import { + PublicKeyEd25519, + PublicKeySecp256k1, + PublicKey, // eslint-disable-line + VerificationRelationship, // eslint-disable-line +} from '../public-keys'; -import { Signature } from '../signatures'; // eslint-disable-line -import { PublicKey, VerificationRelationship } from '../public-keys'; // eslint-disable-line +import { Signature } from "../signatures"; // eslint-disable-line +import { + getPublicKeyFromKeyringPair, + getSignatureFromKeyringPair, + getStateChange, +} from './misc'; export const DockDIDMethod = 'dock'; +export const Secp256k1PublicKeyPrefix = 'zQ3s'; +export const Ed25519PublicKeyPrefix = 'z6Mk'; + export const DockDIDQualifier = `did:${DockDIDMethod}:`; +export const DockDIDMethodKeyQualifier = 'did:key:'; export const DockDIDByteSize = 32; +export const DockDIDMethodKeySecp256k1ByteSize = 33; +export const DockDIDMethodKeyEd25519ByteSize = 32; + +export const DockDidMethodKeySecp256k1Prefix = `${DockDIDMethodKeyQualifier}${Secp256k1PublicKeyPrefix}`; +export const DockDidMethodKeyEd25519Prefix = `${DockDIDMethodKeyQualifier}${Ed25519PublicKeyPrefix}`; + +export class DidKeypair { + constructor(keyPair, keyId) { + this.keyPair = keyPair; + this.keyId = keyId; + } + + publicKey() { + return getPublicKeyFromKeyringPair(this.keyPair); + } + + sign(message) { + return getSignatureFromKeyringPair(this.keyPair, message); + } + + /** + * Create a new keypair from a DockAPI object. + * @param {DockAPI} dockApi + * @param seed - Generates 32 byte random seed if not provided + * @param keypairType - Defaults to ed25519. + * @param meta + * @param keyId - Defaults to 1 + * @returns {DidKeypair} + */ + static fromApi( + dockApi, + { + seed = randomAsHex(32), + keypairType = 'ed25519', + meta = null, + keyId = 1, + } = {}, + ) { + return new DidKeypair( + dockApi.keyring.addFromUri(seed, meta, keypairType), + keyId, + ); + } +} + +export class DidActor { + signStateChange(api, name, payload, keyRef) { + const stateChange = getStateChange(api, name, payload); + const keySignature = keyRef.sign(stateChange); + + return createDidSig(this, keyRef, keySignature); + } + + changeState(api, method, name, payload, keyRef) { + const signature = this.signStateChange(api, name, payload, keyRef); + + return method(payload, signature); + } +} + +export class DockDidOrDidMethodKey extends DidActor { + get asDid() { + throw new Error('Not a `Did`'); + } + + get asDidMethodKey() { + throw new Error('Not a `DidMethodKey`'); + } + + get isDid() { + return false; + } + + get isDidMethodKey() { + return false; + } +} + +export class DockDid extends DockDidOrDidMethodKey { + constructor(did) { + super(); + this.did = did; + } + + get isDid() { + return true; + } + + get asDid() { + return this.did; + } + + toJSON() { + return { Did: this.did }; + } + + toString() { + return `${DockDIDQualifier}${this.asDid}`; + } + + toStringSS58() { + return `${DockDIDQualifier}${encodeAddress(this.asDid)}`; + } +} + +export class DockDidMethodKey extends DockDidOrDidMethodKey { + constructor(didMethodKey) { + super(); + + if (didMethodKey instanceof PublicKeyEd25519) { + this.didMethodKey = { ed25519: didMethodKey.value }; + } else if (didMethodKey instanceof PublicKeySecp256k1) { + this.didMethodKey = { secp256k1: didMethodKey.value }; + } else { + throw new Error('Unsopported public key type'); + } + } + + get isDidMethodKey() { + return true; + } + + get asDidMethodKey() { + return this.didMethodKey; + } + + toJSON() { + return { + DidMethodKey: this.didMethodKey.ed25519 + ? { Ed25519: this.didMethodKey.ed25519 } + : { Secp256k1: this.didMethodKey.secp256k1 }, + }; + } + + toString() { + return this.toStringSS58(); + } + + toStringSS58() { + let prefix; let + address; + if (this.didMethodKey.ed25519) { + prefix = DockDidMethodKeyEd25519Prefix; + address = this.didMethodKey.ed25519; + } else if (this.didMethodKey.secp256k1) { + prefix = DockDidMethodKeySecp256k1Prefix; + address = this.didMethodKey.secp256k1; + } else { + throw new Error('Unsopported public key type'); + } + + return `${prefix}${encodeAddress(address)}`; + } +} /** * Error thrown when a DID document lookup was successful, but the DID in question does not exist. @@ -50,7 +219,7 @@ export class NoOffchainDIDError extends Error { } /** - * Check if the given identifier is 32 byte hex + * Check if the given identifier is the hex representation of a Dock DID. * @param {string} identifier - The identifier to check. * @return {void} Throws exception if invalid identifier */ @@ -76,23 +245,127 @@ export function validateDockDIDSS58Identifier(identifier) { } /** - * Gets the hexadecimal value of the given DID. + * Temporary solution for the DID's backward compatibility. + * + * -------------------------------------------------------- + */ +// eslint-disable-next-line no-extend-native +Object.defineProperty(String.prototype, 'asDid', { + get() { + if (this.isDid) { + return String(this); + } else { + throw new Error('Not a `Did`'); + } + }, +}); +// eslint-disable-next-line no-extend-native +Object.defineProperty(String.prototype, 'isDid', { + get() { + return isHexWithGivenByteSize(String(this), DockDIDByteSize); + }, +}); +// eslint-disable-next-line no-extend-native +Object.defineProperty(String.prototype, 'toStringSS58', { + get() { + return new DockDid(this.asDid).toStringSS58(); + }, +}); + +/** + * -------------------------------------------------------- + */ + +/** + * Takes a DID string, gets the hexadecimal value of that and returns a `DockDidMethodKey` or `DockDid` object. + * @param api + * @param {string} did - The DID can be passed as fully qualified DID like `did:dock:` or + * `did:key:` or a 32 byte hex string + * @return {string|DockDidOrDidMethodKey} Returns a `string` or `DockDidMethodKey` or `DockDid` object. + */ +export function typedHexDID(api, did) { + const strDid = did.toString(); + if (api.specVersion < 50) { + return getHexIdentifier(strDid, DockDIDQualifier, DockDIDByteSize); + } + + if (strDid.startsWith(DockDidMethodKeySecp256k1Prefix)) { + const hex = getHexIdentifier( + strDid, + DockDidMethodKeySecp256k1Prefix, + DockDIDMethodKeySecp256k1ByteSize, + ); + + return new DockDidMethodKey(new PublicKeySecp256k1(hex)); + } else if (strDid.startsWith(DockDidMethodKeyEd25519Prefix)) { + const hex = getHexIdentifier( + strDid, + DockDidMethodKeyEd25519Prefix, + DockDIDMethodKeyEd25519ByteSize, + ); + + return new DockDidMethodKey(new PublicKeyEd25519(hex)); + } else { + const hex = getHexIdentifier(strDid, DockDIDQualifier, DockDIDByteSize); + + return new DockDid(hex); + } +} + +/** + * Gets the hexadecimal value of the given DID received from the substrate side. + * @param api * @param {string} did - The DID can be passed as fully qualified DID like `did:dock:` or * a 32 byte hex string - * @return {string} Returns the hexadecimal representation of the DID. + * @return {string|DockDidOrDidMethodKey} Returns an object wrapping the DID. */ -export function getHexIdentifierFromDID(did) { - return getHexIdentifier(did, DockDIDQualifier, validateDockDIDHexIdentifier, DockDIDByteSize); +export function typedHexDIDFromSubstrate(api, did) { + if (api.specVersion < 50) { + return getHexIdentifier(did, DockDIDQualifier, DockDIDByteSize); + } else if (did.isDid) { + const hex = getHexIdentifier(u8aToHex(did.asDid), [], DockDIDByteSize); + + return new DockDid(hex); + } else if (did.isDidMethodKey) { + const key = did.asDidMethodKey; + + if (key.isSecp256k1) { + const hex = getHexIdentifier( + u8aToHex(did.asSecp256k1), + [], + DockDIDMethodKeySecp256k1ByteSize, + ); + + return new DockDidMethodKey(hex); + } else if (key.isEd25519) { + const hex = getHexIdentifier( + u8aToHex(did.asEd25519), + [], + DockDIDMethodKeyEd25519ByteSize, + ); + + return new DockDidMethodKey(hex); + } else { + throw new Error(`Invalid did key: provided: \`${key}\``); + } + } else { + throw new Error(`Invalid did provided: \`${did}\``); + } } /** * Return a fully qualified Dock DID id, i.e. "did:dock:" - * @param {string} hexId - The hex blob id (without the qualifier) - * @returns {string} - The fully qualified Blob id + * @param {string|object} hexDid - The hex DID (without the qualifier) or wrapper on DID + * @returns {string} - The fully qualified DID */ -export function hexDIDToQualified(hexId) { - const ss58Id = encodeAddress(hexId); - return `${DockDIDQualifier}${ss58Id}`; +export function hexDIDToQualified(hexDid) { + if (typeof hexDid?.toStringSS58 === 'function') { + return hexDid.toStringSS58(); + } else { + const ss58Address = encodeAddress(hexDid); + + return `${DockDIDQualifier}${ss58Address}`; + } } /** @@ -120,13 +393,39 @@ export function createDidKey(publicKey, verRel) { /** * - * @param {string} did - DID as hex + * @param {string|DockDidOrDidMethodKey} did - DID as string or an object * @param {number} keyId - + * @param rawSig * @param {Signature} sig * @returns {{sig: *, keyId, did}} */ -export function createDidSig(did, keyId = 1, sig) { - return { - did, keyId, sig: sig.toJSON(), - }; +export function createDidSig(did, { keyId }, rawSig) { + const sig = rawSig.toJSON(); + + if (typeof did === 'string') { + return { + did, + keyId, + sig, + }; + } else if (did.isDid) { + return { + DidSignature: { + did: did.asDid, + keyId, + sig, + }, + }; + } else if (did.isDidMethodKey) { + return { + DidMethodKeySignature: { + didMethodKey: did.asDidMethodKey, + sig, + }, + }; + } else { + throw new Error( + `Incorrect DID passed: \`${did}\`, expected instance of either \`DockDid\` or \`DockDidMethodKey\``, + ); + } } diff --git a/src/utils/misc.js b/src/utils/misc.js index 491565f99..2be84e5ad 100644 --- a/src/utils/misc.js +++ b/src/utils/misc.js @@ -3,10 +3,14 @@ import { blake2AsHex } from '@polkadot/util-crypto'; import { sha256 } from 'js-sha256'; import { - PublicKey, PublicKeyEd25519, PublicKeySecp256k1, PublicKeySr25519, // eslint-disable-line + PublicKeyEd25519, + PublicKeySecp256k1, + PublicKeySr25519, // eslint-disable-line } from '../public-keys'; import { - Signature, SignatureEd25519, SignatureSecp256k1, SignatureSr25519, // eslint-disable-line + SignatureEd25519, + SignatureSecp256k1, + SignatureSr25519, // eslint-disable-line } from '../signatures'; const EC = elliptic.ec; @@ -60,7 +64,11 @@ export function verifyEcdsaSecp256k1Sig(message, signature, publicKey) { * @param {PublicKeySecp256k1} publicKey - Secp256k1 public key for verification * @returns {boolean} True when signature is valid, false otherwise */ -export function verifyEcdsaSecp256k1SigPrehashed(messageHash, signature, publicKey) { +export function verifyEcdsaSecp256k1SigPrehashed( + messageHash, + signature, + publicKey, +) { // Remove the leading `0x` const sigHex = signature.value.slice(2); // Break it in 2 chunks of 32 bytes each @@ -151,29 +159,26 @@ export function encodeExtrinsicAsHash(api, tx) { return blake2AsHex(api.createType('Call', tx).toU8a()); } -/** - * Convert bytes to struct `WrappedBytes` expected by chain - * @param bytes - * @returns {{'0'}} - */ -export function bytesToWrappedBytes(bytes) { - return bytes; -} - /** * Get the nonce to be used for sending the next transaction if not provided already. - * @param hexDid - DID whose nonce is needed + * @param {DockDidOrDidMethodKey} didOrDidMethodKey - DID whose nonce is needed * @param nonce - If provided, returned as it is. * @param didModule - Reference to the DID module. If nonce is not provided then the next nonce for the DID is fetched by * using this * @returns {Promise} */ -export async function getNonce(hexDid, nonce = undefined, didModule = undefined) { +export async function getDidNonce( + didOrDidMethodKey, + nonce = undefined, + didModule = undefined, +) { if (nonce === undefined && didModule === undefined) { - throw new Error('Provide either nonce or didModule to fetch nonce but none provided'); + throw new Error( + 'Provide either nonce or didModule to fetch nonce but none provided', + ); } if (nonce === undefined) { - return didModule.getNextNonceForDID(hexDid); + return didModule.getNextNonceForDid(didOrDidMethodKey); } return nonce; } diff --git a/src/utils/revocation/one-of-policy.js b/src/utils/revocation/one-of-policy.js index 285d8cc86..069ee76e8 100644 --- a/src/utils/revocation/one-of-policy.js +++ b/src/utils/revocation/one-of-policy.js @@ -1,4 +1,3 @@ -import { getHexIdentifierFromDID } from '../did'; import Policy from './policy'; // Revocation policy that allows one of the pre-decided controllers to update the registry. @@ -10,7 +9,7 @@ export default class OneOfPolicy extends Policy { */ constructor(controllers = []) { super(); - this.controllers = new Set([...controllers].map((did) => getHexIdentifierFromDID(did))); + this.controllers = new Set(controllers); } /** @@ -18,12 +17,12 @@ export default class OneOfPolicy extends Policy { * @param {string} ownerDID - Owner's DID */ addOwner(ownerDID) { - this.controllers.add(getHexIdentifierFromDID(ownerDID)); + this.controllers.add(ownerDID); } /** * Returns list containing unique sorted owner DIDs. - * @param {string} ownerDID - Owner's DID + * @returns {DockDidOrDidMethodKey[]} */ controllerIds() { const controllerIds = [...this.controllers]; diff --git a/src/utils/vc/helpers.js b/src/utils/vc/helpers.js index dd6ab9a04..e444d95f2 100644 --- a/src/utils/vc/helpers.js +++ b/src/utils/vc/helpers.js @@ -41,7 +41,7 @@ export function getKeyDoc(did, keypair, type, id) { id: id || `${did}#keys-1`, controller: did, type, - keypair, + keypair: keypair.keyPair || keypair, }; } diff --git a/src/utils/vc/schema.js b/src/utils/vc/schema.js index 128a764fe..f8fc66236 100644 --- a/src/utils/vc/schema.js +++ b/src/utils/vc/schema.js @@ -16,6 +16,7 @@ import { * @param {object} credential - The credential to use, must be expanded JSON-LD * @param {object} schema - The schema to use * @param context + * @param documentLoader * @returns {Promise} - Returns promise to a boolean or throws error */ export async function validateCredentialSchema( diff --git a/tests/integration/anoncreds/accumulator.test.js b/tests/integration/anoncreds/accumulator.test.js index 7c83fa10b..6fc675f67 100644 --- a/tests/integration/anoncreds/accumulator.test.js +++ b/tests/integration/anoncreds/accumulator.test.js @@ -1,18 +1,30 @@ -import { randomAsHex } from '@polkadot/util-crypto'; +import { randomAsHex } from "@polkadot/util-crypto"; import { - initializeWasm, Accumulator, PositiveAccumulator, WitnessUpdatePublicInfo, AccumulatorParams, -} from '@docknetwork/crypto-wasm-ts'; -import { InMemoryState } from '@docknetwork/crypto-wasm-ts/lib/accumulator/in-memory-persistence'; -import { hexToU8a, stringToHex, u8aToHex } from '@polkadot/util'; -import { DockAPI } from '../../../src'; -import { FullNodeEndpoint, TestAccountURI, TestKeyringOpts } from '../../test-constants'; -import { createNewDockDID, getHexIdentifierFromDID } from '../../../src/utils/did'; - -import AccumulatorModule from '../../../src/modules/accumulator'; -import { getAllEventsFromBlock } from '../../../src/utils/chain-ops'; -import { registerNewDIDUsingPair } from '../helpers'; - -describe('Accumulator Module', () => { + initializeWasm, + Accumulator, + PositiveAccumulator, + WitnessUpdatePublicInfo, + AccumulatorParams, +} from "@docknetwork/crypto-wasm-ts"; +import { InMemoryState } from "@docknetwork/crypto-wasm-ts/lib/accumulator/in-memory-persistence"; +import { hexToU8a, stringToHex, u8aToHex } from "@polkadot/util"; +import { DockAPI } from "../../../src"; +import { + FullNodeEndpoint, + TestAccountURI, + TestKeyringOpts, +} from "../../test-constants"; +import { + DidKeypair, + createNewDockDID, + typedHexDID, +} from "../../../src/utils/did"; + +import AccumulatorModule from "../../../src/modules/accumulator"; +import { getAllEventsFromBlock } from "../../../src/utils/chain-ops"; +import { registerNewDIDUsingPair } from "../helpers"; + +describe("Accumulator Module", () => { const dock = new DockAPI(); let account; let did1; @@ -35,8 +47,8 @@ describe('Accumulator Module', () => { chainModule = dock.accumulatorModule; account = dock.keyring.addFromUri(TestAccountURI); dock.setAccount(account); - pair1 = dock.keyring.addFromUri(seed1); - pair2 = dock.keyring.addFromUri(seed2); + pair1 = new DidKeypair(dock.keyring.addFromUri(seed1), 1); + pair2 = new DidKeypair(dock.keyring.addFromUri(seed2), 1); did1 = createNewDockDID(); did2 = createNewDockDID(); await registerNewDIDUsingPair(dock, did1, pair1); @@ -44,12 +56,22 @@ describe('Accumulator Module', () => { await initializeWasm(); }, 20000); - test('Can create new params', async () => { - let label = stringToHex('accumulator-params-label'); + test("Can create new params", async () => { + let label = stringToHex("accumulator-params-label"); let params = Accumulator.generateParams(hexToU8a(label)); const bytes1 = u8aToHex(params.bytes); - const params1 = chainModuleClass.prepareAddParameters(bytes1, undefined, label); - await chainModule.addParams(params1, did1, pair1, 1, { didModule: dock.did }, false); + const params1 = chainModuleClass.prepareAddParameters( + bytes1, + undefined, + label + ); + await chainModule.addParams( + params1, + did1, + pair1, + { didModule: dock.did }, + false + ); const paramsWritten1 = await chainModule.getLastParamsWritten(did1); expect(paramsWritten1.bytes).toEqual(params1.bytes); expect(paramsWritten1.label).toEqual(params1.label); @@ -57,11 +79,17 @@ describe('Accumulator Module', () => { const queriedParams1 = await chainModule.getParams(did1, 1); expect(paramsWritten1).toEqual(queriedParams1); - label = stringToHex('some label'); + label = stringToHex("some label"); params = Accumulator.generateParams(hexToU8a(label)); const bytes2 = u8aToHex(params.bytes); const params2 = chainModuleClass.prepareAddParameters(bytes2); - await chainModule.addParams(params2, did2, pair2, 1, { didModule: dock.did }, false); + await chainModule.addParams( + params2, + did2, + pair2, + { didModule: dock.did }, + false + ); const paramsWritten2 = await chainModule.getLastParamsWritten(did2); expect(paramsWritten2.bytes).toEqual(params2.bytes); expect(paramsWritten2.label).toBe(null); @@ -69,11 +97,17 @@ describe('Accumulator Module', () => { const queriedParams2 = await chainModule.getParams(did2, 1); expect(paramsWritten2).toEqual(queriedParams2); - label = stringToHex('some label'); + label = stringToHex("some label"); params = Accumulator.generateParams(hexToU8a(label)); const bytes3 = u8aToHex(params.bytes); const params3 = chainModuleClass.prepareAddParameters(bytes3); - await chainModule.addParams(params3, did1, pair1, 1, { didModule: dock.did }, false); + await chainModule.addParams( + params3, + did1, + pair1, + { didModule: dock.did }, + false + ); const paramsWritten3 = await chainModule.getLastParamsWritten(did1); expect(paramsWritten3.bytes).toEqual(params3.bytes); expect(paramsWritten3.label).toBe(null); @@ -89,12 +123,18 @@ describe('Accumulator Module', () => { expect(paramsByDid2[0]).toEqual(paramsWritten2); }, 30000); - test('Can create public keys', async () => { + test("Can create public keys", async () => { const params = Accumulator.generateParams(); let keypair = Accumulator.generateKeypair(params); const bytes1 = u8aToHex(keypair.publicKey.bytes); - const pk1 = chainModuleClass.prepareAddPublicKey(bytes1); - await chainModule.addPublicKey(pk1, did1, pair1, 1, { didModule: dock.did }, false); + const pk1 = chainModuleClass.prepareAddPublicKey(dock.api, bytes1); + await chainModule.addPublicKey( + pk1, + did1, + pair1, + { didModule: dock.did }, + false + ); const queriedPk1 = await chainModule.getPublicKey(did1, 1); expect(queriedPk1.bytes).toEqual(pk1.bytes); @@ -104,12 +144,21 @@ describe('Accumulator Module', () => { const aparams1 = new AccumulatorParams(hexToU8a(params1.bytes)); keypair = Accumulator.generateKeypair(aparams1, hexToU8a(seedAccum)); const bytes2 = u8aToHex(keypair.publicKey.bytes); - const pk2 = chainModuleClass.prepareAddPublicKey(bytes2, undefined, [did1, 1]); - await chainModule.addPublicKey(pk2, did2, pair2, 1, { didModule: dock.did }, false); + const pk2 = chainModuleClass.prepareAddPublicKey(dock.api, bytes2, undefined, [ + did1, + 1, + ]); + await chainModule.addPublicKey( + pk2, + did2, + pair2, + { didModule: dock.did }, + false + ); const queriedPk2 = await chainModule.getPublicKey(did2, 1); expect(queriedPk2.bytes).toEqual(pk2.bytes); - expect(queriedPk2.paramsRef).toEqual([getHexIdentifierFromDID(did1), 1]); + expect(queriedPk2.paramsRef).toEqual([typedHexDID(dock.api, did1), 1]); const queriedPk2WithParams = await chainModule.getPublicKey(did2, 1, true); expect(queriedPk2WithParams.params).toEqual(params1); @@ -118,12 +167,21 @@ describe('Accumulator Module', () => { const aparams2 = new AccumulatorParams(hexToU8a(params2.bytes)); keypair = Accumulator.generateKeypair(aparams2); const bytes3 = u8aToHex(keypair.publicKey.bytes); - const pk3 = chainModuleClass.prepareAddPublicKey(bytes3, undefined, [did1, 2]); - await chainModule.addPublicKey(pk3, did2, pair2, 1, { didModule: dock.did }, false); + const pk3 = chainModuleClass.prepareAddPublicKey(dock.api, bytes3, undefined, [ + did1, + 2, + ]); + await chainModule.addPublicKey( + pk3, + did2, + pair2, + { didModule: dock.did }, + false + ); const queriedPk3 = await chainModule.getPublicKey(did2, 2); expect(queriedPk3.bytes).toEqual(pk3.bytes); - expect(queriedPk3.paramsRef).toEqual([getHexIdentifierFromDID(did1), 2]); + expect(queriedPk3.paramsRef).toEqual([typedHexDID(dock.api, did1), 2]); const queriedPk3WithParams = await chainModule.getPublicKey(did2, 2, true); expect(queriedPk3WithParams.params).toEqual(params2); @@ -137,38 +195,55 @@ describe('Accumulator Module', () => { const pksWithParamsByDid2 = await chainModule.getAllPublicKeysByDid( did2, - true, + true ); expect(pksWithParamsByDid2[0]).toEqual(queriedPk2WithParams); expect(pksWithParamsByDid2[1]).toEqual(queriedPk3WithParams); }, 30000); - test('Can add and remove accumulator', async () => { + test("Can add and remove accumulator", async () => { const id1 = randomAsHex(32); const accumulated1 = randomAsHex(100); - await chainModule.addPositiveAccumulator(id1, accumulated1, [did1, 1], did1, pair1, 1, { didModule: dock.did }, false); + await chainModule.addPositiveAccumulator( + id1, + accumulated1, + [did1, 1], + did1, + pair1, + { didModule: dock.did }, + false + ); const id2 = randomAsHex(32); const accumulated2 = randomAsHex(100); const maxSize = 100000; - await chainModule.addUniversalAccumulator(id2, accumulated2, [did2, 1], maxSize, did2, pair2, 1, { didModule: dock.did }, false); + await chainModule.addUniversalAccumulator( + id2, + accumulated2, + [did2, 1], + maxSize, + did2, + pair2, + { didModule: dock.did }, + false + ); const accum1 = await chainModule.getAccumulator(id1, false); expect(accum1.created > 0).toBe(true); expect(accum1.lastModified > 0).toBe(true); expect(accum1.created).toEqual(accum1.lastModified); - expect(accum1.type).toEqual('positive'); + expect(accum1.type).toEqual("positive"); expect(accum1.accumulated).toEqual(accumulated1); - expect(accum1.keyRef).toEqual([getHexIdentifierFromDID(did1), 1]); + expect(accum1.keyRef).toEqual([typedHexDID(dock.api, did1), 1]); expect(accum1.publicKey).toBeUndefined(); const accum2 = await chainModule.getAccumulator(id2, false); expect(accum2.created > 0).toBe(true); expect(accum2.lastModified > 0).toBe(true); expect(accum2.created).toEqual(accum2.lastModified); - expect(accum2.type).toEqual('universal'); + expect(accum2.type).toEqual("universal"); expect(accum2.accumulated).toEqual(accumulated2); - expect(accum2.keyRef).toEqual([getHexIdentifierFromDID(did2), 1]); + expect(accum2.keyRef).toEqual([typedHexDID(dock.api, did2), 1]); expect(accum2.publicKey).toBeUndefined(); const keyWithParams = await chainModule.getPublicKey(did2, 1, true); @@ -176,37 +251,70 @@ describe('Accumulator Module', () => { expect(accum2WithKeyAndParams.created > 0).toBe(true); expect(accum2WithKeyAndParams.lastModified > 0).toBe(true); expect(accum2WithKeyAndParams.created).toEqual( - accum2WithKeyAndParams.lastModified, + accum2WithKeyAndParams.lastModified ); - expect(accum2WithKeyAndParams.type).toEqual('universal'); + expect(accum2WithKeyAndParams.type).toEqual("universal"); expect(accum2WithKeyAndParams.accumulated).toEqual(accumulated2); - expect(accum2WithKeyAndParams.keyRef).toEqual([getHexIdentifierFromDID(did2), 1]); + expect(accum2WithKeyAndParams.keyRef).toEqual([typedHexDID(dock.api, did2), 1]); expect(accum2WithKeyAndParams.publicKey).toEqual(keyWithParams); - await chainModule.removeAccumulator(id1, did1, pair1, 1, { didModule: dock.did }, false); + await chainModule.removeAccumulator( + id1, + did1, + pair1, + { didModule: dock.did }, + false + ); expect(await chainModule.getAccumulator(id1, false)).toEqual(null); - await chainModule.removeAccumulator(id2, did2, pair2, 1, { didModule: dock.did }, false); + await chainModule.removeAccumulator( + id2, + did2, + pair2, + { didModule: dock.did }, + false + ); expect(await chainModule.getAccumulator(id2, false)).toEqual(null); }, 50000); - test('Update accumulator', async () => { + test("Update accumulator", async () => { const queriedPkWithParams = await chainModule.getPublicKey(did2, 1, true); - const aparams = new AccumulatorParams(hexToU8a(queriedPkWithParams.params.bytes)); + const aparams = new AccumulatorParams( + hexToU8a(queriedPkWithParams.params.bytes) + ); const keypair = Accumulator.generateKeypair(aparams, hexToU8a(seedAccum)); - const accumulator = PositiveAccumulator.initialize(aparams, keypair.secretKey); + const accumulator = PositiveAccumulator.initialize( + aparams, + keypair.secretKey + ); const member1 = Accumulator.encodePositiveNumberAsAccumulatorMember(25); await accumulator.add(member1, keypair.secretKey, accumState); const accumulated1 = u8aToHex(accumulator.accumulated); const id = randomAsHex(32); - await chainModule.addPositiveAccumulator(id, accumulated1, [did2, 1], did2, pair2, 1, { didModule: dock.did }, false); + await chainModule.addPositiveAccumulator( + id, + accumulated1, + [did2, 1], + did2, + pair2, + { didModule: dock.did }, + false + ); const accum1 = await chainModule.getAccumulator(id, false); expect(accum1.accumulated).toEqual(accumulated1); const accumulated2 = u8aToHex(accumulator.accumulated); - await chainModule.updateAccumulator(id, accumulated2, {}, did2, pair2, 1, { didModule: dock.did }, false); + await chainModule.updateAccumulator( + id, + accumulated2, + {}, + did2, + pair2, + { didModule: dock.did }, + false + ); const accum2 = await chainModule.getAccumulator(id, false); expect(accum2.accumulated).toEqual(accumulated2); @@ -221,8 +329,27 @@ describe('Accumulator Module', () => { const accumulated3 = u8aToHex(accumulator.accumulated); const additions1 = [u8aToHex(member2), u8aToHex(member3)]; const removals1 = [u8aToHex(member1)]; - const witUpd1 = u8aToHex(WitnessUpdatePublicInfo.new(hexToU8a(accumulated2), [member2, member3], [member1], keypair.secretKey).value); - await chainModule.updateAccumulator(id, accumulated3, { additions: additions1, removals: removals1, witnessUpdateInfo: witUpd1 }, did2, pair2, 1, { didModule: dock.did }, false); + const witUpd1 = u8aToHex( + WitnessUpdatePublicInfo.new( + hexToU8a(accumulated2), + [member2, member3], + [member1], + keypair.secretKey + ).value + ); + await chainModule.updateAccumulator( + id, + accumulated3, + { + additions: additions1, + removals: removals1, + witnessUpdateInfo: witUpd1, + }, + did2, + pair2, + { didModule: dock.did }, + false + ); const accum3 = await chainModule.getAccumulator(id, false); expect(accum3.accumulated).toEqual(accumulated3); @@ -234,8 +361,23 @@ describe('Accumulator Module', () => { const accumulated4 = u8aToHex(accumulator.accumulated); const additions2 = [u8aToHex(member4), u8aToHex(member5)]; - const witUpd2 = u8aToHex(WitnessUpdatePublicInfo.new(hexToU8a(accumulated3), [member4, member5], [], keypair.secretKey).value); - await chainModule.updateAccumulator(id, accumulated4, { additions: additions2, witnessUpdateInfo: witUpd2 }, did2, pair2, 1, { didModule: dock.did }, false); + const witUpd2 = u8aToHex( + WitnessUpdatePublicInfo.new( + hexToU8a(accumulated3), + [member4, member5], + [], + keypair.secretKey + ).value + ); + await chainModule.updateAccumulator( + id, + accumulated4, + { additions: additions2, witnessUpdateInfo: witUpd2 }, + did2, + pair2, + { didModule: dock.did }, + false + ); const accum4 = await chainModule.getAccumulator(id, false); expect(accum4.accumulated).toEqual(accumulated4); @@ -244,14 +386,29 @@ describe('Accumulator Module', () => { const accumulated5 = u8aToHex(accumulator.accumulated); const removals3 = [u8aToHex(member2), u8aToHex(member4)]; - const witUpd3 = u8aToHex(WitnessUpdatePublicInfo.new(hexToU8a(accumulated4), [], [member2, member4], keypair.secretKey).value); - await chainModule.updateAccumulator(id, accumulated5, { removals: removals3, witnessUpdateInfo: witUpd3 }, did2, pair2, 1, { didModule: dock.did }, false); + const witUpd3 = u8aToHex( + WitnessUpdatePublicInfo.new( + hexToU8a(accumulated4), + [], + [member2, member4], + keypair.secretKey + ).value + ); + await chainModule.updateAccumulator( + id, + accumulated5, + { removals: removals3, witnessUpdateInfo: witUpd3 }, + did2, + pair2, + { didModule: dock.did }, + false + ); const accum5 = await chainModule.getAccumulator(id, false); expect(accum5.accumulated).toEqual(accumulated5); const updates1 = await chainModule.getUpdatesFromBlock( id, - accum2.lastModified, + accum2.lastModified ); expect(updates1[0].newAccumulated).toEqual(accumulated2); expect(updates1[0].additions).toEqual(null); @@ -260,15 +417,15 @@ describe('Accumulator Module', () => { const events1 = ( await getAllEventsFromBlock(chainModule.api, accum2.lastModified, false) - ).filter(({ event }) => event.section === 'accumulator'); + ).filter(({ event }) => event.section === "accumulator"); expect( - chainModuleClass.parseEventAsAccumulatorUpdate(events1[0].event), + chainModuleClass.parseEventAsAccumulatorUpdate(events1[0].event) ).toEqual([id, accumulated2]); const updates2 = await chainModule.getUpdatesFromBlock( id, - accum3.lastModified, + accum3.lastModified ); expect(updates2[0].newAccumulated).toEqual(accumulated3); expect(updates2[0].additions).toEqual(additions1); @@ -277,14 +434,14 @@ describe('Accumulator Module', () => { const events2 = ( await getAllEventsFromBlock(chainModule.api, accum3.lastModified, false) - ).filter(({ event }) => event.section === 'accumulator'); + ).filter(({ event }) => event.section === "accumulator"); expect( - chainModuleClass.parseEventAsAccumulatorUpdate(events2[0].event), + chainModuleClass.parseEventAsAccumulatorUpdate(events2[0].event) ).toEqual([id, accumulated3]); const updates3 = await chainModule.getUpdatesFromBlock( id, - accum4.lastModified, + accum4.lastModified ); expect(updates3[0].newAccumulated).toEqual(accumulated4); expect(updates3[0].additions).toEqual(additions2); @@ -293,7 +450,7 @@ describe('Accumulator Module', () => { const updates4 = await chainModule.getUpdatesFromBlock( id, - accum5.lastModified, + accum5.lastModified ); expect(updates4[0].newAccumulated).toEqual(accumulated5); expect(updates4[0].additions).toEqual(null); @@ -301,21 +458,39 @@ describe('Accumulator Module', () => { expect(updates4[0].witnessUpdateInfo).toEqual(witUpd3); }, 50000); - test('Can remove public keys and params', async () => { - await chainModule.removePublicKey(1, did1, pair1, 1, { didModule: dock.did }, false); + test("Can remove public keys and params", async () => { + await chainModule.removePublicKey( + 1, + did1, + pair1, + { didModule: dock.did }, + false + ); const pk1 = await chainModule.getPublicKey(did1, 1); expect(pk1).toEqual(null); const pksByDid1 = await chainModule.getAllPublicKeysByDid(did1); expect(pksByDid1.length).toEqual(0); - await chainModule.removeParams(1, did1, pair1, 1, { didModule: dock.did }, false); + await chainModule.removeParams( + 1, + did1, + pair1, + { didModule: dock.did }, + false + ); const params1 = await chainModule.getParams(did1, 1); expect(params1).toEqual(null); await expect(chainModule.getPublicKey(did2, 1, true)).rejects.toThrow(); - await chainModule.removePublicKey(1, did2, pair2, 1, { didModule: dock.did }, false); + await chainModule.removePublicKey( + 1, + did2, + pair2, + { didModule: dock.did }, + false + ); const pk2 = await chainModule.getPublicKey(did2, 1); expect(pk2).toEqual(null); @@ -325,15 +500,33 @@ describe('Accumulator Module', () => { const queriedPk2 = await chainModule.getPublicKey(did2, 2); expect(pksByDid2[0]).toEqual(queriedPk2); - await chainModule.removePublicKey(2, did2, pair2, 1, { didModule: dock.did }, false); + await chainModule.removePublicKey( + 2, + did2, + pair2, + { didModule: dock.did }, + false + ); const pk3 = await chainModule.getPublicKey(did2, 2); expect(pk3).toEqual(null); - await chainModule.removeParams(2, did1, pair1, 1, { didModule: dock.did }, false); + await chainModule.removeParams( + 2, + did1, + pair1, + { didModule: dock.did }, + false + ); const params2 = await chainModule.getParams(did1, 2); expect(params2).toEqual(null); - await chainModule.removeParams(1, did2, pair2, 1, { didModule: dock.did }, false); + await chainModule.removeParams( + 1, + did2, + pair2, + { didModule: dock.did }, + false + ); const params3 = await chainModule.getParams(did2, 1); expect(params3).toEqual(null); }, 50000); diff --git a/tests/integration/anoncreds/demo.test.js b/tests/integration/anoncreds/demo.test.js index 811c0120a..f3655a58c 100644 --- a/tests/integration/anoncreds/demo.test.js +++ b/tests/integration/anoncreds/demo.test.js @@ -27,7 +27,7 @@ import { TestKeyringOpts, Schemes, } from '../../test-constants'; -import { createNewDockDID } from '../../../src/utils/did'; +import { createNewDockDID, DidKeypair } from '../../../src/utils/did'; import AccumulatorModule from '../../../src/modules/accumulator'; import { getAllEventsFromBlock } from '../../../src/utils/chain-ops'; import { getRevealedUnrevealed } from './utils'; @@ -165,10 +165,16 @@ for (const { }); account = dock.keyring.addFromUri(TestAccountURI); dock.setAccount(account); - issuerKeypair = dock.keyring.addFromUri(randomAsHex(32)); + issuerKeypair = new DidKeypair( + dock.keyring.addFromUri(randomAsHex(32)), + 1, + ); issuerDid = createNewDockDID(); await registerNewDIDUsingPair(dock, issuerDid, issuerKeypair); - accumulatorManagerKeypair = dock.keyring.addFromUri(randomAsHex(32)); + accumulatorManagerKeypair = new DidKeypair( + dock.keyring.addFromUri(randomAsHex(32)), + 1, + ); accumulatorManagerDid = createNewDockDID(); await registerNewDIDUsingPair( dock, @@ -188,7 +194,6 @@ for (const { params, issuerDid, issuerKeypair, - 1, { didModule: dock.did }, false, ); @@ -210,7 +215,7 @@ for (const { ); issuerBbsPlusKeypair = KeyPair.generate(params); - const pk = Module.prepareAddPublicKey( + const pk = Module.prepareAddPublicKey(dock.api, u8aToHex(issuerBbsPlusKeypair.publicKey.bytes), undefined, [issuerDid, 1], @@ -220,7 +225,6 @@ for (const { issuerDid, issuerDid, issuerKeypair, - 1, { didModule: dock.did }, false, ); @@ -238,7 +242,6 @@ for (const { params, accumulatorManagerDid, accumulatorManagerKeypair, - 1, { didModule: dock.did }, false, ); @@ -259,7 +262,7 @@ for (const { hexToU8a(seedAccum), ); - const pk = AccumulatorModule.prepareAddPublicKey( + const pk = AccumulatorModule.prepareAddPublicKey(dock.api, u8aToHex(accumulatorKeypair.publicKey.bytes), undefined, [accumulatorManagerDid, 1], @@ -268,7 +271,6 @@ for (const { pk, accumulatorManagerDid, accumulatorManagerKeypair, - 1, { didModule: dock.did }, false, ); @@ -292,7 +294,6 @@ for (const { [accumulatorManagerDid, 1], accumulatorManagerDid, accumulatorManagerKeypair, - 1, { didModule: dock.did }, false, ); @@ -349,7 +350,6 @@ for (const { { additions: [u8aToHex(encodedAttrs[attributeCount - 1])] }, accumulatorManagerDid, accumulatorManagerKeypair, - 1, { didModule: dock.did }, false, ); @@ -406,7 +406,6 @@ for (const { }, accumulatorManagerDid, accumulatorManagerKeypair, - 1, { didModule: dock.did }, false, ); @@ -498,7 +497,6 @@ for (const { }, accumulatorManagerDid, accumulatorManagerKeypair, - 1, { didModule: dock.did }, false, ); @@ -531,7 +529,6 @@ for (const { }, accumulatorManagerDid, accumulatorManagerKeypair, - 1, { didModule: dock.did }, false, ); @@ -563,7 +560,6 @@ for (const { }, accumulatorManagerDid, accumulatorManagerKeypair, - 1, { didModule: dock.did }, false, ); @@ -658,7 +654,6 @@ for (const { }, accumulatorManagerDid, accumulatorManagerKeypair, - 1, { didModule: dock.did }, false, ); diff --git a/tests/integration/anoncreds/derived-credentials.test.js b/tests/integration/anoncreds/derived-credentials.test.js index 99a7a1467..e52d44add 100644 --- a/tests/integration/anoncreds/derived-credentials.test.js +++ b/tests/integration/anoncreds/derived-credentials.test.js @@ -8,7 +8,7 @@ import { TestKeyringOpts, Schemes, } from '../../test-constants'; -import { createNewDockDID } from '../../../src/utils/did'; +import { createNewDockDID, DidKeypair } from '../../../src/utils/did'; import { registerNewDIDUsingPair } from '../helpers'; import { getKeyDoc } from '../../../src/utils/vc/helpers'; import { @@ -122,7 +122,7 @@ describe.each(Schemes)('Derived Credentials', ({ account = dock.keyring.addFromUri(TestAccountURI); dock.setAccount(account); - pair1 = dock.keyring.addFromUri(randomAsHex(32)); + pair1 = new DidKeypair(dock.keyring.addFromUri(randomAsHex(32)), 1); did1 = createNewDockDID(); await registerNewDIDUsingPair(dock, did1, pair1); @@ -130,13 +130,12 @@ describe.each(Schemes)('Derived Credentials', ({ controller: did1, msgCount: 100, }); - const pk1 = Module.prepareAddPublicKey(u8aToHex(keypair.publicKeyBuffer)); + const pk1 = Module.prepareAddPublicKey(dock.api, u8aToHex(keypair.publicKeyBuffer)); await chainModule.addPublicKey( pk1, did1, did1, pair1, - 1, { didModule: dock.did }, false, ); @@ -151,14 +150,14 @@ describe.each(Schemes)('Derived Credentials', ({ await registerNewDIDUsingPair( dock, holder3DID, - dock.keyring.addFromUri(holder3KeySeed, null, 'sr25519'), + new DidKeypair(dock.keyring.addFromUri(holder3KeySeed, null, 'sr25519'), 1), ); }, 30000); async function createAndVerifyPresentation(credentials, verifyOptions = {}) { const holderKey = getKeyDoc( holder3DID, - dock.keyring.addFromUri(holder3KeySeed, null, 'sr25519'), + new DidKeypair(dock.keyring.addFromUri(holder3KeySeed, null, 'sr25519'), 1), 'Sr25519VerificationKey2020', ); diff --git a/tests/integration/anoncreds/issuing.test.js b/tests/integration/anoncreds/issuing.test.js index 5650a7d40..ed082363d 100644 --- a/tests/integration/anoncreds/issuing.test.js +++ b/tests/integration/anoncreds/issuing.test.js @@ -2,7 +2,7 @@ import { randomAsHex } from '@polkadot/util-crypto'; import { u8aToHex } from '@polkadot/util'; import { CredentialBuilder, CredentialSchema, initializeWasm } from '@docknetwork/crypto-wasm-ts'; import { DockAPI } from '../../../src'; -import { createNewDockDID } from '../../../src/utils/did'; +import { createNewDockDID, DidKeypair } from '../../../src/utils/did'; import { DockResolver } from '../../../src/resolver'; import { registerNewDIDUsingPair, @@ -11,7 +11,7 @@ import { } from '../helpers'; import { issueCredential, verifyCredential } from '../../../src/utils/vc/index'; import { getKeyDoc } from '../../../src/utils/vc/helpers'; -import { getJsonSchemaFromCredential, } from '../../../src/utils/vc/credentials'; +import { getJsonSchemaFromCredential } from '../../../src/utils/vc/credentials'; import { getResidentCardCredentialAndSchema, setupExternalSchema } from './utils'; import { FullNodeEndpoint, @@ -49,7 +49,7 @@ describe.each(Schemes)('Issuance', ({ chainModule = getModule(dock); account = dock.keyring.addFromUri(TestAccountURI); dock.setAccount(account); - pair1 = dock.keyring.addFromUri(randomAsHex(32)); + pair1 = new DidKeypair(dock.keyring.addFromUri(randomAsHex(32)), 1); did1 = createNewDockDID(); await registerNewDIDUsingPair(dock, did1, pair1); }, 20000); @@ -60,13 +60,12 @@ describe.each(Schemes)('Issuance', ({ msgCount: 100, }); - const pk1 = Module.prepareAddPublicKey(u8aToHex(keypair.publicKeyBuffer)); + const pk1 = Module.prepareAddPublicKey(dock.api, u8aToHex(keypair.publicKeyBuffer)); await chainModule.addPublicKey( pk1, did1, did1, pair1, - 1, { didModule: dock.did }, false, ); @@ -81,7 +80,7 @@ describe.each(Schemes)('Issuance', ({ }, 30000); test(`Can issue+verify a ${Name} credential with external schema reference`, async () => { - const [externalSchemaEncoded, schemaId] = await setupExternalSchema(residentCardSchema, 'Resident Card Example', did1, pair1, 1, dock); + const [externalSchemaEncoded, schemaId] = await setupExternalSchema(residentCardSchema, 'Resident Card Example', did1, pair1, dock); const issuerKey = getKeyDoc(did1, keypair, keypair.type, keypair.id); const unsignedCred = { diff --git a/tests/integration/anoncreds/prefilled-positive-accumulator.test.js b/tests/integration/anoncreds/prefilled-positive-accumulator.test.js index 99d2c4b27..91d3c097f 100644 --- a/tests/integration/anoncreds/prefilled-positive-accumulator.test.js +++ b/tests/integration/anoncreds/prefilled-positive-accumulator.test.js @@ -11,7 +11,7 @@ import { InMemoryState } from '@docknetwork/crypto-wasm-ts/lib/accumulator/in-me import { DockAPI } from '../../../src'; import AccumulatorModule from '../../../src/modules/accumulator'; import { FullNodeEndpoint, TestAccountURI, TestKeyringOpts } from '../../test-constants'; -import { createNewDockDID } from '../../../src/utils/did'; +import { createNewDockDID, DidKeypair } from '../../../src/utils/did'; import { registerNewDIDUsingPair } from '../helpers'; describe('Prefilled positive accumulator', () => { @@ -53,7 +53,7 @@ describe('Prefilled positive accumulator', () => { chainModule = dock.accumulatorModule; account = dock.keyring.addFromUri(TestAccountURI); dock.setAccount(account); - pair = dock.keyring.addFromUri(seed1); + pair = new DidKeypair(dock.keyring.addFromUri(seed1), 1); did = createNewDockDID(); await registerNewDIDUsingPair(dock, did, pair); await initializeWasm(); @@ -64,12 +64,12 @@ describe('Prefilled positive accumulator', () => { const params = Accumulator.generateParams(hexToU8a(label)); const bytes1 = u8aToHex(params.bytes); const params1 = chainModuleClass.prepareAddParameters(bytes1, undefined, label); - await chainModule.addParams(params1, did, pair, 1, { didModule: dock.didModule }, false); + await chainModule.addParams(params1, did, pair, { didModule: dock.didModule }, false); keypair = Accumulator.generateKeypair(params, seedAccum); const bytes2 = u8aToHex(keypair.publicKey.bytes); - const pk1 = chainModuleClass.prepareAddPublicKey(bytes2, undefined, [did, 1]); - await chainModule.addPublicKey(pk1, did, pair, 1, { didModule: dock.didModule }, false); + const pk1 = chainModuleClass.prepareAddPublicKey(dock.api, bytes2, undefined, [did, 1]); + await chainModule.addPublicKey(pk1, did, pair, { didModule: dock.didModule }, false); accumulator = PositiveAccumulator.initialize(params, keypair.secretKey); @@ -81,7 +81,7 @@ describe('Prefilled positive accumulator', () => { accumulatorId = randomAsHex(32); const accumulated = u8aToHex(accumulator.accumulated); - await dock.accumulatorModule.addPositiveAccumulator(accumulatorId, accumulated, [did, 1], did, pair, 1, { didModule: dock.didModule }, false); + await dock.accumulatorModule.addPositiveAccumulator(accumulatorId, accumulated, [did, 1], did, pair, { didModule: dock.didModule }, false); const queriedAccum = await dock.accumulatorModule.getAccumulator(accumulatorId, true); expect(queriedAccum.accumulated).toEqual(u8aToHex(accumulator.accumulated)); }); @@ -118,7 +118,7 @@ describe('Prefilled positive accumulator', () => { let accum = await dock.accumulatorModule.getAccumulator(accumulatorId, false); const accumulated = u8aToHex(accumulator.accumulated); const witUpdBytes = u8aToHex(witnessUpdInfo.value); - await dock.accumulatorModule.updateAccumulator(accumulatorId, accumulated, { removals: [u8aToHex(member2)], witnessUpdateInfo: witUpdBytes }, did, pair, 1, { didModule: dock.didModule }, false); + await dock.accumulatorModule.updateAccumulator(accumulatorId, accumulated, { removals: [u8aToHex(member2)], witnessUpdateInfo: witUpdBytes }, did, pair, { didModule: dock.didModule }, false); queriedAccum = await dock.accumulatorModule.getAccumulator(accumulatorId, true); expect(queriedAccum.accumulated).toEqual(accumulated); diff --git a/tests/integration/anoncreds/presentation.test.js b/tests/integration/anoncreds/presentation.test.js index 4c2c98e94..131be205d 100644 --- a/tests/integration/anoncreds/presentation.test.js +++ b/tests/integration/anoncreds/presentation.test.js @@ -11,7 +11,7 @@ import { TestKeyringOpts, Schemes, } from '../../test-constants'; -import { createNewDockDID } from '../../../src/utils/did'; +import { createNewDockDID, DidKeypair } from '../../../src/utils/did'; import { registerNewDIDUsingPair } from '../helpers'; import { getKeyDoc } from '../../../src/utils/vc/helpers'; import { issueCredential, verifyPresentation } from '../../../src/utils/vc'; @@ -49,7 +49,7 @@ describe.each(Schemes)('Presentation', ({ account = dock.keyring.addFromUri(TestAccountURI); dock.setAccount(account); - pair1 = dock.keyring.addFromUri(randomAsHex(32)); + pair1 = new DidKeypair(dock.keyring.addFromUri(randomAsHex(32)), 1); did1 = createNewDockDID(); await registerNewDIDUsingPair(dock, did1, pair1); @@ -60,13 +60,12 @@ describe.each(Schemes)('Presentation', ({ chainModule = getModule(dock); - const pk1 = Module.prepareAddPublicKey(u8aToHex(keypair.publicKeyBuffer)); + const pk1 = Module.prepareAddPublicKey(dock.api, u8aToHex(keypair.publicKeyBuffer)); await chainModule.addPublicKey( pk1, did1, did1, pair1, - 1, { didModule: dock.did }, false, ); @@ -103,7 +102,7 @@ describe.each(Schemes)('Presentation', ({ } test(`from ${Name} credentials with external schema reference and embedded schema`, async () => { - const [externalSchemaEncoded, schemaId] = await setupExternalSchema(residentCardSchema, 'Resident Card Example', did1, pair1, 1, dock); + const [externalSchemaEncoded, schemaId] = await setupExternalSchema(residentCardSchema, 'Resident Card Example', did1, pair1, dock); const issuerKey = getKeyDoc(did1, keypair, keypair.type, keypair.id); // This credential has external schema diff --git a/tests/integration/anoncreds/r1cs-circom.test.js b/tests/integration/anoncreds/r1cs-circom.test.js index 41b9de14d..eefc9fa4e 100644 --- a/tests/integration/anoncreds/r1cs-circom.test.js +++ b/tests/integration/anoncreds/r1cs-circom.test.js @@ -27,7 +27,7 @@ import { TestKeyringOpts, Schemes, } from '../../test-constants'; -import { createNewDockDID } from '../../../src/utils/did'; +import { createNewDockDID, DidKeypair } from '../../../src/utils/did'; import { getWasmBytes, parseR1CSFile } from './utils'; import { checkMapsEqual, registerNewDIDUsingPair } from '../helpers'; @@ -119,7 +119,7 @@ for (const { account = dock.keyring.addFromUri(TestAccountURI); dock.setAccount(account); - issuerKeypair = dock.keyring.addFromUri(randomAsHex(32)); + issuerKeypair = new DidKeypair(dock.keyring.addFromUri(randomAsHex(32)), 1); issuerDid = createNewDockDID(); await registerNewDIDUsingPair(dock, issuerDid, issuerKeypair); @@ -144,7 +144,7 @@ for (const { // Not writing the params on chain as its assumed that the label is hardcoded in the code as system parameter issuerSchemeKeypair = KeyPair.generate(sigParams); - const pk = Module.prepareAddPublicKey( + const pk = Module.prepareAddPublicKey(dock.api, u8aToHex(issuerSchemeKeypair.publicKey.bytes), ); await getModule(dock).addPublicKey( @@ -152,7 +152,6 @@ for (const { issuerDid, issuerDid, issuerKeypair, - 1, { didModule: dock.didModule }, false, ); diff --git a/tests/integration/anoncreds/saver-and-bound-check.test.js b/tests/integration/anoncreds/saver-and-bound-check.test.js index 9ff37d7d5..ed3a9e419 100644 --- a/tests/integration/anoncreds/saver-and-bound-check.test.js +++ b/tests/integration/anoncreds/saver-and-bound-check.test.js @@ -27,7 +27,7 @@ import { TestKeyringOpts, Schemes, } from '../../test-constants'; -import { createNewDockDID } from '../../../src/utils/did'; +import { createNewDockDID, DidKeypair } from '../../../src/utils/did'; import { getRevealedUnrevealed } from './utils'; import { registerNewDIDUsingPair } from '../helpers'; @@ -93,11 +93,11 @@ for (const { account = dock.keyring.addFromUri(TestAccountURI); dock.setAccount(account); - issuerKeypair = dock.keyring.addFromUri(randomAsHex(32)); + issuerKeypair = new DidKeypair(dock.keyring.addFromUri(randomAsHex(32)), 1); issuerDid = createNewDockDID(); await registerNewDIDUsingPair(dock, issuerDid, issuerKeypair); - decryptorKeypair = dock.keyring.addFromUri(randomAsHex(32)); + decryptorKeypair = new DidKeypair(dock.keyring.addFromUri(randomAsHex(32)), 1); decryptorDid = createNewDockDID(); await registerNewDIDUsingPair(dock, decryptorDid, decryptorKeypair); @@ -116,7 +116,6 @@ for (const { params, issuerDid, issuerKeypair, - 1, { didModule: dock.didModule }, false, ); @@ -127,7 +126,7 @@ for (const { expect(paramsWritten.label).toEqual(params.label); issuerSchemeKeypair = KeyPair.generate(sigParams); - const pk = Module.prepareAddPublicKey( + const pk = Module.prepareAddPublicKey(dock.api, u8aToHex(issuerSchemeKeypair.publicKey.bytes), undefined, [issuerDid, 1], @@ -137,7 +136,6 @@ for (const { issuerDid, issuerDid, issuerKeypair, - 1, { didModule: dock.didModule }, false, ); diff --git a/tests/integration/anoncreds/scheme.test.js b/tests/integration/anoncreds/scheme.test.js index 3e5c4dd32..96af798dd 100644 --- a/tests/integration/anoncreds/scheme.test.js +++ b/tests/integration/anoncreds/scheme.test.js @@ -10,7 +10,8 @@ import { } from '../../test-constants'; import { createNewDockDID, - getHexIdentifierFromDID, + typedHexDID, + DidKeypair, } from '../../../src/utils/did'; import { registerNewDIDUsingPair } from '../helpers'; @@ -54,8 +55,8 @@ for (const { chainModule = getModule(dock); account = dock.keyring.addFromUri(TestAccountURI); dock.setAccount(account); - pair1 = dock.keyring.addFromUri(seed1); - pair2 = dock.keyring.addFromUri(seed2); + pair1 = new DidKeypair(dock.keyring.addFromUri(seed1), 1); + pair2 = new DidKeypair(dock.keyring.addFromUri(seed2), 1); did1 = createNewDockDID(); did2 = createNewDockDID(); await registerNewDIDUsingPair(dock, did1, pair1); @@ -76,7 +77,6 @@ for (const { params1, did1, pair1, - 1, { didModule: dock.did }, false, ); @@ -86,7 +86,7 @@ for (const { expect(paramsWritten1.label).toEqual(params1.label); const allParams = await getParamsByDid( dock.api, - getHexIdentifierFromDID(did1), + typedHexDID(dock.api, did1), ); expect(Object.values(allParams.toJSON())).toEqual([params1]); @@ -100,7 +100,6 @@ for (const { params2, did2, pair2, - 1, { didModule: dock.did }, false, ); @@ -123,7 +122,6 @@ for (const { params3, did1, pair1, - 1, { didModule: dock.did }, false, ); @@ -146,13 +144,12 @@ for (const { const params = SignatureParams.generate(5); let keypair = KeyPair.generate(params); const bytes1 = u8aToHex(keypair.publicKey.bytes); - const pk1 = chainModuleClass.prepareAddPublicKey(bytes1); + const pk1 = chainModuleClass.prepareAddPublicKey(dock.api, bytes1); await chainModule.addPublicKey( pk1, did1, did1, pair1, - 1, { didModule: dock.did }, false, ); @@ -170,7 +167,7 @@ for (const { ); keypair = KeyPair.generate(params1); const bytes2 = u8aToHex(keypair.publicKey.bytes); - const pk2 = chainModuleClass.prepareAddPublicKey(bytes2, undefined, [ + const pk2 = chainModuleClass.prepareAddPublicKey(dock.api, bytes2, undefined, [ did1, 1, ]); @@ -179,15 +176,14 @@ for (const { did2, did2, pair2, - 1, { didModule: dock.did }, false, ); const queriedPk2 = await chainModule.getPublicKey(did2, 2); expect(queriedPk2.bytes).toEqual(pk2.bytes); - expect(queriedPk2.paramsRef).toEqual([getHexIdentifierFromDID(did1), 1]); + expect(queriedPk2.paramsRef).toEqual([typedHexDID(dock.api, did1), 1]); const keyWithParams = await getPublicKeyWithParamsByStorageKey(dock.api, [ - getHexIdentifierFromDID(did2), + typedHexDID(dock.api, did2).asDid, 2, ]); const jsonKeyWithParams = keyWithParams.toJSON(); @@ -211,7 +207,7 @@ for (const { ); keypair = KeyPair.generate(params2); const bytes3 = u8aToHex(keypair.publicKey.bytes); - const pk3 = chainModuleClass.prepareAddPublicKey(bytes3, undefined, [ + const pk3 = chainModuleClass.prepareAddPublicKey(dock.api, bytes3, undefined, [ did1, 2, ]); @@ -220,14 +216,13 @@ for (const { did2, did2, pair2, - 1, { didModule: dock.did }, false, ); const queriedPk3 = await chainModule.getPublicKey(did2, 3); expect(queriedPk3.bytes).toEqual(pk3.bytes); - expect(queriedPk3.paramsRef).toEqual([getHexIdentifierFromDID(did1), 2]); + expect(queriedPk3.paramsRef).toEqual([typedHexDID(dock.api, did1), 2]); const queriedPk3WithParams = await chainModule.getPublicKey( did2, @@ -237,7 +232,7 @@ for (const { expect(queriedPk3WithParams.params).toEqual(queriedParams2); const allPks = await getPublicKeysByDid( dock.api, - getHexIdentifierFromDID(did2), + typedHexDID(dock.api, did2), ); expect( Object.values(allPks.toJSON()).map((keyWithParams) => { @@ -279,7 +274,6 @@ for (const { did1, did1, pair1, - 1, { didModule: dock.did }, false, ); @@ -299,7 +293,6 @@ for (const { 1, did1, pair1, - 1, { didModule: dock.did }, false, ); @@ -313,7 +306,6 @@ for (const { did2, did2, pair2, - 1, { didModule: dock.did }, false, ); @@ -337,7 +329,6 @@ for (const { did2, did2, pair2, - 1, { didModule: dock.did }, false, ); @@ -357,7 +348,6 @@ for (const { 2, did1, pair1, - 1, { didModule: dock.did }, false, ); @@ -368,7 +358,6 @@ for (const { 1, did2, pair2, - 1, { didModule: dock.did }, false, ); diff --git a/tests/integration/anoncreds/utils.js b/tests/integration/anoncreds/utils.js index 35e11d367..11fc893d5 100644 --- a/tests/integration/anoncreds/utils.js +++ b/tests/integration/anoncreds/utils.js @@ -46,11 +46,10 @@ export async function parseR1CSFile(r1csName) { * @param title * @param did * @param pair - * @param keyId * @param dock * @returns {Promise<[{id: string, type: string},{$schema: string, title, type: string, $id: string},string]>} */ -export async function setupExternalSchema(fullSchema, title, did, pair, keyId, dock) { +export async function setupExternalSchema(fullSchema, title, did, pair, dock) { const blobId = randomAsHex(DockBlobIdByteSize); const schemaExternal = { $schema: 'http://json-schema.org/draft-07/schema#', @@ -64,7 +63,7 @@ export async function setupExternalSchema(fullSchema, title, did, pair, keyId, d id: blobId, blob: stringToHex(blobStr), }; - await dock.blob.new(blob, did, pair, keyId, { didModule: dock.didModule }, false); + await dock.blob.new(blob, did, pair, { didModule: dock.didModule }, false); return [{ id: `data:application/json;charset=utf-8,${encodeURIComponent( diff --git a/tests/integration/blob.test.js b/tests/integration/blob.test.js index 4e96e8374..63690f2b2 100644 --- a/tests/integration/blob.test.js +++ b/tests/integration/blob.test.js @@ -3,7 +3,7 @@ import { randomAsHex } from '@polkadot/util-crypto'; import { DockAPI } from '../../src/index'; -import { createNewDockDID, getHexIdentifierFromDID } from '../../src/utils/did'; +import { createNewDockDID, typedHexDID, DidKeypair } from '../../src/utils/did'; import { FullNodeEndpoint, TestKeyringOpts, TestAccountURI } from '../test-constants'; import { DockBlobIdByteSize, BLOB_MAX_BYTE_SIZE } from '../../src/modules/blob'; import { registerNewDIDUsingPair } from './helpers'; @@ -34,9 +34,9 @@ describe('Blob Module', () => { }); account = dock.keyring.addFromUri(TestAccountURI); dock.setAccount(account); - pair = dock.keyring.addFromUri(firstKeySeed); + pair = DidKeypair.fromApi(dock, {seed: firstKeySeed}); dockDID = createNewDockDID(); - await registerNewDIDUsingPair(dock, dockDID, pair); + await registerNewDIDUsingPair(dock, typedHexDID(dock.api, dockDID), pair); }); afterAll(async () => { @@ -55,13 +55,13 @@ describe('Blob Module', () => { id: blobId, blob: blobJSON, }; - const result = await dock.blob.new(blob, dockDID, pair, 1, { didModule: dock.didModule }, false); + const result = await dock.blob.new(blob, dockDID, pair, dock, false); expect(!!result).toBe(true); const chainBlob = await dock.blob.get(blobId); expect(!!chainBlob).toBe(true); - expect(chainBlob[0]).toEqual(getHexIdentifierFromDID(dockDID)); + expect(chainBlob[0]).toEqual(typedHexDID(dock.api, dockDID)); expect(chainBlob[1]).toEqual(blobJSON); }, 30000); @@ -71,13 +71,13 @@ describe('Blob Module', () => { id: blobId, blob: blobHex, }; - const result = await dock.blob.new(blob, dockDID, pair, 1, { didModule: dock.didModule }, false); + const result = await dock.blob.new(blob, dockDID, pair, dock, false); expect(!!result).toBe(true); const chainBlob = await dock.blob.get(blobId); expect(!!chainBlob).toBe(true); - expect(chainBlob[0]).toEqual(getHexIdentifierFromDID(dockDID)); + expect(chainBlob[0]).toEqual(typedHexDID(dock.api, dockDID)); expect(u8aToString(chainBlob[1])).toEqual(blobHex); }, 30000); @@ -88,13 +88,13 @@ describe('Blob Module', () => { blob: blobHex, }; - const result = await dock.blob.new(blob, dockDID, pair, 1, { didModule: dock.didModule }, false); + const result = await dock.blob.new(blob, dockDID, pair, dock, false); expect(!!result).toBe(true); const chainBlob = await dock.blob.get(blobId); expect(!!chainBlob).toBe(true); - expect(chainBlob[0]).toEqual(getHexIdentifierFromDID(dockDID)); + expect(chainBlob[0]).toEqual(typedHexDID(dock.api, dockDID)); expect(u8aToHex(chainBlob[1])).toEqual(blobHex); }, 30000); @@ -105,13 +105,13 @@ describe('Blob Module', () => { blob: blobVect, }; - const result = await dock.blob.new(blob, dockDID, pair, 1, { didModule: dock.didModule }, false); + const result = await dock.blob.new(blob, dockDID, pair, dock, false); expect(!!result).toBe(true); const chainBlob = await dock.blob.get(blobId); expect(!!chainBlob).toBe(true); - expect(chainBlob[0]).toEqual(getHexIdentifierFromDID(dockDID)); + expect(chainBlob[0]).toEqual(typedHexDID(dock.api, dockDID)); expect(chainBlob[1]).toEqual(blobVect); }, 30000); @@ -121,7 +121,7 @@ describe('Blob Module', () => { id: blobId, blob: blobHex, }; - await expect(dock.blob.new(blob, dockDID, pair, 1, { didModule: dock.didModule }, false)).rejects.toThrow(); + await expect(dock.blob.new(blob, dockDID, pair, dock, false)).rejects.toThrow(); await expect( dock.blob.get(blobId), @@ -134,7 +134,7 @@ describe('Blob Module', () => { id: blobId, blob: blobHexFirst, }; - const resultFirst = await dock.blob.new(blob, dockDID, pair, 1, { didModule: dock.didModule }, false); + const resultFirst = await dock.blob.new(blob, dockDID, pair, dock, false); expect(!!resultFirst).toBe(true); expect(errorInResult(resultFirst)).toBe(false); @@ -144,7 +144,7 @@ describe('Blob Module', () => { blob: randomAsHex(123), }; - await expect(dock.blob.new(blob, dockDID, pair, 1, { didModule: dock.didModule }, false)).rejects.toThrow(); + await expect(dock.blob.new(blob, dockDID, pair, dock, false)).rejects.toThrow(); }, 60000); test('Should throw error when cannot read blob with given id from chain.', async () => { diff --git a/tests/integration/credential-revocation.test.js b/tests/integration/credential-revocation.test.js index b784fafb9..50c700e2d 100644 --- a/tests/integration/credential-revocation.test.js +++ b/tests/integration/credential-revocation.test.js @@ -21,7 +21,7 @@ import { registerNewDIDUsingPair, } from './helpers'; import { getKeyDoc } from '../../src/utils/vc/helpers'; -import { createNewDockDID } from '../../src/utils/did'; +import { createNewDockDID, DidKeypair, typedHexDID } from '../../src/utils/did'; import { addRevRegIdToCredential, getPrivateStatus } from '../../src/utils/vc/credentials'; import { getPrivateStatuses } from '../../src/utils/vc/presentations'; @@ -59,16 +59,16 @@ describe('Credential revocation with issuer as the revocation authority', () => dockAPI.setAccount(account); // Register issuer DID - issuerKeyPair = dockAPI.keyring.addFromUri(issuerSeed, null, 'ed25519'); + issuerKeyPair = DidKeypair.fromApi(dockAPI, {seed: issuerSeed}); await registerNewDIDUsingPair(dockAPI, issuerDID, issuerKeyPair); // Register holder DID - const pair1 = dockAPI.keyring.addFromUri(holderSeed, null, 'ed25519'); + const pair1 = DidKeypair.fromApi(dockAPI, {seed: holderSeed}); await registerNewDIDUsingPair(dockAPI, holderDID, pair1); // Create a new policy const policy = new OneOfPolicy(); - policy.addOwner(issuerDID); + policy.addOwner(typedHexDID(dockAPI.api, issuerDID)); // Add a new revocation registry with above policy await dockAPI.revocation.newRegistry(registryId, policy, false, false); @@ -99,7 +99,7 @@ describe('Credential revocation with issuer as the revocation authority', () => expect(getPrivateStatus(credential)).not.toBeDefined(); // Revoke the credential - await dockAPI.revocation.revokeCredentialWithOneOfPolicy(registryId, revId, issuerDID, issuerKeyPair, 1, { didModule: dockAPI.did }, false); + await dockAPI.revocation.revokeCredentialWithOneOfPolicy(registryId, revId, issuerDID, issuerKeyPair, { didModule: dockAPI.did }, false); // The credential verification should fail as the credential has been revoked. const result1 = await verifyCredential(credential, { @@ -114,7 +114,7 @@ describe('Credential revocation with issuer as the revocation authority', () => test('Holder can create a presentation and verifier can verify it successfully when it is not revoked else the verification fails', async () => { // The previous test revokes credential so unrevoke it. Its fine if the previous test is not run as unrevoking does not // throw error if the credential is not revoked. - await dockAPI.revocation.unrevokeCredentialWithOneOfPolicy(registryId, revId, issuerDID, issuerKeyPair, 1, { didModule: dockAPI.did }, false); + await dockAPI.revocation.unrevokeCredentialWithOneOfPolicy(registryId, revId, issuerDID, issuerKeyPair, { didModule: dockAPI.did }, false); const holderKey = getKeyDoc(holderDID, dockAPI.keyring.addFromUri(holderSeed, null, 'ed25519'), 'Ed25519VerificationKey2018'); @@ -145,7 +145,7 @@ describe('Credential revocation with issuer as the revocation authority', () => expect(getPrivateStatuses(signedPres)[0]).not.toBeDefined(); // Revoke credential - await dockAPI.revocation.revokeCredentialWithOneOfPolicy(registryId, revId, issuerDID, issuerKeyPair, 1, { didModule: dockAPI.did }, false); + await dockAPI.revocation.revokeCredentialWithOneOfPolicy(registryId, revId, issuerDID, issuerKeyPair, { didModule: dockAPI.did }, false); // As the credential is revoked, the presentation should verify successfully. const result1 = await verifyPresentation(signedPres, { diff --git a/tests/integration/custom-nonce.test.js b/tests/integration/custom-nonce.test.js index e5193e566..7fd702dc4 100644 --- a/tests/integration/custom-nonce.test.js +++ b/tests/integration/custom-nonce.test.js @@ -1,15 +1,15 @@ import { randomAsHex } from '@polkadot/util-crypto'; import { - hexToU8a, stringToHex, u8aToHex, u8aToString, + hexToU8a, stringToHex, u8aToHex, } from '@polkadot/util'; import { Accumulator, initializeWasm, BBSPlusKeypairG2, BBSPlusSignatureParamsG1, } from '@docknetwork/crypto-wasm-ts'; import { DockAPI, PublicKeySecp256k1 } from '../../src'; import { FullNodeEndpoint, TestAccountURI, TestKeyringOpts } from '../test-constants'; -import { createNewDockDID, getHexIdentifierFromDID, NoDIDError } from '../../src/utils/did'; +import { createNewDockDID, typedHexDID, NoDIDError, DidKeypair } from '../../src/utils/did'; import { registerNewDIDUsingPair } from './helpers'; -import { generateEcdsaSecp256k1Keypair, getPublicKeyFromKeyringPair } from '../../src/utils/misc'; +import { generateEcdsaSecp256k1Keypair } from '../../src/utils/misc'; import { DidKey, VerificationRelationship } from '../../src/public-keys'; import { ServiceEndpointType } from '../../src/modules/did/service-endpoint'; import { DockBlobIdByteSize } from '../../src/modules/blob'; @@ -44,7 +44,7 @@ describe('Custom nonce', () => { }); const account = dock.keyring.addFromUri(TestAccountURI); dock.setAccount(account); - const pair = dock.keyring.addFromUri(seed1); + const pair = new DidKeypair(dock.keyring.addFromUri(seed1), 1); await registerNewDIDUsingPair(dock, did1, pair); await initializeWasm(); }); @@ -54,9 +54,9 @@ describe('Custom nonce', () => { }, 10000); test('Add key, controller, service endpoint, blob, BBS+ params and keys and accumulator in a batch', async () => { - const nonce = await dock.didModule.getNonceForDID(getHexIdentifierFromDID(did1)); + const nonce = await dock.didModule.getNonceForDid(typedHexDID(dock.api, did1)); - const pair = dock.keyring.addFromUri(seed1); + const pair = new DidKeypair(dock.keyring.addFromUri(seed1), 1); const txs = []; // Add key @@ -65,11 +65,11 @@ describe('Custom nonce', () => { const verRels = new VerificationRelationship(); verRels.setAssertion(); const didKey = new DidKey(publicKey, verRels); - const tx1 = await dock.did.createAddKeysTx([didKey], did1, did1, pair, 1, nonce + 1); + const tx1 = await dock.did.createAddKeysTx([didKey], did1, did1, pair, nonce + 1); txs.push(tx1); // Add controller - const tx2 = await dock.did.createAddControllersTx([did2], did1, did1, pair, 1, nonce + 2); + const tx2 = await dock.did.createAddControllersTx([did2], did1, did1, pair, nonce + 2); txs.push(tx2); // Add service endpoint @@ -77,7 +77,7 @@ describe('Custom nonce', () => { spType.setLinkedDomains(); const spId = randomAsHex(10); const origins = [randomAsHex(50), randomAsHex(70)]; - const tx3 = await dock.did.createAddServiceEndpointTx(spId, spType, origins, did1, did1, pair, 1, nonce + 3); + const tx3 = await dock.did.createAddServiceEndpointTx(spId, spType, origins, did1, did1, pair, nonce + 3); txs.push(tx3); // Add a blob @@ -87,42 +87,42 @@ describe('Custom nonce', () => { id: blobId, blob: blobHex, }; - const tx4 = await dock.blob.createNewTx(blob, did1, pair, 1, { nonce: nonce + 4 }); + const tx4 = await dock.blob.createNewTx(blob, did1, pair, { nonce: nonce + 4 }); txs.push(tx4); // Add BBS+ params and keys const label = stringToHex('test-label'); const params = BBSPlusSignatureParamsG1.generate(10, hexToU8a(label)); const addParams = BBSPlusModule.prepareAddParameters(u8aToHex(params.toBytes()), undefined, label); - const tx5 = await dock.bbsPlusModule.createAddParamsTx(addParams, did1, pair, 1, { nonce: nonce + 5 }); + const tx5 = await dock.bbsPlusModule.createAddParamsTx(addParams, did1, pair, { nonce: nonce + 5 }); txs.push(tx5); const keypair = BBSPlusKeypairG2.generate(params); - const pk = BBSPlusModule.prepareAddPublicKey(u8aToHex(keypair.publicKey.bytes), undefined, [did1, 1]); - const tx6 = await dock.bbsPlusModule.createAddPublicKeyTx(pk, did1, did1, pair, 1, { nonce: nonce + 6 }); + const pk = BBSPlusModule.prepareAddPublicKey(dock.api, u8aToHex(keypair.publicKey.bytes), undefined, [did1, 1]); + const tx6 = await dock.bbsPlusModule.createAddPublicKeyTx(pk, did1, did1, pair, { nonce: nonce + 6 }); txs.push(tx6); // Add accumulator params and keys const params1 = Accumulator.generateParams(hexToU8a(label)); const addParams1 = AccumulatorModule.prepareAddParameters(u8aToHex(params1.bytes), undefined, label); - const tx7 = await dock.accumulatorModule.createAddParamsTx(addParams1, did1, pair, 1, { nonce: nonce + 7 }); + const tx7 = await dock.accumulatorModule.createAddParamsTx(addParams1, did1, pair, { nonce: nonce + 7 }); txs.push(tx7); const keypair1 = Accumulator.generateKeypair(params1); - const pk1 = AccumulatorModule.prepareAddPublicKey(u8aToHex(keypair1.publicKey.bytes), undefined, [did1, 1]); - const tx8 = await dock.accumulatorModule.createAddPublicKeyTx(pk1, did1, pair, 1, { nonce: nonce + 8 }); + const pk1 = AccumulatorModule.prepareAddPublicKey(dock.api, u8aToHex(keypair1.publicKey.bytes), undefined, [did1, 1]); + const tx8 = await dock.accumulatorModule.createAddPublicKeyTx(pk1, did1, pair, { nonce: nonce + 8 }); txs.push(tx8); // Add accumulators const id1 = randomAsHex(32); const accumulated1 = randomAsHex(100); - const tx9 = await dock.accumulatorModule.createAddPositiveAccumulatorTx(id1, accumulated1, [did1, 1], did1, pair, 1, { nonce: nonce + 9 }); + const tx9 = await dock.accumulatorModule.createAddPositiveAccumulatorTx(id1, accumulated1, [did1, 1], did1, pair, { nonce: nonce + 9 }); txs.push(tx9); const id2 = randomAsHex(32); const accumulated2 = randomAsHex(100); const maxSize = 100000; - const tx10 = await dock.accumulatorModule.createAddUniversalAccumulatorTx(id2, accumulated2, [did1, 1], maxSize, did1, pair, 1, { nonce: nonce + 10 }); + const tx10 = await dock.accumulatorModule.createAddUniversalAccumulatorTx(id2, accumulated2, [did1, 1], maxSize, did1, pair, { nonce: nonce + 10 }); txs.push(tx10); // Send batch of transactions @@ -148,7 +148,7 @@ describe('Custom nonce', () => { const queriedPk = await dock.bbsPlusModule.getPublicKey(did1, 3); expect(queriedPk.bytes).toEqual(pk.bytes); - expect(queriedPk.paramsRef).toEqual([getHexIdentifierFromDID(did1), 1]); + expect(queriedPk.paramsRef).toEqual([typedHexDID(dock.api, did1), 1]); const queriedParams1 = await dock.accumulatorModule.getParams(did1, 1); expect(queriedParams1.bytes).toEqual(addParams1.bytes); @@ -156,24 +156,24 @@ describe('Custom nonce', () => { const queriedPk1 = await dock.accumulatorModule.getPublicKey(did1, 1); expect(queriedPk1.bytes).toEqual(pk1.bytes); - expect(queriedPk1.paramsRef).toEqual([getHexIdentifierFromDID(did1), 1]); + expect(queriedPk1.paramsRef).toEqual([typedHexDID(dock.api, did1), 1]); const accum1 = await dock.accumulatorModule.getAccumulator(id1, true); expect(accum1.type).toEqual('positive'); expect(accum1.accumulated).toEqual(accumulated1); - expect(accum1.keyRef).toEqual([getHexIdentifierFromDID(did1), 1]); + expect(accum1.keyRef).toEqual([typedHexDID(dock.api, did1), 1]); const accum2 = await dock.accumulatorModule.getAccumulator(id2, true); expect(accum2.type).toEqual('universal'); expect(accum2.accumulated).toEqual(accumulated2); - expect(accum2.keyRef).toEqual([getHexIdentifierFromDID(did1), 1]); + expect(accum2.keyRef).toEqual([typedHexDID(dock.api, did1), 1]); expect(accum1.created).toEqual(accum2.created); expect(accum1.lastModified).toEqual(accum2.lastModified); }, 20000); test('Add 3 registries and submit revocations for all in a batch', async () => { const owners = new Set(); - owners.add(did1); + owners.add(typedHexDID(dock.api, did1)); const [revokeIds1, revokeIds2, revokeIds3] = [1, 2, 3].map((_) => { const r = new Set(); @@ -192,15 +192,15 @@ describe('Custom nonce', () => { await dock.revocation.newRegistry(registryId2, policy, false, false); await dock.revocation.newRegistry(registryId3, policy, false, false); - const pair = dock.keyring.addFromUri(seed1); - let currentNonce = await dock.didModule.getNonceForDID(getHexIdentifierFromDID(did1)); + const pair = new DidKeypair(dock.keyring.addFromUri(seed1), 1); + let currentNonce = await dock.didModule.getNonceForDid(typedHexDID(dock.api, did1)); let txs = []; // Revoke from all 3 registries in the same transaction batch for (const [regId, revs, nonce] of [[registryId1, revokeIds1, currentNonce + 1], [registryId2, revokeIds2, currentNonce + 2], [registryId3, revokeIds3, currentNonce + 3]]) { - const [revoke, sig, computedNonce] = await dock.revocation.createSignedRevoke(regId, revs, did1, pair, 1, { nonce }); + const [revoke, sig, computedNonce] = await dock.revocation.createSignedRevoke(regId, revs, did1, pair, { nonce }); expect(computedNonce).toEqual(nonce); - const tx = await dock.revocation.createRevokeTx(revoke, [{ sig, nonce }]); + const tx = await dock.revocation.createRevokeTx(revoke, [{ nonce, sig }]); txs.push(tx); } @@ -218,12 +218,12 @@ describe('Custom nonce', () => { } // Remove from all 3 registries in the same transaction batch - currentNonce = await dock.didModule.getNonceForDID(getHexIdentifierFromDID(did1)); + currentNonce = await dock.didModule.getNonceForDid(typedHexDID(dock.api, did1)); txs = []; for (const [regId, nonce] of [[registryId1, currentNonce + 1], [registryId2, currentNonce + 2], [registryId3, currentNonce + 3]]) { - const [remove, sig, computedNonce] = await dock.revocation.createSignedRemove(regId, did1, pair, 1, { nonce }); + const [remove, sig, computedNonce] = await dock.revocation.createSignedRemove(regId, did1, pair, { nonce }); expect(computedNonce).toEqual(nonce); - const tx = await dock.revocation.createRemoveRegistryTx(remove, [[sig, nonce]]); + const tx = await dock.revocation.createRemoveRegistryTx(remove, [{ nonce, sig }]); txs.push(tx); } @@ -248,26 +248,26 @@ describe('Custom nonce', () => { let vr = new VerificationRelationship(); vr.setAuthentication(); - const pair3 = dock.keyring.addFromUri(seed3); - const pair4 = dock.keyring.addFromUri(seed4); - const pair5 = dock.keyring.addFromUri(seed5); + const pair3 = new DidKeypair(dock.keyring.addFromUri(seed3), 1); + const pair4 = new DidKeypair(dock.keyring.addFromUri(seed4), 1); + const pair5 = new DidKeypair(dock.keyring.addFromUri(seed5), 1); await registerNewDIDUsingPair(dock, did3, pair3, vr, [did1]); await registerNewDIDUsingPair(dock, did4, pair4, vr, [did1]); await registerNewDIDUsingPair(dock, did5, pair5, vr, [did1]); - const pair = dock.keyring.addFromUri(seed1); + const pair = new DidKeypair(dock.keyring.addFromUri(seed1), 1); - let nonce = await dock.didModule.getNonceForDID(getHexIdentifierFromDID(did1)); + let nonce = await dock.didModule.getNonceForDid(typedHexDID(dock.api, did1)); let txs = []; // Add a key and a service endpoint to each DID vr = new VerificationRelationship(); vr.setAssertion(); - const tx1 = await dock.did.createAddKeysTx([new DidKey(getPublicKeyFromKeyringPair(pair3), vr)], did3, did1, pair, 1, nonce + 1); + const tx1 = await dock.did.createAddKeysTx([new DidKey(pair3.publicKey(), vr)], did3, did1, pair, nonce + 1); txs.push(tx1); - const tx2 = await dock.did.createAddKeysTx([new DidKey(getPublicKeyFromKeyringPair(pair4), vr)], did4, did1, pair, 1, nonce + 2); + const tx2 = await dock.did.createAddKeysTx([new DidKey(pair4.publicKey(), vr)], did4, did1, pair, nonce + 2); txs.push(tx2); - const tx3 = await dock.did.createAddKeysTx([new DidKey(getPublicKeyFromKeyringPair(pair5), vr)], did5, did1, pair, 1, nonce + 3); + const tx3 = await dock.did.createAddKeysTx([new DidKey(pair5.publicKey(), vr)], did5, did1, pair, nonce + 3); txs.push(tx3); const spType = new ServiceEndpointType(); @@ -276,28 +276,28 @@ describe('Custom nonce', () => { const spId3 = randomAsHex(10); const spId4 = randomAsHex(10); const spId5 = randomAsHex(10); - const tx4 = await dock.did.createAddServiceEndpointTx(spId3, spType, origins[0], did3, did1, pair, 1, nonce + 4); + const tx4 = await dock.did.createAddServiceEndpointTx(spId3, spType, origins[0], did3, did1, pair, nonce + 4); txs.push(tx4); - const tx5 = await dock.did.createAddServiceEndpointTx(spId4, spType, origins[1], did4, did1, pair, 1, nonce + 5); + const tx5 = await dock.did.createAddServiceEndpointTx(spId4, spType, origins[1], did4, did1, pair, nonce + 5); txs.push(tx5); - const tx6 = await dock.did.createAddServiceEndpointTx(spId5, spType, origins[2], did5, did1, pair, 1, nonce + 6); + const tx6 = await dock.did.createAddServiceEndpointTx(spId5, spType, origins[2], did5, did1, pair, nonce + 6); txs.push(tx6); // Send batch of transactions await sendBatch(txs); // Check results of all transactions - await expect(dock.did.getDidKey(did3, 2)).resolves.toEqual(new DidKey(getPublicKeyFromKeyringPair(pair3), vr)); - await expect(dock.did.getDidKey(did4, 2)).resolves.toEqual(new DidKey(getPublicKeyFromKeyringPair(pair4), vr)); - await expect(dock.did.getDidKey(did5, 2)).resolves.toEqual(new DidKey(getPublicKeyFromKeyringPair(pair5), vr)); + await expect(dock.did.getDidKey(did3, 2)).resolves.toEqual(new DidKey(pair3.publicKey(), vr)); + await expect(dock.did.getDidKey(did4, 2)).resolves.toEqual(new DidKey(pair4.publicKey(), vr)); + await expect(dock.did.getDidKey(did5, 2)).resolves.toEqual(new DidKey(pair5.publicKey(), vr)); await expect(dock.did.getServiceEndpoint(did3, spId3)).resolves.toEqual({ type: spType, origins: origins[0] }); await expect(dock.did.getServiceEndpoint(did4, spId4)).resolves.toEqual({ type: spType, origins: origins[1] }); await expect(dock.did.getServiceEndpoint(did5, spId5)).resolves.toEqual({ type: spType, origins: origins[2] }); // Each DID adds 2 blobs - const nonce3 = await dock.didModule.getNonceForDID(getHexIdentifierFromDID(did3)); - const nonce4 = await dock.didModule.getNonceForDID(getHexIdentifierFromDID(did4)); - const nonce5 = await dock.didModule.getNonceForDID(getHexIdentifierFromDID(did5)); + const nonce3 = await dock.didModule.getNonceForDid(typedHexDID(dock.api, did3)); + const nonce4 = await dock.didModule.getNonceForDid(typedHexDID(dock.api, did4)); + const nonce5 = await dock.didModule.getNonceForDid(typedHexDID(dock.api, did5)); txs = []; const [[blobId1, blobHex1, blob1], [blobId2, blobHex2, blob2], [blobId3, blobHex3, blob3], [blobId4, blobHex4, blob4], [blobId5, blobHex5, blob5], [blobId6, blobHex6, blob6]] = [1, 2, 3, 4, 5, 6].map((_) => { @@ -309,18 +309,18 @@ describe('Custom nonce', () => { }; return [bi, bh, b]; }); - const tx7 = await dock.blob.createNewTx(blob1, did3, pair3, 1, { nonce: nonce3 + 1 }); - const tx8 = await dock.blob.createNewTx(blob2, did3, pair3, 1, { nonce: nonce3 + 2 }); + const tx7 = await dock.blob.createNewTx(blob1, did3, pair3, { nonce: nonce3 + 1 }); + const tx8 = await dock.blob.createNewTx(blob2, did3, pair3, { nonce: nonce3 + 2 }); txs.push(tx7); txs.push(tx8); - const tx9 = await dock.blob.createNewTx(blob3, did4, pair4, 1, { nonce: nonce4 + 1 }); - const tx10 = await dock.blob.createNewTx(blob4, did4, pair4, 1, { nonce: nonce4 + 2 }); + const tx9 = await dock.blob.createNewTx(blob3, did4, pair4, { nonce: nonce4 + 1 }); + const tx10 = await dock.blob.createNewTx(blob4, did4, pair4, { nonce: nonce4 + 2 }); txs.push(tx9); txs.push(tx10); - const tx11 = await dock.blob.createNewTx(blob5, did5, pair5, 1, { nonce: nonce5 + 1 }); - const tx12 = await dock.blob.createNewTx(blob6, did5, pair5, 1, { nonce: nonce5 + 2 }); + const tx11 = await dock.blob.createNewTx(blob5, did5, pair5, { nonce: nonce5 + 1 }); + const tx12 = await dock.blob.createNewTx(blob6, did5, pair5, { nonce: nonce5 + 2 }); txs.push(tx11); txs.push(tx12); @@ -332,18 +332,18 @@ describe('Custom nonce', () => { const chainBlob = await dock.blob.get(bi); expect(!!chainBlob).toBe(true); expect(u8aToHex(chainBlob[1])).toEqual(bh); - expect(chainBlob[0]).toEqual(getHexIdentifierFromDID(d)); + expect(chainBlob[0]).toEqual(typedHexDID(dock.api, d)); } // Remove all DIDs in a batch - nonce = await dock.didModule.getNonceForDID(getHexIdentifierFromDID(did1)); + nonce = await dock.didModule.getNonceForDid(typedHexDID(dock.api, did1)); txs = []; - const tx13 = await dock.did.createRemoveTx(did3, did1, pair, 1, nonce + 1); + const tx13 = await dock.did.createRemoveTx(did3, did1, pair, nonce + 1); txs.push(tx13); - const tx14 = await dock.did.createRemoveTx(did4, did1, pair, 1, nonce + 2); + const tx14 = await dock.did.createRemoveTx(did4, did1, pair, nonce + 2); txs.push(tx14); - const tx15 = await dock.did.createRemoveTx(did5, did1, pair, 1, nonce + 3); + const tx15 = await dock.did.createRemoveTx(did5, did1, pair, nonce + 3); txs.push(tx15); // Send batch of transactions diff --git a/tests/integration/did/controllers.test.js b/tests/integration/did/controllers.test.js index b20ed26e0..f81544b0c 100644 --- a/tests/integration/did/controllers.test.js +++ b/tests/integration/did/controllers.test.js @@ -1,6 +1,6 @@ import { randomAsHex } from '@polkadot/util-crypto'; import { DockAPI } from '../../../src'; -import { createNewDockDID, getHexIdentifierFromDID, NoDIDError } from '../../../src/utils/did'; +import { createNewDockDID, typedHexDID, NoDIDError, DidKeypair } from '../../../src/utils/did'; import { FullNodeEndpoint, TestAccountURI, TestKeyringOpts } from '../../test-constants'; import { getPublicKeyFromKeyringPair } from '../../../src/utils/misc'; import { DidKey, VerificationRelationship } from '../../../src/public-keys'; @@ -10,15 +10,15 @@ describe('DID controllers', () => { const dock = new DockAPI(); const dockDid1 = createNewDockDID(); - const hexDid1 = getHexIdentifierFromDID(dockDid1); + let hexDid1; // This DID will be controlled by itself and dockDid1 const dockDid2 = createNewDockDID(); - const hexDid2 = getHexIdentifierFromDID(dockDid2); + let hexDid2; // This DID will not control itself but will be controlled by dockDid1 and dockDid2 const dockDid3 = createNewDockDID(); - const hexDid3 = getHexIdentifierFromDID(dockDid3); + let hexDid3; const seed1 = randomAsHex(32); const seed2 = randomAsHex(32); @@ -32,6 +32,10 @@ describe('DID controllers', () => { }); const account = dock.keyring.addFromUri(TestAccountURI); dock.setAccount(account); + + hexDid1 = typedHexDID(dock.api, dockDid1); + hexDid2 = typedHexDID(dock.api, dockDid2); + hexDid3 = typedHexDID(dock.api, dockDid3); }); afterAll(async () => { @@ -51,29 +55,28 @@ describe('DID controllers', () => { const didKey2 = new DidKey(publicKey2, verRels2); await dock.did.new(dockDid2, [didKey2], [dockDid1], false); - const didDetail1 = await dock.did.getOnchainDidDetail(hexDid1); + const didDetail1 = await dock.did.getOnchainDidDetail(hexDid1.asDid); expect(didDetail1.lastKeyId).toBe(1); expect(didDetail1.activeControllerKeys).toBe(1); expect(didDetail1.activeControllers).toBe(1); await expect(dock.did.isController(dockDid1, dockDid1)).resolves.toEqual(true); - const didDetail2 = await dock.did.getOnchainDidDetail(hexDid2); + const didDetail2 = await dock.did.getOnchainDidDetail(hexDid2.asDid); expect(didDetail2.lastKeyId).toBe(1); expect(didDetail2.activeControllerKeys).toBe(1); expect(didDetail2.activeControllers).toBe(2); await expect(dock.did.isController(dockDid2, dockDid2)).resolves.toEqual(true); await expect(dock.did.isController(dockDid2, dockDid1)).resolves.toEqual(true); - for (const [newSeed, signer, pair, keyCount] of [[seed3, hexDid1, pair1, 2], [seed4, hexDid2, pair2, 3]]) { + for (const [newSeed, signer, pair, keyCount] of [[seed3, dockDid1, pair1, 2], [seed4, dockDid2, pair2, 3]]) { const newPair = dock.keyring.addFromUri(newSeed); const publicKey = getPublicKeyFromKeyringPair(newPair); const verRels = new VerificationRelationship(); verRels.setAssertion(); const didKey = new DidKey(publicKey, verRels); - await dock.did.addKeys([didKey], dockDid2, signer, pair, 1); - - const didDetail = await dock.did.getOnchainDidDetail(hexDid2); + await dock.did.addKeys([didKey], dockDid2, signer, new DidKeypair(pair, 1)); + const didDetail = await dock.did.getOnchainDidDetail(hexDid2.asDid); expect(didDetail.lastKeyId).toBe(keyCount); expect(didDetail.activeControllerKeys).toBe(1); expect(didDetail.activeControllers).toBe(2); @@ -113,7 +116,7 @@ describe('DID controllers', () => { test('Create DID controlled by other', async () => { await dock.did.new(dockDid3, [], [dockDid1], false); - const didDetail1 = await dock.did.getOnchainDidDetail(hexDid3); + const didDetail1 = await dock.did.getOnchainDidDetail(hexDid3.asDid); expect(didDetail1.lastKeyId).toBe(0); expect(didDetail1.activeControllerKeys).toBe(0); expect(didDetail1.activeControllers).toBe(1); @@ -131,7 +134,7 @@ describe('DID controllers', () => { }, 10000); test('Add keys and more controllers to a DID by its other controller', async () => { - const pair1 = dock.keyring.addFromUri(seed1); + const pair1 = new DidKeypair(dock.keyring.addFromUri(seed1), 1); // Add key to the DID using its controller const pair3 = dock.keyring.addFromUri(seed3); @@ -140,9 +143,9 @@ describe('DID controllers', () => { verRels1.setAuthentication(); const didKey3 = new DidKey(publicKey1, verRels1); - await dock.did.addKeys([didKey3], dockDid3, dockDid1, pair1, 1); + await dock.did.addKeys([didKey3], dockDid3, dockDid1, pair1); - let didDetail = await dock.did.getOnchainDidDetail(hexDid3); + let didDetail = await dock.did.getOnchainDidDetail(hexDid3.asDid); expect(didDetail.lastKeyId).toBe(1); expect(didDetail.activeControllerKeys).toBe(0); expect(didDetail.activeControllers).toBe(1); @@ -157,9 +160,9 @@ describe('DID controllers', () => { expect(dk1.verRels.isKeyAgreement()).toEqual(false); // Add another controller to the DID using its existing controller - await dock.did.addControllers([dockDid2], dockDid3, dockDid1, pair1, 1); + await dock.did.addControllers([dockDid2], dockDid3, dockDid1, pair1); - didDetail = await dock.did.getOnchainDidDetail(hexDid3); + didDetail = await dock.did.getOnchainDidDetail(hexDid3.asDid); expect(didDetail.lastKeyId).toBe(1); expect(didDetail.activeControllerKeys).toBe(0); expect(didDetail.activeControllers).toBe(2); @@ -180,10 +183,10 @@ describe('DID controllers', () => { }, 10000); test('Remove existing controllers from a DID by its controller', async () => { - const pair2 = dock.keyring.addFromUri(seed2); - await dock.did.removeControllers([dockDid1], dockDid3, dockDid2, pair2, 1); + const pair2 = new DidKeypair(dock.keyring.addFromUri(seed2), 1); + await dock.did.removeControllers([dockDid1], dockDid3, dockDid2, pair2); - const didDetail = await dock.did.getOnchainDidDetail(hexDid3); + const didDetail = await dock.did.getOnchainDidDetail(hexDid3.asDid); expect(didDetail.lastKeyId).toBe(1); expect(didDetail.activeControllerKeys).toBe(0); expect(didDetail.activeControllers).toBe(1); @@ -193,31 +196,31 @@ describe('DID controllers', () => { }); test('Remove DID using its controller', async () => { - const pair2 = dock.keyring.addFromUri(seed2); - await dock.did.remove(dockDid3, dockDid2, pair2, 1); + const pair2 = new DidKeypair(dock.keyring.addFromUri(seed2), 1); + await dock.did.remove(dockDid3, dockDid2, pair2); await expect(dock.did.getDocument(dockDid3)).rejects.toThrow(NoDIDError); - await expect(dock.did.getOnchainDidDetail(hexDid3)).rejects.toThrow(NoDIDError); + await expect(dock.did.getOnchainDidDetail(hexDid3.asDid)).rejects.toThrow(NoDIDError); await expect(dock.did.getDidKey(dockDid3, 1)).rejects.toThrow(); await expect(dock.did.isController(dockDid3, dockDid2)).resolves.toEqual(false); }); test('Add and remove multiple controllers', async () => { - const pair1 = dock.keyring.addFromUri(seed1); - const pair2 = dock.keyring.addFromUri(seed2); + const pair1 = new DidKeypair(dock.keyring.addFromUri(seed1), 1); + const pair2 = new DidKeypair(dock.keyring.addFromUri(seed2), 1); const dockDid4 = createNewDockDID(); - await dock.did.addControllers([dockDid3, dockDid4], dockDid2, dockDid1, pair1, 1); + await dock.did.addControllers([dockDid3, dockDid4], dockDid2, dockDid1, pair1); - let didDetail = await dock.did.getOnchainDidDetail(hexDid2); + let didDetail = await dock.did.getOnchainDidDetail(hexDid2.asDid); expect(didDetail.activeControllers).toBe(4); await expect(dock.did.isController(dockDid2, dockDid1)).resolves.toEqual(true); await expect(dock.did.isController(dockDid2, dockDid2)).resolves.toEqual(true); await expect(dock.did.isController(dockDid2, dockDid3)).resolves.toEqual(true); await expect(dock.did.isController(dockDid2, dockDid4)).resolves.toEqual(true); - await dock.did.removeControllers([dockDid1, dockDid3, dockDid4], dockDid2, dockDid2, pair2, 1); - didDetail = await dock.did.getOnchainDidDetail(hexDid2); + await dock.did.removeControllers([dockDid1, dockDid3, dockDid4], dockDid2, dockDid2, pair2); + didDetail = await dock.did.getOnchainDidDetail(hexDid2.asDid); expect(didDetail.activeControllers).toBe(1); await expect(dock.did.isController(dockDid2, dockDid1)).resolves.toEqual(false); await expect(dock.did.isController(dockDid2, dockDid2)).resolves.toEqual(true); diff --git a/tests/integration/did/did-basic.test.js b/tests/integration/did/did-basic.test.js index 927d13048..e1d643d43 100644 --- a/tests/integration/did/did-basic.test.js +++ b/tests/integration/did/did-basic.test.js @@ -5,12 +5,12 @@ import { ATTESTS_IRI } from '../../../src/modules/did'; import { createNewDockDID, - getHexIdentifierFromDID, + typedHexDID, NoDIDError, NoOffchainDIDError, + DidKeypair, } from '../../../src/utils/did'; import { FullNodeEndpoint, TestKeyringOpts, TestAccountURI } from '../../test-constants'; -import { getPublicKeyFromKeyringPair } from '../../../src/utils/misc'; import { VerificationRelationship, DidKey, } from '../../../src/public-keys'; @@ -21,7 +21,8 @@ describe('Basic DID tests', () => { // Generate a random DID const dockDid = createNewDockDID(); - const hexDid = getHexIdentifierFromDID(dockDid); + let typedDid; + let hexDid; // Generate first key with this seed. The key type is Sr25519 const seed = randomAsHex(32); @@ -31,6 +32,9 @@ describe('Basic DID tests', () => { keyring: TestKeyringOpts, address: FullNodeEndpoint, }); + + typedDid = typedHexDID(dock.api, dockDid); + hexDid = typedDid.asDid; }); afterAll(async () => { @@ -48,8 +52,8 @@ describe('Basic DID tests', () => { // DID does not exist already await expect(dock.did.getOnchainDidDetail(hexDid)).rejects.toThrow(NoDIDError); - const pair = dock.keyring.addFromUri(seed); - const publicKey = getPublicKeyFromKeyringPair(pair); + const pair = new DidKeypair(dock.keyring.addFromUri(seed)); + const publicKey = pair.publicKey(); const verRels = new VerificationRelationship(); const didKey = new DidKey(publicKey, verRels); @@ -67,8 +71,8 @@ describe('Basic DID tests', () => { test('Get key for DID', async () => { const dk = await dock.did.getDidKey(dockDid, 1); - const pair = dock.keyring.addFromUri(seed); - expect(dk.publicKey).toEqual(getPublicKeyFromKeyringPair(pair)); + const pair = new DidKeypair(dock.keyring.addFromUri(seed)); + expect(dk.publicKey).toEqual(pair.publicKey()); expect(dk.verRels.isAuthentication()).toEqual(true); expect(dk.verRels.isAssertion()).toEqual(true); expect(dk.verRels.isCapabilityInvocation()).toEqual(true); @@ -102,11 +106,11 @@ describe('Basic DID tests', () => { test('Can attest with a DID', async () => { const priority = 1; const iri = 'my iri'; - const pair = dock.keyring.addFromUri(seed); + const pair = new DidKeypair(dock.keyring.addFromUri(seed), 1); - await dock.did.setClaim(priority, iri, dockDid, pair, 1, undefined, false); + await dock.did.setClaim(priority, iri, dockDid, pair, undefined, false); - const att = await dock.did.getAttests(hexDid); + const att = await dock.did.getAttests(typedDid); expect(att).toEqual(iri); // Get document to verify the claim is there @@ -117,12 +121,12 @@ describe('Basic DID tests', () => { }, 30000); test('Can remove DID', async () => { - const pair = dock.keyring.addFromUri(seed); - await dock.did.remove(dockDid, dockDid, pair, 1, undefined, false); + const pair = new DidKeypair(dock.keyring.addFromUri(seed), 1); + await dock.did.remove(dockDid, dockDid, pair, undefined, false); // DID removed await expect(dock.did.getDocument(dockDid)).rejects.toThrow(NoDIDError); await expect(dock.did.getOnchainDidDetail(hexDid)).rejects.toThrow(NoDIDError); await expect(dock.did.getDidKey(dockDid, 1)).rejects.toThrow(); - await expect(dock.did.isController(hexDid, hexDid)).resolves.toEqual(false); + await expect(dock.did.isController(dockDid, dockDid)).resolves.toEqual(false); }); }); diff --git a/tests/integration/did/keys.test.js b/tests/integration/did/keys.test.js index 8d8ff2777..4e76db195 100644 --- a/tests/integration/did/keys.test.js +++ b/tests/integration/did/keys.test.js @@ -1,6 +1,6 @@ import { randomAsHex } from '@polkadot/util-crypto'; import { DockAPI, PublicKeySecp256k1 } from '../../../src'; -import { createNewDockDID, getHexIdentifierFromDID } from '../../../src/utils/did'; +import { createNewDockDID, typedHexDID, DidKeypair } from '../../../src/utils/did'; import { FullNodeEndpoint, TestAccountURI, TestKeyringOpts } from '../../test-constants'; import { generateEcdsaSecp256k1Keypair, getPublicKeyFromKeyringPair } from '../../../src/utils/misc'; import { DidKey, VerificationRelationship } from '../../../src/public-keys'; @@ -12,7 +12,7 @@ describe('Key support for DIDs', () => { // Generate a random DID const dockDid = createNewDockDID(); - const hexDid = getHexIdentifierFromDID(dockDid); + let hexDid; const seed1 = randomAsHex(32); const seed2 = randomAsHex(32); @@ -26,6 +26,8 @@ describe('Key support for DIDs', () => { }); const account = dock.keyring.addFromUri(TestAccountURI); dock.setAccount(account); + + hexDid = typedHexDID(dock.api, dockDid); }); afterAll(async () => { @@ -51,7 +53,7 @@ describe('Key support for DIDs', () => { await dock.did.new(dockDid, [didKey1, didKey2, didKey3], [], false); - const didDetail = await dock.did.getOnchainDidDetail(hexDid); + const didDetail = await dock.did.getOnchainDidDetail(hexDid.asDid); expect(didDetail.lastKeyId).toBe(3); expect(didDetail.activeControllerKeys).toBe(2); expect(didDetail.activeControllers).toBe(1); @@ -112,10 +114,10 @@ describe('Key support for DIDs', () => { verRels1.setAssertion(); const didKey1 = new DidKey(publicKey1, verRels1); - const pair = dock.keyring.addFromUri(seed2, null, 'ed25519'); - await dock.did.addKeys([didKey1], dockDid, dockDid, pair, 2); + const pair = new DidKeypair(dock.keyring.addFromUri(seed2, null, 'ed25519'), 2); + await dock.did.addKeys([didKey1], dockDid, dockDid, pair); - const didDetail = await dock.did.getOnchainDidDetail(hexDid); + const didDetail = await dock.did.getOnchainDidDetail(hexDid.asDid); expect(didDetail.lastKeyId).toBe(4); expect(didDetail.activeControllerKeys).toBe(3); expect(didDetail.activeControllers).toBe(1); @@ -165,10 +167,10 @@ describe('Key support for DIDs', () => { }); test('Remove keys from DID', async () => { - const pair = generateEcdsaSecp256k1Keypair(seed4); - await dock.did.removeKeys([1, 3], dockDid, dockDid, pair, 4); + const pair = new DidKeypair(generateEcdsaSecp256k1Keypair(seed4), 4); + await dock.did.removeKeys([1, 3], dockDid, dockDid, pair); - const didDetail = await dock.did.getOnchainDidDetail(hexDid); + const didDetail = await dock.did.getOnchainDidDetail(hexDid.asDid); expect(didDetail.lastKeyId).toBe(4); expect(didDetail.activeControllerKeys).toBe(2); expect(didDetail.activeControllers).toBe(1); @@ -220,9 +222,9 @@ describe('Key support for DIDs', () => { const publicKey = new PublicKeyX25519(randomAsHex(32)); const didKey = new DidKey(publicKey, verRels); - const pair = dock.keyring.addFromUri(seed2, null, 'ed25519'); - await dock.did.addKeys([didKey], dockDid, dockDid, pair, 2); - const didDetail = await dock.did.getOnchainDidDetail(hexDid); + const pair = new DidKeypair(dock.keyring.addFromUri(seed2, null, 'ed25519'), 2); + await dock.did.addKeys([didKey], dockDid, dockDid, pair); + const didDetail = await dock.did.getOnchainDidDetail(hexDid.asDid); expect(didDetail.lastKeyId).toBe(5); const dk = await dock.did.getDidKey(dockDid, 5); expect(dk.publicKey).toEqual(publicKey); diff --git a/tests/integration/did/offchain-did.test.js b/tests/integration/did/offchain-did.test.js index c5bcd7f17..1de835b99 100644 --- a/tests/integration/did/offchain-did.test.js +++ b/tests/integration/did/offchain-did.test.js @@ -3,7 +3,7 @@ import { randomAsHex } from '@polkadot/util-crypto'; import { u8aToHex } from '@polkadot/util'; import { DockAPI } from '../../../src'; import { - createNewDockDID, getHexIdentifierFromDID, NoDIDError, NoOnchainDIDError, + createNewDockDID, typedHexDID, NoDIDError, NoOnchainDIDError, } from '../../../src/utils/did'; import { FullNodeEndpoint, TestAccountURI, TestKeyringOpts } from '../../test-constants'; import { OffChainDidDocRef } from '../../../src/modules/did'; @@ -13,7 +13,7 @@ describe('Off-chain DIDs', () => { // Generate a random DID const dockDID = createNewDockDID(); - const hexDID = getHexIdentifierFromDID(dockDID); + let hexDID; const firstDocRef = randomAsHex(100); const secondDocRef = randomAsHex(110); @@ -26,6 +26,8 @@ describe('Off-chain DIDs', () => { }); const account = dock.keyring.addFromUri(TestAccountURI); dock.setAccount(account); + + hexDID = typedHexDID(dock.api, dockDID); }); afterAll(async () => { @@ -34,22 +36,22 @@ describe('Off-chain DIDs', () => { test('Can create an off-chain DID', async () => { // DID does not exist already - await expect(dock.did.getOffchainDidDetail(hexDID)).rejects.toThrow(NoDIDError); + await expect(dock.did.getOffchainDidDetail(hexDID.asDid)).rejects.toThrow(NoDIDError); const docRef = OffChainDidDocRef.cid(firstDocRef); await dock.did.newOffchain(dockDID, docRef, false); - const didDetail = await dock.did.getOffchainDidDetail(hexDID); + const didDetail = await dock.did.getOffchainDidDetail(hexDID.asDid); expect(didDetail.docRef).toEqual(docRef); expect(didDetail.accountId).toEqual(u8aToHex(dock.account.addressRaw)); // DID cannot be fetched as on-chain DID - await expect(dock.did.getOnchainDidDetail(hexDID)).rejects.toThrow(NoOnchainDIDError); + await expect(dock.did.getOnchainDidDetail(hexDID.asDid)).rejects.toThrow(NoOnchainDIDError); }); test('Can update DIDDoc reference for the DID to URL', async () => { const docRef = OffChainDidDocRef.url(secondDocRef); await dock.did.setOffchainDidRef(dockDID, docRef, false); - const didDetail = await dock.did.getOffchainDidDetail(hexDID); + const didDetail = await dock.did.getOffchainDidDetail(hexDID.asDid); expect(didDetail.docRef).toEqual(docRef); expect(didDetail.accountId).toEqual(u8aToHex(dock.account.addressRaw)); }); @@ -57,13 +59,13 @@ describe('Off-chain DIDs', () => { test('Can update DIDDoc reference for the DID to Custom', async () => { const docRef = OffChainDidDocRef.custom(thirdDocRef); await dock.did.setOffchainDidRef(dockDID, docRef, false); - const didDetail = await dock.did.getOffchainDidDetail(hexDID); + const didDetail = await dock.did.getOffchainDidDetail(hexDID.asDid); expect(didDetail.docRef).toEqual(docRef); expect(didDetail.accountId).toEqual(u8aToHex(dock.account.addressRaw)); }); test('Can remove the DID', async () => { await dock.did.removeOffchainDid(dockDID, false); - await expect(dock.did.getOffchainDidDetail(hexDID)).rejects.toThrow(NoDIDError); + await expect(dock.did.getOffchainDidDetail(hexDID.asDid)).rejects.toThrow(NoDIDError); }); }); diff --git a/tests/integration/did/service-endpoint.test.js b/tests/integration/did/service-endpoint.test.js index 31ce0415e..ab0dca4e2 100644 --- a/tests/integration/did/service-endpoint.test.js +++ b/tests/integration/did/service-endpoint.test.js @@ -1,9 +1,8 @@ import { randomAsHex } from '@polkadot/util-crypto'; import { u8aToHex } from '@polkadot/util'; import { DockAPI } from '../../../src'; -import { createNewDockDID, getHexIdentifierFromDID, NoDIDError } from '../../../src/utils/did'; +import { createNewDockDID, typedHexDID, NoDIDError, DidKeypair } from '../../../src/utils/did'; import { FullNodeEndpoint, TestAccountURI, TestKeyringOpts } from '../../test-constants'; -import { getPublicKeyFromKeyringPair } from '../../../src/utils/misc'; import { DidKey, VerificationRelationship } from '../../../src/public-keys'; import { ServiceEndpointType } from '../../../src/modules/did/service-endpoint'; @@ -13,11 +12,11 @@ describe('DID service endpoints', () => { const dock = new DockAPI(); const dockDid1 = createNewDockDID(); - const hexDid1 = getHexIdentifierFromDID(dockDid1); + let hexDid1; // This DID will not be controlled by itself const dockDid2 = createNewDockDID(); - const hexDid2 = getHexIdentifierFromDID(dockDid2); + let hexDid2; const seed1 = randomAsHex(32); const seed2 = randomAsHex(32); @@ -40,6 +39,9 @@ describe('DID service endpoints', () => { }); const account = dock.keyring.addFromUri(TestAccountURI); dock.setAccount(account); + + hexDid1 = typedHexDID(dock.api, dockDid1); + hexDid2 = typedHexDID(dock.api, dockDid2); }); afterAll(async () => { @@ -47,8 +49,8 @@ describe('DID service endpoints', () => { }, 10000); test('Create DIDs and add service endpoint', async () => { - const pair1 = dock.keyring.addFromUri(seed1); - const publicKey1 = getPublicKeyFromKeyringPair(pair1); + const pair1 = new DidKeypair(dock.keyring.addFromUri(seed1), 1); + const publicKey1 = pair1.publicKey(); const didKey1 = new DidKey(publicKey1, new VerificationRelationship()); await dock.did.new(dockDid1, [didKey1], [], false); @@ -58,14 +60,14 @@ describe('DID service endpoints', () => { // `dockDid1` adds service endpoint for itself const origins1 = origins1Text.map((u) => u8aToHex(encoder.encode(u))); - await dock.did.addServiceEndpoint(spId1, spType, origins1, hexDid1, hexDid1, pair1, 1, undefined, false); + await dock.did.addServiceEndpoint(spId1, spType, origins1, hexDid1, hexDid1, pair1, undefined, false); const sp = await dock.did.getServiceEndpoint(dockDid1, spId1); expect(sp.type).toEqual(spType); expect(sp.origins).toEqual(origins1); - const pair2 = dock.keyring.addFromUri(seed2); - const publicKey2 = getPublicKeyFromKeyringPair(pair2); + const pair2 = new DidKeypair(dock.keyring.addFromUri(seed2), 1); + const publicKey2 = pair2.publicKey(); const vr = new VerificationRelationship(); vr.setAssertion(); const didKey2 = new DidKey(publicKey2, vr); @@ -74,7 +76,7 @@ describe('DID service endpoints', () => { // `dockDid1` adds service endpoint to `dockDid2` const origins2 = origins2Text.map((u) => u8aToHex(encoder.encode(u))); - await dock.did.addServiceEndpoint(spId2, spType, origins2, hexDid2, hexDid1, pair1, 1, undefined, false); + await dock.did.addServiceEndpoint(spId2, spType, origins2, hexDid2, hexDid1, pair1, undefined, false); const sp1 = await dock.did.getServiceEndpoint(dockDid2, spId2); expect(sp1.type).toEqual(spType); @@ -96,11 +98,11 @@ describe('DID service endpoints', () => { }, 10000); test('Add another service endpoint', async () => { - const pair1 = dock.keyring.addFromUri(seed1); + const pair1 = new DidKeypair(dock.keyring.addFromUri(seed1), 1); const spType = new ServiceEndpointType(); spType.setLinkedDomains(); const origins = origins3Text.map((u) => u8aToHex(encoder.encode(u))); - await dock.did.addServiceEndpoint(spId3, spType, origins, hexDid2, hexDid1, pair1, 1, undefined, false); + await dock.did.addServiceEndpoint(spId3, spType, origins, hexDid2, hexDid1, pair1, undefined, false); const sp = await dock.did.getServiceEndpoint(dockDid2, spId3); expect(sp.type).toEqual(spType); expect(sp.origins).toEqual(origins); @@ -123,18 +125,18 @@ describe('DID service endpoints', () => { }); test('Remove service endpoint', async () => { - const pair1 = dock.keyring.addFromUri(seed1); + const pair1 = new DidKeypair(dock.keyring.addFromUri(seed1), 1); // `dockDid1` removes service endpoint of `dockDid2` - await dock.did.removeServiceEndpoint(spId2, hexDid2, hexDid1, pair1, 1, undefined, false); + await dock.did.removeServiceEndpoint(spId2, hexDid2, hexDid1, pair1, undefined, false); await expect(dock.did.getServiceEndpoint(dockDid2, spId2)).rejects.toThrow(); }); test('Removing DID removes service endpoint as well', async () => { - const pair1 = dock.keyring.addFromUri(seed1); + const pair1 = new DidKeypair(dock.keyring.addFromUri(seed1), 1); - await dock.did.remove(dockDid1, dockDid1, pair1, 1); + await dock.did.remove(dockDid1, dockDid1, pair1); - await expect(dock.did.getOnchainDidDetail(hexDid1)).rejects.toThrow(NoDIDError); + await expect(dock.did.getOnchainDidDetail(hexDid1.asDid)).rejects.toThrow(NoDIDError); await expect(dock.did.getServiceEndpoint(dockDid1, spId1)).rejects.toThrow(); }); }); diff --git a/tests/integration/fees.test.js b/tests/integration/fees.test.js index 030a85045..d1852b8fb 100644 --- a/tests/integration/fees.test.js +++ b/tests/integration/fees.test.js @@ -13,7 +13,7 @@ import { } from '@polkadot/util'; import { randomAsHex } from '@polkadot/util-crypto'; import { DockAPI } from '../../src/index'; -import { createNewDockDID } from '../../src/utils/did'; +import { createNewDockDID, typedHexDID } from '../../src/utils/did'; import { createDidPair, getBalance } from './helpers'; import { createRandomRegistryId, @@ -114,32 +114,32 @@ describe.skip('Fees', () => { // Add DID key with all verification relationships const [, , dk1] = createDidPair(dock); - await withPaidFeeMatchingSnapshot(() => dock.did.addKeys([dk1], did, did, pair, 1, undefined, false)); + await withPaidFeeMatchingSnapshot(() => dock.did.addKeys([dk1], did, did, pair, undefined, false)); // Add DID key with only 1 verification relationship const [, , dk2] = createDidPair(dock); dk2.verRels.setAuthentication(); - await withPaidFeeMatchingSnapshot(() => dock.did.addKeys([dk2], did, did, pair, 1, undefined, false)); + await withPaidFeeMatchingSnapshot(() => dock.did.addKeys([dk2], did, did, pair, undefined, false)); // Add DID key with only 2 verification relationships const [, , dk3] = createDidPair(dock); dk3.verRels.setAuthentication(); dk3.verRels.setAssertion(); - await withPaidFeeMatchingSnapshot(() => dock.did.addKeys([dk3], did, did, pair, 1, undefined, false)); + await withPaidFeeMatchingSnapshot(() => dock.did.addKeys([dk3], did, did, pair, undefined, false)); // Add DID key with 3 verification relationships const [, , dk4] = createDidPair(dock); dk4.verRels.setAuthentication(); dk4.verRels.setAssertion(); dk4.verRels.setCapabilityInvocation(); - await withPaidFeeMatchingSnapshot(() => dock.did.addKeys([dk4], did, did, pair, 1, undefined, false)); + await withPaidFeeMatchingSnapshot(() => dock.did.addKeys([dk4], did, did, pair, undefined, false)); // Add 2 DID keys with only 1 verification relationship const [, , dk5] = createDidPair(dock); const [, , dk6] = createDidPair(dock); dk5.verRels.setAuthentication(); dk6.verRels.setCapabilityInvocation(); - await withPaidFeeMatchingSnapshot(() => dock.did.addKeys([dk5, dk6], did, did, pair, 1, undefined, false)); + await withPaidFeeMatchingSnapshot(() => dock.did.addKeys([dk5, dk6], did, did, pair, undefined, false)); // Add 3 DID keys with only 1 verification relationship const [, , dk7] = createDidPair(dock); @@ -231,13 +231,13 @@ describe.skip('Fees', () => { // Add DID key with all verification relationships to a DID that doesn't control itself const [, , dk__] = createDidPair(dock); - await withPaidFeeMatchingSnapshot(() => dock.did.addKeys([dk__], did1, did, pair, 1, undefined, false)); + await withPaidFeeMatchingSnapshot(() => dock.did.addKeys([dk__], did1, did, pair, undefined, false)); // Removing 1 key - await withPaidFeeMatchingSnapshot(() => dock.did.removeKeys([2], did, did, pair, 1, undefined, false)); + await withPaidFeeMatchingSnapshot(() => dock.did.removeKeys([2], did, did, pair, undefined, false)); // Removing 2 keys - await withPaidFeeMatchingSnapshot(() => dock.did.removeKeys([3, 4], did, did, pair, 1, undefined, false)); + await withPaidFeeMatchingSnapshot(() => dock.did.removeKeys([3, 4], did, did, pair, undefined, false)); // Removing 1 controller await withPaidFeeMatchingSnapshot(() => dock.did.removeControllers( @@ -273,7 +273,7 @@ describe.skip('Fees', () => { )); // Remove DID - await withPaidFeeMatchingSnapshot(() => dock.did.remove(did, did, pair, 1, undefined, false)); + await withPaidFeeMatchingSnapshot(() => dock.did.remove(did, did, pair, undefined, false)); }, 40000); test('revocation', async () => { @@ -283,7 +283,7 @@ describe.skip('Fees', () => { const registryId = createRandomRegistryId(); // Create owners const owners = new Set(); - owners.add(did); + owners.add(typedHexDID(dock.api, did)); const policy = new OneOfPolicy(owners); await withPaidFeeMatchingSnapshot(() => dock.revocation.newRegistry(registryId, policy, false, false)); @@ -303,7 +303,7 @@ describe.skip('Fees', () => { 1, { didModule: dock.did }, ); - const revTx = dock.revocation.createRevokeTx(update, [[sig, nonce]]); + const revTx = dock.revocation.createRevokeTx(update, [{ nonce, sig }]); await withPaidFeeMatchingSnapshot(async () => { await dock.signAndSend(revTx, false); @@ -318,7 +318,7 @@ describe.skip('Fees', () => { { didModule: dock.did }, ); const revTx = dock.revocation.createRemoveRegistryTx(update, [ - [sig, nonce], + { nonce, sig }, ]); await withPaidFeeMatchingSnapshot(() => dock.signAndSend(revTx, false)); @@ -338,7 +338,7 @@ describe.skip('Fees', () => { id: blobId, blob: randomAsHex(BLOB_MAX_BYTE_SIZE), }; - await withPaidFeeMatchingSnapshot(() => dock.blob.new(blob, did, pair, 1, { didModule: dock.did }, false)); + await withPaidFeeMatchingSnapshot(() => dock.blob.new(blob, did, pair, { didModule: dock.did }, false)); }, 30000); test('bbsPlus', async () => { @@ -373,7 +373,7 @@ describe.skip('Fees', () => { const kp = BBSPlusKeypairG2.generate( BBSPlusSignatureParamsG1.generate(10, hexToU8a(label)), ); - const pk = BBSPlusModule.prepareAddPublicKey( + const pk = BBSPlusModule.prepareAddPublicKey(dock.api, u8aToHex(kp.publicKey.bytes), undefined, [did, 1], @@ -434,7 +434,7 @@ describe.skip('Fees', () => { new AccumulatorParams(hexToU8a(params.bytes)), ); - const pk = AccumulatorModule.prepareAddPublicKey( + const pk = AccumulatorModule.prepareAddPublicKey(dock.api, u8aToHex(kp.publicKey.bytes), undefined, [did, 1], diff --git a/tests/integration/helpers.js b/tests/integration/helpers.js index 7bed24ec1..db7f3a189 100644 --- a/tests/integration/helpers.js +++ b/tests/integration/helpers.js @@ -15,13 +15,12 @@ import { createNewDockDID } from '../../src/utils/did'; * @returns {Promise} */ export async function registerNewDIDUsingPair(dockAPI, did, pair, verRels = undefined, controllers = []) { - const publicKey = getPublicKeyFromKeyringPair(pair); - if (verRels === undefined) { + // eslint-disable-next-line no-param-reassign verRels = new VerificationRelationship(); } // No additional controller - const didKey = new DidKey(publicKey, verRels); + const didKey = new DidKey(pair.publicKey(), verRels); return dockAPI.did.new(did, [didKey], controllers, false); } diff --git a/tests/integration/issuing-and-presentation-with-2-subjects.test.js b/tests/integration/issuing-and-presentation-with-2-subjects.test.js index 7fa99e6d0..6556c481c 100644 --- a/tests/integration/issuing-and-presentation-with-2-subjects.test.js +++ b/tests/integration/issuing-and-presentation-with-2-subjects.test.js @@ -4,7 +4,7 @@ import jsonld from 'jsonld'; import mockFetch from '../mocks/fetch'; import { - createNewDockDID, + createNewDockDID, DidKeypair, } from '../../src/utils/did'; import { DockAPI } from '../../src/index'; @@ -77,11 +77,11 @@ describe('Verifiable Credential issuance and presentation where the credential h // The DIDs should be written before any test begins // issuer DID - const pair1 = dock.keyring.addFromUri(issuerKeySeed, null, 'ed25519'); + const pair1 = new DidKeypair(dock.keyring.addFromUri(issuerKeySeed, null, 'ed25519'), 1); await registerNewDIDUsingPair(dock, issuerDID, pair1); // 1st subject's DID - const pair2 = dock.keyring.addFromUri(subject1Seed, null, 'ed25519'); + const pair2 = new DidKeypair(dock.keyring.addFromUri(subject1Seed, null, 'ed25519'), 1); await registerNewDIDUsingPair(dock, subject1DID, pair2); // 2nd subject's DID, has no key but is controlled by subject1DID diff --git a/tests/integration/issuing.test.js b/tests/integration/issuing.test.js index 85fd1b675..0de5e7378 100644 --- a/tests/integration/issuing.test.js +++ b/tests/integration/issuing.test.js @@ -2,7 +2,7 @@ import { randomAsHex } from '@polkadot/util-crypto'; import mockFetch from '../mocks/fetch'; -import { createNewDockDID } from '../../src/utils/did'; +import { createNewDockDID, DidKeypair } from '../../src/utils/did'; import { DockAPI } from '../../src/index'; import { DockResolver } from '../../src/resolver'; @@ -54,15 +54,15 @@ describe('Verifiable Credential issuance where issuer has a Dock DID', () => { // The DIDs should be written before any test begins // DID with ed25519 key - const pair1 = dock.keyring.addFromUri(issuer1KeySeed, null, 'ed25519'); + const pair1 = new DidKeypair(dock.keyring.addFromUri(issuer1KeySeed, null, 'ed25519'), 1); await registerNewDIDUsingPair(dock, issuer1DID, pair1); // DID with secp key - const pair2 = generateEcdsaSecp256k1Keypair(issuer2KeyEntropy); + const pair2 = new DidKeypair(generateEcdsaSecp256k1Keypair(issuer2KeyEntropy), 1); await registerNewDIDUsingPair(dock, issuer2DID, pair2); // DID with sr25519 key - const pair3 = dock.keyring.addFromUri(issuer3KeySeed, null, 'sr25519'); + const pair3 = new DidKeypair(dock.keyring.addFromUri(issuer3KeySeed, null, 'sr25519'), 1); await registerNewDIDUsingPair(dock, issuer3DID, pair3); }, 60000); diff --git a/tests/integration/master.test.js b/tests/integration/master.test.js index d375c17de..cf7017e85 100644 --- a/tests/integration/master.test.js +++ b/tests/integration/master.test.js @@ -4,7 +4,7 @@ import { assert, u8aToHex, stringToU8a } from '@polkadot/util'; import { FullNodeEndpoint, TestAccountURI, TestKeyringOpts } from '../test-constants'; import { DockAPI } from '../../src'; import { getSignatureFromKeyringPair, getStateChange } from '../../src/utils/misc'; -import { createDidSig } from '../../src/utils/did'; +import { createDidSig, typedHexDID } from '../../src/utils/did'; const ALICE_DID = u8aToHex(stringToU8a('Alice\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0')); const BOB_DID = u8aToHex(stringToU8a('Bob\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0')); @@ -13,7 +13,7 @@ const ALICE_SK = u8aToHex(stringToU8a('Alicesk\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 const BOB_SK = u8aToHex(stringToU8a('Bobsk\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0')); const CHARLIE_SK = u8aToHex(stringToU8a('Charliesk\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0')); -describe('Master Module', () => { +describe.skip('Master Module', () => { // node client let nc; let systemModule; @@ -244,12 +244,13 @@ async function allVote( const votes = []; for (const [did, key] of did_to_key) { - const nonce = await nc.didModule.getNextNonceForDID(did); + const nonce = await nc.didModule.getNextNonceForDid(typedHexDID(dock.api, did)); const vote = { nonce, data: { proposal: encodedProposal, roundNo } }; const encodedStateChange = getStateChange(nc.api, 'MasterVote', vote); const signature = getSignatureFromKeyringPair(key, encodedStateChange); - const didSig = createDidSig(did, 1, signature); + const didSig = createDidSig(typedHexDID(dock.api, did), 1, signature); votes.push({ sig: didSig, nonce }); } return votes; } + diff --git a/tests/integration/presenting.test.js b/tests/integration/presenting.test.js index 1ec1c0594..d9f51d64e 100644 --- a/tests/integration/presenting.test.js +++ b/tests/integration/presenting.test.js @@ -1,7 +1,7 @@ import { randomAsHex } from '@polkadot/util-crypto'; import { - createNewDockDID, + createNewDockDID, DidKeypair, } from '../../src/utils/did'; import { DockAPI } from '../../src/index'; @@ -63,19 +63,19 @@ describe('Verifiable Presentation where both issuer and holder have a Dock DID', // The DIDs should be written before any test begins // Register issuer DID with ed25519 key - const pair1 = dock.keyring.addFromUri(issuerKeySeed, null, 'ed25519'); + const pair1 = new DidKeypair(dock.keyring.addFromUri(issuerKeySeed, null, 'ed25519'), 1); await registerNewDIDUsingPair(dock, issuerDID, pair1); // Register holder DID with ed25519 key - const pair2 = dock.keyring.addFromUri(holder1KeySeed, null, 'ed25519'); + const pair2 = new DidKeypair(dock.keyring.addFromUri(holder1KeySeed, null, 'ed25519'), 1); await registerNewDIDUsingPair(dock, holder1DID, pair2); // Register holder DID with secp key - const pair3 = generateEcdsaSecp256k1Keypair(holder2KeyEntropy); + const pair3 = new DidKeypair(generateEcdsaSecp256k1Keypair(holder2KeyEntropy), 1); await registerNewDIDUsingPair(dock, holder2DID, pair3); // Register holder DID with sr25519 key - const pair4 = dock.keyring.addFromUri(holder3KeySeed, null, 'sr25519'); + const pair4 = new DidKeypair(dock.keyring.addFromUri(holder3KeySeed, null, 'sr25519'), 1); await registerNewDIDUsingPair(dock, holder3DID, pair4); const issuerKeyDoc = getKeyDoc(issuerDID, dock.keyring.addFromUri(issuerKeySeed, null, 'ed25519'), 'Ed25519VerificationKey2018'); diff --git a/tests/integration/private-status-list-credential.test.js b/tests/integration/private-status-list-credential.test.js index 13a9449ae..793a40dc2 100644 --- a/tests/integration/private-status-list-credential.test.js +++ b/tests/integration/private-status-list-credential.test.js @@ -1,7 +1,7 @@ import { randomAsHex } from '@polkadot/util-crypto'; import { DockAPI } from '../../src'; import { DockResolver } from '../../src/resolver'; -import { createNewDockDID } from '../../src/utils/did'; +import { createNewDockDID, DidKeypair } from '../../src/utils/did'; import { FullNodeEndpoint, TestAccountURI, TestKeyringOpts } from '../test-constants'; import { getUnsignedCred, registerNewDIDUsingPair } from './helpers'; import { @@ -65,11 +65,11 @@ describe('PrivateStatusList2021Credential', () => { dockAPI.setAccount(account); // Register issuer DID - issuerKeyPair = dockAPI.keyring.addFromUri(issuerSeed, null, 'ed25519'); + issuerKeyPair = new DidKeypair(dockAPI.keyring.addFromUri(issuerSeed, null, 'ed25519'), 1); await registerNewDIDUsingPair(dockAPI, issuerDID, issuerKeyPair); // Register holder DID - const pair1 = dockAPI.keyring.addFromUri(holderSeed, null, 'ed25519'); + const pair1 = new DidKeypair(dockAPI.keyring.addFromUri(holderSeed, null, 'ed25519'), 1); await registerNewDIDUsingPair(dockAPI, holderDID, pair1); issuerKey = getKeyDoc( @@ -159,7 +159,7 @@ describe('PrivateStatusList2021Credential', () => { const holderKey = getKeyDoc( holderDID, - dockAPI.keyring.addFromUri(holderSeed, null, 'ed25519'), + new DidKeypair(dockAPI.keyring.addFromUri(holderSeed, null, 'ed25519'), 1), 'Ed25519VerificationKey2018', ); diff --git a/tests/integration/resolvers.test.js b/tests/integration/resolvers.test.js index 750bddf69..9a64c2ca2 100644 --- a/tests/integration/resolvers.test.js +++ b/tests/integration/resolvers.test.js @@ -1,6 +1,6 @@ import { randomAsHex } from '@polkadot/util-crypto'; import { DockResolver, DockStatusList2021Resolver } from '../../src/resolver'; -import { getHexIdentifierFromDID, createNewDockDID } from '../../src/utils/did'; +import { createNewDockDID, DidKeypair, typedHexDID } from '../../src/utils/did'; import { DockAPI } from '../../src/index'; @@ -32,10 +32,9 @@ describe('Resolvers', () => { // Create owners const owners = new Set(); - owners.add(ownerDID); // Create a status list policy - const policy = new OneOfPolicy(owners); + let policy; beforeAll(async () => { await dock.init({ @@ -43,6 +42,9 @@ describe('Resolvers', () => { address: FullNodeEndpoint, }); + owners.add(typedHexDID(dock.api, ownerDID)); + policy = new OneOfPolicy(owners); + ownerKey = getKeyDoc( ownerDID, dock.keyring.addFromUri(ownerSeed, null, 'ed25519'), @@ -54,7 +56,7 @@ describe('Resolvers', () => { dock.setAccount(account); // Thees DIDs should be written before any test begins - pair = dock.keyring.addFromUri(ownerSeed, null, 'sr25519'); + pair = DidKeypair.fromApi(dock, { seed: ownerSeed, keypairType: 'sr25519' }); // The controller is same as the DID await registerNewDIDUsingPair(dock, ownerDID, pair); @@ -88,7 +90,7 @@ describe('Resolvers', () => { expect(resolver.supports('status-list2021:*:')).toBe(false); expect(resolver.supports('status-list2020:doc:')).toBe(false); expect(await resolver.resolve(ownerDID)).toEqual( - await dock.did.getDocument(getHexIdentifierFromDID(ownerDID)), + await dock.did.getDocument(ownerDID), ); if (!DisableStatusListTests) { expect(await resolver.resolve(statusListCred.id)).toEqual( @@ -124,7 +126,7 @@ describe('Resolvers', () => { expect(resolver.supports('status-list2021:*:')).toBe(false); expect(resolver.supports('status-list2020:doc:')).toBe(false); expect(await resolver.resolve(ownerDID)).toEqual( - await dock.did.getDocument(getHexIdentifierFromDID(ownerDID)), + await dock.did.getDocument(ownerDID), ); if (!DisableStatusListTests) { expect(resolver.resolve(statusListCred.id)).rejects.toThrowError( diff --git a/tests/integration/revocation.test.js b/tests/integration/revocation.test.js index 22750d4d5..c034535ba 100644 --- a/tests/integration/revocation.test.js +++ b/tests/integration/revocation.test.js @@ -7,6 +7,7 @@ import { FullNodeEndpoint, TestKeyringOpts, TestAccountURI } from '../test-const import { OneOfPolicy, } from '../../src/utils/revocation'; +import { DidKeypair, typedHexDID, typedHexDIDFromSubstrate } from '../../src/utils/did'; import { registerNewDIDUsingPair } from './helpers'; describe('Revocation Module', () => { @@ -28,10 +29,7 @@ describe('Revocation Module', () => { // Create owners const owners = new Set(); - owners.add(ownerDID); - - // Create a registry policy - const policy = new OneOfPolicy(owners); + let policy; // Create revoke IDs const revokeId = randomAsHex(32); @@ -44,13 +42,18 @@ describe('Revocation Module', () => { address: FullNodeEndpoint, }); + owners.add(typedHexDID(dock.api, ownerDID)); + + // Create a registry policy + policy = new OneOfPolicy(owners); + // The keyring should be initialized before any test begins as this suite is testing revocation const account = dock.keyring.addFromUri(TestAccountURI); dock.setAccount(account); // Thees DIDs should be written before any test begins - pair = dock.keyring.addFromUri(ownerSeed, null, 'sr25519'); - pair2 = dock.keyring.addFromUri(ownerSeed2, null, 'sr25519'); + pair = DidKeypair.fromApi(dock, { seed: ownerSeed, keypairType: 'sr25519' }); + pair2 = DidKeypair.fromApi(dock, { seed: ownerSeed2, keypairType: 'sr25519' }); // The controller is same as the DID await registerNewDIDUsingPair(dock, ownerDID, pair); @@ -69,15 +72,15 @@ describe('Revocation Module', () => { }, 40000); test('Can revoke single from a registry', async () => { - const [revoke, sig, nonce] = await dock.revocation.createSignedRevoke(registryId, revokeIds, ownerDID, pair, 1, { didModule: dock.did }); - await dock.revocation.revoke(revoke, [[sig, nonce]], false); + const [revoke, sig, nonce] = await dock.revocation.createSignedRevoke(registryId, revokeIds, ownerDID, pair, { didModule: dock.did }); + await dock.revocation.revoke(revoke, [{ nonce, sig }], false); const revocationStatus = await dock.revocation.getIsRevoked(registryId, revokeId); expect(revocationStatus).toBe(true); }, 40000); test('Can unrevoke single from a registry', async () => { - const [unrevoke, sig, nonce] = await dock.revocation.createSignedUnRevoke(registryId, revokeIds, ownerDID, pair, 1, { didModule: dock.did }); - await dock.revocation.unrevoke(unrevoke, [[sig, nonce]], false); + const [unrevoke, sig, nonce] = await dock.revocation.createSignedUnRevoke(registryId, revokeIds, ownerDID, pair, { didModule: dock.did }); + await dock.revocation.unrevoke(unrevoke, [{ nonce, sig }], false); const revocationStatus = await dock.revocation.getIsRevoked(registryId, revokeId); expect(revocationStatus).toBe(false); @@ -93,8 +96,8 @@ describe('Revocation Module', () => { const rIdsArr = Array.from(rIds); - const [revoke, sig, nonce] = await dock.revocation.createSignedRevoke(registryId, rIds, ownerDID, pair, 1, { didModule: dock.did }); - await dock.revocation.revoke(revoke, [[sig, nonce]], false); + const [revoke, sig, nonce] = await dock.revocation.createSignedRevoke(registryId, rIds, ownerDID, pair, { didModule: dock.did }); + await dock.revocation.revoke(revoke, [{ nonce, sig }], false); console.time(`Check ${count} revocation status one by one`); for (let i = 0; i < rIdsArr.length; i++) { @@ -110,11 +113,11 @@ describe('Revocation Module', () => { revocationStatuses.forEach((s) => expect(s).toBe(true)); console.timeEnd(`Check ${count} revocation status in a batch`); - const [unrevoke, sig1, nonce1] = await dock.revocation.createSignedUnRevoke(registryId, rIds, ownerDID, pair, 1, { didModule: dock.did }); + const [unrevoke, sig1, nonce1] = await dock.revocation.createSignedUnRevoke(registryId, rIds, ownerDID, pair, { didModule: dock.did }); // Note: Intentionally passing true and waiting for finalization as not doing that makes the multi-query check fail. // This seems like a bug since the single query check done in next loop work. Even the upgrade to @polkadot/api version 9.14 didn't fix - await dock.revocation.unrevoke(unrevoke, [[sig1, nonce1]], true); + await dock.revocation.unrevoke(unrevoke, [{ nonce: nonce1, sig: sig1 }], true); for (let i = 0; i < rIdsArr.length; i++) { // eslint-disable-next-line no-await-in-loop @@ -128,8 +131,8 @@ describe('Revocation Module', () => { }, 40000); test('Can remove a registry', async () => { - const [remove, sig, nonce] = await dock.revocation.createSignedRemove(registryId, ownerDID, pair, 1, { didModule: dock.did }); - await dock.revocation.removeRegistry(remove, [[sig, nonce]], false); + const [remove, sig, nonce] = await dock.revocation.createSignedRemove(registryId, ownerDID, pair, { didModule: dock.did }); + await dock.revocation.removeRegistry(remove, [{ nonce, sig }], false); await expect(dock.revocation.getRevocationRegistry(registryId)).rejects.toThrow(/Could not find revocation registry/); }, 40000); @@ -143,8 +146,8 @@ describe('Revocation Module', () => { const reg = await dock.revocation.getRevocationRegistry(registryId); expect(!!reg).toBe(true); - const [revoke, sig, nonce] = await dock.revocation.createSignedRevoke(registryId, revokeIds, ownerDID, pair, 1, { didModule: dock.did }); - await dock.revocation.revoke(revoke, [[sig, nonce]], false); + const [revoke, sig, nonce] = await dock.revocation.createSignedRevoke(registryId, revokeIds, ownerDID, pair, { didModule: dock.did }); + await dock.revocation.revoke(revoke, [{ nonce, sig }], false); const revocationStatus = await dock.revocation.getIsRevoked(registryId, revokeId); expect(revocationStatus).toBe(true); @@ -154,9 +157,9 @@ describe('Revocation Module', () => { const reg = await dock.revocation.getRevocationRegistry(registryId); expect(!!reg).toBe(true); - const [unrevoke, sig, nonce] = await dock.revocation.createSignedUnRevoke(registryId, revokeIds, ownerDID, pair, 1, { didModule: dock.did }); + const [unrevoke, sig, nonce] = await dock.revocation.createSignedUnRevoke(registryId, revokeIds, ownerDID, pair, { didModule: dock.did }); await expect( - dock.revocation.unrevoke(unrevoke, [[sig, nonce]], false), + dock.revocation.unrevoke(unrevoke, [{ nonce, sig }], false), ).rejects.toThrow(); const revocationStatus = await dock.revocation.getIsRevoked(registryId, revokeId); @@ -167,9 +170,9 @@ describe('Revocation Module', () => { const reg = await dock.revocation.getRevocationRegistry(registryId); expect(!!reg).toBe(true); - const [remove, sig, nonce] = await dock.revocation.createSignedRemove(registryId, ownerDID, pair, 1, { didModule: dock.did }); + const [remove, sig, nonce] = await dock.revocation.createSignedRemove(registryId, ownerDID, pair, { didModule: dock.did }); await expect( - dock.revocation.removeRegistry(remove, [[sig, nonce]], false), + dock.revocation.removeRegistry(remove, [{ nonce, sig }], false), ).rejects.toThrow(); await expect(dock.revocation.getRevocationRegistry(registryId)).resolves.toBeDefined(); @@ -177,8 +180,8 @@ describe('Revocation Module', () => { test('Can create a registry with multiple owners', async () => { const controllersNew = new Set(); - controllersNew.add(ownerDID); - controllersNew.add(ownerDID2); + controllersNew.add(typedHexDID(dock.api, ownerDID)); + controllersNew.add(typedHexDID(dock.api, ownerDID2)); // Create policy and registry with multiple owners const policyNew = new OneOfPolicy(controllersNew); @@ -186,18 +189,25 @@ describe('Revocation Module', () => { const reg = await dock.revocation.getRevocationRegistry(multipleControllerRegistryID); expect(reg.policy.isOneOf).toBe(true); - const controllerSet = reg.policy.toJSON().oneOf; - expect(controllerSet.length).toBe(2); + const controllerSet = reg.policy.asOneOf; + expect(controllerSet.toJSON().length).toBe(2); let hasFirstDID = false; let hasSecondDID = false; - controllerSet.forEach((controller) => { - if (controller === ownerDID) { - hasFirstDID = true; - } else if (controller === ownerDID2) { - hasSecondDID = true; - } - }); + [...controllerSet.entries()] + .flatMap((v) => v) + .map((cnt) => typedHexDIDFromSubstrate(dock.api, cnt)) + .forEach((controller) => { + if ( + controller.toString() === typedHexDID(dock.api, ownerDID).toString() + ) { + hasFirstDID = true; + } else if ( + controller.toString() === typedHexDID(dock.api, ownerDID2).toString() + ) { + hasSecondDID = true; + } + }); expect(hasFirstDID && hasSecondDID).toBe(true); }, 40000); @@ -205,17 +215,17 @@ describe('Revocation Module', () => { const revId = randomAsHex(32); // Revoke - await dock.revocation.revokeCredentialWithOneOfPolicy(multipleControllerRegistryID, revId, ownerDID, pair, 1, { didModule: dock.did }, false); + await dock.revocation.revokeCredentialWithOneOfPolicy(multipleControllerRegistryID, revId, ownerDID, pair, { didModule: dock.did }, false); const revocationStatus = await dock.revocation.getIsRevoked(multipleControllerRegistryID, revId); expect(revocationStatus).toBe(true); // Unrevoke from another DID - await dock.revocation.unrevokeCredentialWithOneOfPolicy(multipleControllerRegistryID, revId, ownerDID2, pair2, 1, { didModule: dock.did }, false); + await dock.revocation.unrevokeCredentialWithOneOfPolicy(multipleControllerRegistryID, revId, ownerDID2, pair2, { didModule: dock.did }, false); const revocationStatus1 = await dock.revocation.getIsRevoked(multipleControllerRegistryID, revId); expect(revocationStatus1).toBe(false); // Remove - await dock.revocation.removeRegistryWithOneOfPolicy(multipleControllerRegistryID, ownerDID, pair, 1, { didModule: dock.did }, false); + await dock.revocation.removeRegistryWithOneOfPolicy(multipleControllerRegistryID, ownerDID, pair, { didModule: dock.did }, false); await expect(dock.revocation.getRevocationRegistry(multipleControllerRegistryID)).rejects.toThrow(/Could not find revocation registry/); }, 30000); }); diff --git a/tests/integration/schema.test.js b/tests/integration/schema.test.js index 7f657b1dc..b01fda246 100644 --- a/tests/integration/schema.test.js +++ b/tests/integration/schema.test.js @@ -4,7 +4,7 @@ import { randomAsHex } from '@polkadot/util-crypto'; import { DockAPI } from '../../src/index'; import { - createNewDockDID, getHexIdentifierFromDID, hexDIDToQualified, + createNewDockDID, typedHexDID, DidKeypair, hexDIDToQualified, } from '../../src/utils/did'; import { FullNodeEndpoint, TestKeyringOpts, TestAccountURI } from '../test-constants'; import { verifyCredential, verifyPresentation } from '../../src/utils/vc/index'; @@ -20,8 +20,8 @@ import { registerNewDIDUsingPair } from './helpers'; let account; let pair; -let dockDID; let hexDid; +let dockDID; let blobId; let keyDoc; let validCredential; @@ -56,9 +56,9 @@ describe('Schema Blob Module Integration', () => { }); account = dockApi.keyring.addFromUri(TestAccountURI); dockApi.setAccount(account); - pair = dockApi.keyring.addFromUri(firstKeySeed); + pair = DidKeypair.fromApi(dockApi); dockDID = createNewDockDID(); - hexDid = getHexIdentifierFromDID(dockDID); + hexDid = typedHexDID(dockApi.api, dockDID); await registerNewDIDUsingPair(dockApi, dockDID, pair); blobId = randomAsHex(DockBlobIdByteSize); @@ -68,7 +68,7 @@ describe('Schema Blob Module Integration', () => { id: invalidFormatBlobId, blob: stringToHex('hello world'), }; - await dockApi.blob.new(blob, dockDID, pair, 1, { didModule: dockApi.didModule }, false); + await dockApi.blob.new(blob, dockDID, pair, { didModule: dockApi.didModule }, false); // Write schema blob const blobStr = JSON.stringify(exampleSchema); @@ -76,7 +76,7 @@ describe('Schema Blob Module Integration', () => { id: blobId, blob: stringToHex(blobStr), }; - await dockApi.blob.new(blob, dockDID, pair, 1, { didModule: dockApi.didModule }, false); + await dockApi.blob.new(blob, dockDID, pair, { didModule: dockApi.didModule }, false); // Properly format a keyDoc to use for signing keyDoc = getKeyDoc( @@ -122,11 +122,12 @@ describe('Schema Blob Module Integration', () => { test('Set and get schema', async () => { const schema = new Schema(); await schema.setJSONSchema(exampleSchema); - await dockApi.blob.new(schema.toBlob(), hexDid, pair, 1, { didModule: dockApi.didModule }, false); - await expect(Schema.get(blobId, dockApi)).resolves.toMatchObject({ + await dockApi.blob.new(schema.toBlob(), dockDID, pair, { didModule: dockApi.didModule }, false); + const schemaObj = await Schema.get(blobId, dockApi); + expect(schemaObj).toMatchObject({ ...exampleSchema, id: blobId, - author: hexDIDToQualified(getHexIdentifierFromDID(dockDID)), + author: hexDIDToQualified(hexDid), }); }, 20000); diff --git a/tests/integration/status-list-credential-module.test.js b/tests/integration/status-list-credential-module.test.js index d93411509..ac3890156 100644 --- a/tests/integration/status-list-credential-module.test.js +++ b/tests/integration/status-list-credential-module.test.js @@ -9,7 +9,12 @@ import { DisableStatusListTests, } from '../test-constants'; -import { getHexIdentifierFromDID, createNewDockDID } from '../../src/utils/did'; +import { + typedHexDID, + createNewDockDID, + DidKeypair, + typedHexDIDFromSubstrate, +} from '../../src/utils/did'; import { OneOfPolicy } from '../../src/utils/revocation'; import { registerNewDIDUsingPair } from './helpers'; import { getKeyDoc } from '../../src/utils/vc/helpers'; @@ -45,10 +50,7 @@ buildTest('StatusListCredential Module', () => { // Create owners const owners = new Set(); - owners.add(ownerDID); - - // Create a status list policy - const policy = new OneOfPolicy(owners); + let policy; // Create revoke IDs const revokeId = (Math.random() * 10e3) | 0; @@ -61,6 +63,11 @@ buildTest('StatusListCredential Module', () => { address: FullNodeEndpoint, }); + // Create a status list policy + owners.add(typedHexDID(dock.api, ownerDID)); + + policy = new OneOfPolicy(owners); + ownerKey = getKeyDoc( ownerDID, dock.keyring.addFromUri(ownerSeed, null, 'ed25519'), @@ -78,8 +85,14 @@ buildTest('StatusListCredential Module', () => { dock.setAccount(account); // Thees DIDs should be written before any test begins - pair = dock.keyring.addFromUri(ownerSeed, null, 'sr25519'); - pair2 = dock.keyring.addFromUri(ownerSeed2, null, 'sr25519'); + pair = new DidKeypair( + dock.keyring.addFromUri(ownerSeed, null, 'sr25519'), + 1, + ); + pair2 = new DidKeypair( + dock.keyring.addFromUri(ownerSeed2, null, 'sr25519'), + 1, + ); // The controller is same as the DID await registerNewDIDUsingPair(dock, ownerDID, pair); @@ -120,12 +133,11 @@ buildTest('StatusListCredential Module', () => { cred, ownerDID, pair, - 1, { didModule: dock.did }, ); await dock.statusListCredential.updateStatusListCredential( revoke, - [[sig, nonce]], + [{ nonce, sig }], false, ); const fetchedCred = await dock.statusListCredential.fetchStatusList2021Credential( @@ -139,14 +151,14 @@ buildTest('StatusListCredential Module', () => { const cred = await dock.statusListCredential.fetchStatusList2021Credential( statusListCredId, ); - expect( + await expect( cred.update(ownerKey, { unsuspendIndices: revokeIds }), ).rejects.toEqual( new Error( "Can't unsuspend indices for credential with `statusPurpose` = `revocation`, it's only possible with `statusPurpose` = `suspension`", ), ); - expect( + await expect( cred.update(ownerKey, { unsuspendIndices: revokeIds }), ).rejects.toEqual( new Error( @@ -169,12 +181,11 @@ buildTest('StatusListCredential Module', () => { credential, ownerDID, pair, - 1, { didModule: dock.did }, ); await dock.statusListCredential.updateStatusListCredential( update, - [[sig, nonce]], + [{ nonce, sig }], false, ); let fetchedCred = await dock.statusListCredential.fetchStatusList2021Credential( @@ -190,12 +201,11 @@ buildTest('StatusListCredential Module', () => { fetchedCred, ownerDID, pair, - 1, { didModule: dock.did }, ); await dock.statusListCredential.updateStatusListCredential( update, - [[sig, nonce]], + [{ nonce, sig }], false, ); @@ -210,12 +220,11 @@ buildTest('StatusListCredential Module', () => { statusListCredId, ownerDID, pair, - 1, { didModule: dock.did }, ); await dock.statusListCredential.removeStatusListCredential( remove, - [[sig, nonce]], + [{ nonce, sig }], false, ); expect( @@ -227,8 +236,8 @@ buildTest('StatusListCredential Module', () => { test('Can create a status list with multiple owners', async () => { const controllersNew = new Set(); - controllersNew.add(ownerDID); - controllersNew.add(ownerDID2); + controllersNew.add(typedHexDID(dock.api, ownerDID)); + controllersNew.add(typedHexDID(dock.api, ownerDID2)); const cred = await StatusList2021Credential.create( ownerKey, @@ -254,18 +263,25 @@ buildTest('StatusListCredential Module', () => { ).unwrap(); expect(fetchedCred.policy.isOneOf).toBe(true); - const controllerSet = fetchedCred.policy.toJSON().oneOf; - expect(controllerSet.length).toBe(2); + const controllerSet = fetchedCred.policy.asOneOf; + expect(controllerSet.toJSON().length).toBe(2); let hasFirstDID = false; let hasSecondDID = false; - controllerSet.forEach((controller) => { - if (controller === getHexIdentifierFromDID(ownerDID)) { - hasFirstDID = true; - } else if (controller === getHexIdentifierFromDID(ownerDID2)) { - hasSecondDID = true; - } - }); + [...controllerSet.entries()] + .flatMap((v) => v) + .map((cnt) => typedHexDIDFromSubstrate(dock.api, cnt)) + .forEach((controller) => { + if ( + controller.toString() === typedHexDID(dock.api, ownerDID).toString() + ) { + hasFirstDID = true; + } else if ( + controller.toString() === typedHexDID(dock.api, ownerDID2).toString() + ) { + hasSecondDID = true; + } + }); expect(hasFirstDID && hasSecondDID).toBe(true); }, 40000); @@ -282,7 +298,6 @@ buildTest('StatusListCredential Module', () => { fetchedCred, ownerDID, pair, - 1, { didModule: dock.did }, false, ); @@ -300,7 +315,6 @@ buildTest('StatusListCredential Module', () => { fetchedCred, ownerDID2, pair2, - 1, { didModule: dock.did }, false, ); @@ -314,7 +328,6 @@ buildTest('StatusListCredential Module', () => { multipleControllerstatusListCredID, ownerDID, pair, - 1, { didModule: dock.did }, false, ); diff --git a/tests/integration/status-list-credential.test.js b/tests/integration/status-list-credential.test.js index e89b594a7..f84b1be02 100644 --- a/tests/integration/status-list-credential.test.js +++ b/tests/integration/status-list-credential.test.js @@ -21,7 +21,7 @@ import { createPresentation } from '../create-presentation'; import { OneOfPolicy } from '../../src/utils/revocation'; import { getUnsignedCred, registerNewDIDUsingPair } from './helpers'; import { getKeyDoc } from '../../src/utils/vc/helpers'; -import { createNewDockDID } from '../../src/utils/did'; +import { createNewDockDID, DidKeypair, typedHexDID } from '../../src/utils/did'; import StatusList2021Credential from '../../src/status-list-credential/status-list2021-credential'; import { addStatusList21EntryToCredential } from '../../src/utils/vc/credentials'; @@ -62,16 +62,16 @@ buildTest('StatusList2021Credential', () => { dockAPI.setAccount(account); // Register issuer DID - issuerKeyPair = dockAPI.keyring.addFromUri(issuerSeed, null, 'ed25519'); + issuerKeyPair = new DidKeypair(dockAPI.keyring.addFromUri(issuerSeed, null, 'ed25519'), 1); await registerNewDIDUsingPair(dockAPI, issuerDID, issuerKeyPair); // Register holder DID - const pair1 = dockAPI.keyring.addFromUri(holderSeed, null, 'ed25519'); + const pair1 = new DidKeypair(dockAPI.keyring.addFromUri(holderSeed, null, 'ed25519'), 1); await registerNewDIDUsingPair(dockAPI, holderDID, pair1); // Create a new policy const policy = new OneOfPolicy(); - policy.addOwner(issuerDID); + policy.addOwner(typedHexDID(dockAPI.api, issuerDID)); issuerKey = getKeyDoc( issuerDID, issuerKeyPair, @@ -144,7 +144,6 @@ buildTest('StatusList2021Credential', () => { fetchedCred, issuerDID, issuerKeyPair, - 1, dockAPI, ); @@ -175,7 +174,6 @@ buildTest('StatusList2021Credential', () => { fetchedCred, issuerDID, issuerKeyPair, - 1, dockAPI, ); const holderKey = getKeyDoc( @@ -219,7 +217,6 @@ buildTest('StatusList2021Credential', () => { fetchedCred, issuerDID, issuerKeyPair, - 1, dockAPI, ); diff --git a/tests/integration/trust-registry-module.test.js b/tests/integration/trust-registry-module.test.js new file mode 100644 index 000000000..dd7f2784b --- /dev/null +++ b/tests/integration/trust-registry-module.test.js @@ -0,0 +1,483 @@ +import { randomAsHex } from '@polkadot/util-crypto'; +import { BTreeSet, BTreeMap } from '@polkadot/types'; +import { u8aToHex, stringToU8a } from '@polkadot/util'; + +import { DockAPI } from '../../src/index'; + +import { + FullNodeEndpoint, + TestKeyringOpts, + TestAccountURI, + DisableTrustRegistryTests, +} from '../test-constants'; + +import { + createNewDockDID, + DidKeypair, + DockDidMethodKey, + typedHexDID, +} from '../../src/utils/did'; +import { registerNewDIDUsingPair } from './helpers'; + +const buildTest = DisableTrustRegistryTests ? describe.skip : describe; + +buildTest('Trust Registry', () => { + const dock = new DockAPI(); + + // Create a random trust registry id + const trustRegistryId = randomAsHex(32); + + // Create a new convener DID, the DID will be registered on the network and own the trust registry + const convenerDID = createNewDockDID(); + const ownerSeed = randomAsHex(32); + let convenerPair; + + const issuerDID = createNewDockDID(); + const issuerSeed = randomAsHex(32); + let issuerPair; + + const issuerDID2 = createNewDockDID(); + const issuerSeed2 = randomAsHex(32); + let issuerPair2; + + const verifierDID = createNewDockDID(); + const verifierSeed = randomAsHex(32); + let verifierPair; + + const verifierDID2 = createNewDockDID(); + const verifierSeed2 = randomAsHex(32); + let verifierPair2; + + const verifierDIDMethodKeySeed = randomAsHex(32); + let verifierDIDMethodKeyPair; + let verifierDIDMethodKey; + + beforeAll(async () => { + await dock.init({ + keyring: TestKeyringOpts, + address: FullNodeEndpoint, + }); + + convenerPair = new DidKeypair( + dock.keyring.addFromUri(ownerSeed, null, 'ed25519'), + 1, + ); + + issuerPair = new DidKeypair( + dock.keyring.addFromUri(issuerSeed, null, 'ed25519'), + 1, + ); + + issuerPair2 = new DidKeypair( + dock.keyring.addFromUri(issuerSeed2, null, 'ed25519'), + 1, + ); + + verifierPair = new DidKeypair( + dock.keyring.addFromUri(verifierSeed, null, 'ed25519'), + 1, + ); + + verifierPair2 = new DidKeypair( + dock.keyring.addFromUri(verifierSeed2, null, 'ed25519'), + 1, + ); + + verifierDIDMethodKeyPair = new DidKeypair( + dock.keyring.addFromUri(verifierDIDMethodKeySeed, null, 'ed25519'), + ); + verifierDIDMethodKey = new DockDidMethodKey(verifierDIDMethodKeyPair.publicKey()); + + // The keyring should be initialized before any test begins as this suite is testing trust registry + const account = dock.keyring.addFromUri(TestAccountURI); + dock.setAccount(account); + + // Register convener + await registerNewDIDUsingPair(dock, convenerDID, convenerPair); + // Register issuer DID + await registerNewDIDUsingPair(dock, issuerDID, issuerPair); + await registerNewDIDUsingPair(dock, issuerDID2, issuerPair2); + await registerNewDIDUsingPair(dock, verifierDID, verifierPair); + await registerNewDIDUsingPair(dock, verifierDID2, verifierPair2); + await dock.did.newDidMethodKey(verifierDIDMethodKey.asDidMethodKey); + }, 40000); + + afterAll(async () => { + await dock.disconnect(); + }, 10000); + + it('Initializes Trust Registry', async () => { + expect( + (await dock.api.query.trustRegistry.trustRegistriesInfo(trustRegistryId)) + .isNone, + ).toEqual(true); + + await dock.trustRegistry.init( + convenerDID, + trustRegistryId, + 'Test Registry', + 'Gov framework', + convenerPair, + dock, + ); + + const registryInfo = ( + await dock.api.query.trustRegistry.trustRegistriesInfo(trustRegistryId) + ).toJSON(); + expect(registryInfo).toEqual({ + convener: typedHexDID(dock.api, convenerDID), + name: 'Test Registry', + govFramework: u8aToHex(stringToU8a('Gov framework')), + }); + }); + + it('Adds schemas to the existing Trust Registry', async () => { + // Create a random trust registry id + const schemaId = randomAsHex(32); + + await dock.trustRegistry.init( + convenerDID, + trustRegistryId, + 'Test Registry', + 'Gov framework', + convenerPair, + dock, + ); + + const verifiers = new BTreeSet(); + verifiers.add(typedHexDID(dock.api, verifierDID)); + verifiers.add(typedHexDID(dock.api, verifierDID2)); + verifiers.add(verifierDIDMethodKey); + + const issuers = new BTreeMap(); + const issuerPrices = new BTreeMap(); + issuerPrices.set('A', 20); + const issuer2Prices = new BTreeMap(); + issuer2Prices.set('A', 20); + + issuers.set(typedHexDID(dock.api, issuerDID), issuerPrices); + issuers.set(typedHexDID(dock.api, issuerDID2), issuer2Prices); + + const schemas = new BTreeMap(); + schemas.set(schemaId, { + issuers, + verifiers, + }); + + await dock.trustRegistry.addSchemaMetadata( + convenerDID, + trustRegistryId, + schemas, + convenerPair, + dock, + ); + + expect( + ( + await dock.api.query.trustRegistry.trustRegistrySchemasMetadata( + schemaId, + trustRegistryId, + ) + ).toJSON(), + ).toEqual({ + issuers: expectedFormattedIssuers(issuers), + verifiers: expectedFormattedVerifiers(verifiers), + }); + }); + + it('Suspends issuers in the existing Trust Registry', async () => { + // Create a random trust registry id + const schemaId = randomAsHex(32); + + await dock.trustRegistry.init( + convenerDID, + trustRegistryId, + 'Test Registry', + 'Gov framework', + convenerPair, + dock, + ); + + const verifiers = new BTreeSet(); + verifiers.add(typedHexDID(dock.api, verifierDID)); + verifiers.add(typedHexDID(dock.api, verifierDID2)); + verifiers.add(verifierDIDMethodKey); + + const issuers = new BTreeMap(); + const issuerPrices = new BTreeMap(); + issuerPrices.set('A', 20); + const issuer2Prices = new BTreeMap(); + issuer2Prices.set('A', 20); + + issuers.set(typedHexDID(dock.api, issuerDID), issuerPrices); + issuers.set(typedHexDID(dock.api, issuerDID2), issuer2Prices); + + const schemas = new BTreeMap(); + schemas.set(schemaId, { + issuers, + verifiers, + }); + + await dock.trustRegistry.addSchemaMetadata( + convenerDID, + trustRegistryId, + schemas, + convenerPair, + dock, + ); + + await dock.trustRegistry.suspendIssuers( + convenerDID, + trustRegistryId, + [issuerDID, issuerDID2], + convenerPair, + dock, + ); + + for (const issuer of [issuerDID, issuerDID2]) { + expect((await dock.api.query.trustRegistry.trustRegistryIssuerConfigurations(trustRegistryId, typedHexDID(dock.api, issuer))).toJSON()).toEqual({ + suspended: true, + delegated: [], + }); + } + + await dock.trustRegistry.unsuspendIssuers( + convenerDID, + trustRegistryId, + [issuerDID], + convenerPair, + dock, + ); + + for (const issuer of [issuerDID]) { + expect((await dock.api.query.trustRegistry.trustRegistryIssuerConfigurations(trustRegistryId, typedHexDID(dock.api, issuer))).toJSON()).toEqual({ + suspended: false, + delegated: [], + }); + } + + for (const issuer of [issuerDID2]) { + expect((await dock.api.query.trustRegistry.trustRegistryIssuerConfigurations(trustRegistryId, typedHexDID(dock.api, issuer))).toJSON()).toEqual({ + suspended: true, + delegated: [], + }); + } + }); + + it('Updates delegated issuers in the existing Trust Registry', async () => { + // Create a random trust registry id + await dock.trustRegistry.init( + convenerDID, + trustRegistryId, + 'Test Registry', + 'Gov framework', + convenerPair, + dock, + ); + + expect((await dock.api.query.trustRegistry.trustRegistryIssuerConfigurations(trustRegistryId, typedHexDID(dock.api, issuerDID))).toJSON()).toEqual({ + suspended: false, + delegated: [], + }); + + const issuers = new BTreeSet(); + issuers.add(typedHexDID(dock.api, issuerDID2)); + + await dock.trustRegistry.updateDelegatedIssuers( + issuerDID, + trustRegistryId, + { Set: issuers }, + issuerPair, + dock, + ); + + expect((await dock.api.query.trustRegistry.trustRegistryIssuerConfigurations(trustRegistryId, typedHexDID(dock.api, issuerDID))).toJSON()).toEqual({ + suspended: false, + delegated: [typedHexDID(dock.api, issuerDID2)], + }); + }); + + it('Updates schemas in the existing Trust Registry', async () => { + // Create a random trust registry id + const schemaId = randomAsHex(32); + + await dock.trustRegistry.init( + convenerDID, + trustRegistryId, + 'Test Registry', + 'Gov framework', + convenerPair, + dock, + ); + + const verifiers = new BTreeSet(); + verifiers.add(typedHexDID(dock.api, verifierDID)); + verifiers.add(typedHexDID(dock.api, verifierDID2)); + verifiers.add(verifierDIDMethodKey); + + let issuers = new BTreeMap(); + let issuerPrices = new BTreeMap(); + issuerPrices.set('A', 20); + let issuer2Prices = new BTreeMap(); + issuer2Prices.set('A', 20); + + issuers.set(typedHexDID(dock.api, issuerDID), issuerPrices); + issuers.set(typedHexDID(dock.api, issuerDID2), issuer2Prices); + + const schemas = new BTreeMap(); + schemas.set(schemaId, { + issuers, + verifiers, + }); + + await dock.trustRegistry.addSchemaMetadata( + convenerDID, + trustRegistryId, + schemas, + convenerPair, + dock, + ); + + expect( + ( + await dock.api.query.trustRegistry.trustRegistrySchemasMetadata( + schemaId, + trustRegistryId, + ) + ).toJSON(), + ).toEqual({ + issuers: expectedFormattedIssuers(issuers), + verifiers: expectedFormattedVerifiers(verifiers), + }); + + let schemasUpdate = new BTreeMap(); + + issuers = new BTreeMap(); + issuerPrices = new BTreeMap(); + issuerPrices.set('A', 65); + issuer2Prices = new BTreeMap(); + issuer2Prices.set('A', 75); + + issuers.set(typedHexDID(dock.api, issuerDID), issuerPrices); + issuers.set(typedHexDID(dock.api, issuerDID2), issuer2Prices); + + schemasUpdate.set(schemaId, { + issuers: { + Set: issuers, + }, + }); + + await dock.trustRegistry.updateSchemaMetadata( + convenerDID, + trustRegistryId, + schemasUpdate, + convenerPair, + dock, + ); + + expect( + ( + await dock.api.query.trustRegistry.trustRegistrySchemasMetadata( + schemaId, + trustRegistryId, + ) + ).toJSON(), + ).toEqual({ + issuers: expectedFormattedIssuers(issuers), + verifiers: expectedFormattedVerifiers(verifiers), + }); + + schemasUpdate = new BTreeMap(); + issuer2Prices = new BTreeMap(); + issuer2Prices.set('A', 25); + issuer2Prices.set('B', 36); + + const issuersUpdate = new BTreeMap(); + issuersUpdate.set(typedHexDID(dock.api, issuerDID2), { + Set: issuer2Prices, + }); + schemasUpdate.set(schemaId, { + issuers: { + Modify: issuersUpdate, + }, + }); + issuers = new BTreeMap(); + issuers.set(typedHexDID(dock.api, issuerDID2), issuer2Prices); + issuers.set(typedHexDID(dock.api, issuerDID), issuerPrices); + schemas.set(schemaId, { + issuers, + verifiers: schemas.get(schemaId).verifiers, + }); + + await dock.trustRegistry.updateSchemaMetadata( + issuerDID2, + trustRegistryId, + schemasUpdate, + issuerPair2, + dock, + ); + + expect( + ( + await dock.api.query.trustRegistry.trustRegistrySchemasMetadata( + schemaId, + trustRegistryId, + ) + ).toJSON(), + ).toEqual({ + issuers: expectedFormattedIssuers(issuers), + verifiers: expectedFormattedVerifiers(verifiers), + }); + + schemasUpdate = new BTreeMap(); + const verifiersUpdate = new BTreeMap(); + const innerUpdate = new BTreeSet(); + innerUpdate.add(verifierDIDMethodKey); + verifiersUpdate.set(verifierDIDMethodKey, { Remove: innerUpdate }); + schemasUpdate.set(schemaId, { + verifiers: { + Modify: verifiersUpdate, + }, + }); + + await dock.trustRegistry.updateSchemaMetadata( + verifierDIDMethodKey, + trustRegistryId, + schemasUpdate, + verifierDIDMethodKeyPair, + dock, + ); + + verifiers.delete(verifierDIDMethodKey); + expect( + ( + await dock.api.query.trustRegistry.trustRegistrySchemasMetadata( + schemaId, + trustRegistryId, + ) + ).toJSON(), + ).toEqual({ + issuers: expectedFormattedIssuers(issuers), + verifiers: expectedFormattedVerifiers(verifiers), + }); + }); +}); + +function expectedFormattedIssuers(issuers) { + return Object.fromEntries( + [...issuers.entries()].map(([issuer, prices]) => [ + JSON.stringify( + issuer.isDid + ? { did: issuer.asDid } + : { didMethodKey: issuer.asDidMethodKey }, + ), + Object.fromEntries([...prices.entries()]), + ]), + ); +} + +function expectedFormattedVerifiers(verifiers) { + return [...verifiers.values()] + .map((verifier) => (verifier.isDid ? { did: verifier.asDid } : { didMethodKey: verifier.asDidMethodKey })) + .sort((a, b) => JSON.stringify(a).localeCompare(JSON.stringify(b))); +} diff --git a/tests/test-constants.js b/tests/test-constants.js index 04b5e6036..b340d3814 100644 --- a/tests/test-constants.js +++ b/tests/test-constants.js @@ -78,6 +78,9 @@ export const TestSchemes = fromEnv('TestSchemes', DefaultTestSchemes); export const DisableStatusListTests = boolEnv( fromEnv('DisableStatusListTests', 'false'), ); +export const DisableTrustRegistryTests = boolEnv( + fromEnv('DisableTrustRegistryTests', 'false'), +); export const BBS = { Name: 'BBS', @@ -100,7 +103,7 @@ export const BBS = { VerKey: 'Bls12381BBSVerificationKeyDock2023', getParamsByDid: (api, did) => api.rpc.core_mods.bbsParamsByDid(did), getPublicKeyWithParamsByStorageKey: (api, storageKey) => api.rpc.core_mods.bbsPublicKeyWithParams(storageKey), - getPublicKeysByDid: (api, did) => api.rpc.core_mods.bbsPublicKeysByDid(did), + getPublicKeysByDid: (api, did) => api.rpc.core_mods.bbsPublicKeysByDid(did.asDid), }; export const BBSPlus = { Name: 'BBS+', @@ -123,7 +126,7 @@ export const BBSPlus = { SigType: 'Bls12381BBS+SignatureDock2022', getParamsByDid: (api, did) => api.rpc.core_mods.bbsPlusParamsByDid(did), getPublicKeyWithParamsByStorageKey: (api, storageKey) => api.rpc.core_mods.bbsPlusPublicKeyWithParams(storageKey), - getPublicKeysByDid: (api, did) => api.rpc.core_mods.bbsPlusPublicKeysByDid(did), + getPublicKeysByDid: (api, did) => api.rpc.core_mods.bbsPlusPublicKeysByDid(did.asDid), }; export const PS = { Name: 'PS', @@ -146,7 +149,7 @@ export const PS = { VerKey: 'Bls12381PSVerificationKeyDock2023', getParamsByDid: (api, did) => api.rpc.core_mods.psParamsByDid(did), getPublicKeyWithParamsByStorageKey: (api, storageKey) => api.rpc.core_mods.psPublicKeyWithParams(storageKey), - getPublicKeysByDid: (api, did) => api.rpc.core_mods.psPublicKeysByDid(did), + getPublicKeysByDid: (api, did) => api.rpc.core_mods.psPublicKeysByDid(did.asDid), }; export const AllSchemes = Object.setPrototypeOf({ BBS, BBSPlus, PS }, null); diff --git a/tests/unit/did.test.js b/tests/unit/did.test.js index 9494ce28b..f89a0886e 100644 --- a/tests/unit/did.test.js +++ b/tests/unit/did.test.js @@ -3,9 +3,15 @@ import { randomAsHex, encodeAddress } from '@polkadot/util-crypto'; import { validateDockDIDHexIdentifier, validateDockDIDSS58Identifier, - getHexIdentifierFromDID, - DockDIDQualifier, + DockDIDQualifier, DockDIDByteSize, DockDIDMethodKeyQualifier, } from '../../src/utils/did'; +import { getHexIdentifier } from '../../src/utils/codec'; + +const hexDid = (did) => getHexIdentifier( + did, + [DockDIDQualifier, DockDIDMethodKeyQualifier], + DockDIDByteSize, +); describe('DID utilities', () => { test('On input as 40 byte hex, validateDockDIDIdentifier throws error', () => { @@ -20,48 +26,48 @@ describe('DID utilities', () => { expect(() => validateDockDIDHexIdentifier(randomAsHex(32))).not.toThrow(); }); - test('On input as 33 byte hex, getHexIdentifierFromDID throws error', () => { + test('On input as 33 byte hex, hexDid throws error', () => { const hex = randomAsHex(33); - expect(() => getHexIdentifierFromDID(hex)).toThrow(/Invalid hex/); + expect(() => hexDid(hex)).toThrow(/Invalid hex/); }); - test('On input as 32 byte hex, getHexIdentifierFromDID returns the input', () => { + test('On input as 32 byte hex, hexDid returns the input', () => { const hex = randomAsHex(32); - expect(getHexIdentifierFromDID(hex)).toBe(hex); + expect(hexDid(hex)).toBe(hex); }); - test('On input valid SS58 but without qualifier, getHexIdentifierFromDID throws error', () => { + test('On input valid SS58 but without qualifier, hexDid throws error', () => { const hex = randomAsHex(32); const id = encodeAddress(hex); // Without the qualifier, the function tries to parse as hex - expect(() => getHexIdentifierFromDID(id)).toThrow(/Invalid hex/); + expect(() => hexDid(id)).toThrow(/Invalid hex/); }); - test('On input invalid SS58 but with qualifier, getHexIdentifierFromDID throws error', () => { + test('On input invalid SS58 but with qualifier, hexDid throws error', () => { const did = `${DockDIDQualifier}oO12`; // Without the qualifier, the function tries to parse as hex - expect(() => getHexIdentifierFromDID(did)).toThrow(/Invalid SS58/); + expect(() => hexDid(did)).toThrow(/Invalid SS58/); }); - test('On input fully qualified Dock DID, getHexIdentifierFromDID returns valid hex representation', () => { + test('On input fully qualified Dock DID, hexDid returns valid hex representation', () => { // create a valid DID const hex = randomAsHex(32); const did = `${DockDIDQualifier}${encodeAddress(hex)}`; - expect(getHexIdentifierFromDID(did)).toBe(hex); + expect(hexDid(did)).toBe(hex); }); - test('On input valid SS58 and with qualifier but smaller than 32 bytes, getHexIdentifierFromDID throws error', () => { + test('On input valid SS58 and with qualifier but smaller than 32 bytes, hexDid throws error', () => { const hex = randomAsHex(8); const did = `${DockDIDQualifier}${encodeAddress(hex)}`; // Without the qualifier, the function tries to parse as hex - expect(() => getHexIdentifierFromDID(did)).toThrow(/Invalid SS58/); + expect(() => hexDid(did)).toThrow(/Invalid SS58/); }); - test('On input valid SS58 and with qualifier but larger than 32 bytes, getHexIdentifierFromDID throws error', () => { + test('On input valid SS58 and with qualifier but larger than 32 bytes, hexDid throws error', () => { const ss58 = encodeAddress(randomAsHex(32)); const did = `${DockDIDQualifier}${ss58}${ss58}`; // Without the qualifier, the function tries to parse as hex - expect(() => getHexIdentifierFromDID(did)).toThrow(/Invalid SS58/); + expect(() => hexDid(did)).toThrow(/Invalid SS58/); }); test('On input valid SS58 identifier but smaller than 32 bytes, validateDockDIDSS58Identifier throws error', () => { diff --git a/tutorials/src/tutorial_blobs_schemas.md b/tutorials/src/tutorial_blobs_schemas.md index 04617391c..3dbc89fc6 100644 --- a/tutorials/src/tutorial_blobs_schemas.md +++ b/tutorials/src/tutorial_blobs_schemas.md @@ -31,7 +31,7 @@ const blobStruct = { id: blobId, blob: blobHexOrArray, // Contents of your blob as a hex string or byte array } -const result = await dock.blob.new(blobStruct, signerDid, keyPair, 1, { didModule: dock.didModule }); +const result = await dock.blob.new(blobStruct, signerDid, keypair, { didModule: dock.didModule }); ``` If everything worked properly `result` will indicate a successful transaction. We'll see how to retrieve the blob next. @@ -117,7 +117,7 @@ to be able to use it. That's where the `toBlob` method comes in handy: Writing a Schema to the Dock chain is similar to writing any other Blob. `1` is the key id for the on-chain public key corresponding to `keyPair` ```javascript > const formattedBlob = myNewSchema.toBlob(dockDID); -> await myNewSchema.writeToChain(dock, dockDID, keyPair, 1); +> await myNewSchema.writeToChain(dock, dockDID, keypair); ``` ### Reading a Schema from the Dock chain diff --git a/tutorials/src/tutorial_did.md b/tutorials/src/tutorial_did.md index 1c63411d9..2d07c3c2a 100644 --- a/tutorials/src/tutorial_did.md +++ b/tutorials/src/tutorial_did.md @@ -127,7 +127,7 @@ which 1 is greater than the last used index. Key indices start from 1. In the arguments, the first `did` specifies that a key must be added to DID `did` and the second `did` specifies that DID `did` is signing the payload The `1` below is for the key index. ```js - dock.did.addKeys([newDidKey], did, did, currentPair, 1, undefined, false); + dock.did.addKeys([newDidKey], did, did, currentpair, undefined, false); ``` ## Removing an existing DID from chain @@ -139,7 +139,7 @@ A DID can be removed from the chain by sending the corresponding message signed ``` 1. Now send the message with the signature to the chain in a transaction ```js - dock.did.remove(did, did, pair, 1) + dock.did.remove(did, did, pair) ``` For more details see example in `examples/dock-did.js` or the integration tests. diff --git a/tutorials/src/tutorial_revocation.md b/tutorials/src/tutorial_revocation.md index 1bb116401..c76ed4cb6 100644 --- a/tutorials/src/tutorial_revocation.md +++ b/tutorials/src/tutorial_revocation.md @@ -43,7 +43,7 @@ Now get the registry id, `registryId` and the revocation id (the hash of credent Revoking an already revoked credential has no effect. ```js -await dock.revocation.revokeCredentialWithOneOfPolicy(registryId, revokeId, ownerDID, ownerKeypair, 1, {didModule: dock.did}); +await dock.revocation.revokeCredentialWithOneOfPolicy(registryId, revokeId, ownerDID, ownerKeypair, {didModule: dock.did}); ``` Revoking multiple ids in a single transaction is possible but with a lower level method `dock.revocation.revoke`. See tests for its usage @@ -54,7 +54,7 @@ Get the registry id, `registryId` and the revocation id to undo, `revokeId` and Unrevoking an unrevoked credential has no effect. ```js -await dock.revocation.unrevokeCredentialWithOneOfPolicy(registryId, revokeId, ownerDID, ownerKeypair, 1, {didModule: dock.did}); +await dock.revocation.unrevokeCredentialWithOneOfPolicy(registryId, revokeId, ownerDID, ownerKeypair, {didModule: dock.did}); ``` Undoing revocation for multiple ids in a single transaction is possible but with a lower level method `dock.revocation.unrevoke`. See tests for its usage @@ -72,5 +72,5 @@ To get the details of the registry like policy, add-only status and block number A registry can be deleted leading to all the corresponding revocation ids being deleted as well. This requires the signature from owner like other updates. Use the `dock.revocation.removeRegistry` method to remove a registry. ```js -await dock.revocation.removeRegistryWithOneOfPolicy(registryId, ownerDID, ownerKeypair, 1, {didModule: dock.did}, false); +await dock.revocation.removeRegistryWithOneOfPolicy(registryId, ownerDID, ownerKeypair, {didModule: dock.did}, false); ```