Skip to content

Commit 4215575

Browse files
committed
feat: add signFreezeIssuanceAck to issuance namespace
Also changed the names of the ack signature procedures to reflect that they're a confirmation instead of actual data being sent, added missing tests
1 parent aa78b04 commit 4215575

File tree

9 files changed

+245
-12
lines changed

9 files changed

+245
-12
lines changed

src/entities/SecurityToken/Controller.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
SetController,
66
ControllerRedeem,
77
DisableController,
8-
SignDisableControllerData,
8+
SignDisableControllerAck,
99
} from '../../procedures';
1010

1111
export class Controller extends SubModule {
@@ -87,10 +87,10 @@ export class Controller extends SubModule {
8787
*
8888
* Note that only the owner's signature is valid for this operation
8989
*/
90-
public signDisableControllerData = async () => {
90+
public signDisableControllerAck = async () => {
9191
const { symbol } = this.securityToken;
9292

93-
const procedure = new SignDisableControllerData({ symbol }, this.context);
93+
const procedure = new SignDisableControllerAck({ symbol }, this.context);
9494

9595
return procedure.prepare();
9696
};

src/entities/SecurityToken/Issuance/Issuance.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { IssuanceDataEntry } from '../../../types';
44
import { Offerings } from './Offerings';
55
import { SecurityToken } from '../SecurityToken';
66
import { Context } from '../../../Context';
7+
import { SignFreezeIssuanceAck } from '../../../procedures/SignFreezeIssuanceAck';
78

89
export class Issuance extends SubModule {
910
public offerings: Offerings;
@@ -41,11 +42,27 @@ export class Issuance extends SubModule {
4142

4243
/**
4344
* Permanently freeze issuance of the security token
44-
* @param signature optional signed data. If not passed, signing will be requested on the spot
45+
*
46+
* @param signature optional signed data. If not passed, signing will be requested when the transaction queue is run. The data can be generated beforehand by the token owner calling `signFreezeIssuanceData`
4547
*/
4648
public freeze = async (args?: { signature?: string }) => {
4749
const { symbol } = this.securityToken;
50+
4851
const procedure = new FreezeIssuance({ ...args, symbol }, this.context);
52+
53+
return procedure.prepare();
54+
};
55+
56+
/**
57+
* Generate a signature string that can be used to permanently freeze issuance of the Security Token
58+
*
59+
* Note that only the owner's signature is valid for this operation
60+
*/
61+
public signFreezeIssuanceAck = async () => {
62+
const { symbol } = this.securityToken;
63+
64+
const procedure = new SignFreezeIssuanceAck({ symbol }, this.context);
65+
4966
return procedure.prepare();
5067
};
5168
}

src/procedures/SignDisableControllerData.ts renamed to src/procedures/SignDisableControllerAck.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { Procedure } from './Procedure';
2-
import { ProcedureType, ErrorCode, SignDisableControllerDataProcedureArgs } from '../types';
2+
import { ProcedureType, ErrorCode, SignDisableControllerAckProcedureArgs } from '../types';
33
import { PolymathError } from '../PolymathError';
44

5-
export class SignDisableControllerData extends Procedure<SignDisableControllerDataProcedureArgs> {
6-
public type = ProcedureType.SignDisableControllerData;
5+
export class SignDisableControllerAck extends Procedure<SignDisableControllerAckProcedureArgs> {
6+
public type = ProcedureType.SignDisableControllerAck;
77

88
public async prepareTransactions() {
99
const { symbol } = this.args;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Procedure } from './Procedure';
2+
import { ProcedureType, ErrorCode, SignFreezeIssuanceAckProcedureArgs } from '../types';
3+
import { PolymathError } from '../PolymathError';
4+
5+
export class SignFreezeIssuanceAck extends Procedure<SignFreezeIssuanceAckProcedureArgs> {
6+
public type = ProcedureType.SignFreezeIssuanceAck;
7+
8+
public async prepareTransactions() {
9+
const { symbol } = this.args;
10+
const { contractWrappers } = this.context;
11+
12+
let securityToken;
13+
14+
try {
15+
securityToken = await contractWrappers.tokenFactory.getSecurityTokenInstanceFromTicker(
16+
symbol
17+
);
18+
} catch (err) {
19+
throw new PolymathError({
20+
code: ErrorCode.ProcedureValidationError,
21+
message: `There is no Security Token with symbol ${symbol}`,
22+
});
23+
}
24+
25+
await this.addSignatureRequest(securityToken.signFreezeIssuanceAck)({});
26+
}
27+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { ImportMock, MockManager } from 'ts-mock-imports';
2+
import { spy, restore } from 'sinon';
3+
import * as contractWrappersModule from '@polymathnetwork/contract-wrappers';
4+
import * as contextModule from '../../Context';
5+
import { Factories } from '../../Context';
6+
import * as wrappersModule from '../../PolymathBase';
7+
import * as tokenFactoryModule from '../../testUtils/MockedTokenFactoryModule';
8+
import { SignDisableControllerAck } from '../SignDisableControllerAck';
9+
import { Procedure } from '../Procedure';
10+
import { ProcedureType, ErrorCode } from '../../types';
11+
import { PolymathError } from '../../PolymathError';
12+
import { mockFactories } from '../../testUtils/mockFactories';
13+
14+
const params = {
15+
symbol: 'TEST1',
16+
};
17+
18+
describe('SignDisableControllerAck', () => {
19+
let target: SignDisableControllerAck;
20+
let contextMock: MockManager<contextModule.Context>;
21+
let wrappersMock: MockManager<wrappersModule.PolymathBase>;
22+
let tokenFactoryMock: MockManager<tokenFactoryModule.MockedTokenFactoryModule>;
23+
let securityTokenMock: MockManager<contractWrappersModule.SecurityToken_3_0_0>;
24+
let factoriesMockedSetup: Factories;
25+
26+
beforeEach(() => {
27+
// Mock the context, wrappers, tokenFactory and securityToken to test SignDisableControllerAck
28+
contextMock = ImportMock.mockClass(contextModule, 'Context');
29+
wrappersMock = ImportMock.mockClass(wrappersModule, 'PolymathBase');
30+
31+
tokenFactoryMock = ImportMock.mockClass(tokenFactoryModule, 'MockedTokenFactoryModule');
32+
securityTokenMock = ImportMock.mockClass(contractWrappersModule, 'SecurityToken_3_0_0');
33+
34+
tokenFactoryMock.mock(
35+
'getSecurityTokenInstanceFromTicker',
36+
securityTokenMock.getMockInstance()
37+
);
38+
39+
contextMock.set('contractWrappers', wrappersMock.getMockInstance());
40+
wrappersMock.set('tokenFactory', tokenFactoryMock.getMockInstance());
41+
42+
factoriesMockedSetup = mockFactories();
43+
contextMock.set('factories', factoriesMockedSetup);
44+
45+
target = new SignDisableControllerAck(params, contextMock.getMockInstance());
46+
});
47+
48+
afterEach(() => {
49+
restore();
50+
});
51+
52+
describe('Types', () => {
53+
test('should extend procedure and have SignDisableControllerAck type', async () => {
54+
expect(target instanceof Procedure).toBe(true);
55+
expect(target.type).toBe(ProcedureType.SignDisableControllerAck);
56+
});
57+
});
58+
59+
describe('SignDisableControllerAck', () => {
60+
test('should throw if there is no valid security token being provided', async () => {
61+
tokenFactoryMock
62+
.mock('getSecurityTokenInstanceFromTicker')
63+
.withArgs(params.symbol)
64+
.throws();
65+
66+
await expect(target.prepareTransactions()).rejects.toThrow(
67+
new PolymathError({
68+
code: ErrorCode.ProcedureValidationError,
69+
message: `There is no Security Token with symbol ${params.symbol}`,
70+
})
71+
);
72+
});
73+
74+
test('should add a signature request to the queue to sign confirmation for disabling the controller functionality', async () => {
75+
const addSignatureRequestSpy = spy(target, 'addSignatureRequest');
76+
securityTokenMock.mock(
77+
'signDisableControllerAck',
78+
Promise.resolve('SignDisableControllerAck')
79+
);
80+
81+
// Real call
82+
await target.prepareTransactions();
83+
84+
// Verifications
85+
expect(
86+
addSignatureRequestSpy
87+
.getCall(0)
88+
.calledWith(securityTokenMock.getMockInstance().signDisableControllerAck)
89+
).toEqual(true);
90+
expect(addSignatureRequestSpy.callCount).toEqual(1);
91+
});
92+
});
93+
});
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { ImportMock, MockManager } from 'ts-mock-imports';
2+
import { spy, restore } from 'sinon';
3+
import * as contractWrappersModule from '@polymathnetwork/contract-wrappers';
4+
import * as contextModule from '../../Context';
5+
import { Factories } from '../../Context';
6+
import * as wrappersModule from '../../PolymathBase';
7+
import * as tokenFactoryModule from '../../testUtils/MockedTokenFactoryModule';
8+
import { SignFreezeIssuanceAck } from '../SignFreezeIssuanceAck';
9+
import { Procedure } from '../Procedure';
10+
import { ProcedureType, ErrorCode } from '../../types';
11+
import { PolymathError } from '../../PolymathError';
12+
import { mockFactories } from '../../testUtils/mockFactories';
13+
14+
const params = {
15+
symbol: 'TEST1',
16+
};
17+
18+
describe('SignFreezeIssuanceAck', () => {
19+
let target: SignFreezeIssuanceAck;
20+
let contextMock: MockManager<contextModule.Context>;
21+
let wrappersMock: MockManager<wrappersModule.PolymathBase>;
22+
let tokenFactoryMock: MockManager<tokenFactoryModule.MockedTokenFactoryModule>;
23+
let securityTokenMock: MockManager<contractWrappersModule.SecurityToken_3_0_0>;
24+
let factoriesMockedSetup: Factories;
25+
26+
beforeEach(() => {
27+
// Mock the context, wrappers, tokenFactory and securityToken to test SignFreezeIssuanceAck
28+
contextMock = ImportMock.mockClass(contextModule, 'Context');
29+
wrappersMock = ImportMock.mockClass(wrappersModule, 'PolymathBase');
30+
31+
tokenFactoryMock = ImportMock.mockClass(tokenFactoryModule, 'MockedTokenFactoryModule');
32+
securityTokenMock = ImportMock.mockClass(contractWrappersModule, 'SecurityToken_3_0_0');
33+
34+
tokenFactoryMock.mock(
35+
'getSecurityTokenInstanceFromTicker',
36+
securityTokenMock.getMockInstance()
37+
);
38+
39+
contextMock.set('contractWrappers', wrappersMock.getMockInstance());
40+
wrappersMock.set('tokenFactory', tokenFactoryMock.getMockInstance());
41+
42+
factoriesMockedSetup = mockFactories();
43+
contextMock.set('factories', factoriesMockedSetup);
44+
45+
target = new SignFreezeIssuanceAck(params, contextMock.getMockInstance());
46+
});
47+
48+
afterEach(() => {
49+
restore();
50+
});
51+
52+
describe('Types', () => {
53+
test('should extend procedure and have SignFreezeIssuanceAck type', async () => {
54+
expect(target instanceof Procedure).toBe(true);
55+
expect(target.type).toBe(ProcedureType.SignFreezeIssuanceAck);
56+
});
57+
});
58+
59+
describe('SignFreezeIssuanceAck', () => {
60+
test('should throw if there is no valid security token being provided', async () => {
61+
tokenFactoryMock
62+
.mock('getSecurityTokenInstanceFromTicker')
63+
.withArgs(params.symbol)
64+
.throws();
65+
66+
await expect(target.prepareTransactions()).rejects.toThrow(
67+
new PolymathError({
68+
code: ErrorCode.ProcedureValidationError,
69+
message: `There is no Security Token with symbol ${params.symbol}`,
70+
})
71+
);
72+
});
73+
74+
test('should add a signature request to the queue to sign confirmation for disabling the controller functionality', async () => {
75+
const addSignatureRequestSpy = spy(target, 'addSignatureRequest');
76+
securityTokenMock.mock('signFreezeIssuanceAck', Promise.resolve('SignFreezeIssuanceAck'));
77+
78+
// Real call
79+
await target.prepareTransactions();
80+
81+
// Verifications
82+
expect(
83+
addSignatureRequestSpy
84+
.getCall(0)
85+
.calledWith(securityTokenMock.getMockInstance().signFreezeIssuanceAck)
86+
).toEqual(true);
87+
expect(addSignatureRequestSpy.callCount).toEqual(1);
88+
});
89+
});
90+
});

src/procedures/__tests__/SignTransferData.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import * as wrappersModule from '../../PolymathBase';
77
import * as tokenFactoryModule from '../../testUtils/MockedTokenFactoryModule';
88
import { SignTransferData } from '../../procedures/SignTransferData';
99
import { Procedure } from '../../procedures/Procedure';
10-
import { ProcedureType, ErrorCode, PolyTransactionTag } from '../../types';
10+
import { ProcedureType, ErrorCode } from '../../types';
1111
import { PolymathError } from '../../PolymathError';
1212
import { mockFactories } from '../../testUtils/mockFactories';
1313

src/procedures/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,4 @@ export { ToggleFreezeTransfers } from './ToggleFreezeTransfers';
4242
export { ModifyDividendsDefaultExclusionList } from './ModifyDividendsDefaultExclusionList';
4343
export { ModifyPreIssuing } from './ModifyPreIssuing';
4444
export { SignTransferData } from './SignTransferData';
45-
export { SignDisableControllerData } from './SignDisableControllerData';
45+
export { SignDisableControllerAck } from './SignDisableControllerAck';

src/types/index.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ export enum ProcedureType {
160160
TransferSecurityTokens = 'TransferSecurityTokens',
161161
ToggleFreezeTransfers = 'ToggleFreezeTransfers',
162162
SignTransferData = 'SignTransferData',
163-
SignDisableControllerData = 'SignDisableControllerData',
163+
SignDisableControllerAck = 'SignDisableControllerAck',
164+
SignFreezeIssuanceAck = 'SignFreezeIssuanceAck',
164165
}
165166

166167
export enum PolyTransactionTag {
@@ -607,7 +608,11 @@ export interface SignTransferDataProcedureArgs {
607608
validTo: Date;
608609
}
609610

610-
export interface SignDisableControllerDataProcedureArgs {
611+
export interface SignDisableControllerAckProcedureArgs {
612+
symbol: string;
613+
}
614+
615+
export interface SignFreezeIssuanceAckProcedureArgs {
611616
symbol: string;
612617
}
613618

@@ -655,7 +660,8 @@ export interface ProcedureArguments {
655660
[ProcedureType.TransferSecurityTokens]: TransferSecurityTokensProcedureArgs;
656661
[ProcedureType.ToggleFreezeTransfers]: ToggleFreezeTransfersProcedureArgs;
657662
[ProcedureType.SignTransferData]: SignTransferDataProcedureArgs;
658-
[ProcedureType.SignDisableControllerData]: SignDisableControllerDataProcedureArgs;
663+
[ProcedureType.SignDisableControllerAck]: SignDisableControllerAckProcedureArgs;
664+
[ProcedureType.SignFreezeIssuanceAck]: SignFreezeIssuanceAckProcedureArgs;
659665
[ProcedureType.UnnamedProcedure]: {};
660666
}
661667

0 commit comments

Comments
 (0)