Skip to content

Commit

Permalink
feat: 🎸 Make ticker optional while creating an asset
Browse files Browse the repository at this point in the history
  • Loading branch information
prashantasdeveloper committed Oct 17, 2024
1 parent 1a3c9e6 commit 9460b22
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 35 deletions.
50 changes: 47 additions & 3 deletions src/api/procedures/__tests__/createAsset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,19 @@ describe('createAsset procedure', () => {
);
});

it('should throw an error if the ticker is not provided for v6 chain', () => {
mockContext.isV6 = true;
const proc = procedureMockUtils.getInstance<Params, FungibleAsset, Storage>(mockContext, {
customTypeData: null,
status: undefined,
signingIdentity,
});

return expect(prepareCreateAsset.call(proc, { ...args, ticker: undefined })).rejects.toThrow(
'Ticker is mandatory for v6 chains'
);
});

it('should throw an error if the ticker contains non numeric characters', () => {
const proc = procedureMockUtils.getInstance<Params, FungibleAsset, Storage>(mockContext, {
customTypeData: null,
Expand Down Expand Up @@ -389,6 +402,26 @@ describe('createAsset procedure', () => {
fee: undefined,
resolver: expect.objectContaining({ id: assetId }),
});

result = await prepareCreateAsset.call(proc, {
...args,
initialSupply: new BigNumber(0),
securityIdentifiers: undefined,
fundingRound: undefined,
requireInvestorUniqueness: false,
ticker: undefined,
});

expect(result).toEqual({
transactions: [
{
transaction: createAssetTransaction,
args: [rawName, rawIsDivisible, rawType, [], null],
},
],
fee: undefined,
resolver: expect.objectContaining({ id: assetId }),
});
});

it('should issue Asset to the default portfolio if initial supply is provided', async () => {
Expand Down Expand Up @@ -778,6 +811,17 @@ describe('createAsset procedure', () => {
const proc = procedureMockUtils.getInstance<Params, FungibleAsset, Storage>(mockContext);
const boundFunc = prepareStorage.bind(proc);

let result = await boundFunc({
assetType: KnownAssetType.EquityCommon,
ticker: undefined,
} as Params);

expect(result).toEqual({
customTypeData: null,
status: undefined,
signingIdentity,
});

entityMockUtils.configureMocks({
tickerReservationOptions: {
details: {
Expand All @@ -788,7 +832,7 @@ describe('createAsset procedure', () => {
},
});

let result = await boundFunc({ assetType: KnownAssetType.EquityCommon } as Params);
result = await boundFunc({ assetType: KnownAssetType.EquityCommon, ticker } as Params);

expect(result).toEqual({
customTypeData: null,
Expand All @@ -804,7 +848,7 @@ describe('createAsset procedure', () => {
returnValue: dsMockUtils.createMockOption(id),
});

result = await boundFunc({ assetType: 'something' } as Params);
result = await boundFunc({ assetType: 'something', ticker } as Params);

expect(result).toEqual({
customTypeData: {
Expand All @@ -818,7 +862,7 @@ describe('createAsset procedure', () => {
id = dsMockUtils.createMockU32(new BigNumber(10));
customTypesMock.mockResolvedValue(dsMockUtils.createMockOption(id));

result = await boundFunc({ assetType: 'something' } as Params);
result = await boundFunc({ assetType: 'something', ticker } as Params);

expect(result).toEqual({
customTypeData: {
Expand Down
79 changes: 48 additions & 31 deletions src/api/procedures/createAsset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export interface Storage {
rawValue: Bytes;
} | null;

status: TickerReservationStatus;
status?: TickerReservationStatus;

signingIdentity: Identity;
}
Expand All @@ -69,10 +69,13 @@ export interface Storage {
* @throws if the Ticker is not available
*/
function assertTickerAvailable(
ticker: string,
status: TickerReservationStatus,
ticker: string | undefined,
status: TickerReservationStatus | undefined,
reservationRequired: boolean
): void {
if (!ticker) {
return;
}
if (status === TickerReservationStatus.AssetCreated) {
throw new PolymeshError({
code: ErrorCode.UnmetPrerequisite,
Expand Down Expand Up @@ -116,7 +119,10 @@ async function getCreateAssetTransaction(

const { ticker, name, isDivisible, assetType, securityIdentifiers = [], fundingRound } = args;

const rawTicker = stringToTicker(ticker, context);
let rawTicker;
if (ticker) {
rawTicker = stringToTicker(ticker, context);
}
const rawName = nameToAssetName(name, context);
/* istanbul ignore next: this will be removed after dual version support for v6-v7 */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down Expand Up @@ -170,7 +176,7 @@ async function getCreateAssetTransaction(
* since 7.x, we need to separately register ticker first if ticker does not exists and then link to asset
*/
function getTickerTransactions(
rawTicker: PolymeshPrimitivesTicker,
rawTicker: PolymeshPrimitivesTicker | undefined,
rawAssetId: PolymeshPrimitivesAssetAssetId,
context: Context,
status: Storage['status']
Expand All @@ -180,25 +186,26 @@ function getTickerTransactions(
isV6,
} = context;
const transactions = [];
if (!isV6) {
if (status === TickerReservationStatus.Free) {
transactions.push(
checkTxType({
transaction: tx.asset.registerUniqueTicker,
args: [rawTicker],
})
);
}
if (status !== TickerReservationStatus.AssetCreated) {
transactions.push(
checkTxType({
transaction: tx.asset.linkTickerToAssetId,
args: [rawTicker, rawAssetId],
})
);
if (rawTicker) {
if (!isV6) {
if (status === TickerReservationStatus.Free) {
transactions.push(
checkTxType({
transaction: tx.asset.registerUniqueTicker,
args: [rawTicker],
})
);
}
if (status !== TickerReservationStatus.AssetCreated) {
transactions.push(
checkTxType({
transaction: tx.asset.linkTickerToAssetId,
args: [rawTicker, rawAssetId],
})
);
}
}
}

return transactions;
}

Expand Down Expand Up @@ -274,12 +281,21 @@ export async function prepareCreateAsset(
let assetId: string;

assertTickerAvailable(ticker, status, reservationRequired);
const rawTicker = stringToTicker(ticker, context);
let rawTicker: PolymeshPrimitivesTicker | undefined;

if (ticker) {
rawTicker = stringToTicker(ticker, context);
} else if (isV6) {
throw new PolymeshError({
code: ErrorCode.DataUnavailable,
message: 'Ticker is mandatory for v6 chains',
});
}

/* istanbul ignore if: this will be removed after dual version support for v6-v7 */
if (isV6) {
rawAssetId = rawTicker;
assetId = ticker;
rawAssetId = rawTicker!;
assetId = ticker!;
} else {
assetId = await context.getSigningAccount().getNextAssetId();
rawAssetId = stringToAssetId(assetId, context);
Expand Down Expand Up @@ -378,7 +394,7 @@ export async function getAuthorization(
},
};

if (status !== TickerReservationStatus.Free) {
if (ticker && status !== TickerReservationStatus.Free) {
return {
...auth,
roles: [{ type: RoleType.TickerOwner, ticker }],
Expand All @@ -396,11 +412,12 @@ export async function prepareStorage(
): Promise<Storage> {
const { context } = this;

const reservation = new TickerReservation({ ticker }, context);
const [{ status }, signingIdentity] = await Promise.all([
reservation.details(),
context.getSigningIdentity(),
]);
let status;
if (ticker) {
const reservation = new TickerReservation({ ticker }, context);
({ status } = await reservation.details());
}
const signingIdentity = await context.getSigningIdentity();

const isCustomType = !values<string>(KnownAssetType).includes(assetType);

Expand Down
7 changes: 6 additions & 1 deletion src/api/procedures/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,12 @@ export interface IssueTokensParams {
}

export interface CreateAssetWithTickerParams extends CreateAssetParams {
ticker: string;
/**
* (optional) ticker to be linked with the Asset
*
* @note from 7.x chain, ticker has been made optional. For 6.x chain, it is still mandatory.
*/
ticker?: string;
}

export interface GlobalCollectionKeyInput {
Expand Down

0 comments on commit 9460b22

Please sign in to comment.