Skip to content

Commit

Permalink
Merge pull request #1442 from input-output-hk/refactor/move-cip20-to-…
Browse files Browse the repository at this point in the history
…tx-construction

Refactor/ Move CIP20 to tx-construction
  • Loading branch information
rhyslbw authored Aug 23, 2024
2 parents b7ec9fb + 09aeb2d commit f33bc2c
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 92 deletions.
1 change: 0 additions & 1 deletion packages/core/src/TxMetadata/index.ts

This file was deleted.

1 change: 0 additions & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
export * as Asset from './Asset';
export * as Cardano from './Cardano';
export * as Serialization from './Serialization';
export * as TxMetadata from './TxMetadata';
export * from './Provider';
export * from './util';
export * from './errors';
Expand Down
81 changes: 0 additions & 81 deletions packages/core/test/TxMetadata/cip20.test.ts

This file was deleted.

1 change: 1 addition & 0 deletions packages/tx-construction/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export * from './fees';
export * from './input-selection';
export * from './output-validation';
export * from './tx-builder';
export * from './tx-metadata';
export * from './ensureValidityInterval';
export * from './types';
export * from './computeScriptDataHash';
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Cardano } from '@cardano-sdk/core';
import { CustomError } from 'ts-custom-error';
import { StringUtils } from '@cardano-sdk/util';
import { TxMetadata } from '../Cardano';

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): 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]])]]);
};
1 change: 1 addition & 0 deletions packages/tx-construction/src/tx-metadata/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * as CIP20 from './cip20';
74 changes: 74 additions & 0 deletions packages/tx-construction/test/tx-metadata/cip20.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { CIP20 } from '../../src';
import { Cardano } from '@cardano-sdk/core';

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(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(CIP20.validateMessage(oversizeMessage)).toStrictEqual({
failure: CIP20.MessageValidationFailure.oversize,
valid: false
});
});
it('invalidates a CIP-20 message if wrong type', () => {
expect(CIP20.validateMessage(1 as unknown as string)).toStrictEqual({
failure: CIP20.MessageValidationFailure.wrongType,
valid: false
});
expect(CIP20.validateMessage({ message: compliantShortMessage } as unknown as string)).toStrictEqual({
failure: CIP20.MessageValidationFailure.wrongType,
valid: false
});
expect(CIP20.validateMessage([compliantShortMessage] as unknown as string)).toStrictEqual({
failure: CIP20.MessageValidationFailure.wrongType,
valid: false
});
expect(
CIP20.validateMessage(new Map([[CIP20.METADATUM_LABEL, compliantShortMessage]]) as unknown as string)
).toStrictEqual({ failure: CIP20.MessageValidationFailure.wrongType, valid: false });
});
});
describe('toTxMetadata', () => {
describe('args object', () => {
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(() =>
CIP20.toTxMetadata({
messages: [compliantShortMessage, compliantMaxMessage, oversizeMessage]
})
).toThrowError(CIP20.MessageValidationError);
});
});
describe('produces a CIP20-compliant TxMetadata map with a string arg', () => {
test('larger than 64 bytes', () => {
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 = 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 = 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);
});
});
});
});

0 comments on commit f33bc2c

Please sign in to comment.