@0xpolygonid/js-sdk 1.7.5 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/dist/browser/esm/index.js +13076 -11775
  2. package/dist/browser/esm/index.js.map +1 -1
  3. package/dist/browser/umd/index.js +13104 -11781
  4. package/dist/browser/umd/index.js.map +1 -1
  5. package/dist/node/cjs/circuits/atomic-query-mtp-v2.js +3 -3
  6. package/dist/node/cjs/circuits/atomic-query-sig-v2.js +3 -3
  7. package/dist/node/cjs/circuits/atomic-query-v3-on-chain.js +22 -14
  8. package/dist/node/cjs/circuits/auth-v2.js +1 -1
  9. package/dist/node/cjs/credentials/credential-wallet.js +1 -3
  10. package/dist/node/cjs/credentials/index.js +1 -0
  11. package/dist/node/cjs/credentials/models.js +2 -0
  12. package/dist/node/cjs/credentials/status/credential-status-publisher.js +23 -4
  13. package/dist/node/cjs/iden3comm/constants.js +3 -1
  14. package/dist/node/cjs/iden3comm/handlers/auth.js +119 -14
  15. package/dist/node/cjs/kms/key-providers/sec256k1-provider.js +5 -2
  16. package/dist/node/cjs/proof/common.js +3 -4
  17. package/dist/node/cjs/proof/index.js +2 -1
  18. package/dist/node/cjs/proof/proof-service.js +22 -2
  19. package/dist/node/cjs/proof/provers/index.js +19 -0
  20. package/dist/node/cjs/proof/{inputs-generator.js → provers/inputs-generator.js} +42 -23
  21. package/dist/node/cjs/proof/{prover.js → provers/prover.js} +1 -1
  22. package/dist/node/cjs/proof/verifiers/index.js +18 -0
  23. package/dist/node/cjs/proof/verifiers/pub-signals-verifier.js +344 -0
  24. package/dist/node/cjs/proof/verifiers/query.js +190 -0
  25. package/dist/node/cjs/schema-processor/json/parser.js +39 -198
  26. package/dist/node/cjs/schema-processor/utils.js +13 -26
  27. package/dist/node/cjs/storage/blockchain/state.js +53 -8
  28. package/dist/node/cjs/utils/compare-func.js +11 -0
  29. package/dist/node/cjs/utils/index.js +2 -0
  30. package/dist/node/cjs/utils/message-bus.js +73 -0
  31. package/dist/node/cjs/verifiable/core-utils.js +234 -0
  32. package/dist/node/cjs/verifiable/credential.js +139 -1
  33. package/dist/node/cjs/verifiable/index.js +1 -0
  34. package/dist/node/esm/circuits/atomic-query-mtp-v2.js +3 -3
  35. package/dist/node/esm/circuits/atomic-query-sig-v2.js +3 -3
  36. package/dist/node/esm/circuits/atomic-query-v3-on-chain.js +22 -14
  37. package/dist/node/esm/circuits/auth-v2.js +2 -2
  38. package/dist/node/esm/credentials/credential-wallet.js +1 -3
  39. package/dist/node/esm/credentials/index.js +1 -0
  40. package/dist/node/esm/credentials/models.js +1 -0
  41. package/dist/node/esm/credentials/status/credential-status-publisher.js +23 -4
  42. package/dist/node/esm/iden3comm/constants.js +3 -1
  43. package/dist/node/esm/iden3comm/handlers/auth.js +116 -13
  44. package/dist/node/esm/kms/key-providers/sec256k1-provider.js +5 -2
  45. package/dist/node/esm/proof/common.js +4 -5
  46. package/dist/node/esm/proof/index.js +2 -1
  47. package/dist/node/esm/proof/proof-service.js +22 -2
  48. package/dist/node/esm/proof/provers/index.js +3 -0
  49. package/dist/node/esm/proof/{inputs-generator.js → provers/inputs-generator.js} +39 -20
  50. package/dist/node/esm/proof/{prover.js → provers/prover.js} +1 -1
  51. package/dist/node/esm/proof/verifiers/index.js +2 -0
  52. package/dist/node/esm/proof/verifiers/pub-signals-verifier.js +340 -0
  53. package/dist/node/esm/proof/verifiers/query.js +186 -0
  54. package/dist/node/esm/schema-processor/json/parser.js +40 -199
  55. package/dist/node/esm/schema-processor/utils.js +13 -26
  56. package/dist/node/esm/storage/blockchain/state.js +53 -8
  57. package/dist/node/esm/utils/compare-func.js +7 -0
  58. package/dist/node/esm/utils/index.js +2 -0
  59. package/dist/node/esm/utils/message-bus.js +66 -0
  60. package/dist/node/esm/verifiable/core-utils.js +200 -0
  61. package/dist/node/esm/verifiable/credential.js +118 -3
  62. package/dist/node/esm/verifiable/index.js +1 -0
  63. package/dist/types/credentials/credential-wallet.d.ts +2 -60
  64. package/dist/types/credentials/index.d.ts +1 -0
  65. package/dist/types/credentials/models.d.ts +68 -0
  66. package/dist/types/credentials/status/credential-status-publisher.d.ts +2 -0
  67. package/dist/types/iden3comm/constants.d.ts +1 -0
  68. package/dist/types/iden3comm/handlers/auth.d.ts +53 -13
  69. package/dist/types/iden3comm/types/protocol/credentials.d.ts +16 -0
  70. package/dist/types/identity/identity-wallet.d.ts +3 -1
  71. package/dist/types/kms/key-providers/sec256k1-provider.d.ts +1 -1
  72. package/dist/types/proof/index.d.ts +2 -1
  73. package/dist/types/proof/proof-service.d.ts +28 -3
  74. package/dist/types/proof/provers/index.d.ts +3 -0
  75. package/dist/types/proof/{inputs-generator.d.ts → provers/inputs-generator.d.ts} +14 -7
  76. package/dist/types/proof/{prover.d.ts → provers/prover.d.ts} +2 -2
  77. package/dist/types/proof/verifiers/index.d.ts +2 -0
  78. package/dist/types/proof/verifiers/pub-signals-verifier.d.ts +58 -0
  79. package/dist/types/proof/verifiers/query.d.ts +25 -0
  80. package/dist/types/schema-processor/json/parser.d.ts +47 -28
  81. package/dist/types/schema-processor/utils.d.ts +9 -4
  82. package/dist/types/storage/blockchain/state.d.ts +5 -1
  83. package/dist/types/storage/interfaces/state.d.ts +8 -0
  84. package/dist/types/utils/compare-func.d.ts +1 -0
  85. package/dist/types/utils/index.d.ts +2 -0
  86. package/dist/types/utils/message-bus.d.ts +62 -0
  87. package/dist/types/verifiable/core-utils.d.ts +84 -0
  88. package/dist/types/verifiable/credential.d.ts +11 -1
  89. package/dist/types/verifiable/index.d.ts +1 -0
  90. package/dist/types/verifiable/proof.d.ts +4 -0
  91. package/package.json +10 -10
  92. /package/dist/node/cjs/proof/{witness_calculator.js → provers/witness_calculator.js} +0 -0
  93. /package/dist/node/esm/proof/{witness_calculator.js → provers/witness_calculator.js} +0 -0
  94. /package/dist/types/proof/{witness_calculator.d.ts → provers/witness_calculator.d.ts} +0 -0
@@ -1,16 +1,6 @@
1
- import { MerklizedRootPosition, SubjectPosition } from '../../verifiable';
2
- import { Claim as CoreClaim, ClaimOptions, DID } from '@iden3/js-iden3-core';
3
- import { createSchemaHash, fillSlot } from '../utils';
4
- import { byteDecoder, byteEncoder } from '../../utils';
5
- import { Path } from '@iden3/js-jsonld-merklization';
1
+ import { getSerializationAttrFromContext, parseSerializationAttr, getFieldSlotIndex, findCredentialType, getSerializationAttrFromParsedContext, parseCoreClaimSlots } from '../../verifiable';
6
2
  import * as jsonld from 'jsonld/lib';
7
3
  import * as ldcontext from 'jsonld/lib/context';
8
- const credentialSubjectFullKey = 'https://www.w3.org/2018/credentials#credentialSubject';
9
- const verifiableCredentialFullKey = 'https://www.w3.org/2018/credentials#VerifiableCredential';
10
- const typeFullKey = '@type';
11
- const contextFullKey = '@context';
12
- const serializationFullKey = 'iden3_serialization';
13
- const fieldPrefix = 'iden3:v1:';
14
4
  /**
15
5
  * Parser can parse claim and schema data according to specification
16
6
  *
@@ -19,6 +9,7 @@ const fieldPrefix = 'iden3:v1:';
19
9
  */
20
10
  export class Parser {
21
11
  /**
12
+ * @deprecated The method should not be used. Use credential.toCoreClaim instead.
22
13
  * ParseClaim creates core.Claim object from W3CCredential
23
14
  *
24
15
  * @param {W3CCredential} credential - Verifiable Credential
@@ -26,163 +17,53 @@ export class Parser {
26
17
  * @returns `Promise<CoreClaim>`
27
18
  */
28
19
  static async parseClaim(credential, opts) {
29
- if (!opts) {
30
- opts = {
31
- revNonce: 0,
32
- version: 0,
33
- subjectPosition: SubjectPosition.Index,
34
- merklizedRootPosition: MerklizedRootPosition.None,
35
- updatable: false,
36
- merklizeOpts: {}
37
- };
38
- }
39
- const mz = await credential.merklize(opts.merklizeOpts);
40
- const credentialType = Parser.findCredentialType(mz);
41
- const subjectId = credential.credentialSubject['id'];
42
- const { slots, nonMerklized } = await this.parseSlots(mz, credential, credentialType);
43
- // if schema is for non merklized credential, root position must be set to none ('')
44
- // otherwise default position for merklized position is index.
45
- if (nonMerklized && opts.merklizedRootPosition !== MerklizedRootPosition.None) {
46
- throw new Error('merklized root position is not supported for non-merklized claims');
47
- }
48
- if (!nonMerklized && opts.merklizedRootPosition === MerklizedRootPosition.None) {
49
- opts.merklizedRootPosition = MerklizedRootPosition.Index;
50
- }
51
- const schemaHash = createSchemaHash(byteEncoder.encode(credentialType));
52
- const claim = CoreClaim.newClaim(schemaHash, ClaimOptions.withIndexDataBytes(slots.indexA, slots.indexB), ClaimOptions.withValueDataBytes(slots.valueA, slots.valueB), ClaimOptions.withRevocationNonce(BigInt(opts.revNonce)), ClaimOptions.withVersion(opts.version));
53
- if (opts.updatable) {
54
- claim.setFlagUpdatable(opts.updatable);
55
- }
56
- if (credential.expirationDate) {
57
- claim.setExpirationDate(new Date(credential.expirationDate));
58
- }
59
- if (subjectId) {
60
- const did = DID.parse(subjectId.toString());
61
- const id = DID.idFromDID(did);
62
- switch (opts.subjectPosition) {
63
- case '':
64
- case SubjectPosition.Index:
65
- claim.setIndexId(id);
66
- break;
67
- case SubjectPosition.Value:
68
- claim.setValueId(id);
69
- break;
70
- default:
71
- throw new Error('unknown subject position');
72
- }
73
- }
74
- switch (opts.merklizedRootPosition) {
75
- case MerklizedRootPosition.Index: {
76
- const mk = await credential.merklize(opts.merklizeOpts);
77
- claim.setIndexMerklizedRoot((await mk.root()).bigInt());
78
- break;
79
- }
80
- case MerklizedRootPosition.Value: {
81
- const mk = await credential.merklize(opts.merklizeOpts);
82
- claim.setValueMerklizedRoot((await mk.root()).bigInt());
83
- break;
84
- }
85
- case MerklizedRootPosition.None:
86
- break;
87
- default:
88
- throw new Error('unknown merklized root position');
89
- }
90
- return claim;
20
+ return credential.toCoreClaim(opts);
91
21
  }
22
+ /**
23
+ * @deprecated The method should not be used. Use findCredentialType from verifiable.
24
+ */
92
25
  static findCredentialType(mz) {
93
- const opts = mz.options;
94
- try {
95
- // try to look into credentialSubject.@type to get type of credentials
96
- const path1 = new Path([credentialSubjectFullKey, typeFullKey], opts.hasher);
97
- const e = mz.rawValue(path1);
98
- return e;
99
- }
100
- catch (err) {
101
- // if type of credentials not found in credentialSubject.@type, loop at
102
- // top level @types if it contains two elements: type we are looking for
103
- // and "VerifiableCredential" type.
104
- const path2 = new Path([typeFullKey], opts.hasher);
105
- const topLevelTypes = mz.rawValue(path2);
106
- if (!Array.isArray(topLevelTypes)) {
107
- throw new Error('top level @type expected to be an array');
108
- }
109
- if (topLevelTypes.length !== 2) {
110
- throw new Error('top level @type expected to be of length 2');
111
- }
112
- switch (verifiableCredentialFullKey) {
113
- case topLevelTypes[0]:
114
- return topLevelTypes[1];
115
- case topLevelTypes[1]:
116
- return topLevelTypes[0];
117
- default:
118
- throw new Error('@type(s) are expected to contain VerifiableCredential type');
119
- }
120
- }
26
+ return findCredentialType(mz);
121
27
  }
122
- // Get `iden3_serialization` attr definition from context document either using
123
- // type name like DeliverAddressMultiTestForked or by type id like
124
- // urn:uuid:ac2ede19-b3b9-454d-b1a9-a7b3d5763100.
28
+ /**
29
+ * @deprecated The method should not be used. Use credential.getSerializationAttr instead.
30
+ *
31
+ * Get `iden3_serialization` attr definition from context document either using
32
+ * type name like DeliverAddressMultiTestForked or by type id like
33
+ * urn:uuid:ac2ede19-b3b9-454d-b1a9-a7b3d5763100.
34
+ * */
125
35
  static async getSerializationAttr(credential, opts, tp) {
126
36
  const ldCtx = await jsonld.processContext(ldcontext.getInitialContext({}), credential['@context'], opts);
127
37
  return Parser.getSerializationAttrFromParsedContext(ldCtx, tp);
128
38
  }
129
- // Get `iden3_serialization` attr definition from context document either using
130
- // type name like DeliverAddressMultiTestForked or by type id like
131
- // urn:uuid:ac2ede19-b3b9-454d-b1a9-a7b3d5763100.
39
+ /**
40
+ * @deprecated The method should not be used. Use getSerializationAttrFromContext from verifiable.
41
+ *
42
+ * Get `iden3_serialization` attr definition from context document either using
43
+ * type name like DeliverAddressMultiTestForked or by type id like
44
+ * urn:uuid:ac2ede19-b3b9-454d-b1a9-a7b3d5763100.
45
+ *
46
+ */
132
47
  static async getSerializationAttrFromContext(context, opts, tp) {
133
- const ldCtx = await jsonld.processContext(ldcontext.getInitialContext({}), context, opts);
134
- return Parser.getSerializationAttrFromParsedContext(ldCtx, tp);
48
+ return getSerializationAttrFromContext(context, opts, tp);
135
49
  }
50
+ /**
51
+ * @deprecated The method should not be used. Use getSerializationAttrFromParsedContext from verifiable.
52
+ *
53
+ * */
136
54
  static async getSerializationAttrFromParsedContext(ldCtx, tp) {
137
- const termDef = ldCtx.mappings;
138
- if (!termDef) {
139
- throw new Error('terms definitions is not of correct type');
140
- }
141
- const term = termDef.get(tp) ?? [...termDef.values()].find((value) => value['@id'] === tp);
142
- if (!term) {
143
- return '';
144
- }
145
- const termCtx = term[contextFullKey];
146
- if (!termCtx) {
147
- throw new Error('type @context is not of correct type');
148
- }
149
- const serStr = termCtx[serializationFullKey] ?? '';
150
- return serStr;
55
+ return getSerializationAttrFromParsedContext(ldCtx, tp);
151
56
  }
57
+ /**
58
+ * @deprecated The method should not be used. Use parseSerializationAttr from verifiable.
59
+ *
60
+ */
152
61
  static parseSerializationAttr(serAttr) {
153
- if (!serAttr.startsWith(fieldPrefix)) {
154
- throw new Error('serialization attribute does not have correct prefix');
155
- }
156
- const parts = serAttr.slice(fieldPrefix.length).split('&');
157
- if (parts.length > 4) {
158
- throw new Error('serialization attribute has too many parts');
159
- }
160
- const paths = {};
161
- for (const part of parts) {
162
- const kv = part.split('=');
163
- if (kv.length !== 2) {
164
- throw new Error('serialization attribute part does not have correct format');
165
- }
166
- switch (kv[0]) {
167
- case 'slotIndexA':
168
- paths.indexAPath = kv[1];
169
- break;
170
- case 'slotIndexB':
171
- paths.indexBPath = kv[1];
172
- break;
173
- case 'slotValueA':
174
- paths.valueAPath = kv[1];
175
- break;
176
- case 'slotValueB':
177
- paths.valueBPath = kv[1];
178
- break;
179
- default:
180
- throw new Error('unknown serialization attribute slot');
181
- }
182
- }
183
- return paths;
62
+ return parseSerializationAttr(serAttr);
184
63
  }
185
64
  /**
65
+ *
66
+ * @deprecated The method should not be used. Use credential.parseSlots instead.
186
67
  * ParseSlots converts payload to claim slots using provided schema
187
68
  *
188
69
  * @param {Merklizer} mz - Merklizer
@@ -191,30 +72,12 @@ export class Parser {
191
72
  * @returns `ParsedSlots`
192
73
  */
193
74
  static async parseSlots(mz, credential, credentialType) {
194
- // parseSlots converts payload to claim slots using provided schema
195
- const slots = {
196
- indexA: new Uint8Array(32),
197
- indexB: new Uint8Array(32),
198
- valueA: new Uint8Array(32),
199
- valueB: new Uint8Array(32)
200
- };
201
- const jsonLDOpts = mz.options;
202
- const serAttr = await Parser.getSerializationAttr(credential, jsonLDOpts, credentialType);
203
- if (!serAttr) {
204
- return { slots, nonMerklized: false };
205
- }
206
- const sPaths = Parser.parseSerializationAttr(serAttr);
207
- const isSPathEmpty = !Object.values(sPaths).some(Boolean);
208
- if (isSPathEmpty) {
209
- return { slots, nonMerklized: true };
210
- }
211
- await fillSlot(slots.indexA, mz, sPaths.indexAPath);
212
- await fillSlot(slots.indexB, mz, sPaths.indexBPath);
213
- await fillSlot(slots.valueA, mz, sPaths.valueAPath);
214
- await fillSlot(slots.valueB, mz, sPaths.valueBPath);
215
- return { slots, nonMerklized: true };
75
+ const ldCtx = await jsonld.processContext(ldcontext.getInitialContext({}), credential['@context'], mz.options);
76
+ return parseCoreClaimSlots(ldCtx, mz, credentialType);
216
77
  }
217
78
  /**
79
+ * @deprecated The method should not be used. Use getFieldSlotIndex from verifiable.
80
+ *
218
81
  * GetFieldSlotIndex return index of slot from 0 to 7 (each claim has by default 8 slots) for non-merklized claims
219
82
  *
220
83
  * @param {string} field - field name
@@ -222,29 +85,7 @@ export class Parser {
222
85
  * @returns `number`
223
86
  */
224
87
  static async getFieldSlotIndex(field, typeName, schemaBytes) {
225
- let ctxDoc = JSON.parse(byteDecoder.decode(schemaBytes));
226
- ctxDoc = ctxDoc[contextFullKey];
227
- if (ctxDoc === undefined) {
228
- throw new Error('document has no @context');
229
- }
230
- const ldCtx = await jsonld.processContext(ldcontext.getInitialContext({}), ctxDoc, {});
231
- const serAttr = await Parser.getSerializationAttrFromParsedContext(ldCtx, typeName);
232
- if (!serAttr) {
233
- throw new Error('serialization attribute is not set');
234
- }
235
- const sPaths = Parser.parseSerializationAttr(serAttr);
236
- switch (field) {
237
- case sPaths.indexAPath:
238
- return 2;
239
- case sPaths.indexBPath:
240
- return 3;
241
- case sPaths.valueAPath:
242
- return 6;
243
- case sPaths.valueBPath:
244
- return 7;
245
- default:
246
- throw new Error(`field ${field} not specified in serialization info`);
247
- }
88
+ return getFieldSlotIndex(field, typeName, schemaBytes);
248
89
  }
249
90
  /**
250
91
  * ExtractCredentialSubjectProperties return credential subject types from JSON schema
@@ -1,6 +1,5 @@
1
- import { Hex } from '@iden3/js-crypto';
2
- import { BytesHelper, checkBigIntInField, SchemaHash } from '@iden3/js-iden3-core';
3
- import { keccak256 } from 'js-sha3';
1
+ import { BytesHelper, checkBigIntInField } from '@iden3/js-iden3-core';
2
+ import { caclulateCoreSchemaHash, fillCoreClaimSlot } from '../verifiable';
4
3
  /**
5
4
  * SwapEndianness swaps the endianness of the value encoded in buf. If buf is
6
5
  * Big-Endian, the result will be Little-Endian and vice-versa.
@@ -48,39 +47,27 @@ export function checkDataInField(data) {
48
47
  return checkBigIntInField(BytesHelper.bytesToInt(data));
49
48
  }
50
49
  /**
50
+ *
51
+ * @deprecated The method should not be used. Use caclulateCoreSchemaHash from verifiable.
51
52
  * Calculates schema hash
52
53
  *
53
54
  * @param {Uint8Array} schemaId
54
55
  * @returns {*} {SchemaHash}
55
56
  */
56
57
  export const createSchemaHash = (schemaId) => {
57
- const sHash = Hex.decodeString(keccak256(schemaId));
58
- return new SchemaHash(sHash.slice(sHash.length - 16, sHash.length));
58
+ return caclulateCoreSchemaHash(schemaId);
59
59
  };
60
- export const credentialSubjectKey = 'credentialSubject';
61
60
  /**
61
+ *
62
+ * @deprecated The method should not be used. Use fillCoreClaimSlot from verifiable.
62
63
  * checks if data can fill the slot
63
64
  *
64
- * @param {*} data - object that contains field
65
- * @param {string} fieldName - field name
66
- * @returns Uint8Array - filled slot
65
+ * @param {Uint8Array} slotData - slot data
66
+ * @param {Merklizer} mz - merklizer
67
+ * @param {string} path - path
68
+ * @returns {void}
67
69
  */
68
70
  export const fillSlot = async (slotData, mz, path) => {
69
- if (!path) {
70
- return;
71
- }
72
- path = credentialSubjectKey + '.' + path;
73
- try {
74
- const p = await mz.resolveDocPath(path, mz.options);
75
- const entry = await mz.entry(p);
76
- const intVal = await entry.getValueMtEntry();
77
- const bytesVal = BytesHelper.intToBytes(intVal);
78
- slotData.set(bytesVal, 0);
79
- }
80
- catch (err) {
81
- if (err.toString().includes('entry not found')) {
82
- throw new Error(`field not found in credential ${path}`);
83
- }
84
- throw err;
85
- }
71
+ return fillCoreClaimSlot(slotData, mz, path);
86
72
  };
73
+ export const credentialSubjectKey = 'credentialSubject';
@@ -2,6 +2,7 @@ import { Contract, JsonRpcProvider } from 'ethers';
2
2
  import { StateTransitionPubSignals } from '../../circuits';
3
3
  import { byteEncoder } from '../../utils';
4
4
  import abi from './abi/State.json';
5
+ import { DID, getChainId, Id } from '@iden3/js-iden3-core';
5
6
  export /** @type {EthConnectionConfig} - default configuration for EthConnectionConfig */ const defaultEthConnectionConfig = {
6
7
  url: 'http://localhost:8545',
7
8
  defaultGasLimit: 600000,
@@ -27,14 +28,31 @@ export class EthStateStorage {
27
28
  * Creates an instance of EthStateStorage.
28
29
  * @param {EthConnectionConfig} [ethConfig=defaultEthConnectionConfig]
29
30
  */
30
- constructor(ethConfig = defaultEthConnectionConfig) {
31
+ constructor(ethConfig) {
31
32
  this.ethConfig = ethConfig;
32
- this.provider = new JsonRpcProvider(this.ethConfig.url);
33
- this.stateContract = new Contract(this.ethConfig.contractAddress, abi, this.provider);
33
+ const config = Array.isArray(ethConfig) ? ethConfig[0] : ethConfig;
34
+ this.provider = new JsonRpcProvider(config.url);
35
+ this.stateContract = new Contract(config.contractAddress, abi, this.provider);
34
36
  }
35
37
  /** {@inheritdoc IStateStorage.getLatestStateById} */
36
38
  async getLatestStateById(id) {
37
- const rawData = await this.stateContract.getStateInfoById(id);
39
+ const { stateContract } = this.getStateContractAndProviderForId(id);
40
+ const rawData = await stateContract.getStateInfoById(id);
41
+ const stateInfo = {
42
+ id: BigInt(rawData[0]),
43
+ state: BigInt(rawData[1]),
44
+ replacedByState: BigInt(rawData[2]),
45
+ createdAtTimestamp: BigInt(rawData[3]),
46
+ replacedAtTimestamp: BigInt(rawData[4]),
47
+ createdAtBlock: BigInt(rawData[5]),
48
+ replacedAtBlock: BigInt(rawData[6])
49
+ };
50
+ return stateInfo;
51
+ }
52
+ /** {@inheritdoc IStateStorage.getStateInfoByIdAndState} */
53
+ async getStateInfoByIdAndState(id, state) {
54
+ const { stateContract } = this.getStateContractAndProviderForId(id);
55
+ const rawData = await stateContract.getStateInfoByIdAndState(id, state);
38
56
  const stateInfo = {
39
57
  id: BigInt(rawData[0]),
40
58
  state: BigInt(rawData[1]),
@@ -48,10 +66,11 @@ export class EthStateStorage {
48
66
  }
49
67
  /** {@inheritdoc IStateStorage.publishState} */
50
68
  async publishState(proof, signer) {
51
- const contract = this.stateContract.connect(signer);
52
69
  const stateTransitionPubSig = new StateTransitionPubSignals();
53
70
  stateTransitionPubSig.pubSignalsUnmarshal(byteEncoder.encode(JSON.stringify(proof.pub_signals)));
54
71
  const { userId, oldUserState, newUserState, isOldStateGenesis } = stateTransitionPubSig;
72
+ const { stateContract, provider } = this.getStateContractAndProviderForId(userId.bigInt());
73
+ const contract = stateContract.connect(signer);
55
74
  const payload = [
56
75
  userId.bigInt().toString(),
57
76
  oldUserState.bigInt().toString(),
@@ -64,7 +83,7 @@ export class EthStateStorage {
64
83
  ],
65
84
  proof.proof.pi_c.slice(0, 2)
66
85
  ];
67
- const feeData = await this.provider.getFeeData();
86
+ const feeData = await provider.getFeeData();
68
87
  const maxFeePerGas = defaultEthConnectionConfig.maxFeePerGas
69
88
  ? BigInt(defaultEthConnectionConfig.maxFeePerGas)
70
89
  : feeData.maxFeePerGas;
@@ -94,7 +113,8 @@ export class EthStateStorage {
94
113
  }
95
114
  /** {@inheritdoc IStateStorage.getGISTProof} */
96
115
  async getGISTProof(id) {
97
- const data = await this.stateContract.getGISTProof(id);
116
+ const { stateContract } = this.getStateContractAndProviderForId(id);
117
+ const data = await stateContract.getGISTProof(id);
98
118
  return {
99
119
  root: BigInt(data.root.toString()),
100
120
  existence: data.existence,
@@ -108,7 +128,8 @@ export class EthStateStorage {
108
128
  }
109
129
  /** {@inheritdoc IStateStorage.getGISTRootInfo} */
110
130
  async getGISTRootInfo(id) {
111
- const data = await this.stateContract.getGISTRootInfo(id);
131
+ const { stateContract } = this.getStateContractAndProviderForId(id);
132
+ const data = await stateContract.getGISTRootInfo(id);
112
133
  return {
113
134
  root: BigInt(data.root.toString()),
114
135
  replacedByRoot: BigInt(data.replacedByRoot.toString()),
@@ -118,4 +139,28 @@ export class EthStateStorage {
118
139
  replacedAtBlock: BigInt(data.replacedAtBlock.toString())
119
140
  };
120
141
  }
142
+ getStateContractAndProviderForId(id) {
143
+ const idTyped = Id.fromBigInt(id);
144
+ if (!Array.isArray(this.ethConfig)) {
145
+ return {
146
+ stateContract: this.stateContract,
147
+ provider: this.provider
148
+ };
149
+ }
150
+ const chainId = getChainId(DID.blockchainFromId(idTyped), DID.networkIdFromId(idTyped));
151
+ const config = this.networkByChainId(chainId);
152
+ const provider = new JsonRpcProvider(config.url);
153
+ const stateContract = new Contract(config.contractAddress, abi, this.provider);
154
+ return { stateContract, provider };
155
+ }
156
+ networkByChainId(chainId) {
157
+ if (Array.isArray(this.ethConfig)) {
158
+ const network = this.ethConfig.find((c) => c.chainId === chainId);
159
+ if (!network) {
160
+ throw new Error(`chainId "${chainId}" not supported`);
161
+ }
162
+ return network;
163
+ }
164
+ return this.ethConfig;
165
+ }
121
166
  }
@@ -0,0 +1,7 @@
1
+ export const bigIntCompare = (a, b) => {
2
+ if (a < b)
3
+ return -1;
4
+ if (a > b)
5
+ return 1;
6
+ return 0;
7
+ };
@@ -1,3 +1,5 @@
1
1
  export * from './encoding';
2
2
  export * from './object';
3
3
  export * from './did-helper';
4
+ export * from './message-bus';
5
+ export * from './compare-func';
@@ -0,0 +1,66 @@
1
+ import PubSub from 'pubsub-js';
2
+ export const SDK_EVENTS = {
3
+ TX_RECEIPT_ACCEPTED: 'TX_RECEIPT_ACCEPTED'
4
+ };
5
+ /**
6
+ * Represents a message bus that allows publishing and subscribing to topics.
7
+ */
8
+ export class MessageBus {
9
+ /**
10
+ * Private constructor for the MessageBus class.
11
+ */
12
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
13
+ constructor() { }
14
+ /**
15
+ * Returns the singleton instance of the MessageBus class.
16
+ * If the instance doesn't exist, it creates a new one.
17
+ * @returns The singleton instance of the MessageBus class.
18
+ */
19
+ static getInstance() {
20
+ // If the instance doesn't exist, create it
21
+ if (!MessageBus.instance) {
22
+ MessageBus.instance = new MessageBus();
23
+ }
24
+ // Return the instance
25
+ return MessageBus.instance;
26
+ }
27
+ /**
28
+ * Publishes a message to the specified topic.
29
+ *
30
+ * @template T - The type of data being published.
31
+ * @param {SdkTopic} topic - The topic to publish the message to.
32
+ * @param {T} data - The data to be published.
33
+ * @returns {boolean} - Returns true if the message was successfully published, false otherwise.
34
+ */
35
+ publish(topic, data) {
36
+ return PubSub.publish(topic.toString(), data);
37
+ }
38
+ /**
39
+ * Subscribes to a specific topic and registers a callback function to be executed when a message is published.
40
+ *
41
+ * @param topic - The topic to subscribe to.
42
+ * @param callback - The callback function to be executed when a message is published.
43
+ */
44
+ subscribe(topic, callback) {
45
+ return PubSub.subscribe(topic.toString(), (_, data) => callback(data));
46
+ }
47
+ /**
48
+ * Subscribes to a specific topic and registers a callback function to be executed when a message is published.
49
+ * The callback function is executed only once.
50
+ *
51
+ * @param topic - The topic to subscribe to.
52
+ * @param callback - The callback function to be executed when a message is published.
53
+ */
54
+ subscribeOnce(topic, callback) {
55
+ PubSub.subscribeOnce(topic.toString(), (_, data) => callback(data));
56
+ }
57
+ /**
58
+ * Unsubscribes from a specific topic in the message bus.
59
+ *
60
+ * @param topic - The topic to unsubscribe from.
61
+ * @returns A string or boolean indicating the success of the unsubscribe operation.
62
+ */
63
+ unsubscribe(topic) {
64
+ return PubSub.unsubscribe(topic.toString());
65
+ }
66
+ }