Skip to content

Commit

Permalink
feat: 🎸 get asset groups for did
Browse files Browse the repository at this point in the history
  • Loading branch information
sansan committed Dec 6, 2024
1 parent 4722a46 commit 8bf926b
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 4 deletions.
26 changes: 25 additions & 1 deletion src/identities/identities.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { DeepMocked } from '@golevelup/ts-jest';
import { createMock, DeepMocked } from '@golevelup/ts-jest';
import { Test } from '@nestjs/testing';
import { BigNumber } from '@polymeshassociation/polymesh-sdk';
import {
Asset,
AuthorizationType,
CddClaim,
ClaimData,
ClaimScope,
ClaimType,
CustomPermissionGroup,
GenericAuthorizationData,
ResultSet,
} from '@polymeshassociation/polymesh-sdk/types';
Expand All @@ -27,6 +29,7 @@ import { RegisterIdentityDto } from '~/identities/dto/register-identity.dto';
import { IdentitiesController } from '~/identities/identities.controller';
import { IdentitiesService } from '~/identities/identities.service';
import { AccountModel } from '~/identities/models/account.model';
import { AssetWithGroupModel } from '~/identities/models/asset-with-group.model';
import { IdentityModel } from '~/identities/models/identity.model';
import { IdentitySignerModel } from '~/identities/models/identity-signer.model';
import { mockPolymeshLoggerProvider } from '~/logger/mock-polymesh-logger';
Expand Down Expand Up @@ -755,4 +758,25 @@ describe('IdentitiesController', () => {
);
});
});

describe('getAssetPermissions', () => {
it('should return the Assets for which the Identity has permissions', async () => {
const asset = createMock<Asset>({
id: '3616b82e-8e10-80ae-dc95-2ea28b9db8b3',
ticker: 'SOME_TICKER',
});
const assetGroups = [
{ asset, group: createMock<CustomPermissionGroup>({ id: new BigNumber(1), asset }) },
];
mockIdentitiesService.findDidExternalAgentOf.mockResolvedValue(assetGroups);

const result = await controller.getAssetPermissions({ did });

expect(result).toEqual(
new ResultsModel({
results: assetGroups.map(assetGroup => new AssetWithGroupModel(assetGroup)),
})
);
});
});
});
35 changes: 33 additions & 2 deletions src/identities/identities.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
ClaimType,
FungibleAsset,
NftCollection,
PermissionGroupType,
TickerReservation,
Venue,
} from '@polymeshassociation/polymesh-sdk/types';
Expand Down Expand Up @@ -50,12 +51,12 @@ import { ResultsModel } from '~/common/models/results.model';
import { handleServiceResult, TransactionResponseModel } from '~/common/utils';
import { createDividendDistributionDetailsModel } from '~/corporate-actions/corporate-actions.util';
import { DividendDistributionDetailsModel } from '~/corporate-actions/models/dividend-distribution-details.model';
import { DeveloperTestingService } from '~/developer-testing/developer-testing.service';
import { AddSecondaryAccountParamsDto } from '~/identities/dto/add-secondary-account-params.dto';
import { RegisterIdentityDto } from '~/identities/dto/register-identity.dto';
import { RotatePrimaryKeyParamsDto } from '~/identities/dto/rotate-primary-key-params.dto';
import { IdentitiesService } from '~/identities/identities.service';
import { createIdentityModel } from '~/identities/identities.util';
import { AssetWithGroupModel } from '~/identities/models/asset-with-group.model';
import { CreatedIdentityModel } from '~/identities/models/created-identity.model';
import { IdentityModel } from '~/identities/models/identity.model';
import { createIdentityResolver } from '~/identities/models/identity.util';
Expand All @@ -75,7 +76,6 @@ export class IdentitiesController {
private readonly authorizationsService: AuthorizationsService,
private readonly claimsService: ClaimsService,
private readonly tickerReservationsService: TickerReservationsService,
private readonly developerTestingService: DeveloperTestingService,
private readonly logger: PolymeshLogger
) {
logger.setContext(IdentitiesController.name);
Expand Down Expand Up @@ -765,4 +765,35 @@ export class IdentitiesController {
),
});
}

@ApiTags('assets')
@ApiOperation({
summary: 'Fetch all Assets for which an Identity has permissions',
})
@ApiParam({
name: 'did',
description: 'The DID of the Identity for which the Asset permissions are to be fetched',
type: 'string',
example: '0x0600000000000000000000000000000000000000000000000000000000000000',
})
@ApiArrayResponse('string', {
description: 'List of Assets for which the Identity has permissions',
paginated: false,
example: [
{
asset: 'SOME_TICKER',
group: {
type: PermissionGroupType.Full,
assetId: '3616b82e-8e10-80ae-dc95-2ea28b9db8b3',
ticker: 'SOME_TICKER',
},
},
],
})
@Get(':did/external-agent')
async getAssetPermissions(@Param() { did }: DidDto): Promise<ResultsModel<AssetWithGroupModel>> {
const results = await this.identitiesService.findDidExternalAgentOf(did);

return new ResultsModel({ results: results.map(result => new AssetWithGroupModel(result)) });
}
}
30 changes: 29 additions & 1 deletion src/identities/identities.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
/* eslint-disable import/first */
const mockIsPolymeshTransaction = jest.fn();

import { createMock } from '@golevelup/ts-jest';
import { Test, TestingModule } from '@nestjs/testing';
import { BigNumber } from '@polymeshassociation/polymesh-sdk';
import { TxTags } from '@polymeshassociation/polymesh-sdk/types';
import {
Asset,
CustomPermissionGroup,
Identity,
TxTags,
} from '@polymeshassociation/polymesh-sdk/types';

import { AccountsService } from '~/accounts/accounts.service';
import { MockDistributionWithDetails } from '~/corporate-actions/mocks/distribution-with-details.mock';
Expand Down Expand Up @@ -308,4 +314,26 @@ describe('IdentitiesService', () => {
expect(result).toEqual(mockDistributions);
});
});

describe('findDidExternalAgentOf', () => {
it('should return the list of AssetsGroups for which the Identity has permissions', async () => {
const asset = createMock<Asset>({
id: '3616b82e-8e10-80ae-dc95-2ea28b9db8b3',
ticker: 'SOME_TICKER',
});
const assetGroups = [
{ asset, group: createMock<CustomPermissionGroup>({ id: new BigNumber(1), asset }) },
];
const mockIdentity = createMock<Identity>({
did,
assetPermissions: { get: jest.fn().mockResolvedValue(assetGroups) },
});

const findOneSpy = jest.spyOn(service, 'findOne');
findOneSpy.mockResolvedValue(mockIdentity);

const result = await service.findDidExternalAgentOf(did);
expect(result).toEqual(assetGroups);
});
});
});
7 changes: 7 additions & 0 deletions src/identities/identities.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Injectable } from '@nestjs/common';
import { BigNumber } from '@polymeshassociation/polymesh-sdk';
import {
AssetWithGroup,
AuthorizationRequest,
DistributionWithDetails,
FungibleAsset,
Expand Down Expand Up @@ -159,4 +160,10 @@ export class IdentitiesService {

return identity.getPendingDistributions();
}

public async findDidExternalAgentOf(did: string): Promise<AssetWithGroup[]> {
const identity = await this.findOne(did);

return identity.assetPermissions.get();
}
}
35 changes: 35 additions & 0 deletions src/identities/models/asset-with-group.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* istanbul ignore file */

import { ApiProperty } from '@nestjs/swagger';
import {
Asset,
CustomPermissionGroup,
KnownPermissionGroup,
PermissionGroupType,
} from '@polymeshassociation/polymesh-sdk/types';

import { FromEntity } from '~/common/decorators';

export class AssetWithGroupModel {
@ApiProperty({
description: 'The Asset ID to which the Identity has permissions',
example: '3616b82e-8e10-80ae-dc95-2ea28b9db8b3',
})
@FromEntity()
readonly asset: Asset;

@ApiProperty({
description: 'The assigned group details',
example: {
type: PermissionGroupType.Full,
assetId: '3616b82e-8e10-80ae-dc95-2ea28b9db8b3',
ticker: 'SOME_TICKER',
},
})
@FromEntity()
readonly group: KnownPermissionGroup | CustomPermissionGroup;

constructor(model: AssetWithGroupModel) {
Object.assign(this, model);
}
}
1 change: 1 addition & 0 deletions src/test-utils/service-mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ export class MockIdentitiesService {
isAssetPreApproved = jest.fn();
getPreApprovedAssets = jest.fn();
getPendingDistributions = jest.fn();
findDidExternalAgentOf = jest.fn();
}

export class MockSettlementsService {
Expand Down

0 comments on commit 8bf926b

Please sign in to comment.