Skip to content

Commit

Permalink
refactor!: export CIP-20 helper functions as CIP20 module
Browse files Browse the repository at this point in the history
- Removes the "CIP20" prefix from individual functions, exports the module as CIP20.
- Now access inner exports using the namespace, e.g CIP20.METADATUM_LABEL
- Renames toCIP20Metadata to toTxMetadata
  • Loading branch information
rhyslbw committed Aug 22, 2024
1 parent 33422e4 commit 09aeb2d
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 46 deletions.
16 changes: 8 additions & 8 deletions packages/tx-construction/src/tx-metadata/cip20.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Cardano } from '@cardano-sdk/core';
import { CustomError } from 'ts-custom-error';
import { StringUtils } from '@cardano-sdk/util';

export const CIP_20_METADATUM_LABEL = 674n;
export const METADATUM_LABEL = 674n;
const MAX_BYTES = 64;

export enum MessageValidationFailure {
Expand All @@ -15,14 +15,14 @@ export type MessageValidationResult = {
failure?: MessageValidationFailure;
};

export type CIP20TxMetadataMessage = string;
export type TxMetadataMessage = string;

export type CIP20TxMetadataArgs = {
export type TxMetadataArgs = {
// An array of message strings, limited to 64 bytes each
messages: CIP20TxMetadataMessage[];
messages: TxMetadataMessage[];
};

export type ValidationResultMap = Map<CIP20TxMetadataMessage, MessageValidationResult>;
export type ValidationResultMap = Map<TxMetadataMessage, MessageValidationResult>;

export class MessageValidationError extends CustomError {
public constructor(failures: ValidationResultMap) {
Expand All @@ -49,17 +49,17 @@ export const validateMessage = (entry: unknown): MessageValidationResult => {
* Converts an object containing an array of individual messages into https://cips.cardano.org/cip/CIP-20 compliant
* transaction metadata
*
* @param args CIP20TxMetadataArgs or a string to be transformed into an array
* @param args Object containing a message property or a string to be transformed into an array
* @returns CIP20-compliant transaction metadata
* @throws Message validation error containing details. Use validateMessage to independently check each message before calling this function
*/
export const toCIP20Metadata = (args: CIP20TxMetadataArgs | string): Cardano.TxMetadata => {
export const toTxMetadata = (args: TxMetadataArgs | string): Cardano.TxMetadata => {
const messages = typeof args === 'string' ? StringUtils.chunkByBytes(args, MAX_BYTES) : args.messages;
const invalidMessages: ValidationResultMap = new Map();
for (const message of messages) {
const result = validateMessage(message);
if (!result.valid) invalidMessages.set(message, result);
}
if (invalidMessages.size > 0) throw new MessageValidationError(invalidMessages);
return new Map([[CIP_20_METADATUM_LABEL, new Map([['msg', messages]])]]);
return new Map([[METADATUM_LABEL, new Map([['msg', messages]])]]);
};
2 changes: 1 addition & 1 deletion packages/tx-construction/src/tx-metadata/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './cip20';
export * as CIP20 from './cip20';
68 changes: 31 additions & 37 deletions packages/tx-construction/test/tx-metadata/cip20.test.ts
Original file line number Diff line number Diff line change
@@ -1,78 +1,72 @@
import {
CIP_20_METADATUM_LABEL,
MessageValidationError,
MessageValidationFailure,
toCIP20Metadata,
validateMessage
} from '../../src';
import { CIP20 } from '../../src';
import { Cardano } from '@cardano-sdk/core';

describe('CIP-20 helper functions', () => {
describe('CIP20', () => {
const compliantShortMessage = 'Lorem ipsum dolor';
const compliantMaxMessage = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean';
const oversizeMessage = `${compliantMaxMessage}1`;
describe('validateMessage', () => {
it('validates a CIP-20 message if a string and less than or equal to 64 bytes', () => {
expect(validateMessage(compliantShortMessage)).toStrictEqual({ valid: true });
expect(validateMessage(compliantMaxMessage)).toStrictEqual({ valid: true });
expect(CIP20.validateMessage(compliantShortMessage)).toStrictEqual({ valid: true });
expect(CIP20.validateMessage(compliantMaxMessage)).toStrictEqual({ valid: true });
});
it('invalidates a CIP-20 message if a string but over 64 bytes', () => {
expect(validateMessage(oversizeMessage)).toStrictEqual({
failure: MessageValidationFailure.oversize,
expect(CIP20.validateMessage(oversizeMessage)).toStrictEqual({
failure: CIP20.MessageValidationFailure.oversize,
valid: false
});
});
it('invalidates a CIP-20 message if wrong type', () => {
expect(validateMessage(1 as unknown as string)).toStrictEqual({
failure: MessageValidationFailure.wrongType,
expect(CIP20.validateMessage(1 as unknown as string)).toStrictEqual({
failure: CIP20.MessageValidationFailure.wrongType,
valid: false
});
expect(validateMessage({ message: compliantShortMessage } as unknown as string)).toStrictEqual({
failure: MessageValidationFailure.wrongType,
expect(CIP20.validateMessage({ message: compliantShortMessage } as unknown as string)).toStrictEqual({
failure: CIP20.MessageValidationFailure.wrongType,
valid: false
});
expect(validateMessage([compliantShortMessage] as unknown as string)).toStrictEqual({
failure: MessageValidationFailure.wrongType,
expect(CIP20.validateMessage([compliantShortMessage] as unknown as string)).toStrictEqual({
failure: CIP20.MessageValidationFailure.wrongType,
valid: false
});
expect(
validateMessage(new Map([[CIP_20_METADATUM_LABEL, compliantShortMessage]]) as unknown as string)
).toStrictEqual({ failure: MessageValidationFailure.wrongType, valid: false });
CIP20.validateMessage(new Map([[CIP20.METADATUM_LABEL, compliantShortMessage]]) as unknown as string)
).toStrictEqual({ failure: CIP20.MessageValidationFailure.wrongType, valid: false });
});
});
describe('toCIP20Metadata', () => {
describe('toTxMetadata', () => {
describe('args object', () => {
it('produces a CIP-20-compliant TxMetadata map', () => {
const metadata = toCIP20Metadata({ messages: [compliantShortMessage] }) as Cardano.TxMetadata;
expect(metadata.has(CIP_20_METADATUM_LABEL)).toBe(true);
const cip20Metadata = metadata.get(CIP_20_METADATUM_LABEL) as Cardano.MetadatumMap;
it('produces a CIP20-compliant TxMetadata map', () => {
const metadata = CIP20.toTxMetadata({ messages: [compliantShortMessage] }) as Cardano.TxMetadata;
expect(metadata.has(CIP20.METADATUM_LABEL)).toBe(true);
const cip20Metadata = metadata.get(CIP20.METADATUM_LABEL) as Cardano.MetadatumMap;
expect(cip20Metadata.get('msg')).toStrictEqual([compliantShortMessage]);
});
it('throws an error if any messages are invalid', () => {
expect(() =>
toCIP20Metadata({
CIP20.toTxMetadata({
messages: [compliantShortMessage, compliantMaxMessage, oversizeMessage]
})
).toThrowError(MessageValidationError);
).toThrowError(CIP20.MessageValidationError);
});
});
describe('producing a CIP-20-compliant TxMetadata map with a string arg', () => {
describe('produces a CIP20-compliant TxMetadata map with a string arg', () => {
test('larger than 64 bytes', () => {
const metadata = toCIP20Metadata(oversizeMessage) as Cardano.TxMetadata;
expect(metadata.has(CIP_20_METADATUM_LABEL)).toBe(true);
const cip20Metadata = metadata.get(CIP_20_METADATUM_LABEL) as Cardano.MetadatumMap;
const metadata = CIP20.toTxMetadata(oversizeMessage) as Cardano.TxMetadata;
expect(metadata.has(CIP20.METADATUM_LABEL)).toBe(true);
const cip20Metadata = metadata.get(CIP20.METADATUM_LABEL) as Cardano.MetadatumMap;
expect((cip20Metadata.get('msg') as string[]).length).toBe(2);
});
test('equal to 64 bytes', () => {
const metadata = toCIP20Metadata(compliantMaxMessage) as Cardano.TxMetadata;
expect(metadata.has(CIP_20_METADATUM_LABEL)).toBe(true);
const cip20Metadata = metadata.get(CIP_20_METADATUM_LABEL) as Cardano.MetadatumMap;
const metadata = CIP20.toTxMetadata(compliantMaxMessage) as Cardano.TxMetadata;
expect(metadata.has(CIP20.METADATUM_LABEL)).toBe(true);
const cip20Metadata = metadata.get(CIP20.METADATUM_LABEL) as Cardano.MetadatumMap;
expect((cip20Metadata.get('msg') as string[]).length).toBe(1);
});
test('smaller than to 64 bytes', () => {
const metadata = toCIP20Metadata(compliantShortMessage) as Cardano.TxMetadata;
expect(metadata.has(CIP_20_METADATUM_LABEL)).toBe(true);
const cip20Metadata = metadata.get(CIP_20_METADATUM_LABEL) as Cardano.MetadatumMap;
const metadata = CIP20.toTxMetadata(compliantShortMessage) as Cardano.TxMetadata;
expect(metadata.has(CIP20.METADATUM_LABEL)).toBe(true);
const cip20Metadata = metadata.get(CIP20.METADATUM_LABEL) as Cardano.MetadatumMap;
expect((cip20Metadata.get('msg') as string[]).length).toBe(1);
});
});
Expand Down

0 comments on commit 09aeb2d

Please sign in to comment.