From fb5bb5978563ea34ad88d24c6c7a9e5fc8317539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A1n=20Valverde?= Date: Fri, 5 Jul 2024 01:23:12 -0600 Subject: [PATCH] feat: added new data types test: added new tests for data types --- .../utils/CairoTypes/CairoInt128.test.ts | 93 ++++++++++++++++ __tests__/utils/CairoTypes/CairoInt16.test.ts | 93 ++++++++++++++++ __tests__/utils/CairoTypes/CairoInt32.test.ts | 93 ++++++++++++++++ __tests__/utils/CairoTypes/CairoInt64.test.ts | 93 ++++++++++++++++ __tests__/utils/CairoTypes/CairoInt8.test.ts | 93 ++++++++++++++++ src/utils/cairoDataTypes/cairoInt.ts | 103 ++++++++++++++++++ src/utils/cairoDataTypes/int128.ts | 58 ++++++++++ src/utils/cairoDataTypes/int16.ts | 58 ++++++++++ src/utils/cairoDataTypes/int32.ts | 58 ++++++++++ src/utils/cairoDataTypes/int64.ts | 58 ++++++++++ src/utils/cairoDataTypes/int8.ts | 58 ++++++++++ 11 files changed, 858 insertions(+) create mode 100644 __tests__/utils/CairoTypes/CairoInt128.test.ts create mode 100644 __tests__/utils/CairoTypes/CairoInt16.test.ts create mode 100644 __tests__/utils/CairoTypes/CairoInt32.test.ts create mode 100644 __tests__/utils/CairoTypes/CairoInt64.test.ts create mode 100644 __tests__/utils/CairoTypes/CairoInt8.test.ts create mode 100644 src/utils/cairoDataTypes/cairoInt.ts create mode 100644 src/utils/cairoDataTypes/int128.ts create mode 100644 src/utils/cairoDataTypes/int16.ts create mode 100644 src/utils/cairoDataTypes/int32.ts create mode 100644 src/utils/cairoDataTypes/int64.ts create mode 100644 src/utils/cairoDataTypes/int8.ts diff --git a/__tests__/utils/CairoTypes/CairoInt128.test.ts b/__tests__/utils/CairoTypes/CairoInt128.test.ts new file mode 100644 index 000000000..b8f5da638 --- /dev/null +++ b/__tests__/utils/CairoTypes/CairoInt128.test.ts @@ -0,0 +1,93 @@ +/* eslint-disable no-new */ +import { Cairoint128, INT_128_MAX, INT_128_MIN } from '../../../src/utils/cairoDataTypes/int128'; + +describe('Cairoint128 class test', () => { + test('constructor 1 should throw on < INT_128_MIN', () => { + expect(() => { + new Cairoint128(INT_128_MIN - 1n); + }).toThrow('bigNumberish is smaller than the int minimum'); + }); + + test('constructor should throw on > INT_128_MAX', () => { + expect(() => { + new Cairoint128(INT_128_MAX + 1n); + }).toThrow('bigNumberish is bigger than the int maximum'); + }); + + test('should convert INT_128_MAX to API Request', () => { + const i128 = new Cairoint128(INT_128_MAX); + expect(i128.toApiRequest()).toEqual('170141183460469231731687303715884105727'); + }); + + test('should serialize negative number to felt252', () => { + const i128 = new Cairoint128(INT_128_MIN); + expect(i128.toApiRequest()).toEqual( + '3618502788666131213697322783095070105452966031871127468241404752419987914754' + ); + }); + + test('should convert negative serialized number to BigInt', () => { + const i128 = new Cairoint128(INT_128_MIN); + expect(i128.negativeFelt252ToBigInt()).toEqual(-170141183460469231731687303715884105727n); + }); + + test('validate should throw on < INT_128_MIN', () => { + expect(() => { + Cairoint128.validate(INT_128_MIN - 1n); + }).toThrow('bigNumberish is smaller than INT_128_MIN'); + }); + + test('validate should throw on > INT_128_MAX', () => { + expect(() => { + Cairoint128.validate(INT_128_MAX + 1n); + }).toThrow('bigNumberish is bigger than INT_128_MAX'); + }); + + test('validate should pass and return bigint', () => { + const validate = Cairoint128.validate(INT_128_MAX); + expect(typeof validate).toBe('bigint'); + }); + + test('is should return true', () => { + const is = Cairoint128.is(INT_128_MAX); + expect(is).toBe(true); + }); + + test('is should return false', () => { + const is = Cairoint128.is(INT_128_MAX + 1n); + expect(is).toBe(false); + }); + + test('constructor should support BigNumberish', () => { + const case1 = new Cairoint128(10n); + const case2 = new Cairoint128(10); + const case3 = new Cairoint128('10'); + const case4 = new Cairoint128('0xA'); + + expect(case1).toEqual(case2); + expect(case3).toEqual(case4); + expect(case1).toEqual(case4); + }); + + test('should convert INT_128_MAX to Int128 dec struct', () => { + const i128 = new Cairoint128(INT_128_MAX); + const i128Decimal = i128.toIntDecimalString(); + expect(i128Decimal).toEqual('170141183460469231731687303715884105727'); + }); + + test('should convert INT_128_MAX to Int128 hex struct', () => { + const i128 = new Cairoint128(INT_128_MAX); + const i128Hex = i128.toIntHexString(); + expect(i128Hex).toEqual('0x7fffffffffffffffffffffffffffffff'); + }); + + test('isAbiType should return true', () => { + const isAbiType = Cairoint128.isAbiType('core::integer::i128'); + expect(isAbiType).toBe(true); + }); + + test('should convert INT_128_MAX to BigInt', () => { + const i128 = new Cairoint128(INT_128_MAX); + expect(i128.toBigInt()).toEqual(INT_128_MAX); + }); +}); diff --git a/__tests__/utils/CairoTypes/CairoInt16.test.ts b/__tests__/utils/CairoTypes/CairoInt16.test.ts new file mode 100644 index 000000000..e37488d27 --- /dev/null +++ b/__tests__/utils/CairoTypes/CairoInt16.test.ts @@ -0,0 +1,93 @@ +/* eslint-disable no-new */ +import { Cairoint16, INT_16_MAX, INT_16_MIN } from '../../../src/utils/cairoDataTypes/int16'; + +describe('Cairoint16 class test', () => { + test('constructor 1 should throw on < INT_16_MIN', () => { + expect(() => { + new Cairoint16(INT_16_MIN - 1n); + }).toThrow('bigNumberish is smaller than the int minimum'); + }); + + test('constructor should throw on > INT_16_MAX', () => { + expect(() => { + new Cairoint16(INT_16_MAX + 1n); + }).toThrow('bigNumberish is bigger than the int maximum'); + }); + + test('should convert INT_16_MAX to API Request', () => { + const i16 = new Cairoint16(INT_16_MAX); + expect(i16.toApiRequest()).toEqual('32767'); + }); + + test('should serialize negative number to felt252', () => { + const i16 = new Cairoint16(INT_16_MIN); + expect(i16.toApiRequest()).toEqual( + '3618502788666131213697322783095070105623107215331596699973092056135871987714' + ); + }); + + test('should convert negative serialized number to BigInt', () => { + const i16 = new Cairoint16(INT_16_MIN); + expect(i16.negativeFelt252ToBigInt()).toEqual(-32767n); + }); + + test('validate should throw on < INT_16_MIN', () => { + expect(() => { + Cairoint16.validate(INT_16_MIN - 1n); + }).toThrow('bigNumberish is smaller than INT_16_MIN'); + }); + + test('validate should throw on > INT_16_MAX', () => { + expect(() => { + Cairoint16.validate(INT_16_MAX + 1n); + }).toThrow('bigNumberish is bigger than INT_16_MAX'); + }); + + test('validate should pass and return bigint', () => { + const validate = Cairoint16.validate(INT_16_MAX); + expect(typeof validate).toBe('bigint'); + }); + + test('is should return true', () => { + const is = Cairoint16.is(INT_16_MAX); + expect(is).toBe(true); + }); + + test('is should return false', () => { + const is = Cairoint16.is(INT_16_MAX + 1n); + expect(is).toBe(false); + }); + + test('constructor should support BigNumberish', () => { + const case1 = new Cairoint16(10n); + const case2 = new Cairoint16(10); + const case3 = new Cairoint16('10'); + const case4 = new Cairoint16('0xA'); + + expect(case1).toEqual(case2); + expect(case3).toEqual(case4); + expect(case1).toEqual(case4); + }); + + test('should convert INT_16_MAX to Int16 dec struct', () => { + const i16 = new Cairoint16(INT_16_MAX); + const i16Decimal = i16.toIntDecimalString(); + expect(i16Decimal).toEqual('32767'); + }); + + test('should convert INT_16_MAX to Int16 hex struct', () => { + const i16 = new Cairoint16(INT_16_MAX); + const i16Hex = i16.toIntHexString(); + expect(i16Hex).toEqual('0x7fff'); + }); + + test('isAbiType should return true', () => { + const isAbiType = Cairoint16.isAbiType('core::integer::i16'); + expect(isAbiType).toBe(true); + }); + + test('should convert INT_16_MAX to BigInt', () => { + const i16 = new Cairoint16(INT_16_MAX); + expect(i16.toBigInt()).toEqual(INT_16_MAX); + }); +}); diff --git a/__tests__/utils/CairoTypes/CairoInt32.test.ts b/__tests__/utils/CairoTypes/CairoInt32.test.ts new file mode 100644 index 000000000..175662b78 --- /dev/null +++ b/__tests__/utils/CairoTypes/CairoInt32.test.ts @@ -0,0 +1,93 @@ +/* eslint-disable no-new */ +import { Cairoint32, INT_32_MAX, INT_32_MIN } from '../../../src/utils/cairoDataTypes/int32'; + +describe('Cairoint32 class test', () => { + test('constructor 1 should throw on < INT_32_MIN', () => { + expect(() => { + new Cairoint32(INT_32_MIN - 1n); + }).toThrow('bigNumberish is smaller than the int minimum'); + }); + + test('constructor should throw on > INT_32_MAX', () => { + expect(() => { + new Cairoint32(INT_32_MAX + 1n); + }).toThrow('bigNumberish is bigger than the int maximum'); + }); + + test('should convert INT_32_MAX to API Request', () => { + const i32 = new Cairoint32(INT_32_MAX); + expect(i32.toApiRequest()).toEqual('2147483647'); + }); + + test('should serialize negative number to felt252', () => { + const i32 = new Cairoint32(INT_32_MIN); + expect(i32.toApiRequest()).toEqual( + '3618502788666131213697322783095070105623107215331596699973092056133724536834' + ); + }); + + test('should convert negative serialized number to BigInt', () => { + const i32 = new Cairoint32(INT_32_MIN); + expect(i32.negativeFelt252ToBigInt()).toEqual(-2147483647n); + }); + + test('validate should throw on < INT_32_MIN', () => { + expect(() => { + Cairoint32.validate(INT_32_MIN - 1n); + }).toThrow('bigNumberish is smaller than INT_32_MIN'); + }); + + test('validate should throw on > INT_32_MAX', () => { + expect(() => { + Cairoint32.validate(INT_32_MAX + 1n); + }).toThrow('bigNumberish is bigger than INT_32_MAX'); + }); + + test('validate should pass and return bigint', () => { + const validate = Cairoint32.validate(INT_32_MAX); + expect(typeof validate).toBe('bigint'); + }); + + test('is should return true', () => { + const is = Cairoint32.is(INT_32_MAX); + expect(is).toBe(true); + }); + + test('is should return false', () => { + const is = Cairoint32.is(INT_32_MAX + 1n); + expect(is).toBe(false); + }); + + test('constructor should support BigNumberish', () => { + const case1 = new Cairoint32(10n); + const case2 = new Cairoint32(10); + const case3 = new Cairoint32('10'); + const case4 = new Cairoint32('0xA'); + + expect(case1).toEqual(case2); + expect(case3).toEqual(case4); + expect(case1).toEqual(case4); + }); + + test('should convert INT_32_MAX to Int32 dec struct', () => { + const i32 = new Cairoint32(INT_32_MAX); + const i32Decimal = i32.toIntDecimalString(); + expect(i32Decimal).toEqual('2147483647'); + }); + + test('should convert INT_32_MAX to Int32 hex struct', () => { + const i32 = new Cairoint32(INT_32_MAX); + const i32Hex = i32.toIntHexString(); + expect(i32Hex).toEqual('0x7fffffff'); + }); + + test('isAbiType should return true', () => { + const isAbiType = Cairoint32.isAbiType('core::integer::i32'); + expect(isAbiType).toBe(true); + }); + + test('should convert INT_32_MAX to BigInt', () => { + const i32 = new Cairoint32(INT_32_MAX); + expect(i32.toBigInt()).toEqual(INT_32_MAX); + }); +}); diff --git a/__tests__/utils/CairoTypes/CairoInt64.test.ts b/__tests__/utils/CairoTypes/CairoInt64.test.ts new file mode 100644 index 000000000..59b5f193c --- /dev/null +++ b/__tests__/utils/CairoTypes/CairoInt64.test.ts @@ -0,0 +1,93 @@ +/* eslint-disable no-new */ +import { Cairoint64, INT_64_MAX, INT_64_MIN } from '../../../src/utils/cairoDataTypes/int64'; + +describe('Cairoint64 class test', () => { + test('constructor 1 should throw on < INT_64_MIN', () => { + expect(() => { + new Cairoint64(INT_64_MIN - 1n); + }).toThrow('bigNumberish is smaller than the int minimum'); + }); + + test('constructor should throw on > INT_64_MAX', () => { + expect(() => { + new Cairoint64(INT_64_MAX + 1n); + }).toThrow('bigNumberish is bigger than the int maximum'); + }); + + test('should convert INT_64_MAX to API Request', () => { + const i64 = new Cairoint64(INT_64_MAX); + expect(i64.toApiRequest()).toEqual('9223372036854775807'); + }); + + test('should serialize negative number to felt252', () => { + const i64 = new Cairoint64(INT_64_MIN); + expect(i64.toApiRequest()).toEqual( + '3618502788666131213697322783095070105623107215331596699963868684099017244674' + ); + }); + + test('should convert negative serialized number to BigInt', () => { + const i64 = new Cairoint64(INT_64_MIN); + expect(i64.negativeFelt252ToBigInt()).toEqual(-9223372036854775807n); + }); + + test('validate should throw on < INT_64_MIN', () => { + expect(() => { + Cairoint64.validate(INT_64_MIN - 1n); + }).toThrow('bigNumberish is smaller than INT_64_MIN'); + }); + + test('validate should throw on > INT_64_MAX', () => { + expect(() => { + Cairoint64.validate(INT_64_MAX + 1n); + }).toThrow('bigNumberish is bigger than INT_64_MAX'); + }); + + test('validate should pass and return bigint', () => { + const validate = Cairoint64.validate(INT_64_MAX); + expect(typeof validate).toBe('bigint'); + }); + + test('is should return true', () => { + const is = Cairoint64.is(INT_64_MAX); + expect(is).toBe(true); + }); + + test('is should return false', () => { + const is = Cairoint64.is(INT_64_MAX + 1n); + expect(is).toBe(false); + }); + + test('constructor should support BigNumberish', () => { + const case1 = new Cairoint64(10n); + const case2 = new Cairoint64(10); + const case3 = new Cairoint64('10'); + const case4 = new Cairoint64('0xA'); + + expect(case1).toEqual(case2); + expect(case3).toEqual(case4); + expect(case1).toEqual(case4); + }); + + test('should convert INT_64_MAX to Int64 dec struct', () => { + const i64 = new Cairoint64(INT_64_MAX); + const i64Decimal = i64.toIntDecimalString(); + expect(i64Decimal).toEqual('9223372036854775807'); + }); + + test('should convert INT_64_MAX to Int64 hex struct', () => { + const i64 = new Cairoint64(INT_64_MAX); + const i64Hex = i64.toIntHexString(); + expect(i64Hex).toEqual('0x7fffffffffffffff'); + }); + + test('isAbiType should return true', () => { + const isAbiType = Cairoint64.isAbiType('core::integer::i64'); + expect(isAbiType).toBe(true); + }); + + test('should convert INT_64_MAX to BigInt', () => { + const i64 = new Cairoint64(INT_64_MAX); + expect(i64.toBigInt()).toEqual(INT_64_MAX); + }); +}); diff --git a/__tests__/utils/CairoTypes/CairoInt8.test.ts b/__tests__/utils/CairoTypes/CairoInt8.test.ts new file mode 100644 index 000000000..f240b42f6 --- /dev/null +++ b/__tests__/utils/CairoTypes/CairoInt8.test.ts @@ -0,0 +1,93 @@ +/* eslint-disable no-new */ +import { Cairoint8, INT_8_MAX, INT_8_MIN } from '../../../src/utils/cairoDataTypes/int8'; + +describe('Cairoint8 class test', () => { + test('constructor 1 should throw on < INT_8_MIN', () => { + expect(() => { + new Cairoint8(INT_8_MIN - 1n); + }).toThrow('bigNumberish is smaller than the int minimum'); + }); + + test('constructor should throw on > INT_8_MAX', () => { + expect(() => { + new Cairoint8(INT_8_MAX + 1n); + }).toThrow('bigNumberish is bigger than the int maximum'); + }); + + test('should convert INT_8_MAX to API Request', () => { + const i8 = new Cairoint8(INT_8_MAX); + expect(i8.toApiRequest()).toEqual('127'); + }); + + test('should serialize negative number to felt252', () => { + const i8 = new Cairoint8(INT_8_MIN); + expect(i8.toApiRequest()).toEqual( + '3618502788666131213697322783095070105623107215331596699973092056135872020354' + ); + }); + + test('should convert negative serialized number to BigInt', () => { + const i8 = new Cairoint8(-5); + expect(i8.negativeFelt252ToBigInt()).toEqual(-5n); + }); + + test('validate should throw on < INT_8_MIN', () => { + expect(() => { + Cairoint8.validate(INT_8_MIN - 1n); + }).toThrow('bigNumberish is smaller than INT_8_MIN'); + }); + + test('validate should throw on > INT_8_MAX', () => { + expect(() => { + Cairoint8.validate(INT_8_MAX + 1n); + }).toThrow('bigNumberish is bigger than INT_8_MAX'); + }); + + test('validate should pass and return bigint', () => { + const validate = Cairoint8.validate(INT_8_MAX); + expect(typeof validate).toBe('bigint'); + }); + + test('is should return true', () => { + const is = Cairoint8.is(INT_8_MAX); + expect(is).toBe(true); + }); + + test('is should return false', () => { + const is = Cairoint8.is(INT_8_MAX + 1n); + expect(is).toBe(false); + }); + + test('constructor should support BigNumberish', () => { + const case1 = new Cairoint8(10n); + const case2 = new Cairoint8(10); + const case3 = new Cairoint8('10'); + const case4 = new Cairoint8('0xA'); + + expect(case1).toEqual(case2); + expect(case3).toEqual(case4); + expect(case1).toEqual(case4); + }); + + test('should convert INT_8_MAX to Int8 dec struct', () => { + const i8 = new Cairoint8(INT_8_MAX); + const i8Decimal = i8.toIntDecimalString(); + expect(i8Decimal).toEqual('127'); + }); + + test('should convert INT_8_MAX to Int8 hex struct', () => { + const i8 = new Cairoint8(INT_8_MAX); + const i8Hex = i8.toIntHexString(); + expect(i8Hex).toEqual('0x7f'); + }); + + test('isAbiType should return true', () => { + const isAbiType = Cairoint8.isAbiType('core::integer::i8'); + expect(isAbiType).toBe(true); + }); + + test('should convert INT_8_MAX to BigInt', () => { + const i8 = new Cairoint8(INT_8_MAX); + expect(i8.toBigInt()).toEqual(INT_8_MAX); + }); +}); diff --git a/src/utils/cairoDataTypes/cairoInt.ts b/src/utils/cairoDataTypes/cairoInt.ts new file mode 100644 index 000000000..d34b58c03 --- /dev/null +++ b/src/utils/cairoDataTypes/cairoInt.ts @@ -0,0 +1,103 @@ +/* eslint-disable no-bitwise */ +/** + * Singular class handling cairo integer data type + */ + +import { BigNumberish } from '../../types'; +import { addHexPrefix } from '../encode'; +import { CairoFelt } from './felt'; + +export const P: bigint = 2n ** 251n + 17n * 2n ** 192n + 1n; +// export const INT_8_MAX = (1n << 7n) - 1n; +// export const INT_8_MIN = -(1n << 7n) + 1n; +// export const MIN_252_BITS = P + INT_8_MIN; +// export const MAX_252_BITS = P; + +export class CairoInt { + public felt252: bigint; + + public INT_MAX: bigint = 0n; + + public INT_MIN: bigint = 0n; + + public MAX_FELT_8BITS = P; + + public MIN_FELT_8BITS: bigint = 0n; + + /** + * Default constructor (Lib usage) + * @param bigNumberish BigNumberish value representing i8 + */ + + public constructor(int: BigNumberish, INT_MAX: bigint, INT_MIN: bigint) { + this.INT_MAX = INT_MAX; + this.INT_MIN = INT_MIN; + this.MIN_FELT_8BITS = P + this.INT_MIN; + const bigInt = this.validate(int); + + if (bigInt > 0 && bigInt <= this.INT_MAX) { + this.felt252 = bigInt; + } else { + this.felt252 = P + bigInt; + } + } + + /** + * Validate if BigNumberish can be represented as i8 + */ + validate(bigNumberish: BigNumberish) { + const bigInt = BigInt(bigNumberish); + if (bigInt < this.INT_MIN) throw new Error('bigNumberish is smaller than the int minimum'); + if (bigInt > this.INT_MAX) throw new Error('bigNumberish is bigger than the int maximum'); + return bigInt; + } + + /** + * Validate if BigNumberish is a 8 bits felt252 + */ + validate252Bits(bigNumberish: BigNumberish) { + const bigInt = BigInt(bigNumberish); + if (bigInt > this.MAX_FELT_8BITS) throw new Error('bigNumberish is bigger than MAX_252_BITS'); + if (bigInt < this.MIN_FELT_8BITS) throw new Error('bigNumberish is smaller than MIN_252_BITS'); + return bigInt; + } + + /* + * Return a negative number (felt252) back to bigint + */ + negativeFelt252ToBigInt() { + const bigInt = this.validate252Bits(this.felt252); + return BigInt(bigInt - P); + } + + /** + * Return bigint representation + */ + toBigInt() { + return this.felt252; + } + + /** + * Return i8 structure with HexString + */ + toIntHexString() { + return addHexPrefix(this.felt252.toString(16)); + } + + /** + * Return i8 structure with DecimalString + */ + toIntDecimalString() { + return this.felt252.toString(10); + } + + /** + * Return api requests representation witch is felt + */ + toApiRequest() { + if (this.felt252 > 0) { + return CairoFelt(this.felt252); + } + return this.felt252.toString(); + } +} diff --git a/src/utils/cairoDataTypes/int128.ts b/src/utils/cairoDataTypes/int128.ts new file mode 100644 index 000000000..37f676819 --- /dev/null +++ b/src/utils/cairoDataTypes/int128.ts @@ -0,0 +1,58 @@ +/* eslint-disable no-bitwise */ +/** + * Singular class handling cairo i128 data type + */ + +import { BigNumberish } from '../../types'; +import { CairoInt } from './cairoInt'; + +export const INT_128_MAX = (1n << 127n) - 1n; +export const INT_128_MIN = -(1n << 127n) + 1n; +const abiSelector = 'core::integer::i128'; + +export class Cairoint128 extends CairoInt { + /** + * Default constructor (Lib usage) + * @param bigNumberish BigNumberish value representing i128 + */ + + public constructor(int128: BigNumberish) { + super(int128, INT_128_MAX, INT_128_MIN); + } + + /** + * Check if provided abi type is this data type + */ + static isAbiType(abiType: string) { + return abiType === abiSelector; + } + + /* + * Check if BigNumberish can be represented as 128 bits integer + */ + static is(bigNumberish: BigNumberish) { + try { + Cairoint128.validate(bigNumberish); + } catch (error) { + return false; + } + return true; + } + + static validate(bigNumberish: BigNumberish) { + const bigInt = BigInt(bigNumberish); + if (bigInt < INT_128_MIN) throw new Error('bigNumberish is smaller than INT_128_MIN'); + if (bigInt > INT_128_MAX) throw new Error('bigNumberish is bigger than INT_128_MAX'); + return bigInt; + } + + static validate252Bits(bigNumberish: BigNumberish) { + const P: bigint = 2n ** 251n + 17n * 2n ** 192n + 1n; + const MAX_FELT_128BITS = P; + const MIN_FELT_128BITS = P + INT_128_MIN; + const bigInt = BigInt(bigNumberish); + if (bigInt > MAX_FELT_128BITS) throw new Error('bigNumberish is bigger than MAX_252_BITS'); + if (bigInt < MIN_FELT_128BITS) throw new Error('bigNumberish is smaller than MIN_252_BITS'); + return bigInt; + } +} diff --git a/src/utils/cairoDataTypes/int16.ts b/src/utils/cairoDataTypes/int16.ts new file mode 100644 index 000000000..50e693302 --- /dev/null +++ b/src/utils/cairoDataTypes/int16.ts @@ -0,0 +1,58 @@ +/* eslint-disable no-bitwise */ +/** + * Singular class handling cairo i16 data type + */ + +import { BigNumberish } from '../../types'; +import { CairoInt } from './cairoInt'; + +export const INT_16_MAX = (1n << 15n) - 1n; +export const INT_16_MIN = -(1n << 15n) + 1n; +const abiSelector = 'core::integer::i16'; + +export class Cairoint16 extends CairoInt { + /** + * Default constructor (Lib usage) + * @param bigNumberish BigNumberish value representing i16 + */ + + public constructor(int16: BigNumberish) { + super(int16, INT_16_MAX, INT_16_MIN); + } + + /** + * Check if provided abi type is this data type + */ + static isAbiType(abiType: string) { + return abiType === abiSelector; + } + + /* + * Check if BigNumberish can be represented as 16 bits integer + */ + static is(bigNumberish: BigNumberish) { + try { + Cairoint16.validate(bigNumberish); + } catch (error) { + return false; + } + return true; + } + + static validate(bigNumberish: BigNumberish) { + const bigInt = BigInt(bigNumberish); + if (bigInt < INT_16_MIN) throw new Error('bigNumberish is smaller than INT_16_MIN'); + if (bigInt > INT_16_MAX) throw new Error('bigNumberish is bigger than INT_16_MAX'); + return bigInt; + } + + static validate252Bits(bigNumberish: BigNumberish) { + const P: bigint = 2n ** 251n + 17n * 2n ** 192n + 1n; + const MAX_FELT_16BITS = P; + const MIN_FELT_16BITS = P + INT_16_MIN; + const bigInt = BigInt(bigNumberish); + if (bigInt > MAX_FELT_16BITS) throw new Error('bigNumberish is bigger than MAX_252_BITS'); + if (bigInt < MIN_FELT_16BITS) throw new Error('bigNumberish is smaller than MIN_252_BITS'); + return bigInt; + } +} diff --git a/src/utils/cairoDataTypes/int32.ts b/src/utils/cairoDataTypes/int32.ts new file mode 100644 index 000000000..2f00b6c75 --- /dev/null +++ b/src/utils/cairoDataTypes/int32.ts @@ -0,0 +1,58 @@ +/* eslint-disable no-bitwise */ +/** + * Singular class handling cairo i32 data type + */ + +import { BigNumberish } from '../../types'; +import { CairoInt } from './cairoInt'; + +export const INT_32_MAX = (1n << 31n) - 1n; +export const INT_32_MIN = -(1n << 31n) + 1n; +const abiSelector = 'core::integer::i32'; + +export class Cairoint32 extends CairoInt { + /** + * Default constructor (Lib usage) + * @param bigNumberish BigNumberish value representing i32 + */ + + public constructor(int32: BigNumberish) { + super(int32, INT_32_MAX, INT_32_MIN); + } + + /** + * Check if provided abi type is this data type + */ + static isAbiType(abiType: string) { + return abiType === abiSelector; + } + + /* + * Check if BigNumberish can be represented as 32 bits integer + */ + static is(bigNumberish: BigNumberish) { + try { + Cairoint32.validate(bigNumberish); + } catch (error) { + return false; + } + return true; + } + + static validate(bigNumberish: BigNumberish) { + const bigInt = BigInt(bigNumberish); + if (bigInt < INT_32_MIN) throw new Error('bigNumberish is smaller than INT_32_MIN'); + if (bigInt > INT_32_MAX) throw new Error('bigNumberish is bigger than INT_32_MAX'); + return bigInt; + } + + static validate252Bits(bigNumberish: BigNumberish) { + const P: bigint = 2n ** 251n + 17n * 2n ** 192n + 1n; + const MAX_FELT_32BITS = P; + const MIN_FELT_32BITS = P + INT_32_MIN; + const bigInt = BigInt(bigNumberish); + if (bigInt > MAX_FELT_32BITS) throw new Error('bigNumberish is bigger than MAX_252_BITS'); + if (bigInt < MIN_FELT_32BITS) throw new Error('bigNumberish is smaller than MIN_252_BITS'); + return bigInt; + } +} diff --git a/src/utils/cairoDataTypes/int64.ts b/src/utils/cairoDataTypes/int64.ts new file mode 100644 index 000000000..46860b6b9 --- /dev/null +++ b/src/utils/cairoDataTypes/int64.ts @@ -0,0 +1,58 @@ +/* eslint-disable no-bitwise */ +/** + * Singular class handling cairo i64 data type + */ + +import { BigNumberish } from '../../types'; +import { CairoInt } from './cairoInt'; + +export const INT_64_MAX = (1n << 63n) - 1n; +export const INT_64_MIN = -(1n << 63n) + 1n; +const abiSelector = 'core::integer::i64'; + +export class Cairoint64 extends CairoInt { + /** + * Default constructor (Lib usage) + * @param bigNumberish BigNumberish value representing i64 + */ + + public constructor(int64: BigNumberish) { + super(int64, INT_64_MAX, INT_64_MIN); + } + + /** + * Check if provided abi type is this data type + */ + static isAbiType(abiType: string) { + return abiType === abiSelector; + } + + /* + * Check if BigNumberish can be represented as 64 bits integer + */ + static is(bigNumberish: BigNumberish) { + try { + Cairoint64.validate(bigNumberish); + } catch (error) { + return false; + } + return true; + } + + static validate(bigNumberish: BigNumberish) { + const bigInt = BigInt(bigNumberish); + if (bigInt < INT_64_MIN) throw new Error('bigNumberish is smaller than INT_64_MIN'); + if (bigInt > INT_64_MAX) throw new Error('bigNumberish is bigger than INT_64_MAX'); + return bigInt; + } + + static validate252Bits(bigNumberish: BigNumberish) { + const P: bigint = 2n ** 251n + 17n * 2n ** 192n + 1n; + const MAX_FELT_64BITS = P; + const MIN_FELT_64BITS = P + INT_64_MIN; + const bigInt = BigInt(bigNumberish); + if (bigInt > MAX_FELT_64BITS) throw new Error('bigNumberish is bigger than MAX_252_BITS'); + if (bigInt < MIN_FELT_64BITS) throw new Error('bigNumberish is smaller than MIN_252_BITS'); + return bigInt; + } +} diff --git a/src/utils/cairoDataTypes/int8.ts b/src/utils/cairoDataTypes/int8.ts new file mode 100644 index 000000000..e0923b1fd --- /dev/null +++ b/src/utils/cairoDataTypes/int8.ts @@ -0,0 +1,58 @@ +/* eslint-disable no-bitwise */ +/** + * Singular class handling cairo i8 data type + */ + +import { BigNumberish } from '../../types'; +import { CairoInt } from './cairoInt'; + +export const INT_8_MAX = (1n << 7n) - 1n; +export const INT_8_MIN = -(1n << 7n) + 1n; +const abiSelector = 'core::integer::i8'; + +export class Cairoint8 extends CairoInt { + /** + * Default constructor (Lib usage) + * @param bigNumberish BigNumberish value representing i8 + */ + + public constructor(int8: BigNumberish) { + super(int8, INT_8_MAX, INT_8_MIN); + } + + /** + * Check if provided abi type is this data type + */ + static isAbiType(abiType: string) { + return abiType === abiSelector; + } + + /* + * Check if BigNumberish can be represented as 8 bits integer + */ + static is(bigNumberish: BigNumberish) { + try { + Cairoint8.validate(bigNumberish); + } catch (error) { + return false; + } + return true; + } + + static validate(bigNumberish: BigNumberish) { + const bigInt = BigInt(bigNumberish); + if (bigInt < INT_8_MIN) throw new Error('bigNumberish is smaller than INT_8_MIN'); + if (bigInt > INT_8_MAX) throw new Error('bigNumberish is bigger than INT_8_MAX'); + return bigInt; + } + + static validate252Bits(bigNumberish: BigNumberish) { + const P: bigint = 2n ** 251n + 17n * 2n ** 192n + 1n; + const MAX_FELT_8BITS = P; + const MIN_FELT_8BITS = P + INT_8_MIN; + const bigInt = BigInt(bigNumberish); + if (bigInt > MAX_FELT_8BITS) throw new Error('bigNumberish is bigger than MAX_252_BITS'); + if (bigInt < MIN_FELT_8BITS) throw new Error('bigNumberish is smaller than MIN_252_BITS'); + return bigInt; + } +}