Dorian 0d073fa89e Add comprehensive installation and setup documentation
- Add GETTING_STARTED.md with quick start guide and development modes
- Add INSTALL.sh automated installation script
- Add INSTALLATION_CHECKLIST.md, INSTALLATION_SUCCESS.md, and INSTALLATION_SUMMARY.md
- Add QUICK_REFERENCE.md for common commands
- Add SETUP_GUIDE.md with detailed setup instructions
- Update README.md with improved project overview
- Add did-wallet app dependencies and node_modules
2026-01-27 17:18:21 +00:00

271 lines
13 KiB
JavaScript

var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import * as URI from 'uri-js';
import ErrorCode from './ErrorCode.js';
import InputValidator from './InputValidator.js';
import IonError from './IonError.js';
import IonSdkConfig from './IonSdkConfig.js';
import JsonCanonicalizer from './JsonCanonicalizer.js';
import Multihash from './Multihash.js';
import OperationKeyType from './enums/OperationKeyType.js';
import OperationType from './enums/OperationType.js';
import PatchAction from './enums/PatchAction.js';
/**
* Class containing operations related to ION requests.
*/
export default class IonRequest {
/**
* Creates an ION DID create request.
* @param input.document The initial state to be associate with the ION DID to be created using a `replace` document patch action.
*/
static createCreateRequest(input) {
return __awaiter(this, void 0, void 0, function* () {
const recoveryKey = input.recoveryKey;
const updateKey = input.updateKey;
const didDocumentKeys = input.document.publicKeys;
const services = input.document.services;
// Validate recovery and update public keys.
InputValidator.validateEs256kOperationKey(recoveryKey, OperationKeyType.Public);
InputValidator.validateEs256kOperationKey(updateKey, OperationKeyType.Public);
// Validate all given DID Document keys.
IonRequest.validateDidDocumentKeys(didDocumentKeys);
// Validate all given service.
IonRequest.validateServices(services);
const hashAlgorithmInMultihashCode = IonSdkConfig.hashAlgorithmInMultihashCode;
const patches = [{
action: PatchAction.Replace,
document: input.document
}];
const delta = {
updateCommitment: yield Multihash.canonicalizeThenDoubleHashThenEncode(updateKey, hashAlgorithmInMultihashCode),
patches
};
IonRequest.validateDeltaSize(delta);
const deltaHash = yield Multihash.canonicalizeThenHashThenEncode(delta, hashAlgorithmInMultihashCode);
const suffixData = {
deltaHash,
recoveryCommitment: yield Multihash.canonicalizeThenDoubleHashThenEncode(recoveryKey, hashAlgorithmInMultihashCode)
};
const operationRequest = {
type: OperationType.Create,
suffixData: suffixData,
delta: delta
};
return operationRequest;
});
}
static createDeactivateRequest(input) {
return __awaiter(this, void 0, void 0, function* () {
// Validate DID suffix
IonRequest.validateDidSuffix(input.didSuffix);
// Validates recovery public key
InputValidator.validateEs256kOperationKey(input.recoveryPublicKey, OperationKeyType.Public);
const hashAlgorithmInMultihashCode = IonSdkConfig.hashAlgorithmInMultihashCode;
const revealValue = yield Multihash.canonicalizeThenHashThenEncode(input.recoveryPublicKey, hashAlgorithmInMultihashCode);
const dataToBeSigned = {
didSuffix: input.didSuffix,
recoveryKey: input.recoveryPublicKey
};
const compactJws = yield input.signer.sign({ alg: 'ES256K' }, dataToBeSigned);
return {
type: OperationType.Deactivate,
didSuffix: input.didSuffix,
revealValue: revealValue,
signedData: compactJws
};
});
}
static createRecoverRequest(input) {
return __awaiter(this, void 0, void 0, function* () {
// Validate DID suffix
IonRequest.validateDidSuffix(input.didSuffix);
// Validate recovery public key
InputValidator.validateEs256kOperationKey(input.recoveryPublicKey, OperationKeyType.Public);
// Validate next recovery public key
InputValidator.validateEs256kOperationKey(input.nextRecoveryPublicKey, OperationKeyType.Public);
// Validate next update public key
InputValidator.validateEs256kOperationKey(input.nextUpdatePublicKey, OperationKeyType.Public);
// Validate all given DID Document keys.
IonRequest.validateDidDocumentKeys(input.document.publicKeys);
// Validate all given service.
IonRequest.validateServices(input.document.services);
const hashAlgorithmInMultihashCode = IonSdkConfig.hashAlgorithmInMultihashCode;
const revealValue = yield Multihash.canonicalizeThenHashThenEncode(input.recoveryPublicKey, hashAlgorithmInMultihashCode);
const patches = [{
action: PatchAction.Replace,
document: input.document
}];
const nextUpdateCommitmentHash = yield Multihash.canonicalizeThenDoubleHashThenEncode(input.nextUpdatePublicKey, hashAlgorithmInMultihashCode);
const delta = {
patches,
updateCommitment: nextUpdateCommitmentHash
};
const deltaHash = yield Multihash.canonicalizeThenHashThenEncode(delta, hashAlgorithmInMultihashCode);
const nextRecoveryCommitmentHash = yield Multihash.canonicalizeThenDoubleHashThenEncode(input.nextRecoveryPublicKey, hashAlgorithmInMultihashCode);
const dataToBeSigned = {
recoveryCommitment: nextRecoveryCommitmentHash,
recoveryKey: input.recoveryPublicKey,
deltaHash: deltaHash
};
const compactJws = yield input.signer.sign({ alg: 'ES256K' }, dataToBeSigned);
return {
type: OperationType.Recover,
didSuffix: input.didSuffix,
revealValue: revealValue,
delta: delta,
signedData: compactJws
};
});
}
static createUpdateRequest(input) {
return __awaiter(this, void 0, void 0, function* () {
// Validate DID suffix
IonRequest.validateDidSuffix(input.didSuffix);
// Validate update public key
InputValidator.validateEs256kOperationKey(input.updatePublicKey, OperationKeyType.Public);
// Validate next update public key
InputValidator.validateEs256kOperationKey(input.nextUpdatePublicKey, OperationKeyType.Public);
// Validate all given service.
IonRequest.validateServices(input.servicesToAdd);
// Validate all given DID Document keys.
IonRequest.validateDidDocumentKeys(input.publicKeysToAdd);
// Validate all given service id to remove.
if (input.idsOfServicesToRemove !== undefined) {
for (const id of input.idsOfServicesToRemove) {
InputValidator.validateId(id);
}
}
// Validate all given public key id to remove.
if (input.idsOfPublicKeysToRemove !== undefined) {
for (const id of input.idsOfPublicKeysToRemove) {
InputValidator.validateId(id);
}
}
const patches = [];
// Create patches for add services
const servicesToAdd = input.servicesToAdd;
if (servicesToAdd !== undefined && servicesToAdd.length > 0) {
const patch = {
action: PatchAction.AddServices,
services: servicesToAdd
};
patches.push(patch);
}
// Create patches for remove services
const idsOfServicesToRemove = input.idsOfServicesToRemove;
if (idsOfServicesToRemove !== undefined && idsOfServicesToRemove.length > 0) {
const patch = {
action: PatchAction.RemoveServices,
ids: idsOfServicesToRemove
};
patches.push(patch);
}
// Create patches for adding public keys
const publicKeysToAdd = input.publicKeysToAdd;
if (publicKeysToAdd !== undefined && publicKeysToAdd.length > 0) {
const patch = {
action: PatchAction.AddPublicKeys,
publicKeys: publicKeysToAdd
};
patches.push(patch);
}
// Create patch for removing public keys
const idsOfPublicKeysToRemove = input.idsOfPublicKeysToRemove;
if (idsOfPublicKeysToRemove !== undefined && idsOfPublicKeysToRemove.length > 0) {
const patch = {
action: PatchAction.RemovePublicKeys,
ids: idsOfPublicKeysToRemove
};
patches.push(patch);
}
const hashAlgorithmInMultihashCode = IonSdkConfig.hashAlgorithmInMultihashCode;
const revealValue = yield Multihash.canonicalizeThenHashThenEncode(input.updatePublicKey, hashAlgorithmInMultihashCode);
const nextUpdateCommitmentHash = yield Multihash.canonicalizeThenDoubleHashThenEncode(input.nextUpdatePublicKey, hashAlgorithmInMultihashCode);
const delta = {
patches,
updateCommitment: nextUpdateCommitmentHash
};
const deltaHash = yield Multihash.canonicalizeThenHashThenEncode(delta, hashAlgorithmInMultihashCode);
const dataToBeSigned = {
updateKey: input.updatePublicKey,
deltaHash
};
const compactJws = yield input.signer.sign({ alg: 'ES256K' }, dataToBeSigned);
return {
type: OperationType.Update,
didSuffix: input.didSuffix,
revealValue,
delta,
signedData: compactJws
};
});
}
static validateDidSuffix(didSuffix) {
Multihash.validateEncodedHashComputedUsingSupportedHashAlgorithm(didSuffix, 'didSuffix');
}
static validateDidDocumentKeys(publicKeys) {
if (publicKeys === undefined) {
return;
}
// Validate each public key.
const publicKeyIdSet = new Set();
for (const publicKey of publicKeys) {
if (Array.isArray(publicKey.publicKeyJwk)) {
throw new IonError(ErrorCode.DidDocumentPublicKeyMissingOrIncorrectType, `DID Document key 'publicKeyJwk' property is not a non-array object.`);
}
InputValidator.validateId(publicKey.id);
// 'id' must be unique across all given keys.
if (publicKeyIdSet.has(publicKey.id)) {
throw new IonError(ErrorCode.DidDocumentPublicKeyIdDuplicated, `DID Document key with ID '${publicKey.id}' already exists.`);
}
publicKeyIdSet.add(publicKey.id);
InputValidator.validatePublicKeyPurposes(publicKey.purposes);
}
}
static validateServices(services) {
if (services !== undefined && services.length !== 0) {
const serviceIdSet = new Set();
for (const service of services) {
IonRequest.validateService(service);
if (serviceIdSet.has(service.id)) {
throw new IonError(ErrorCode.DidDocumentServiceIdDuplicated, 'Service id has to be unique');
}
serviceIdSet.add(service.id);
}
}
}
static validateService(service) {
InputValidator.validateId(service.id);
const maxTypeLength = 30;
if (service.type.length > maxTypeLength) {
const errorMessage = `Service endpoint type length ${service.type.length} exceeds max allowed length of ${maxTypeLength}.`;
throw new IonError(ErrorCode.ServiceTypeTooLong, errorMessage);
}
// Throw error if `serviceEndpoint` is an array.
if (Array.isArray(service.serviceEndpoint)) {
const errorMessage = 'Service endpoint value cannot be an array.';
throw new IonError(ErrorCode.ServiceEndpointCannotBeAnArray, errorMessage);
}
if (typeof service.serviceEndpoint === 'string') {
const uri = URI.parse(service.serviceEndpoint);
if (uri.error !== undefined) {
throw new IonError(ErrorCode.ServiceEndpointStringNotValidUri, `Service endpoint string '${service.serviceEndpoint}' is not a URI.`);
}
}
}
static validateDeltaSize(delta) {
const deltaBytes = JsonCanonicalizer.canonicalizeAsBytes(delta);
if (deltaBytes.length > IonSdkConfig.maxCanonicalizedDeltaSizeInBytes) {
const errorMessage = `Delta of ${deltaBytes.length} bytes exceeded limit of ${IonSdkConfig.maxCanonicalizedDeltaSizeInBytes} bytes.`;
throw new IonError(ErrorCode.DeltaExceedsMaximumSize, errorMessage);
}
}
}
//# sourceMappingURL=IonRequest.js.map