Skip to content

Commit 8bf926b

Browse files
committed
feat: 🎸 get asset groups for did
1 parent 4722a46 commit 8bf926b

6 files changed

+130
-4
lines changed

‎src/identities/identities.controller.spec.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
import { DeepMocked } from '@golevelup/ts-jest';
1+
import { createMock, DeepMocked } from '@golevelup/ts-jest';
22
import { Test } from '@nestjs/testing';
33
import { BigNumber } from '@polymeshassociation/polymesh-sdk';
44
import {
5+
Asset,
56
AuthorizationType,
67
CddClaim,
78
ClaimData,
89
ClaimScope,
910
ClaimType,
11+
CustomPermissionGroup,
1012
GenericAuthorizationData,
1113
ResultSet,
1214
} from '@polymeshassociation/polymesh-sdk/types';
@@ -27,6 +29,7 @@ import { RegisterIdentityDto } from '~/identities/dto/register-identity.dto';
2729
import { IdentitiesController } from '~/identities/identities.controller';
2830
import { IdentitiesService } from '~/identities/identities.service';
2931
import { AccountModel } from '~/identities/models/account.model';
32+
import { AssetWithGroupModel } from '~/identities/models/asset-with-group.model';
3033
import { IdentityModel } from '~/identities/models/identity.model';
3134
import { IdentitySignerModel } from '~/identities/models/identity-signer.model';
3235
import { mockPolymeshLoggerProvider } from '~/logger/mock-polymesh-logger';
@@ -755,4 +758,25 @@ describe('IdentitiesController', () => {
755758
);
756759
});
757760
});
761+
762+
describe('getAssetPermissions', () => {
763+
it('should return the Assets for which the Identity has permissions', async () => {
764+
const asset = createMock<Asset>({
765+
id: '3616b82e-8e10-80ae-dc95-2ea28b9db8b3',
766+
ticker: 'SOME_TICKER',
767+
});
768+
const assetGroups = [
769+
{ asset, group: createMock<CustomPermissionGroup>({ id: new BigNumber(1), asset }) },
770+
];
771+
mockIdentitiesService.findDidExternalAgentOf.mockResolvedValue(assetGroups);
772+
773+
const result = await controller.getAssetPermissions({ did });
774+
775+
expect(result).toEqual(
776+
new ResultsModel({
777+
results: assetGroups.map(assetGroup => new AssetWithGroupModel(assetGroup)),
778+
})
779+
);
780+
});
781+
});
758782
});

‎src/identities/identities.controller.ts

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
ClaimType,
1717
FungibleAsset,
1818
NftCollection,
19+
PermissionGroupType,
1920
TickerReservation,
2021
Venue,
2122
} from '@polymeshassociation/polymesh-sdk/types';
@@ -50,12 +51,12 @@ import { ResultsModel } from '~/common/models/results.model';
5051
import { handleServiceResult, TransactionResponseModel } from '~/common/utils';
5152
import { createDividendDistributionDetailsModel } from '~/corporate-actions/corporate-actions.util';
5253
import { DividendDistributionDetailsModel } from '~/corporate-actions/models/dividend-distribution-details.model';
53-
import { DeveloperTestingService } from '~/developer-testing/developer-testing.service';
5454
import { AddSecondaryAccountParamsDto } from '~/identities/dto/add-secondary-account-params.dto';
5555
import { RegisterIdentityDto } from '~/identities/dto/register-identity.dto';
5656
import { RotatePrimaryKeyParamsDto } from '~/identities/dto/rotate-primary-key-params.dto';
5757
import { IdentitiesService } from '~/identities/identities.service';
5858
import { createIdentityModel } from '~/identities/identities.util';
59+
import { AssetWithGroupModel } from '~/identities/models/asset-with-group.model';
5960
import { CreatedIdentityModel } from '~/identities/models/created-identity.model';
6061
import { IdentityModel } from '~/identities/models/identity.model';
6162
import { createIdentityResolver } from '~/identities/models/identity.util';
@@ -75,7 +76,6 @@ export class IdentitiesController {
7576
private readonly authorizationsService: AuthorizationsService,
7677
private readonly claimsService: ClaimsService,
7778
private readonly tickerReservationsService: TickerReservationsService,
78-
private readonly developerTestingService: DeveloperTestingService,
7979
private readonly logger: PolymeshLogger
8080
) {
8181
logger.setContext(IdentitiesController.name);
@@ -765,4 +765,35 @@ export class IdentitiesController {
765765
),
766766
});
767767
}
768+
769+
@ApiTags('assets')
770+
@ApiOperation({
771+
summary: 'Fetch all Assets for which an Identity has permissions',
772+
})
773+
@ApiParam({
774+
name: 'did',
775+
description: 'The DID of the Identity for which the Asset permissions are to be fetched',
776+
type: 'string',
777+
example: '0x0600000000000000000000000000000000000000000000000000000000000000',
778+
})
779+
@ApiArrayResponse('string', {
780+
description: 'List of Assets for which the Identity has permissions',
781+
paginated: false,
782+
example: [
783+
{
784+
asset: 'SOME_TICKER',
785+
group: {
786+
type: PermissionGroupType.Full,
787+
assetId: '3616b82e-8e10-80ae-dc95-2ea28b9db8b3',
788+
ticker: 'SOME_TICKER',
789+
},
790+
},
791+
],
792+
})
793+
@Get(':did/external-agent')
794+
async getAssetPermissions(@Param() { did }: DidDto): Promise<ResultsModel<AssetWithGroupModel>> {
795+
const results = await this.identitiesService.findDidExternalAgentOf(did);
796+
797+
return new ResultsModel({ results: results.map(result => new AssetWithGroupModel(result)) });
798+
}
768799
}

‎src/identities/identities.service.spec.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
/* eslint-disable import/first */
22
const mockIsPolymeshTransaction = jest.fn();
33

4+
import { createMock } from '@golevelup/ts-jest';
45
import { Test, TestingModule } from '@nestjs/testing';
56
import { BigNumber } from '@polymeshassociation/polymesh-sdk';
6-
import { TxTags } from '@polymeshassociation/polymesh-sdk/types';
7+
import {
8+
Asset,
9+
CustomPermissionGroup,
10+
Identity,
11+
TxTags,
12+
} from '@polymeshassociation/polymesh-sdk/types';
713

814
import { AccountsService } from '~/accounts/accounts.service';
915
import { MockDistributionWithDetails } from '~/corporate-actions/mocks/distribution-with-details.mock';
@@ -308,4 +314,26 @@ describe('IdentitiesService', () => {
308314
expect(result).toEqual(mockDistributions);
309315
});
310316
});
317+
318+
describe('findDidExternalAgentOf', () => {
319+
it('should return the list of AssetsGroups for which the Identity has permissions', async () => {
320+
const asset = createMock<Asset>({
321+
id: '3616b82e-8e10-80ae-dc95-2ea28b9db8b3',
322+
ticker: 'SOME_TICKER',
323+
});
324+
const assetGroups = [
325+
{ asset, group: createMock<CustomPermissionGroup>({ id: new BigNumber(1), asset }) },
326+
];
327+
const mockIdentity = createMock<Identity>({
328+
did,
329+
assetPermissions: { get: jest.fn().mockResolvedValue(assetGroups) },
330+
});
331+
332+
const findOneSpy = jest.spyOn(service, 'findOne');
333+
findOneSpy.mockResolvedValue(mockIdentity);
334+
335+
const result = await service.findDidExternalAgentOf(did);
336+
expect(result).toEqual(assetGroups);
337+
});
338+
});
311339
});

‎src/identities/identities.service.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Injectable } from '@nestjs/common';
22
import { BigNumber } from '@polymeshassociation/polymesh-sdk';
33
import {
4+
AssetWithGroup,
45
AuthorizationRequest,
56
DistributionWithDetails,
67
FungibleAsset,
@@ -159,4 +160,10 @@ export class IdentitiesService {
159160

160161
return identity.getPendingDistributions();
161162
}
163+
164+
public async findDidExternalAgentOf(did: string): Promise<AssetWithGroup[]> {
165+
const identity = await this.findOne(did);
166+
167+
return identity.assetPermissions.get();
168+
}
162169
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/* istanbul ignore file */
2+
3+
import { ApiProperty } from '@nestjs/swagger';
4+
import {
5+
Asset,
6+
CustomPermissionGroup,
7+
KnownPermissionGroup,
8+
PermissionGroupType,
9+
} from '@polymeshassociation/polymesh-sdk/types';
10+
11+
import { FromEntity } from '~/common/decorators';
12+
13+
export class AssetWithGroupModel {
14+
@ApiProperty({
15+
description: 'The Asset ID to which the Identity has permissions',
16+
example: '3616b82e-8e10-80ae-dc95-2ea28b9db8b3',
17+
})
18+
@FromEntity()
19+
readonly asset: Asset;
20+
21+
@ApiProperty({
22+
description: 'The assigned group details',
23+
example: {
24+
type: PermissionGroupType.Full,
25+
assetId: '3616b82e-8e10-80ae-dc95-2ea28b9db8b3',
26+
ticker: 'SOME_TICKER',
27+
},
28+
})
29+
@FromEntity()
30+
readonly group: KnownPermissionGroup | CustomPermissionGroup;
31+
32+
constructor(model: AssetWithGroupModel) {
33+
Object.assign(this, model);
34+
}
35+
}

‎src/test-utils/service-mocks.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ export class MockIdentitiesService {
158158
isAssetPreApproved = jest.fn();
159159
getPreApprovedAssets = jest.fn();
160160
getPendingDistributions = jest.fn();
161+
findDidExternalAgentOf = jest.fn();
161162
}
162163

163164
export class MockSettlementsService {

0 commit comments

Comments
 (0)