Skip to content

Commit

Permalink
Merge pull request #598 from credebl/feat/multiple-did-methods
Browse files Browse the repository at this point in the history
feat: platform agent up
  • Loading branch information
KulkarniShashank authored Mar 15, 2024
2 parents ccf9728 + a5eaab6 commit cbcdf55
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 89 deletions.
67 changes: 34 additions & 33 deletions apps/agent-service/src/agent-service.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export class AgentServiceService {
this.agentServiceRepository.getAgentTypeDetails(),
this.agentServiceRepository.getLedgerDetails(agentSpinupDto.ledgerName ? agentSpinupDto.ledgerName : [Ledgers.Indicio_Demonet])
]);

let orgData;
if (!user?.userId && agentSpinupDto?.platformAdminEmail) {

Expand Down Expand Up @@ -158,7 +158,6 @@ export class AgentServiceService {
agentSpinupDto.tenant = agentSpinupDto.tenant || false;
agentSpinupDto.ledgerName = agentSpinupDto.ledgerName?.length ? agentSpinupDto.ledgerName : [Ledgers.Indicio_Demonet];


// Invoke function for validate platform configuration
this.validatePlatformConfig(platformConfig);

Expand Down Expand Up @@ -338,13 +337,28 @@ export class AgentServiceService {
}

async _agentSpinup(walletProvisionPayload: IWalletProvision, agentSpinupDto: IAgentSpinupDto, orgApiKey: string, orgData: organisation, user: IUserRequestInterface, socket: Socket, ledgerId: string[], agentProcess: ICreateOrgAgent): Promise<void> {
try {
let ledgerIdData = [];

try {
if (agentSpinupDto.method !== DidMethod.KEY && agentSpinupDto.method !== DidMethod.WEB) {

const { network } = agentSpinupDto;
const ledger = await ledgerName(network);
const ledgerList = await this._getALlLedgerDetails() as unknown as LedgerListResponse;
const isLedgerExist = ledgerList.response.find((existingLedgers) => existingLedgers.name === ledger);
if (!isLedgerExist) {
throw new BadRequestException(
ResponseMessages.agent.error.invalidLedger,
{ cause: new Error(), description: ResponseMessages.errorMessages.notFound }
);
}

ledgerIdData = await this.agentServiceRepository.getLedgerDetails(ledger);
}
/**
* Invoke wallet create and provision with agent
*/
const walletProvision = await this._walletProvision(walletProvisionPayload);

if (!walletProvision?.response) {
this.logger.error(`Agent not able to spin-up`);
throw new BadRequestException(
Expand All @@ -354,7 +368,6 @@ export class AgentServiceService {
}
const agentDetails = walletProvision.response;
const agentEndPoint = `${process.env.API_GATEWAY_PROTOCOL}://${agentDetails.agentEndPoint}`;

/**
* Socket connection
*/
Expand All @@ -374,11 +387,14 @@ export class AgentServiceService {
orgId: orgData.id,
walletName: agentSpinupDto.walletName,
clientSocketId: agentSpinupDto.clientSocketId,
ledgerId,
method: agentSpinupDto.method,
role: agentSpinupDto.role,
network: agentSpinupDto.network,
keyType: agentSpinupDto.keyType,
ledgerId: ledgerIdData ? ledgerIdData.map(item => item.id) : null,
did: agentSpinupDto.did,
id: agentProcess?.id
};

/**
* Store organization agent details
*/
Expand Down Expand Up @@ -446,7 +462,7 @@ export class AgentServiceService {
/**
* Organization storage data
*/
const storeOrgAgentData = await this._buildStoreOrgAgentData(payload, getDidMethod, orgAgentTypeId);
const storeOrgAgentData = await this._buildStoreOrgAgentData(payload, getDidMethod, `${orgAgentTypeId}`);
/**
* Store org agent details
*/
Expand All @@ -460,33 +476,19 @@ export class AgentServiceService {


private async _getAgentDid(payload: IStoreOrgAgentDetails): Promise<object> {
const { agentEndPoint, apiKey, ledgerId } = payload;

//we take this values as static because of latest changes in afj controller to up agent of platform
const platformAgent: IPlatformAgent = {
seed: `${CommonConstants.SEED}`,
keyType: `${CommonConstants.KEYTYPE}`,
method: `${CommonConstants.METHOD}`,
network: `${CommonConstants.NETWORK}`,
role: `${CommonConstants.ROLE}`
};
const { agentEndPoint, apiKey, ledgerId, seed, keyType, method, network, role, did } = payload;
const writeDid = 'write-did';
const ledgerDetails = await this.agentServiceRepository.getGenesisUrl(ledgerId);
const agentDidWriteUrl = `${agentEndPoint}${CommonConstants.URL_AGENT_WRITE_DID}`;
return this._retryAgentSpinup(agentDidWriteUrl, apiKey, writeDid, platformAgent);
return this._retryAgentSpinup(agentDidWriteUrl, apiKey, writeDid, seed, keyType, method, network, role, did);

}

private async _getDidMethod(payload: IStoreOrgAgentDetails, agentDid: object): Promise<object> {
const getDidDic = 'get-did-doc';
const platformAgent: IPlatformAgent = {
seed: `${CommonConstants.SEED}`,
keyType: `${CommonConstants.KEYTYPE}`,
method: `${CommonConstants.METHOD}`,
network: `${CommonConstants.NETWORK}`,
role: `${CommonConstants.ROLE}`
};
const getDidMethodUrl = `${payload.agentEndPoint}${CommonConstants.URL_AGENT_GET_DID}`.replace('#', agentDid['did']);
return this._retryAgentSpinup(getDidMethodUrl, payload.apiKey, getDidDic, platformAgent);
const { agentEndPoint, apiKey, seed, keyType, method, network, role } = payload;
const getDidDoc = 'get-did-doc';
const getDidMethodUrl = `${agentEndPoint}${CommonConstants.URL_AGENT_GET_DID}/${agentDid['did']}`;
return this._retryAgentSpinup(getDidMethodUrl, apiKey, getDidDoc, seed, keyType, method, network, role, `${agentDid['did']}`);
}

private _buildStoreOrgAgentData(payload: IStoreOrgAgentDetails, getDidMethod: object, orgAgentTypeId: string): IStoreOrgAgentDetails {
Expand Down Expand Up @@ -528,20 +530,19 @@ export class AgentServiceService {
}


async _retryAgentSpinup(agentUrl: string, apiKey: string, agentApiState: string, payload: IPlatformAgent): Promise<object> {

const { seed, keyType, method, network, role} = payload;
async _retryAgentSpinup(agentUrl: string, apiKey: string, agentApiState: string, seed: string, keyType: string, method: string, network: string, role: string, did: string): Promise<object> {
const retryOptions = {
retries: 10
};
try {
return retry(async () => {
if (agentApiState === 'write-did') {
return this.commonService.httpPost(agentUrl, { seed, keyType, method, network, role}, { headers: { 'authorization': apiKey } });
return this.commonService.httpPost(agentUrl, { seed, keyType, method, network, role, did}, { headers: { 'authorization': apiKey } });
} else if (agentApiState === 'get-did-doc') {
return this.commonService.httpGet(agentUrl, { headers: { 'authorization': apiKey } });
}
}, retryOptions);

} catch (error) {
throw error;
}
Expand Down
47 changes: 29 additions & 18 deletions apps/agent-service/src/interface/agent-service.interface.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import { UserRoleOrgPermsDto } from 'apps/api-gateway/src/dtos/user-role-org-perms.dto';

export interface IAgentSpinupDto {

walletName: string;
walletPassword: string;
seed: string;
orgId?: string;
orgName?: string;
ledgerId?: string[];
keyType: string;
domain?: string;
privatekey?: string;
endpoint?: string;
role?: string;
network?: string
endorserDid?: string
method: string;
did?: string;
agentType?: string;
transactionApproval?: boolean;
Expand Down Expand Up @@ -149,23 +156,27 @@ export interface IPlatformConfigDto {
}

export interface IStoreOrgAgentDetails {
id?: string;
clientSocketId?: string;
agentEndPoint?: string;
apiKey?: string;
seed?: string;
did?: string;
verkey?: string;
isDidPublic?: boolean;
agentSpinUpStatus?: number;
walletName?: string;
agentsTypeId?: string;
orgId?: string;
agentId?: string;
orgAgentTypeId?: string;
tenantId?: string;
ledgerId?: string[];
agentType?: string;
id?: string;
clientSocketId?: string;
agentEndPoint?: string;
apiKey?: string;
seed?: string;
keyType?: string;
method?: string;
network?: string;
role?: string;
did?: string;
verkey?: string;
isDidPublic?: boolean;
agentSpinUpStatus?: number;
walletName?: string;
agentsTypeId?: string;
orgId?: string;
agentId?: string;
orgAgentTypeId?: string;
tenantId?: string;
ledgerId?: string[];
agentType?: string;
}

export interface IStoreOrgAgent {
Expand Down
8 changes: 6 additions & 2 deletions apps/agent-service/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,12 @@ async function bootstrap(): Promise<void> {
orgName: `${CommonConstants.PLATFORM_ADMIN_ORG}`,
platformAdminEmail: process.env.PLATFORM_ADMIN_EMAIL,
tenant: true,
ledgerName: [Ledgers.Bcovrin_Testnet, Ledgers.Indicio_Demonet, Ledgers.Indicio_Mainnet, Ledgers.Indicio_Testnet]
};
ledgerName: [Ledgers.Bcovrin_Testnet, Ledgers.Indicio_Demonet, Ledgers.Indicio_Mainnet, Ledgers.Indicio_Testnet],
keyType: `${CommonConstants.KEYTYPE}`,
method: `${CommonConstants.METHOD}`,
network: `${CommonConstants.NETWORK}`,
role: `${CommonConstants.ROLE}`
};

const agentService = app.get(AgentServiceService);
await agentService.walletProvision(agentSpinupPayload, user);
Expand Down
17 changes: 9 additions & 8 deletions apps/api-gateway/src/agent-service/agent-service.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { validateDid } from '@credebl/common/did.validator';
import { CreateWalletDto } from './dto/create-wallet.dto';

const seedLength = 32;

@UseFilters(CustomExceptionFilter)
@Controller()
@ApiTags('agents')
Expand Down Expand Up @@ -122,14 +123,6 @@ export class AgentController {
@Res() res: Response
): Promise<Response> {

if (seedLength !== agentSpinupDto.seed.length) {
this.logger.error(`seed must be at most 32 characters.`);
throw new BadRequestException(
ResponseMessages.agent.error.seedChar,
{ cause: new Error(), description: ResponseMessages.errorMessages.badRequest }
);
}

const regex = new RegExp('^[a-zA-Z0-9]+$');

if (!regex.test(agentSpinupDto.walletName)) {
Expand Down Expand Up @@ -246,6 +239,14 @@ export class AgentController {

validateDid(createDidDto);

if (seedLength !== createDidDto.seed.length) {
this.logger.error(`seed must be at most 32 characters.`);
throw new BadRequestException(
ResponseMessages.agent.error.seedChar,
{ cause: new Error(), description: ResponseMessages.errorMessages.badRequest }
);
}

const didDetails = await this.agentService.createDid(createDidDto, orgId, user);

const finalResponse: IResponse = {
Expand Down
33 changes: 7 additions & 26 deletions apps/api-gateway/src/agent-service/dto/agent-service.dto.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { trim } from '@credebl/common/cast.helper';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Transform } from 'class-transformer';
import { IsBoolean, IsNotEmpty, IsOptional, IsString, Matches, MaxLength, MinLength, IsArray } from 'class-validator';
import { IsBoolean, IsNotEmpty, IsOptional, IsString, Matches, MaxLength, MinLength } from 'class-validator';
import { CreateDidDto } from './create-did.dto';
const regex = /^[a-zA-Z0-9 ]*$/;
export class AgentSpinupDto {
export class AgentSpinupDto extends CreateDidDto {

@ApiProperty()
@MaxLength(25, { message: 'Maximum length for wallet must be 25 characters.' })
@IsString({ message: 'label must be in string format.' })
@Transform(({ value }) => trim(value))
@IsNotEmpty({ message: 'walletName is required' })
@MinLength(2, { message: 'walletName must be at least 2 characters.' })
@MaxLength(50, { message: 'walletName must be at most 50 characters.' })
@IsString({ message: 'walletName must be in string format.' })
@MinLength(2, { message: 'Minimum length for wallet name must be 2 characters.' })
@Matches(regex, { message: 'Wallet name must not contain special characters.' })
@Matches(/^\S*$/, {
message: 'Spaces are not allowed in wallet name'
message: 'Spaces are not allowed in label'
})
walletName: string;

Expand All @@ -23,31 +23,12 @@ export class AgentSpinupDto {
@IsNotEmpty({ message: 'Password is required.' })
walletPassword: string;

@ApiProperty({ example: 'dfuhgfklskmjngrjekjfgjjfkoekfdad' })
@Transform(({ value }) => trim(value))
@IsNotEmpty({ message: 'seed is required' })
@MaxLength(32, { message: 'seed must be at most 32 characters.' })
@IsString({ message: 'seed must be in string format.' })
@Matches(/^\S*$/, {
message: 'Spaces are not allowed in seed'
})
seed: string;

@ApiProperty({ example: 'XzFjo1RTZ2h9UVFCnPUyaQ' })
@IsOptional()
@ApiPropertyOptional()
@IsString({ message: 'did must be in string format.' })
did?: string;

@ApiProperty({ example: ['6ba7b810-9dad-11d1-80b4-00c04fd430c8'] })
@IsOptional()
@ApiPropertyOptional()
@IsArray({ message: 'ledgerId must be an array' })
@IsString({ each: true, message: 'Each ledgerId must be a string' })
@MaxLength(36, { each: true, message: 'ledgerId must be at most 36 characters.' })
@IsNotEmpty({ message: 'please provide valid ledgerId' })
ledgerId?: string[];

@ApiProperty({ example: 'ojIckSD2jqNzOqIrAGzL' })
@IsOptional()
@ApiPropertyOptional()
Expand Down
3 changes: 1 addition & 2 deletions libs/common/src/common.constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ export enum CommonConstants {
// server or agent
URL_SERVER_STATUS = '/status',
URL_AGENT_WRITE_DID = '/dids/write',
URL_AGENT_GET_DID = '/dids/#',
URL_AGENT_GET_DIDS = '/dids',
URL_AGENT_GET_DID = '/dids',
URL_AGENT_GET_ENDPOINT = '/agent',

// CREATE KEYS
Expand Down

0 comments on commit cbcdf55

Please sign in to comment.