File

libs/clients/src/wallet-client/wallet-client.service.ts

Description

Service to interact with the wallet service of basic functions to deal with cryptographic functions like validating a signature.

Index

Properties
Methods

Constructor

constructor(clientWallet: ClientTCP, logger: Logger, configService: ConfigService, httpService: HttpService)

Imports required services.

Parameters :
Name Type Optional
clientWallet ClientTCP No
logger Logger No
configService ConfigService No
httpService HttpService No

Methods

Public Async checkSignature
checkSignature(publicKey: PublicKeyJwkDto, input: string, signature: string)

Checks a given input is signed by a given key.

Parameters :
Name Type Optional
publicKey PublicKeyJwkDto No
input string No
signature string No
Returns : Promise<boolean>
Public Async getCryptoKeyServiceByKey
getCryptoKeyServiceByKey(key: JsonWebKey)

Returns the keycrptoservice based on the key type

Parameters :
Name Type Optional
key JsonWebKey No
Returns : Promise<CryptoKeyService>

object of the cryptokeyservice

Async getOwnInformation
getOwnInformation()

Returns information to identify the issuer.

Returns : Promise<string>
getPublicKey
getPublicKey()

Returns the public key

Public importKey
importKey(keyValue: PublicKeyJwkDto)

Imports the crypto key object from a jwk string

Parameters :
Name Type Optional
keyValue PublicKeyJwkDto No
Returns : Promise<CryptoKey>
onModuleDestroy
onModuleDestroy()

Will close the connection when the application shuts down.

Returns : void
Async requestSignedDid
requestSignedDid(invite: InviteNode)

Requests a signed did to be added to the network. Returns a list of validators to connect with

Parameters :
Name Type Optional
invite InviteNode No
Returns : Promise<string[]>
Async setOwnInformation
setOwnInformation(id: string)

Returns information to identify the issuer.

Parameters :
Name Type Optional
id string No
Returns : Promise<void>
Public Async sign
sign(input: string)

Signs a given string.

Parameters :
Name Type Optional
input string No
Async signIssuer
signIssuer(value: any)

Converts a nested object to an ordered json string and signs it.

Parameters :
Name Type Optional
value any No

Properties

Private cryptoKeyServices
Type : CryptoKeyService[]

An array containing instances of cryptokey services to handle different key types.

Static defaultHashAlgorithm
Type : string
Default value : 'sha256'

Hashing algorithm that should be used.

import { ClientTCP, RpcException } from '@nestjs/microservices';
import { ConfigService } from '@tc/config';
import { Connection } from '@shared/connection';
import { CreateDidIdDto } from '@tc/transactions/did-id/dto/create-did-id.dto';
import {
  CryptoKeyService,
  ECCryptoKeyService,
  RSACryptoKeyService,
  importKey,
  sortKeys,
  verifySignature,
} from '@trustcerts/crypto';
import { HttpService } from '@nestjs/axios';
import { Inject, Injectable, OnModuleDestroy } from '@nestjs/common';
import { InviteNode } from '@tc/invite/dto/invite-node.dto';
import { Logger } from 'winston';
import { PublicKeyInformation } from '@tc/clients/wallet-client/constants';
import { PublicKeyJwkDto } from '@tc/transactions/did-id/dto/public-key-jwk.dto';
import { SignatureDto } from '@tc/blockchain/transaction/signature.dto';
import {
  WALLET_GET_ID,
  WALLET_PUB_KEY,
  WALLET_SET_ID,
  WALLET_SIGN,
} from '@tc/clients/wallet-client/endpoints';
import { WALLET_TCP_INJECTION } from './constants';
import { lastValueFrom } from 'rxjs';

/**
 * Service to interact with the wallet service of basic functions to deal with cryptographic functions like validating a signature.
 */
@Injectable()
export class WalletClientService implements OnModuleDestroy {
  /**
   * An array containing instances of cryptokey services to handle different key types.
   */
  private cryptoKeyServices: CryptoKeyService[];

  /**
   * Hashing algorithm that should be used.
   */
  public static defaultHashAlgorithm = 'sha256';

  /**
   * Imports required services.
   * @param clientWallet
   * @param logger
   * @param configService
   * @param httpService
   */
  constructor(
    @Inject(WALLET_TCP_INJECTION) private clientWallet: ClientTCP,
    @Inject('winston') private readonly logger: Logger,
    private readonly configService: ConfigService,
    private readonly httpService: HttpService,
  ) {
    this.cryptoKeyServices = [
      new RSACryptoKeyService(),
      new ECCryptoKeyService(),
    ];
  }

  /**
   * Checks a given input is signed by a given key.
   * @param publicKey
   * @param {string} input
   * @param {string} signature
   */
  public async checkSignature(
    publicKey: PublicKeyJwkDto,
    input: string,
    signature: string,
  ): Promise<boolean> {
    const key = await this.importKey(publicKey);
    return verifySignature(input, signature, key);
  }

  /**
   * Imports the crypto key object from a jwk string
   * @param keyValue
   * @private
   */
  public importKey(keyValue: PublicKeyJwkDto): Promise<CryptoKey> {
    return importKey(keyValue, 'jwk', ['verify']);
  }

  /**
   * Returns the public key
   */
  getPublicKey(): Promise<PublicKeyInformation> {
    return lastValueFrom(
      this.clientWallet.send<PublicKeyInformation>(WALLET_PUB_KEY, {}),
    );
  }

  /**
   * Returns information to identify the issuer.
   */
  async getOwnInformation(): Promise<string> {
    return lastValueFrom(this.clientWallet.send<string>(WALLET_GET_ID, {}));
  }

  /**
   * Returns information to identify the issuer.
   */
  async setOwnInformation(id: string): Promise<void> {
    return new Promise<void>((resolve) => {
      this.clientWallet.send<string>(WALLET_SET_ID, id).subscribe({
        complete: () => resolve(),
      });
    });
  }

  /**
   * Signs a given string.
   * @param {string} input
   * @returns {string}
   */
  public async sign(input: string): Promise<SignatureDto> {
    return lastValueFrom(
      this.clientWallet.send<SignatureDto>(WALLET_SIGN, input),
    );
  }

  /**
   * Converts a nested object to an ordered json string and signs it.
   * @param value
   */
  async signIssuer(value: any): Promise<SignatureDto> {
    return this.sign(JSON.stringify(sortKeys(value)));
  }

  /**
   * Requests a signed did to be added to the network. Returns a list of validators to connect with
   */
  async requestSignedDid(invite: InviteNode): Promise<string[]> {
    this.logger.debug({
      message: `request cert with code: ${invite.secret}`,
      labels: { source: this.constructor.name },
    });
    const connection = new Connection(this.logger, this.httpService);
    connection.peer = invite.endpoint;
    await connection.waitUntilHealthy();

    // set the new did
    await this.setOwnInformation(invite.id);

    const key = await this.getPublicKey();
    const create: CreateDidIdDto = {
      secret: invite.secret,
      identifier: await this.getOwnInformation(),
      publicKey: key.value,
    };
    try {
      const response = await lastValueFrom(
        this.httpService.post<string[]>(
          `${await connection.getHttpEndpoint()}/did/create`,
          create,
          {
            headers: {
              Authorization: `Bearer ${this.configService.getString(
                'NETWORK_SECRET',
              )}`,
            },
          },
        ),
      );

      this.logger.debug({
        message: `got endpoints: ${response.data}`,
        labels: { source: this.constructor.name },
      });
      return response.data;
    } catch (err: any) {
      this.logger.error({
        message: JSON.stringify(err.response.data),
        labels: { source: this.constructor.name },
      });
      throw new RpcException(err);
    }
  }

  /**
   * Returns the keycrptoservice based on the key type
   * @param algorithm of the key
   * @returns object of the cryptokeyservice
   */
  public async getCryptoKeyServiceByKey(
    key: JsonWebKey,
  ): Promise<CryptoKeyService> {
    for (const service of this.cryptoKeyServices) {
      if (await service.isCorrectKeyType(key)) return service;
    }
    throw Error(`no service found for ${JSON.stringify(key)}`);
  }

  /**
   * Will close the connection when the application shuts down.
   */
  onModuleDestroy() {
    this.clientWallet.close();
  }
}

results matching ""

    No results matching ""