Skip to content

Commit

Permalink
feat: support new custom asset type system
Browse files Browse the repository at this point in the history
- when creating a Security Token, if the token type in the inputs is a custom type that hasn’t
  been registered, an additional transaction is submitted to register it
- when creating a Security Token, only ask for permission to add documents if the documents
  array has elements
- request the correct transaction permissions when accepting an authorization request

BREAKING CHANGE:
- property `tokenType` of the `TickerReservation.create` method's parameters is now always a
  string. Custom types no longer need to be passed as `{ custom: <type> }`, they will be
  detected automatically
  • Loading branch information
monitz87 committed Aug 30, 2021
1 parent e302f05 commit 3a122c6
Show file tree
Hide file tree
Showing 12 changed files with 420 additions and 112 deletions.
22 changes: 21 additions & 1 deletion src/api/entities/SecurityToken/__tests__/index.ts
Expand Up @@ -124,7 +124,7 @@ describe('SecurityToken class', () => {
});

test('should return details for a security token', async () => {
dsMockUtils.createQueryStub('asset', 'tokens', {
const tokensStub = dsMockUtils.createQueryStub('asset', 'tokens', {
returnValue: rawToken,
});

Expand Down Expand Up @@ -152,6 +152,26 @@ describe('SecurityToken class', () => {
details = await securityToken.details();
expect(details.primaryIssuanceAgents).toEqual([]);
expect(details.fullAgents).toEqual([entityMockUtils.getIdentityInstance({ did })]);

tokensStub.resolves(
dsMockUtils.createMockSecurityToken({
/* eslint-disable @typescript-eslint/naming-convention */
owner_did: dsMockUtils.createMockIdentityId(owner),
asset_type: dsMockUtils.createMockAssetType({ Custom: dsMockUtils.createMockU32(10) }),
divisible: dsMockUtils.createMockBool(isDivisible),
total_supply: dsMockUtils.createMockBalance(totalSupply),
/* eslint-enable @typescript-eslint/naming-convention */
})
);

const customType = 'something';

dsMockUtils.createQueryStub('asset', 'customTypes', {
returnValue: dsMockUtils.createMockBytes(customType),
});

details = await securityToken.details();
expect(details.assetType).toEqual(customType);
});

test('should allow subscription', async () => {
Expand Down
25 changes: 19 additions & 6 deletions src/api/entities/SecurityToken/index.ts
Expand Up @@ -37,12 +37,14 @@ import {
import { MAX_TICKER_LENGTH } from '~/utils/constants';
import {
assetIdentifierToTokenIdentifier,
assetTypeToString,
assetTypeToKnownOrId,
balanceToBigNumber,
boolToBoolean,
bytesToString,
fundingRoundNameToString,
identityIdToString,
middlewareEventToEventIdentifier,
numberToU32,
stringToTicker,
tickerToDid,
u64ToBigNumber,
Expand Down Expand Up @@ -203,10 +205,10 @@ export class SecurityToken extends Entity<UniqueIdentifiers, string> {
} = this;

/* eslint-disable @typescript-eslint/naming-convention */
const assembleResult = (
const assembleResult = async (
{ total_supply, divisible, owner_did, asset_type }: MeshSecurityToken,
agentGroups: [StorageKey<[Ticker, IdentityId]>, Option<AgentGroup>][]
): SecurityTokenDetails => {
): Promise<SecurityTokenDetails> => {
const primaryIssuanceAgents: Identity[] = [];
const fullAgents: Identity[] = [];

Expand All @@ -222,8 +224,18 @@ export class SecurityToken extends Entity<UniqueIdentifiers, string> {
});

const owner = new Identity({ did: identityIdToString(owner_did) }, context);
const type = assetTypeToKnownOrId(asset_type);

let assetType: string;
if (typeof type === 'string') {
assetType = type;
} else {
const customType = await asset.customTypes(numberToU32(type, context));
assetType = bytesToString(customType);
}

return {
assetType: assetTypeToString(asset_type),
assetType,
isDivisible: boolToBoolean(divisible),
name: 'placeholder',
owner,
Expand All @@ -241,8 +253,9 @@ export class SecurityToken extends Entity<UniqueIdentifiers, string> {
if (callback) {
const groupOfAgents = await groupOfAgentPromise;

return asset.tokens(rawTicker, securityToken => {
callback(assembleResult(securityToken, groupOfAgents));
return asset.tokens(rawTicker, async securityToken => {
const result = await assembleResult(securityToken, groupOfAgents);
callback(result);
});
}

Expand Down
9 changes: 6 additions & 3 deletions src/api/procedures/__tests__/consumeAuthorizationRequests.ts
Expand Up @@ -257,7 +257,7 @@ describe('consumeAuthorizationRequests procedure', () => {
target: entityMockUtils.getIdentityInstance({ did }),
issuer: entityMockUtils.getIdentityInstance({ did: 'issuerDid1' }),
data: {
type: AuthorizationType.NoData,
type: AuthorizationType.BecomeAgent,
} as Authorization,
},
{
Expand All @@ -266,7 +266,7 @@ describe('consumeAuthorizationRequests procedure', () => {
target: entityMockUtils.getIdentityInstance({ did: 'notTheCurrentIdentity' }),
issuer: entityMockUtils.getIdentityInstance({ did: 'issuerDid2' }),
data: {
type: AuthorizationType.NoData,
type: AuthorizationType.PortfolioCustody,
} as Authorization,
},
];
Expand All @@ -284,7 +284,10 @@ describe('consumeAuthorizationRequests procedure', () => {
permissions: {
tokens: [],
portfolios: [],
transactions: [TxTags.identity.AcceptAuthorization],
transactions: [
TxTags.externalAgents.AcceptBecomeAgent,
TxTags.portfolio.AcceptPortfolioCustody,
],
},
});

Expand Down

0 comments on commit 3a122c6

Please sign in to comment.