From bcfc198dbd81062a6d1a9cd8afc6ec16cf15c460 Mon Sep 17 00:00:00 2001 From: Tasos <50984242+Eengineer1@users.noreply.github.com> Date: Thu, 21 Jul 2022 19:40:03 +0300 Subject: [PATCH] feat(did): Added automated did creation tests & fixes, refactors --- package-lock.json | 322 ++++++++++++++++++++++++++++++++++---- package.json | 4 + src/modules/did.ts | 33 +++- src/signer.ts | 160 +++++++++++++++++-- src/types.ts | 8 + tests/modules/did.test.ts | 57 +++++++ tests/signer.test.ts | 48 ++++-- tests/testutils.test.ts | 24 ++- 8 files changed, 594 insertions(+), 62 deletions(-) create mode 100644 tests/modules/did.test.ts diff --git a/package-lock.json b/package-lock.json index 11e22620..6cd7fe3f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,9 +10,13 @@ "license": "Apache-2.0", "dependencies": { "@cheqd/ts-proto": "^1.0.1", + "@cosmjs/amino": "^0.28.11", + "@cosmjs/encoding": "^0.28.11", + "@cosmjs/math": "^0.28.11", "@cosmjs/proto-signing": "^0.28.10", "@cosmjs/stargate": "^0.28.10", "@cosmjs/tendermint-rpc": "^0.28.10", + "@cosmjs/utils": "^0.28.11", "@stablelib/ed25519": "^1.0.2", "cosmjs-types": "^0.5.0", "did-jwt": "^6.2.0", @@ -597,14 +601,28 @@ } }, "node_modules/@cosmjs/amino": { - "version": "0.28.10", - "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.28.10.tgz", - "integrity": "sha512-z6o0ygmO5mlpeT65MhLlnfIbZqP/1xPeMUOfJcibfk32dM+aK3JbqJuwQcE8Og95vPcNlYNNrzqokIwUpO6/xw==", + "version": "0.28.11", + "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.28.11.tgz", + "integrity": "sha512-WJkQQq8gbk5doJJ/3Gcax26I+VC4HdbbSlNdyT5hc6T+U2Jmyry9RLSE+wEZyFMgEabhr43SbIxf64gWZeR8YA==", "dependencies": { - "@cosmjs/crypto": "0.28.10", - "@cosmjs/encoding": "0.28.10", - "@cosmjs/math": "0.28.10", - "@cosmjs/utils": "0.28.10" + "@cosmjs/crypto": "0.28.11", + "@cosmjs/encoding": "0.28.11", + "@cosmjs/math": "0.28.11", + "@cosmjs/utils": "0.28.11" + } + }, + "node_modules/@cosmjs/amino/node_modules/@cosmjs/crypto": { + "version": "0.28.11", + "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.28.11.tgz", + "integrity": "sha512-oJXOeBX4FP8bp0ZVydJFcRplErHp8cC6vNoULRck+7hcLuvp9tyv3SBOkBkwxTv81VcQyGCgn7WE0NYEKrpUbw==", + "dependencies": { + "@cosmjs/encoding": "0.28.11", + "@cosmjs/math": "0.28.11", + "@cosmjs/utils": "0.28.11", + "@noble/hashes": "^1", + "bn.js": "^5.2.0", + "elliptic": "^6.5.3", + "libsodium-wrappers": "^0.7.6" } }, "node_modules/@cosmjs/crypto": { @@ -621,7 +639,7 @@ "libsodium-wrappers": "^0.7.6" } }, - "node_modules/@cosmjs/encoding": { + "node_modules/@cosmjs/crypto/node_modules/@cosmjs/encoding": { "version": "0.28.10", "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.28.10.tgz", "integrity": "sha512-jxb5V40jS1F+sGjtGbNybyruEjZ+/ILkhx63g3ZRHzeo0SQilpepg6hRzmGT3+OFNBBjr92wIEZMVRV+qbm5wQ==", @@ -631,6 +649,29 @@ "readonly-date": "^1.0.0" } }, + "node_modules/@cosmjs/crypto/node_modules/@cosmjs/math": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.28.10.tgz", + "integrity": "sha512-XSpoPy+rf4ddX9xP+0EpVQHqApLIm7M2IqYl/EDPaSKJAd1r3PNVsj/Yl0Eb57TuGyEfN5SyswSHpSCJxF15zw==", + "dependencies": { + "bn.js": "^5.2.0" + } + }, + "node_modules/@cosmjs/crypto/node_modules/@cosmjs/utils": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.28.10.tgz", + "integrity": "sha512-S0t2kFRiAo1MvIrbXlfrGdsn2D3PApyO1d+GCze14Cg4QOOGWDcTsd6VhHcxKhETO1Z9ofEhE4soJ8ZldBlnpg==" + }, + "node_modules/@cosmjs/encoding": { + "version": "0.28.11", + "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.28.11.tgz", + "integrity": "sha512-J7pvlzAt8hBZn316wGRmUlK3xwMgNXUvj4v56DK4fA0fv6VfGwMvVtHCXaqNQtzOGkC6EQcshzA/fL5MBIwu6A==", + "dependencies": { + "base64-js": "^1.3.0", + "bech32": "^1.1.4", + "readonly-date": "^1.0.0" + } + }, "node_modules/@cosmjs/json-rpc": { "version": "0.28.10", "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.28.10.tgz", @@ -641,9 +682,9 @@ } }, "node_modules/@cosmjs/math": { - "version": "0.28.10", - "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.28.10.tgz", - "integrity": "sha512-XSpoPy+rf4ddX9xP+0EpVQHqApLIm7M2IqYl/EDPaSKJAd1r3PNVsj/Yl0Eb57TuGyEfN5SyswSHpSCJxF15zw==", + "version": "0.28.11", + "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.28.11.tgz", + "integrity": "sha512-MyhPnC4sYu86c2/0PpEeynaPl4nvAmLZH3acPh96SzcjERONbGZjjKtBFPq1avBrev2CCSPrZ4O8u9xpQ4aSvg==", "dependencies": { "bn.js": "^5.2.0" } @@ -662,6 +703,40 @@ "long": "^4.0.0" } }, + "node_modules/@cosmjs/proto-signing/node_modules/@cosmjs/amino": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.28.10.tgz", + "integrity": "sha512-z6o0ygmO5mlpeT65MhLlnfIbZqP/1xPeMUOfJcibfk32dM+aK3JbqJuwQcE8Og95vPcNlYNNrzqokIwUpO6/xw==", + "dependencies": { + "@cosmjs/crypto": "0.28.10", + "@cosmjs/encoding": "0.28.10", + "@cosmjs/math": "0.28.10", + "@cosmjs/utils": "0.28.10" + } + }, + "node_modules/@cosmjs/proto-signing/node_modules/@cosmjs/encoding": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.28.10.tgz", + "integrity": "sha512-jxb5V40jS1F+sGjtGbNybyruEjZ+/ILkhx63g3ZRHzeo0SQilpepg6hRzmGT3+OFNBBjr92wIEZMVRV+qbm5wQ==", + "dependencies": { + "base64-js": "^1.3.0", + "bech32": "^1.1.4", + "readonly-date": "^1.0.0" + } + }, + "node_modules/@cosmjs/proto-signing/node_modules/@cosmjs/math": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.28.10.tgz", + "integrity": "sha512-XSpoPy+rf4ddX9xP+0EpVQHqApLIm7M2IqYl/EDPaSKJAd1r3PNVsj/Yl0Eb57TuGyEfN5SyswSHpSCJxF15zw==", + "dependencies": { + "bn.js": "^5.2.0" + } + }, + "node_modules/@cosmjs/proto-signing/node_modules/@cosmjs/utils": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.28.10.tgz", + "integrity": "sha512-S0t2kFRiAo1MvIrbXlfrGdsn2D3PApyO1d+GCze14Cg4QOOGWDcTsd6VhHcxKhETO1Z9ofEhE4soJ8ZldBlnpg==" + }, "node_modules/@cosmjs/proto-signing/node_modules/cosmjs-types": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.4.1.tgz", @@ -701,6 +776,40 @@ "xstream": "^11.14.0" } }, + "node_modules/@cosmjs/stargate/node_modules/@cosmjs/amino": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.28.10.tgz", + "integrity": "sha512-z6o0ygmO5mlpeT65MhLlnfIbZqP/1xPeMUOfJcibfk32dM+aK3JbqJuwQcE8Og95vPcNlYNNrzqokIwUpO6/xw==", + "dependencies": { + "@cosmjs/crypto": "0.28.10", + "@cosmjs/encoding": "0.28.10", + "@cosmjs/math": "0.28.10", + "@cosmjs/utils": "0.28.10" + } + }, + "node_modules/@cosmjs/stargate/node_modules/@cosmjs/encoding": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.28.10.tgz", + "integrity": "sha512-jxb5V40jS1F+sGjtGbNybyruEjZ+/ILkhx63g3ZRHzeo0SQilpepg6hRzmGT3+OFNBBjr92wIEZMVRV+qbm5wQ==", + "dependencies": { + "base64-js": "^1.3.0", + "bech32": "^1.1.4", + "readonly-date": "^1.0.0" + } + }, + "node_modules/@cosmjs/stargate/node_modules/@cosmjs/math": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.28.10.tgz", + "integrity": "sha512-XSpoPy+rf4ddX9xP+0EpVQHqApLIm7M2IqYl/EDPaSKJAd1r3PNVsj/Yl0Eb57TuGyEfN5SyswSHpSCJxF15zw==", + "dependencies": { + "bn.js": "^5.2.0" + } + }, + "node_modules/@cosmjs/stargate/node_modules/@cosmjs/utils": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.28.10.tgz", + "integrity": "sha512-S0t2kFRiAo1MvIrbXlfrGdsn2D3PApyO1d+GCze14Cg4QOOGWDcTsd6VhHcxKhETO1Z9ofEhE4soJ8ZldBlnpg==" + }, "node_modules/@cosmjs/stargate/node_modules/cosmjs-types": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.4.1.tgz", @@ -735,11 +844,34 @@ "xstream": "^11.14.0" } }, - "node_modules/@cosmjs/utils": { + "node_modules/@cosmjs/tendermint-rpc/node_modules/@cosmjs/encoding": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.28.10.tgz", + "integrity": "sha512-jxb5V40jS1F+sGjtGbNybyruEjZ+/ILkhx63g3ZRHzeo0SQilpepg6hRzmGT3+OFNBBjr92wIEZMVRV+qbm5wQ==", + "dependencies": { + "base64-js": "^1.3.0", + "bech32": "^1.1.4", + "readonly-date": "^1.0.0" + } + }, + "node_modules/@cosmjs/tendermint-rpc/node_modules/@cosmjs/math": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.28.10.tgz", + "integrity": "sha512-XSpoPy+rf4ddX9xP+0EpVQHqApLIm7M2IqYl/EDPaSKJAd1r3PNVsj/Yl0Eb57TuGyEfN5SyswSHpSCJxF15zw==", + "dependencies": { + "bn.js": "^5.2.0" + } + }, + "node_modules/@cosmjs/tendermint-rpc/node_modules/@cosmjs/utils": { "version": "0.28.10", "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.28.10.tgz", "integrity": "sha512-S0t2kFRiAo1MvIrbXlfrGdsn2D3PApyO1d+GCze14Cg4QOOGWDcTsd6VhHcxKhETO1Z9ofEhE4soJ8ZldBlnpg==" }, + "node_modules/@cosmjs/utils": { + "version": "0.28.11", + "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.28.11.tgz", + "integrity": "sha512-FXVEr7Pg6MX9VbY5NemuKbtFVabSlUlArWIV+R74FQg5LIuSa+0QkxSpNldCuOLBEU4/GlrzybT4uEl338vSzg==" + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -4832,14 +4964,30 @@ } }, "@cosmjs/amino": { - "version": "0.28.10", - "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.28.10.tgz", - "integrity": "sha512-z6o0ygmO5mlpeT65MhLlnfIbZqP/1xPeMUOfJcibfk32dM+aK3JbqJuwQcE8Og95vPcNlYNNrzqokIwUpO6/xw==", + "version": "0.28.11", + "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.28.11.tgz", + "integrity": "sha512-WJkQQq8gbk5doJJ/3Gcax26I+VC4HdbbSlNdyT5hc6T+U2Jmyry9RLSE+wEZyFMgEabhr43SbIxf64gWZeR8YA==", "requires": { - "@cosmjs/crypto": "0.28.10", - "@cosmjs/encoding": "0.28.10", - "@cosmjs/math": "0.28.10", - "@cosmjs/utils": "0.28.10" + "@cosmjs/crypto": "0.28.11", + "@cosmjs/encoding": "0.28.11", + "@cosmjs/math": "0.28.11", + "@cosmjs/utils": "0.28.11" + }, + "dependencies": { + "@cosmjs/crypto": { + "version": "0.28.11", + "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.28.11.tgz", + "integrity": "sha512-oJXOeBX4FP8bp0ZVydJFcRplErHp8cC6vNoULRck+7hcLuvp9tyv3SBOkBkwxTv81VcQyGCgn7WE0NYEKrpUbw==", + "requires": { + "@cosmjs/encoding": "0.28.11", + "@cosmjs/math": "0.28.11", + "@cosmjs/utils": "0.28.11", + "@noble/hashes": "^1", + "bn.js": "^5.2.0", + "elliptic": "^6.5.3", + "libsodium-wrappers": "^0.7.6" + } + } } }, "@cosmjs/crypto": { @@ -4854,12 +5002,37 @@ "bn.js": "^5.2.0", "elliptic": "^6.5.3", "libsodium-wrappers": "^0.7.6" + }, + "dependencies": { + "@cosmjs/encoding": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.28.10.tgz", + "integrity": "sha512-jxb5V40jS1F+sGjtGbNybyruEjZ+/ILkhx63g3ZRHzeo0SQilpepg6hRzmGT3+OFNBBjr92wIEZMVRV+qbm5wQ==", + "requires": { + "base64-js": "^1.3.0", + "bech32": "^1.1.4", + "readonly-date": "^1.0.0" + } + }, + "@cosmjs/math": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.28.10.tgz", + "integrity": "sha512-XSpoPy+rf4ddX9xP+0EpVQHqApLIm7M2IqYl/EDPaSKJAd1r3PNVsj/Yl0Eb57TuGyEfN5SyswSHpSCJxF15zw==", + "requires": { + "bn.js": "^5.2.0" + } + }, + "@cosmjs/utils": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.28.10.tgz", + "integrity": "sha512-S0t2kFRiAo1MvIrbXlfrGdsn2D3PApyO1d+GCze14Cg4QOOGWDcTsd6VhHcxKhETO1Z9ofEhE4soJ8ZldBlnpg==" + } } }, "@cosmjs/encoding": { - "version": "0.28.10", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.28.10.tgz", - "integrity": "sha512-jxb5V40jS1F+sGjtGbNybyruEjZ+/ILkhx63g3ZRHzeo0SQilpepg6hRzmGT3+OFNBBjr92wIEZMVRV+qbm5wQ==", + "version": "0.28.11", + "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.28.11.tgz", + "integrity": "sha512-J7pvlzAt8hBZn316wGRmUlK3xwMgNXUvj4v56DK4fA0fv6VfGwMvVtHCXaqNQtzOGkC6EQcshzA/fL5MBIwu6A==", "requires": { "base64-js": "^1.3.0", "bech32": "^1.1.4", @@ -4876,9 +5049,9 @@ } }, "@cosmjs/math": { - "version": "0.28.10", - "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.28.10.tgz", - "integrity": "sha512-XSpoPy+rf4ddX9xP+0EpVQHqApLIm7M2IqYl/EDPaSKJAd1r3PNVsj/Yl0Eb57TuGyEfN5SyswSHpSCJxF15zw==", + "version": "0.28.11", + "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.28.11.tgz", + "integrity": "sha512-MyhPnC4sYu86c2/0PpEeynaPl4nvAmLZH3acPh96SzcjERONbGZjjKtBFPq1avBrev2CCSPrZ4O8u9xpQ4aSvg==", "requires": { "bn.js": "^5.2.0" } @@ -4897,6 +5070,40 @@ "long": "^4.0.0" }, "dependencies": { + "@cosmjs/amino": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.28.10.tgz", + "integrity": "sha512-z6o0ygmO5mlpeT65MhLlnfIbZqP/1xPeMUOfJcibfk32dM+aK3JbqJuwQcE8Og95vPcNlYNNrzqokIwUpO6/xw==", + "requires": { + "@cosmjs/crypto": "0.28.10", + "@cosmjs/encoding": "0.28.10", + "@cosmjs/math": "0.28.10", + "@cosmjs/utils": "0.28.10" + } + }, + "@cosmjs/encoding": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.28.10.tgz", + "integrity": "sha512-jxb5V40jS1F+sGjtGbNybyruEjZ+/ILkhx63g3ZRHzeo0SQilpepg6hRzmGT3+OFNBBjr92wIEZMVRV+qbm5wQ==", + "requires": { + "base64-js": "^1.3.0", + "bech32": "^1.1.4", + "readonly-date": "^1.0.0" + } + }, + "@cosmjs/math": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.28.10.tgz", + "integrity": "sha512-XSpoPy+rf4ddX9xP+0EpVQHqApLIm7M2IqYl/EDPaSKJAd1r3PNVsj/Yl0Eb57TuGyEfN5SyswSHpSCJxF15zw==", + "requires": { + "bn.js": "^5.2.0" + } + }, + "@cosmjs/utils": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.28.10.tgz", + "integrity": "sha512-S0t2kFRiAo1MvIrbXlfrGdsn2D3PApyO1d+GCze14Cg4QOOGWDcTsd6VhHcxKhETO1Z9ofEhE4soJ8ZldBlnpg==" + }, "cosmjs-types": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.4.1.tgz", @@ -4938,6 +5145,40 @@ "xstream": "^11.14.0" }, "dependencies": { + "@cosmjs/amino": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.28.10.tgz", + "integrity": "sha512-z6o0ygmO5mlpeT65MhLlnfIbZqP/1xPeMUOfJcibfk32dM+aK3JbqJuwQcE8Og95vPcNlYNNrzqokIwUpO6/xw==", + "requires": { + "@cosmjs/crypto": "0.28.10", + "@cosmjs/encoding": "0.28.10", + "@cosmjs/math": "0.28.10", + "@cosmjs/utils": "0.28.10" + } + }, + "@cosmjs/encoding": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.28.10.tgz", + "integrity": "sha512-jxb5V40jS1F+sGjtGbNybyruEjZ+/ILkhx63g3ZRHzeo0SQilpepg6hRzmGT3+OFNBBjr92wIEZMVRV+qbm5wQ==", + "requires": { + "base64-js": "^1.3.0", + "bech32": "^1.1.4", + "readonly-date": "^1.0.0" + } + }, + "@cosmjs/math": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.28.10.tgz", + "integrity": "sha512-XSpoPy+rf4ddX9xP+0EpVQHqApLIm7M2IqYl/EDPaSKJAd1r3PNVsj/Yl0Eb57TuGyEfN5SyswSHpSCJxF15zw==", + "requires": { + "bn.js": "^5.2.0" + } + }, + "@cosmjs/utils": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.28.10.tgz", + "integrity": "sha512-S0t2kFRiAo1MvIrbXlfrGdsn2D3PApyO1d+GCze14Cg4QOOGWDcTsd6VhHcxKhETO1Z9ofEhE4soJ8ZldBlnpg==" + }, "cosmjs-types": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.4.1.tgz", @@ -4972,12 +5213,37 @@ "axios": "^0.21.2", "readonly-date": "^1.0.0", "xstream": "^11.14.0" + }, + "dependencies": { + "@cosmjs/encoding": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.28.10.tgz", + "integrity": "sha512-jxb5V40jS1F+sGjtGbNybyruEjZ+/ILkhx63g3ZRHzeo0SQilpepg6hRzmGT3+OFNBBjr92wIEZMVRV+qbm5wQ==", + "requires": { + "base64-js": "^1.3.0", + "bech32": "^1.1.4", + "readonly-date": "^1.0.0" + } + }, + "@cosmjs/math": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.28.10.tgz", + "integrity": "sha512-XSpoPy+rf4ddX9xP+0EpVQHqApLIm7M2IqYl/EDPaSKJAd1r3PNVsj/Yl0Eb57TuGyEfN5SyswSHpSCJxF15zw==", + "requires": { + "bn.js": "^5.2.0" + } + }, + "@cosmjs/utils": { + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.28.10.tgz", + "integrity": "sha512-S0t2kFRiAo1MvIrbXlfrGdsn2D3PApyO1d+GCze14Cg4QOOGWDcTsd6VhHcxKhETO1Z9ofEhE4soJ8ZldBlnpg==" + } } }, "@cosmjs/utils": { - "version": "0.28.10", - "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.28.10.tgz", - "integrity": "sha512-S0t2kFRiAo1MvIrbXlfrGdsn2D3PApyO1d+GCze14Cg4QOOGWDcTsd6VhHcxKhETO1Z9ofEhE4soJ8ZldBlnpg==" + "version": "0.28.11", + "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.28.11.tgz", + "integrity": "sha512-FXVEr7Pg6MX9VbY5NemuKbtFVabSlUlArWIV+R74FQg5LIuSa+0QkxSpNldCuOLBEU4/GlrzybT4uEl338vSzg==" }, "@cspotcode/source-map-support": { "version": "0.8.1", diff --git a/package.json b/package.json index 7ca88614..3bebcf36 100644 --- a/package.json +++ b/package.json @@ -34,9 +34,13 @@ }, "dependencies": { "@cheqd/ts-proto": "^1.0.1", + "@cosmjs/amino": "^0.28.11", + "@cosmjs/encoding": "^0.28.11", + "@cosmjs/math": "^0.28.11", "@cosmjs/proto-signing": "^0.28.10", "@cosmjs/stargate": "^0.28.10", "@cosmjs/tendermint-rpc": "^0.28.10", + "@cosmjs/utils": "^0.28.11", "@stablelib/ed25519": "^1.0.2", "cosmjs-types": "^0.5.0", "did-jwt": "^6.2.0", diff --git a/src/modules/did.ts b/src/modules/did.ts index 62fcb93e..19c7ac4c 100644 --- a/src/modules/did.ts +++ b/src/modules/did.ts @@ -1,8 +1,11 @@ -import { createProtobufRpcClient, DeliverTxResponse, QueryClient } from "@cosmjs/stargate" +import { createProtobufRpcClient, DeliverTxResponse, QueryClient, StdFee } from "@cosmjs/stargate" /* import { QueryClientImpl } from '@cheqd/ts-proto/cheqd/v1/query' */ import { CheqdExtension, AbstractCheqdSDKModule, MinimalImportableCheqdSDKModule } from "./_" import { CheqdSigningStargateClient } from "../signer" -import { IContext } from "../types" +import { DidStdFee, IContext, ISignInputs } from "../types" +import { MsgCreateDid, MsgCreateDidPayload } from "@cheqd/ts-proto/cheqd/v1/tx" +import { MsgCreateDidEncodeObject, typeUrlMsgCreateDid } from "../registry" +import { VerificationMethod } from "@cheqd/ts-proto/cheqd/v1/did" export class DIDModule extends AbstractCheqdSDKModule { constructor(signer: CheqdSigningStargateClient){ @@ -13,11 +16,33 @@ export class DIDModule extends AbstractCheqdSDKModule { } } - async createDidTx(did: string, publicKey: string, context?: IContext): Promise { + async createDidTx(signInputs: ISignInputs[], didPayload: Partial, address: string, fee: DidStdFee | 'auto' | number, memo?: string, context?: IContext): Promise { if (!this._signer) { this._signer = context!.sdk!.signer } - return '' + + const payload = MsgCreateDidPayload.fromPartial(didPayload) + const signatures = await this._signer.signDidTx(signInputs, payload) + + console.warn(payload) + console.warn(signatures) + + const value: MsgCreateDid = { + payload, + signatures + } + + const createDidMsg: MsgCreateDidEncodeObject = { + typeUrl: typeUrlMsgCreateDid, + value + } + + return this._signer.signAndBroadcast( + address, + [createDidMsg], + fee, + memo + ) } async updateDidTx(did: string, publicKey: string): Promise { diff --git a/src/signer.ts b/src/signer.ts index 490531ee..68c3cba3 100644 --- a/src/signer.ts +++ b/src/signer.ts @@ -1,24 +1,73 @@ -import { CheqdExtensions, setupCheqdExtensions } from './modules/_' -import { EncodeObject, OfflineSigner } from "@cosmjs/proto-signing"; -import { DeliverTxResponse, HttpEndpoint, QueryClient, SigningStargateClient, SigningStargateClientOptions, StdFee } from "@cosmjs/stargate"; -import { Tendermint34Client } from "@cosmjs/tendermint-rpc"; -import { createDefaultCheqdRegistry } from "./registry"; -import { MsgCreateDidPayload, SignInfo } from '@cheqd/ts-proto/cheqd/v1/tx'; -import { ISignInputs, TSignerAlgo, VerificationMethods } from './types'; -import { VerificationMethod } from '@cheqd/ts-proto/cheqd/v1/did'; -import { EdDSASigner, hexToBytes, Signer } from 'did-jwt'; +import { CheqdExtensions } from './modules/_' +import { EncodeObject, isOfflineDirectSigner, OfflineSigner, encodePubkey, TxBodyEncodeObject, makeAuthInfoBytes, makeSignDoc } from "@cosmjs/proto-signing" +import { DeliverTxResponse, GasPrice, HttpEndpoint, QueryClient, SigningStargateClient, SigningStargateClientOptions, StdFee, calculateFee, SignerData } from "@cosmjs/stargate" +import { Tendermint34Client } from "@cosmjs/tendermint-rpc" +import { createDefaultCheqdRegistry } from "./registry" +import { MsgCreateDidPayload, SignInfo } from '@cheqd/ts-proto/cheqd/v1/tx' +import { DidStdFee, ISignInputs, TSignerAlgo, VerificationMethods } from './types' +import { VerificationMethod } from '@cheqd/ts-proto/cheqd/v1/did' +import { base64ToBytes, EdDSASigner, hexToBytes, Signer } from 'did-jwt' +import { toString } from 'uint8arrays' +import { assert, assertDefined } from '@cosmjs/utils' +import { encodeSecp256k1Pubkey } from '@cosmjs/amino' +import { Int53 } from '@cosmjs/math' +import { fromBase64 } from '@cosmjs/encoding' +import { AuthInfo, SignerInfo, TxRaw } from 'cosmjs-types/cosmos/tx/v1beta1/tx' +import { SignMode } from 'cosmjs-types/cosmos/tx/signing/v1beta1/signing' +import { Any } from 'cosmjs-types/google/protobuf/any' +import { Coin } from 'cosmjs-types/cosmos/base/v1beta1/coin' +import Long from 'long' + +export function calculateDidFee(gasLimit: number, gasPrice: string | GasPrice): DidStdFee { + return calculateFee(gasLimit, gasPrice) +} + +export function makeSignerInfos( + signers: ReadonlyArray<{ readonly pubkey: Any; readonly sequence: number }>, + signMode: SignMode, +): SignerInfo[] { + return signers.map( + ({ pubkey, sequence }): SignerInfo => ({ + publicKey: pubkey, + modeInfo: { + single: { mode: signMode }, + }, + sequence: Long.fromNumber(sequence), + }), + ); +} + +export function makeDidAuthInfoBytes( + signers: ReadonlyArray<{ readonly pubkey: Any; readonly sequence: number }>, + feeAmount: readonly Coin[], + gasLimit: number, + feePayer: string, + signMode = SignMode.SIGN_MODE_DIRECT, +): Uint8Array { + const authInfo = { + signerInfos: makeSignerInfos(signers, signMode), + fee: { + amount: [...feeAmount], + gasLimit: Long.fromNumber(gasLimit), + payer: feePayer + } + } + return AuthInfo.encode(AuthInfo.fromPartial(authInfo)).finish() +} export class CheqdSigningStargateClient extends SigningStargateClient { public readonly cheqdExtensions: CheqdExtensions | undefined private didSigners: TSignerAlgo = {} + private readonly _gasPrice: GasPrice | undefined + private readonly _signer: OfflineSigner public static async connectWithSigner(endpoint: string | HttpEndpoint, signer: OfflineSigner, options?: SigningStargateClientOptions | undefined): Promise { const tmClient = await Tendermint34Client.connect(endpoint) return new CheqdSigningStargateClient(tmClient, signer, { registry: createDefaultCheqdRegistry(), ...options - }); + }) } constructor( @@ -27,6 +76,8 @@ export class CheqdSigningStargateClient extends SigningStargateClient { options: SigningStargateClientOptions = {} ) { super(tmClient, signer, options) + this._signer = signer + if (options.gasPrice) this._gasPrice = options.gasPrice /** GRPC Connection */ @@ -60,14 +111,99 @@ export class CheqdSigningStargateClient extends SigningStargateClient { return this.didSigners[verificationMethod] ?? EdDSASigner } - async signDIDTx(signInputs: ISignInputs[], payload: MsgCreateDidPayload): Promise { + async signAndBroadcast( + signerAddress: string, + messages: readonly EncodeObject[], + fee: DidStdFee | "auto" | number, + memo = "", + ): Promise { + let usedFee: DidStdFee + if (fee == "auto" || typeof fee === "number") { + assertDefined(this._gasPrice, "Gas price must be set in the client options when auto gas is used.") + const gasEstimation = await this.simulate(signerAddress, messages, memo) + const multiplier = typeof fee === "number" ? fee : 1.3 + usedFee = calculateDidFee(Math.round(gasEstimation * multiplier), this._gasPrice) + usedFee.payer = signerAddress + } else { + usedFee = fee + assertDefined(usedFee.payer, "Payer address must be set when fee is not auto.") + signerAddress = usedFee.payer! + } + const txRaw = await this.sign(signerAddress, messages, usedFee, memo) + const txBytes = TxRaw.encode(txRaw).finish() + return this.broadcastTx(txBytes, this.broadcastTimeoutMs, this.broadcastPollIntervalMs) + } + + public async sign( + signerAddress: string, + messages: readonly EncodeObject[], + fee: DidStdFee, + memo: string, + explicitSignerData?: SignerData, + ): Promise { + let signerData: SignerData + if (explicitSignerData) { + signerData = explicitSignerData + } else { + const { accountNumber, sequence } = await this.getSequence(signerAddress) + const chainId = await this.getChainId() + signerData = { + accountNumber: accountNumber, + sequence: sequence, + chainId: chainId, + } + } + + return this._signDirect(signerAddress, messages, fee, memo, signerData) + + // TODO: override signAmino as well + /* return isOfflineDirectSigner(this._signer) + ? this._signDirect(signerAddress, messages, fee, memo, signerData) + : this._signAmino(signerAddress, messages, fee, memo, signerData) */ + } + + private async _signDirect( + signerAddress: string, + messages: readonly EncodeObject[], + fee: DidStdFee, + memo: string, + { accountNumber, sequence, chainId }: SignerData, + ): Promise { + assert(isOfflineDirectSigner(this._signer)) + const accountFromSigner = (await this._signer.getAccounts()).find( + (account) => account.address === signerAddress, + ) + if (!accountFromSigner) { + throw new Error("Failed to retrieve account from signer") + } + const pubkey = encodePubkey(encodeSecp256k1Pubkey(accountFromSigner.pubkey)) + const txBodyEncodeObject: TxBodyEncodeObject = { + typeUrl: "/cosmos.tx.v1beta1.TxBody", + value: { + messages: messages, + memo: memo, + }, + } + const txBodyBytes = this.registry.encode(txBodyEncodeObject) + const gasLimit = Int53.fromString(fee.gas).toNumber() + const authInfoBytes = makeDidAuthInfoBytes([{ pubkey, sequence }], fee.amount, gasLimit, fee.payer!) + const signDoc = makeSignDoc(txBodyBytes, authInfoBytes, chainId, accountNumber) + const { signature, signed } = await this._signer.signDirect(signerAddress, signDoc) + return TxRaw.fromPartial({ + bodyBytes: signed.bodyBytes, + authInfoBytes: signed.authInfoBytes, + signatures: [fromBase64(signature.signature)], + }) + } + + async signDidTx(signInputs: ISignInputs[], payload: MsgCreateDidPayload): Promise { await this.checkDidSigners(payload?.verificationMethod) const signBytes = MsgCreateDidPayload.encode(payload).finish() const signInfos: SignInfo[] = await Promise.all(signInputs.map(async (signInput) => { return { verificationMethodId: signInput.verificationMethodId, - signature: await (await this.getDidSigner(signInput.verificationMethodId, payload.verificationMethod))(hexToBytes(signInput.privateKeyHex))(signBytes) as string + signature: toString(base64ToBytes((await (await this.getDidSigner(signInput.verificationMethodId, payload.verificationMethod))(hexToBytes(signInput.privateKeyHex))(signBytes)) as string), 'base64pad') } })) diff --git a/src/types.ts b/src/types.ts index 287e6534..d3d8d726 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,6 @@ import { CheqdSDK } from "." import { EdDSASigner, Signer } from 'did-jwt' +import { Coin } from "@cosmjs/proto-signing" export enum CheqdNetwork { Mainnet = 'mainnet', @@ -38,4 +39,11 @@ export interface IKeyPair { export interface IKeyValuePair { key: string value: any +} + +export interface DidStdFee { + readonly amount: readonly Coin[] + readonly gas: string + payer?: string + granter?: string } \ No newline at end of file diff --git a/tests/modules/did.test.ts b/tests/modules/did.test.ts new file mode 100644 index 00000000..c16d178b --- /dev/null +++ b/tests/modules/did.test.ts @@ -0,0 +1,57 @@ +import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing" +import { DeliverTxResponse } from "@cosmjs/stargate" +import { fromString, toString } from 'uint8arrays' +import { DIDModule } from "../../src" +import { CheqdSigningStargateClient } from "../../src/signer" +import { CheqdNetwork, DidStdFee, ISignInputs, VerificationMethods } from "../../src/types" +import { createDidPayload, createKeyPairBase64, exampleCheqdNetwork, faucet } from "../testutils.test" + + +describe('DIDModule', () => { + describe('constructor', () => { + it('should instantiate standalone module', async () => { + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic) + const signer = await CheqdSigningStargateClient.connectWithSigner(exampleCheqdNetwork.rpcUrl, wallet) + const didModule = new DIDModule(signer) + expect(didModule).toBeInstanceOf(DIDModule) + }) + }) + + describe('createDidTx', () => { + it('should create a new DID', async () => { + jest.setTimeout(10000) + + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic, {prefix: faucet.prefix}) + const signer = await CheqdSigningStargateClient.connectWithSigner(exampleCheqdNetwork.rpcUrl, wallet) + const didModule = new DIDModule(signer) + const keyPair = createKeyPairBase64() + const didPayload = createDidPayload(keyPair, VerificationMethods.JWK, CheqdNetwork.Testnet) + const signInputs: ISignInputs[] = [ + { + verificationMethodId: didPayload.verificationMethod[0].id, + privateKeyHex: toString(fromString(keyPair.privateKey, 'base64'), 'hex') + } + ] + const fee: DidStdFee = { + amount: [ + { + denom: 'ncheq', + amount: '5000000' + } + ], + gas: '100000', + payer: (await wallet.getAccounts())[0].address + } + const didTx: DeliverTxResponse = await didModule.createDidTx( + signInputs, + didPayload, + (await wallet.getAccounts())[0].address, + fee + ) + + console.warn(didTx) + + expect(didTx.code).toBe(0) + }) + }) +}) \ No newline at end of file diff --git a/tests/signer.test.ts b/tests/signer.test.ts index 37913d12..b053c0a2 100644 --- a/tests/signer.test.ts +++ b/tests/signer.test.ts @@ -1,11 +1,13 @@ import { VerificationMethod } from "@cheqd/ts-proto/cheqd/v1/did" -import { MsgCreateDid } from "@cheqd/ts-proto/cheqd/v1/tx" +import { MsgCreateDid, MsgCreateDidPayload, SignInfo } from "@cheqd/ts-proto/cheqd/v1/tx" import { DirectSecp256k1HdWallet, Registry } from "@cosmjs/proto-signing" -import { EdDSASigner } from "did-jwt" +import { base64ToBytes, EdDSASigner } from "did-jwt" import { typeUrlMsgCreateDid } from "../src/registry" import { CheqdSigningStargateClient } from "../src/signer" -import { VerificationMethods } from "../src/types" -import { createDidPayload, createKeyPair, exampleCheqdNetwork, faucet } from "./testutils.test" +import { ISignInputs, VerificationMethods } from "../src/types" +import { fromString, toString } from 'uint8arrays' +import { createDidPayload, createKeyPairBase64, exampleCheqdNetwork, faucet } from "./testutils.test" +import { verify } from "@stablelib/ed25519" const nonExistingDid = "did:cHeQd:fantasticnet:123" const nonExistingKeyId = 'did:cHeQd:fantasticnet:123#key-678' @@ -33,7 +35,7 @@ describe('CheqdSigningStargateClient', () => { it('can get a signer for a did', async () => { const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic) const signer = await CheqdSigningStargateClient.connectWithSigner(exampleCheqdNetwork.rpcUrl, wallet) - const didPayload = createDidPayload(createKeyPair(), VerificationMethods.Multibase58) + const didPayload = createDidPayload(createKeyPairBase64(), VerificationMethods.Multibase58) const didSigner = await signer.getDidSigner(didPayload.verificationMethod[0].id, didPayload.verificationMethod) expect(didSigner).toBe(EdDSASigner) @@ -43,7 +45,7 @@ describe('CheqdSigningStargateClient', () => { const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic) const signer = await CheqdSigningStargateClient.connectWithSigner(exampleCheqdNetwork.rpcUrl, wallet) //@ts-ignore - const didPayload = createDidPayload(createKeyPair(), 'ExtraTerrestrialVerificationKey2045') + const didPayload = createDidPayload(createKeyPairBase64(), 'ExtraTerrestrialVerificationKey2045') expect(didPayload).toBe(undefined) }) @@ -51,7 +53,7 @@ describe('CheqdSigningStargateClient', () => { it('should throw for non-matching verification method id', async () => { const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic) const signer = await CheqdSigningStargateClient.connectWithSigner(exampleCheqdNetwork.rpcUrl, wallet) - const didPayload = createDidPayload(createKeyPair(), VerificationMethods.JWK) + const didPayload = createDidPayload(createKeyPairBase64(), VerificationMethods.JWK) await expect(signer.getDidSigner(nonExistingKeyId, didPayload.verificationMethod)).rejects.toThrow() }) }) @@ -60,7 +62,7 @@ describe('CheqdSigningStargateClient', () => { it('it should instantiate a signer for a did', async () => { const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic) const signer = await CheqdSigningStargateClient.connectWithSigner(exampleCheqdNetwork.rpcUrl, wallet) - const didPayload = createDidPayload(createKeyPair(), VerificationMethods.Multibase58) + const didPayload = createDidPayload(createKeyPairBase64(), VerificationMethods.Multibase58) const didSigners = await signer.checkDidSigners(didPayload.verificationMethod) @@ -70,9 +72,9 @@ describe('CheqdSigningStargateClient', () => { it('should instantiate multiple signers for a did with multiple verification methods', async () => { const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic) const signer = await CheqdSigningStargateClient.connectWithSigner(exampleCheqdNetwork.rpcUrl, wallet) - const didPayload = createDidPayload(createKeyPair(), VerificationMethods.Multibase58) + const didPayload = createDidPayload(createKeyPairBase64(), VerificationMethods.Multibase58) - didPayload.verificationMethod.push(createDidPayload(createKeyPair(), VerificationMethods.JWK).verificationMethod[0]) + didPayload.verificationMethod.push(createDidPayload(createKeyPairBase64(), VerificationMethods.JWK).verificationMethod[0]) const didSigners = await signer.checkDidSigners(didPayload.verificationMethod) @@ -93,4 +95,30 @@ describe('CheqdSigningStargateClient', () => { await expect(signer.checkDidSigners([VerificationMethod.fromPartial(verificationMethod)])).rejects.toThrow() }) }) + + describe('signDidTx', () => { + it('should sign a did tx with valid signature', async () => { + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic) + const signer = await CheqdSigningStargateClient.connectWithSigner(exampleCheqdNetwork.rpcUrl, wallet) + const keyPair = createKeyPairBase64() + const didPayload = createDidPayload(keyPair, VerificationMethods.Multibase58) + const signInputs: ISignInputs[] = [ + { + verificationMethodId: didPayload.verificationMethod[0].id, + privateKeyHex: toString(fromString(keyPair.privateKey, 'base64'), 'hex') + } + ] + const signInfos = await signer.signDidTx(signInputs, didPayload) + const publicKeyRaw = fromString(keyPair.publicKey, 'base64') + const messageRaw = MsgCreateDidPayload.encode(didPayload).finish() + const signatureRaw = base64ToBytes(signInfos[0].signature) + const verified = verify( + publicKeyRaw, + messageRaw, + signatureRaw + ) + + expect(verified).toBe(true) + }) + }) }) \ No newline at end of file diff --git a/tests/testutils.test.ts b/tests/testutils.test.ts index 33c4cbcc..4abfee96 100644 --- a/tests/testutils.test.ts +++ b/tests/testutils.test.ts @@ -3,21 +3,27 @@ import { CheqdNetwork, IKeyPair, IKeyValuePair, TSignerAlgo, VerificationMethods import { bases } from 'multiformats/basics' import { base64ToBytes } from "did-jwt" import { fromString, toString } from 'uint8arrays' -import { generateKeyPair } from '@stablelib/ed25519' -import { CheqdSigningStargateClient } from "../src/signer" +import { generateKeyPair, KeyPair } from '@stablelib/ed25519' +import { GasPrice } from "@cosmjs/stargate" +export const faucet = { + prefix: 'cheqd', + minimalDenom: 'ncheq', + mnemonic: 'sketch mountain erode window enact net enrich smoke claim kangaroo another visual write meat latin bacon pulp similar forum guilt father state erase bright', + address: 'cheqd1rnr5jrt4exl0samwj0yegv99jeskl0hsxmcz96', +} export const exampleCheqdNetwork = { network: 'testnet', rpcUrl: 'https://rpc.cheqd.network', + gasPrice: GasPrice.fromString( `25${faucet.minimalDenom}` ) } -export const faucet = { - mnemonic: 'sketch mountain erode window enact net enrich smoke claim kangaroo another visual write meat latin bacon pulp similar forum guilt father state erase bright', - address: 'cheqd1rnr5jrt4exl0samwj0yegv99jeskl0hsxmcz96', +export function createKeyPairRaw(): KeyPair { + return generateKeyPair() } -export function createKeyPair(): IKeyPair { +export function createKeyPairBase64(): IKeyPair { const keyPair = generateKeyPair() return { publicKey: toString(keyPair.publicKey, 'base64'), @@ -27,13 +33,14 @@ export function createKeyPair(): IKeyPair { export function createDidPayload(keyPair: IKeyPair, verificationMethodType: VerificationMethods, network: CheqdNetwork = CheqdNetwork.Testnet): MsgCreateDidPayload { const methodSpecificId = bases['base58btc'].encode(base64ToBytes(keyPair.publicKey)) - const did = `did:cheqd:${network}:${methodSpecificId.substring(0, 32)}` + const did = `did:cheqd:${network}:${methodSpecificId.substring(0, 16)}` const keyId = `${did}#key-1` switch (verificationMethodType) { case VerificationMethods.Multibase58: return MsgCreateDidPayload.fromPartial({ id: did, + controller: [did], verificationMethod: [ { id: keyId, @@ -53,12 +60,13 @@ export function createDidPayload(keyPair: IKeyPair, verificationMethodType: Veri } return MsgCreateDidPayload.fromPartial({ id: did, + controller: [did], verificationMethod: [ { id: keyId, type: VerificationMethods.JWK, controller: did, - publicKeyJwk: parseToKeyValuePair(jwk) + publicKeyJwk: parseToKeyValuePair(jwk), } ], authentication: [keyId]