@cheqd/did-provider-cheqd 4.5.5-develop.1 → 4.6.0
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.
- package/build/esm/agent/ICheqd.d.ts +291 -82
- package/build/esm/agent/ICheqd.d.ts.map +1 -1
- package/build/esm/agent/ICheqd.js +1567 -87
- package/build/esm/agent/ICheqd.js.map +1 -1
- package/build/esm/did-manager/cheqd-did-provider.d.ts +13 -2
- package/build/esm/did-manager/cheqd-did-provider.d.ts.map +1 -1
- package/build/esm/did-manager/cheqd-did-provider.js +10 -2
- package/build/esm/did-manager/cheqd-did-provider.js.map +1 -1
- package/build/esm/dkg-threshold/lit-protocol/v6.d.ts.map +1 -1
- package/build/esm/dkg-threshold/lit-protocol/v6.js +63 -33
- package/build/esm/dkg-threshold/lit-protocol/v6.js.map +1 -1
- package/build/esm/utils/helpers.d.ts +28 -7
- package/build/esm/utils/helpers.d.ts.map +1 -1
- package/build/esm/utils/helpers.js +120 -29
- package/build/esm/utils/helpers.js.map +1 -1
- package/build/tsconfig.esm.tsbuildinfo +1 -1
- package/build/tsconfig.types.tsbuildinfo +1 -1
- package/build/types/agent/ICheqd.d.ts +291 -82
- package/build/types/agent/ICheqd.d.ts.map +1 -1
- package/build/types/did-manager/cheqd-did-provider.d.ts +13 -2
- package/build/types/did-manager/cheqd-did-provider.d.ts.map +1 -1
- package/build/types/dkg-threshold/lit-protocol/v6.d.ts.map +1 -1
- package/build/types/utils/helpers.d.ts +28 -7
- package/build/types/utils/helpers.d.ts.map +1 -1
- package/package.json +6 -4
- package/src/agent/ICheqd.ts +2425 -372
- package/src/did-manager/cheqd-did-provider.ts +19 -4
- package/src/dkg-threshold/lit-protocol/v6.ts +65 -34
- package/src/utils/helpers.ts +172 -34
- package/tsconfig.json +2 -0
|
@@ -82,7 +82,16 @@ export const DefaultStatusList2021ResourceTypes = {
|
|
|
82
82
|
suspension: 'StatusList2021Suspension',
|
|
83
83
|
} as const;
|
|
84
84
|
|
|
85
|
-
export const
|
|
85
|
+
export const BitstringStatusPurposeTypes = {
|
|
86
|
+
refresh: 'refresh',
|
|
87
|
+
revocation: 'revocation',
|
|
88
|
+
suspension: 'suspension',
|
|
89
|
+
message: 'message',
|
|
90
|
+
} as const;
|
|
91
|
+
|
|
92
|
+
export const BitstringStatusListResourceType = 'BitstringStatusListCredential';
|
|
93
|
+
|
|
94
|
+
export const DefaultStatusListEncodings = {
|
|
86
95
|
base64url: 'base64url',
|
|
87
96
|
hex: 'hex',
|
|
88
97
|
} as const;
|
|
@@ -97,14 +106,19 @@ export type DefaultStatusList2021ResourceType =
|
|
|
97
106
|
export type DefaultStatusList2021StatusPurposeType =
|
|
98
107
|
(typeof DefaultStatusList2021StatusPurposeTypes)[keyof typeof DefaultStatusList2021StatusPurposeTypes];
|
|
99
108
|
|
|
100
|
-
export type
|
|
101
|
-
|
|
109
|
+
export type DefaultStatusListEncoding = (typeof DefaultStatusListEncodings)[keyof typeof DefaultStatusListEncodings];
|
|
110
|
+
|
|
111
|
+
export type BitstringStatusListPurposeType =
|
|
112
|
+
(typeof BitstringStatusPurposeTypes)[keyof typeof BitstringStatusPurposeTypes];
|
|
102
113
|
|
|
103
114
|
export type LinkedResource = Omit<MsgCreateResourcePayload, 'data'> & { data?: string };
|
|
104
115
|
|
|
105
116
|
export type ResourcePayload = Partial<MsgCreateResourcePayload>;
|
|
106
117
|
|
|
107
118
|
export type StatusList2021ResourcePayload = ResourcePayload & { resourceType: DefaultStatusList2021ResourceType };
|
|
119
|
+
export type BitstringStatusListResourcePayload = ResourcePayload & {
|
|
120
|
+
resourceType: typeof BitstringStatusListResourceType;
|
|
121
|
+
};
|
|
108
122
|
|
|
109
123
|
export type TImportableEd25519Key = Required<Pick<IKey, 'publicKeyHex' | 'privateKeyHex'>> & {
|
|
110
124
|
kid: TImportableEd25519Key['publicKeyHex'];
|
|
@@ -1076,10 +1090,11 @@ export class CheqdDIDProvider extends AbstractIdentifierProvider {
|
|
|
1076
1090
|
}
|
|
1077
1091
|
|
|
1078
1092
|
async instantiateDkgThresholdProtocolClient(dkgOptions: DkgOptions = this.dkgOptions): Promise<LitProtocol> {
|
|
1093
|
+
const signer = await this._aminoSigner;
|
|
1079
1094
|
return await LitProtocol.create({
|
|
1080
1095
|
chain: dkgOptions.chain || this.dkgOptions.chain,
|
|
1081
1096
|
litNetwork: dkgOptions.network || this.dkgOptions.network,
|
|
1082
|
-
cosmosAuthWallet:
|
|
1097
|
+
cosmosAuthWallet: signer,
|
|
1083
1098
|
});
|
|
1084
1099
|
}
|
|
1085
1100
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
/* eslint-disable no-empty-pattern */
|
|
1
3
|
import { OfflineAminoSigner, Secp256k1HdWallet, Secp256k1Wallet, StdSignDoc } from '@cosmjs/amino';
|
|
2
4
|
import { toString } from 'uint8arrays/to-string';
|
|
3
5
|
import { sha256 } from '@cosmjs/crypto';
|
|
@@ -22,6 +24,7 @@ import { LitProtocolDebugEnabled } from '../../utils/constants.js';
|
|
|
22
24
|
import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers';
|
|
23
25
|
import { ethers } from 'ethers';
|
|
24
26
|
import { LIT_RPC } from '@lit-protocol/constants';
|
|
27
|
+
import { initWasmBlsSdk } from '@lit-protocol/bls-sdk';
|
|
25
28
|
|
|
26
29
|
export type ThresholdEncryptionResult = {
|
|
27
30
|
encryptedString: Uint8Array;
|
|
@@ -152,16 +155,27 @@ export class LitProtocol {
|
|
|
152
155
|
secret: Uint8Array,
|
|
153
156
|
unifiedAccessControlConditions: NonNullable<UnifiedAccessControlConditions>
|
|
154
157
|
): Promise<ThresholdEncryptionResult> {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
158
|
+
try {
|
|
159
|
+
// encrypt
|
|
160
|
+
const { ciphertext: encryptedString, dataToEncryptHash: stringHash } = (await this.client.encrypt({
|
|
161
|
+
dataToEncrypt: secret,
|
|
162
|
+
unifiedAccessControlConditions,
|
|
163
|
+
})) satisfies EncryptStringMethodResult;
|
|
160
164
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
+
return {
|
|
166
|
+
encryptedString: fromString(encryptedString, 'base64'),
|
|
167
|
+
stringHash,
|
|
168
|
+
};
|
|
169
|
+
} catch (error: any) {
|
|
170
|
+
console.error('Encryption failed:', error);
|
|
171
|
+
if (error.stack) {
|
|
172
|
+
console.error('Stack:', error.stack);
|
|
173
|
+
}
|
|
174
|
+
// standardize error
|
|
175
|
+
throw new Error(
|
|
176
|
+
`[did-provider-cheqd]: lit-protocol: Encryption failed: ${(error as Error).message || error}`
|
|
177
|
+
);
|
|
178
|
+
}
|
|
165
179
|
}
|
|
166
180
|
|
|
167
181
|
async decrypt(
|
|
@@ -170,33 +184,44 @@ export class LitProtocol {
|
|
|
170
184
|
unifiedAccessControlConditions: NonNullable<UnifiedAccessControlConditions>,
|
|
171
185
|
capacityDelegationAuthSig?: GenericAuthSig
|
|
172
186
|
): Promise<string> {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
187
|
+
try {
|
|
188
|
+
// generate session signatures
|
|
189
|
+
const sessionSigs = await this.client.getSessionSigs({
|
|
190
|
+
chain: 'cheqd',
|
|
191
|
+
resourceAbilityRequests: [
|
|
192
|
+
{
|
|
193
|
+
resource: new LitAccessControlConditionResource('*'),
|
|
194
|
+
ability: LitAbility.AccessControlConditionDecryption,
|
|
195
|
+
},
|
|
196
|
+
],
|
|
197
|
+
capabilityAuthSigs: capacityDelegationAuthSig ? [capacityDelegationAuthSig] : undefined,
|
|
198
|
+
authNeededCallback: async ({}) => {
|
|
199
|
+
// generate auth signature
|
|
200
|
+
const authSig = await LitProtocol.generateAuthSignature(this.cosmosAuthWallet);
|
|
201
|
+
return authSig;
|
|
180
202
|
},
|
|
181
|
-
|
|
182
|
-
capabilityAuthSigs: capacityDelegationAuthSig ? [capacityDelegationAuthSig] : undefined,
|
|
183
|
-
authNeededCallback: async ({}) => {
|
|
184
|
-
// generate auth signature
|
|
185
|
-
const authSig = await LitProtocol.generateAuthSignature(this.cosmosAuthWallet);
|
|
186
|
-
return authSig;
|
|
187
|
-
},
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
// decrypt
|
|
191
|
-
const { decryptedData } = (await this.client.decrypt({
|
|
192
|
-
chain: this.chain,
|
|
193
|
-
ciphertext: encryptedString,
|
|
194
|
-
dataToEncryptHash: stringHash,
|
|
195
|
-
unifiedAccessControlConditions,
|
|
196
|
-
sessionSigs,
|
|
197
|
-
})) satisfies DecryptToStringMethodResult;
|
|
203
|
+
});
|
|
198
204
|
|
|
199
|
-
|
|
205
|
+
// decrypt
|
|
206
|
+
const { decryptedData } = (await this.client.decrypt({
|
|
207
|
+
chain: this.chain,
|
|
208
|
+
ciphertext: encryptedString,
|
|
209
|
+
dataToEncryptHash: stringHash,
|
|
210
|
+
unifiedAccessControlConditions,
|
|
211
|
+
sessionSigs,
|
|
212
|
+
})) satisfies DecryptToStringMethodResult;
|
|
213
|
+
|
|
214
|
+
return toString(decryptedData, 'utf-8');
|
|
215
|
+
} catch (error: any) {
|
|
216
|
+
console.error('Decryption failed:', error);
|
|
217
|
+
if (error.stack) {
|
|
218
|
+
console.error('Stack:', error.stack);
|
|
219
|
+
}
|
|
220
|
+
// standardize error
|
|
221
|
+
throw new Error(
|
|
222
|
+
`[did-provider-cheqd]: lit-protocol: Decryption failed: ${(error as Error).message || error}`
|
|
223
|
+
);
|
|
224
|
+
}
|
|
200
225
|
}
|
|
201
226
|
|
|
202
227
|
async delegateCapacitCredit(
|
|
@@ -300,6 +325,12 @@ export class LitProtocol {
|
|
|
300
325
|
|
|
301
326
|
const litProtocol = new LitProtocol(options as LitProtocolOptions);
|
|
302
327
|
await litProtocol.connect();
|
|
328
|
+
// Initialize BLS SDK WASM module explicitly
|
|
329
|
+
try {
|
|
330
|
+
await initWasmBlsSdk();
|
|
331
|
+
} catch (initError) {
|
|
332
|
+
throw new Error(`BLS SDK WASM initialization failed: ${(initError as Error).message || initError}`);
|
|
333
|
+
}
|
|
303
334
|
return litProtocol;
|
|
304
335
|
}
|
|
305
336
|
|
package/src/utils/helpers.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
1
2
|
import { DIDDocument } from '@veramo/core-types';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { EncodedList, EncodedListAsArray } from '../agent/index.js';
|
|
3
|
+
import { fromString, toString } from 'uint8arrays';
|
|
4
|
+
import { randomBytes as cryptoRandomBytes } from 'crypto';
|
|
5
|
+
import { Cheqd, EncodedList, EncodedListAsArray, StatusOptions } from '../agent/index.js';
|
|
5
6
|
|
|
6
7
|
export function isEncodedList(list: unknown): list is EncodedList {
|
|
7
8
|
return typeof list === 'string' && list.split('-').every((item) => typeof item === 'string' && item && item.length);
|
|
@@ -55,37 +56,10 @@ export async function randomFromRange(min: number, max: number, notIn: number[])
|
|
|
55
56
|
return random;
|
|
56
57
|
}
|
|
57
58
|
|
|
58
|
-
export async function randomUniqueSubsetInRange(min: number, max: number, count: number): Promise<Array<number>> {
|
|
59
|
-
const subset: number[] = [];
|
|
60
|
-
for (let i = 0; i < count; i++) {
|
|
61
|
-
subset.push(await randomFromRange(min, max, subset));
|
|
62
|
-
}
|
|
63
|
-
return subset;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
59
|
export async function randomBytes(length: number): Promise<Buffer> {
|
|
67
60
|
return Buffer.from(Array.from({ length }, () => Math.floor(Math.random() * 256)));
|
|
68
61
|
}
|
|
69
62
|
|
|
70
|
-
export async function randomUniqueSecret(options?: GenerateOptions): Promise<string> {
|
|
71
|
-
return generateSecret({
|
|
72
|
-
length: 64,
|
|
73
|
-
numbers: true,
|
|
74
|
-
symbols: true,
|
|
75
|
-
uppercase: true,
|
|
76
|
-
...options,
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export async function initialiseIndexArray(length: number): Promise<Array<boolean>> {
|
|
81
|
-
return Array(length).fill(true);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export async function shuffleArray<T>(array: Array<T>): Promise<Array<T>> {
|
|
85
|
-
const shuffled = array.sort(() => Math.random() - 0.5);
|
|
86
|
-
return shuffled;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
63
|
export async function toBlob(data: Uint8Array): Promise<Blob> {
|
|
90
64
|
return new Blob([data]);
|
|
91
65
|
}
|
|
@@ -100,10 +74,9 @@ export async function blobToHexString(blob: Blob): Promise<string> {
|
|
|
100
74
|
return toString(uint8Array, 'hex');
|
|
101
75
|
}
|
|
102
76
|
|
|
103
|
-
export function
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
});
|
|
77
|
+
export async function blobToUint8Array(blob: Blob): Promise<Uint8Array> {
|
|
78
|
+
const arrayBuffer = await blob.arrayBuffer();
|
|
79
|
+
return new Uint8Array(arrayBuffer);
|
|
107
80
|
}
|
|
108
81
|
|
|
109
82
|
export function getControllers(didDocument: DIDDocument): string[] {
|
|
@@ -118,3 +91,168 @@ export function getControllers(didDocument: DIDDocument): string[] {
|
|
|
118
91
|
}
|
|
119
92
|
return controllers;
|
|
120
93
|
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Check if encoded bitstring is valid base64url format
|
|
97
|
+
*/
|
|
98
|
+
export function isValidEncodedBitstring(encodedList: string): boolean {
|
|
99
|
+
try {
|
|
100
|
+
// Should be valid base64url
|
|
101
|
+
fromString(encodedList, 'base64url');
|
|
102
|
+
return true;
|
|
103
|
+
} catch {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Enhanced encoding function that returns metadata
|
|
108
|
+
export async function encodeWithMetadata(
|
|
109
|
+
symmetricEncryptionCiphertext: Blob,
|
|
110
|
+
thresholdEncryptionCiphertext: Uint8Array
|
|
111
|
+
): Promise<{ encodedList: string; symmetricLength: number }> {
|
|
112
|
+
const symmetricBytes = await blobToUint8Array(symmetricEncryptionCiphertext);
|
|
113
|
+
// Concatenate both byte arrays
|
|
114
|
+
const combinedBytes = new Uint8Array(symmetricBytes.length + thresholdEncryptionCiphertext.length);
|
|
115
|
+
combinedBytes.set(symmetricBytes, 0);
|
|
116
|
+
combinedBytes.set(thresholdEncryptionCiphertext, symmetricBytes.length);
|
|
117
|
+
|
|
118
|
+
// Encode as base64url
|
|
119
|
+
const encodedList = toString(combinedBytes, 'base64url');
|
|
120
|
+
|
|
121
|
+
return { encodedList, symmetricLength: symmetricBytes.length };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function decodeWithMetadata(
|
|
125
|
+
encodedList: string,
|
|
126
|
+
symmetricLength: number
|
|
127
|
+
): {
|
|
128
|
+
symmetricEncryptionCiphertext: Blob;
|
|
129
|
+
thresholdEncryptionCiphertext: Uint8Array;
|
|
130
|
+
} {
|
|
131
|
+
// Decode from base64url to bytes
|
|
132
|
+
const combinedBytes = fromString(encodedList, 'base64url');
|
|
133
|
+
|
|
134
|
+
// Split based on the symmetric length
|
|
135
|
+
const symmetricBytes = combinedBytes.slice(0, symmetricLength);
|
|
136
|
+
const thresholdBytes = combinedBytes.slice(symmetricLength);
|
|
137
|
+
|
|
138
|
+
// Return as desired types
|
|
139
|
+
return {
|
|
140
|
+
symmetricEncryptionCiphertext: new Blob([symmetricBytes]),
|
|
141
|
+
thresholdEncryptionCiphertext: thresholdBytes,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
interface IndexGenerationConfig {
|
|
146
|
+
statusSize?: number;
|
|
147
|
+
length?: number; // Bitstring length (default: 131072)
|
|
148
|
+
maxRetries?: number;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Generates a random statusListIndex based on external system constraints
|
|
152
|
+
*
|
|
153
|
+
* @param statusOptions - Constraints from external StatusListIndexManager
|
|
154
|
+
* @param config - Bitstring configuration (statusSize, length, etc.)
|
|
155
|
+
* @returns Random statusListIndex that satisfies all constraints
|
|
156
|
+
*/
|
|
157
|
+
export function generateRandomStatusListIndex(
|
|
158
|
+
statusOptions: StatusOptions,
|
|
159
|
+
config: IndexGenerationConfig = {}
|
|
160
|
+
): number {
|
|
161
|
+
const {
|
|
162
|
+
statusSize = Cheqd.DefaultBitstringStatusSize,
|
|
163
|
+
length = Cheqd.DefaultBitstringLength,
|
|
164
|
+
maxRetries = 1000,
|
|
165
|
+
} = config;
|
|
166
|
+
|
|
167
|
+
// If external system already provided a specific index, validate and return it
|
|
168
|
+
if (statusOptions.statusListIndex !== undefined) {
|
|
169
|
+
validateStatusListIndex(statusOptions.statusListIndex, statusOptions, config);
|
|
170
|
+
return statusOptions.statusListIndex;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Calculate valid range bounds
|
|
174
|
+
const bounds = calculateValidRange(statusOptions, config);
|
|
175
|
+
const excludedIndices = new Set(statusOptions.indexNotIn || []);
|
|
176
|
+
|
|
177
|
+
// Check if generation is possible
|
|
178
|
+
const totalPossibleIndices = bounds.end - bounds.start + 1;
|
|
179
|
+
if (excludedIndices.size >= totalPossibleIndices) {
|
|
180
|
+
throw new Error(`Cannot generate index: all indices in range [${bounds.start}, ${bounds.end}] are excluded`);
|
|
181
|
+
}
|
|
182
|
+
let attempts = 0;
|
|
183
|
+
while (attempts < maxRetries) {
|
|
184
|
+
// Generate cryptographically secure random index within range
|
|
185
|
+
const randBytes = cryptoRandomBytes(4);
|
|
186
|
+
const randomValue = randBytes.readUInt32BE(0);
|
|
187
|
+
|
|
188
|
+
// Map to valid range [bounds.start, bounds.end]
|
|
189
|
+
const rangeSize = bounds.end - bounds.start + 1;
|
|
190
|
+
const statusListIndex = bounds.start + (randomValue % rangeSize);
|
|
191
|
+
|
|
192
|
+
// Check if this index is excluded
|
|
193
|
+
if (!excludedIndices.has(statusListIndex)) {
|
|
194
|
+
return statusListIndex;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
attempts++;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
throw new Error(
|
|
201
|
+
`Failed to generate unique statusListIndex after ${maxRetries} attempts. ` +
|
|
202
|
+
`Range: [${bounds.start}, ${bounds.end}], Excluded: ${excludedIndices.size} indices`
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Validates a specific statusListIndex against constraints
|
|
207
|
+
*/
|
|
208
|
+
function validateStatusListIndex(index: number, statusOptions: StatusOptions, config: IndexGenerationConfig): void {
|
|
209
|
+
const bounds = calculateValidRange(statusOptions, config);
|
|
210
|
+
const excludedIndices = statusOptions.indexNotIn || [];
|
|
211
|
+
|
|
212
|
+
if (index < bounds.start || index > bounds.end) {
|
|
213
|
+
throw new Error(`StatusListIndex ${index} is outside valid range [${bounds.start}, ${bounds.end}]`);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (excludedIndices.includes(index)) {
|
|
217
|
+
throw new Error(`StatusListIndex ${index} is in the excluded list: [${excludedIndices.join(', ')}]`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Calculates the valid range for statusListIndex generation
|
|
222
|
+
*/
|
|
223
|
+
function calculateValidRange(
|
|
224
|
+
statusOptions: StatusOptions,
|
|
225
|
+
config: IndexGenerationConfig
|
|
226
|
+
): { start: number; end: number } {
|
|
227
|
+
const { statusSize = Cheqd.DefaultBitstringStatusSize, length = Cheqd.DefaultBitstringLength } = config;
|
|
228
|
+
|
|
229
|
+
// Calculate maximum possible index based on bitstring configuration
|
|
230
|
+
const totalBits = length * statusSize;
|
|
231
|
+
const alignedLength = Math.ceil(totalBits / 8) * 8;
|
|
232
|
+
const maxPossibleIndex = Math.floor(alignedLength / statusSize) - 1;
|
|
233
|
+
|
|
234
|
+
// Start with external system's range constraints
|
|
235
|
+
let start = statusOptions.statusListRangeStart ?? 0;
|
|
236
|
+
let end = statusOptions.statusListRangeEnd ?? maxPossibleIndex;
|
|
237
|
+
|
|
238
|
+
// Ensure range is within bitstring bounds
|
|
239
|
+
start = Math.max(0, start);
|
|
240
|
+
end = Math.min(maxPossibleIndex, end);
|
|
241
|
+
|
|
242
|
+
// Validate range
|
|
243
|
+
if (start > end) {
|
|
244
|
+
throw new Error(
|
|
245
|
+
`Invalid range: start (${start}) is greater than end (${end}). ` +
|
|
246
|
+
`Maximum possible index for this configuration: ${maxPossibleIndex}`
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (start < 0 || end > maxPossibleIndex) {
|
|
251
|
+
throw new Error(
|
|
252
|
+
`Range [${start}, ${end}] exceeds valid bounds [0, ${maxPossibleIndex}] ` +
|
|
253
|
+
`for statusSize=${statusSize} and length=${length}`
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return { start, end };
|
|
258
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
"sourceMap": true,
|
|
6
6
|
"module": "NodeNext",
|
|
7
7
|
"esModuleInterop": true,
|
|
8
|
+
"resolveJsonModule": true,
|
|
8
9
|
"downlevelIteration": true,
|
|
9
10
|
"declarationMap": true,
|
|
10
11
|
"declaration": true,
|
|
@@ -12,6 +13,7 @@
|
|
|
12
13
|
"noImplicitAny": false,
|
|
13
14
|
"emitDecoratorMetadata": true,
|
|
14
15
|
"experimentalDecorators": true,
|
|
16
|
+
"outDir": "build",
|
|
15
17
|
"skipLibCheck": true,
|
|
16
18
|
"rootDir": "src",
|
|
17
19
|
},
|