diff --git a/__mocks__/cairo/cairo282/u96.cairo b/__mocks__/cairo/cairo282/u96.cairo new file mode 100644 index 000000000..726ff70d7 --- /dev/null +++ b/__mocks__/cairo/cairo282/u96.cairo @@ -0,0 +1,27 @@ +use core::circuit::u96; + +#[starknet::interface] +trait ITestU96 { + //fn test_u384(self:@TContractState)->u384; + fn test_u96(self: @TContractState, inp: u96) -> u96; +} + +#[starknet::contract] +mod test_u96 { + use core::circuit::u96; + + #[storage] + struct Storage { + gift_id: u128, + } + + #[abi(embed_v0)] + impl TestU96 of super::ITestU96 { + fn test_u96(self: @ContractState, inp: u96) -> u96 { + let a: felt252 = inp.into(); + let b = a + 1; + let c: u96 = b.try_into().unwrap(); + c + } + } +} diff --git a/__mocks__/cairo/cairo282/u96.casm b/__mocks__/cairo/cairo282/u96.casm new file mode 100644 index 000000000..e51b557fa --- /dev/null +++ b/__mocks__/cairo/cairo282/u96.casm @@ -0,0 +1 @@ +{"prime":"0x800000000000011000000000000000000000000000000000000000000000001","compiler_version":"2.8.2","bytecode":["0xa0680017fff8000","0x7","0x482680017ffa8000","0x100000000000000000000000000000000","0x400280007ff97fff","0x10780017fff7fff","0xb1","0x4825800180007ffa","0x0","0x400280007ff97fff","0x482680017ff98000","0x1","0x48297ffc80007ffd","0x20680017fff7fff","0x4","0x10780017fff7fff","0xa","0x482680017ffc8000","0x1","0x480a7ffd7fff8000","0x480680017fff8000","0x0","0x480a7ffc7fff8000","0x10780017fff7fff","0x8","0x480a7ffc7fff8000","0x480a7ffd7fff8000","0x480680017fff8000","0x1","0x480680017fff8000","0x0","0x20680017fff7ffe","0x86","0x480080007fff8000","0xa0680017fff8000","0x12","0x4824800180007ffe","0x1000000000000000000000000","0x4844800180008002","0x8000000000000110000000000000000","0x4830800080017ffe","0x480080007ff57fff","0x482480017ffe8000","0xf0000000ffffffddffffffffffffffff","0x480080017ff37fff","0x400080027ff27ffb","0x402480017fff7ffb","0xffffffffffffffffffffffffffffffff","0x20680017fff7fff","0x71","0x402780017fff7fff","0x1","0x400080007ff87ffe","0x482480017ffe8000","0xffffffff000000000000000000000000","0x400080017ff77fff","0x482480017ff78000","0x2","0x48307ff880007ff9","0x20680017fff7fff","0x4","0x10780017fff7fff","0x10","0x40780017fff7fff","0x1","0x480680017fff8000","0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473","0x400080007ffe7fff","0x48127ffc7fff8000","0x48127ff17fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x1104800180018000","0x78","0x482480017fff8000","0x77","0x480080007fff8000","0xa0680017fff8000","0x9","0x4824800180007fef","0x0","0x482480017fff8000","0x100000000000000000000000000000000","0x400080007ff77fff","0x10780017fff7fff","0x39","0x4824800180007fef","0x0","0x400080007ff87fff","0x482480017ff58000","0x1","0xa0680017fff8000","0x12","0x4824800180007ffe","0x1000000000000000000000000","0x4844800180008002","0x8000000000000110000000000000000","0x4830800080017ffe","0x480080017ff37fff","0x482480017ffe8000","0xf0000000ffffffddffffffffffffffff","0x480080027ff17fff","0x400080037ff07ffb","0x402480017fff7ffb","0xffffffffffffffffffffffffffffffff","0x20680017fff7fff","0x15","0x402780017fff7fff","0x1","0x400080017ff67ffe","0x482480017ffe8000","0xffffffff000000000000000000000000","0x400080027ff57fff","0x40780017fff7fff","0x1","0x400080007fff7ffc","0x482480017ff48000","0x3","0x48127ffa7fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x0","0x48127ffb7fff8000","0x482480017ffa8000","0x1","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4f7074696f6e3a3a756e77726170206661696c65642e","0x400080007ffe7fff","0x482480017fee8000","0x4","0x48127ff47fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4f7574206f6620676173","0x400080007ffe7fff","0x482480017ff58000","0x1","0x48127fea7fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x482480017ff28000","0x3","0x10780017fff7fff","0x5","0x40780017fff7fff","0x8","0x48127ff27fff8000","0x40780017fff7fff","0x1","0x480680017fff8000","0x4661696c656420746f20646573657269616c697a6520706172616d202331","0x400080007ffe7fff","0x48127ffd7fff8000","0x48127fed7fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4f7574206f6620676173","0x400080007ffe7fff","0x482680017ff98000","0x1","0x480a7ffa7fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe"],"bytecode_segment_lengths":[197],"hints":[[0,[{"TestLessThanOrEqual":{"lhs":{"Immediate":"0x0"},"rhs":{"Deref":{"register":"FP","offset":-6}},"dst":{"register":"AP","offset":0}}}]],[34,[{"TestLessThan":{"lhs":{"BinOp":{"op":"Add","a":{"register":"AP","offset":-1},"b":{"Immediate":"0x0"}}},"rhs":{"Immediate":"0x1000000000000000000000000"},"dst":{"register":"AP","offset":0}}}]],[38,[{"LinearSplit":{"value":{"Deref":{"register":"AP","offset":-1}},"scalar":{"Immediate":"0x8000000000000110000000000000000"},"max_x":{"Immediate":"0xfffffffffffffffffffffffffffffffe"},"x":{"register":"AP","offset":0},"y":{"register":"AP","offset":1}}}]],[63,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[82,[{"TestLessThanOrEqual":{"lhs":{"Immediate":"0x0"},"rhs":{"Deref":{"register":"AP","offset":-16}},"dst":{"register":"AP","offset":0}}}]],[96,[{"TestLessThan":{"lhs":{"BinOp":{"op":"Add","a":{"register":"AP","offset":-1},"b":{"Immediate":"0x0"}}},"rhs":{"Immediate":"0x1000000000000000000000000"},"dst":{"register":"AP","offset":0}}}]],[100,[{"LinearSplit":{"value":{"Deref":{"register":"AP","offset":-1}},"scalar":{"Immediate":"0x8000000000000110000000000000000"},"max_x":{"Immediate":"0xfffffffffffffffffffffffffffffffe"},"x":{"register":"AP","offset":0},"y":{"register":"AP","offset":1}}}]],[118,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[131,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[146,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[168,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[182,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]]],"entry_points_by_type":{"EXTERNAL":[{"selector":"0x1853d8ddb27dca06517f780f15cc4dcc7d1c02edae57fec4b58627bbf65aaaa","offset":0,"builtins":["range_check"]}],"L1_HANDLER":[],"CONSTRUCTOR":[]}} \ No newline at end of file diff --git a/__mocks__/cairo/cairo282/u96.sierra.json b/__mocks__/cairo/cairo282/u96.sierra.json new file mode 100644 index 000000000..a2569cd36 --- /dev/null +++ b/__mocks__/cairo/cairo282/u96.sierra.json @@ -0,0 +1,328 @@ +{ + "sierra_program": [ + "0x1", + "0x6", + "0x0", + "0x2", + "0x8", + "0x2", + "0x8b", + "0x75", + "0x15", + "0x52616e6765436865636b", + "0x800000000000000100000000000000000000000000000000", + "0x436f6e7374", + "0x800000000000000000000000000000000000000000000002", + "0x1", + "0x13", + "0x2", + "0x4661696c656420746f20646573657269616c697a6520706172616d202331", + "0x4f7574206f6620676173", + "0x4f7074696f6e3a3a756e77726170206661696c65642e", + "0x4172726179", + "0x800000000000000300000000000000000000000000000001", + "0x536e617073686f74", + "0x800000000000000700000000000000000000000000000001", + "0x4", + "0x537472756374", + "0x800000000000000700000000000000000000000000000002", + "0x0", + "0x1baeba72e79e9db2587cf44fedb2f3700b2075a5e8e39a562584862c4b71f62", + "0x5", + "0x2ee1e2b1b89f8c495f200e4956278a4d47395fe262f27b52e5865c9524c08c3", + "0x6", + "0x4275696c74696e436f737473", + "0x800000000000000700000000000000000000000000000000", + "0x53797374656d", + "0x800000000000000f00000000000000000000000000000001", + "0x16a4c8d7c05909052238a862d8cc3e7975bf05a07b3a69c6b28951083a6d672", + "0x800000000000000300000000000000000000000000000003", + "0xb", + "0x456e756d", + "0x9931c641b913035ae674b400b61a51476d506bbe8bba2ff8a6272790aba9e6", + "0x7", + "0xc", + "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", + "0x426f756e646564496e74", + "0xffffffffffffffffffffffff", + "0x426f78", + "0x800000000000000700000000000000000000000000000003", + "0x29d7d57c04a880978e7b3689f6218e507f3be17588744b58dc17762447ad0e7", + "0x11", + "0x10", + "0x66656c74323532", + "0x4761734275696c74696e", + "0x2f", + "0x7265766f6b655f61705f747261636b696e67", + "0x77697468647261775f676173", + "0x6272616e63685f616c69676e", + "0x7374727563745f6465636f6e737472756374", + "0x656e61626c655f61705f747261636b696e67", + "0x73746f72655f74656d70", + "0x61727261795f736e617073686f745f706f705f66726f6e74", + "0x656e756d5f696e6974", + "0x12", + "0x6a756d70", + "0x7374727563745f636f6e737472756374", + "0x656e756d5f6d61746368", + "0x756e626f78", + "0x72656e616d65", + "0x646f776e63617374", + "0xf", + "0x64697361626c655f61705f747261636b696e67", + "0x64726f70", + "0x61727261795f6e6577", + "0x636f6e73745f61735f696d6d656469617465", + "0xe", + "0x61727261795f617070656e64", + "0xd", + "0x14", + "0xa", + "0x6765745f6275696c74696e5f636f737473", + "0x9", + "0x77697468647261775f6761735f616c6c", + "0x757063617374", + "0x8", + "0x66656c743235325f616464", + "0x736e617073686f745f74616b65", + "0x3", + "0x83", + "0xffffffffffffffff", + "0x75", + "0x64", + "0x16", + "0x60", + "0x17", + "0x18", + "0x19", + "0x2b", + "0x1a", + "0x1b", + "0x1c", + "0x1d", + "0x1e", + "0x1f", + "0x20", + "0x21", + "0x22", + "0x23", + "0x52", + "0x24", + "0x25", + "0x26", + "0x27", + "0x28", + "0x29", + "0x2a", + "0x45", + "0x2c", + "0x2d", + "0x2e", + "0x30", + "0x31", + "0x32", + "0x33", + "0x34", + "0x35", + "0x36", + "0x37", + "0x38", + "0x39", + "0x3a", + "0x3b", + "0x3c", + "0x3d", + "0x3e", + "0x3f", + "0x40", + "0x68", + "0x41", + "0x42", + "0x43", + "0x44", + "0x46", + "0x47", + "0x48", + "0x49", + "0x4a", + "0x4b", + "0x4c", + "0x523", + "0x11100f050e0d06050c0b0a0706050403090706050403080706050403020100", + "0x51d0515121c101b121a100219181705070605040316051512111014051312", + "0x261e06050e2515121a10240712071123220706050403210520051f121c1e0f", + "0x605053312050532123116050530122f122e122d2c022b182a290528052712", + "0x39350505380507350507342905053712363505053214050532120735050734", + "0x3c05053e2805053e1405053e123d3c050605073b060505320605053a060505", + "0x3244050532050743050734210505371d05053706050542410505400605053f", + "0xf05054c124b4a05054006053c050749124847050532124643050532450505", + "0x402905053e070505404d05054012074305073420050537160505370f05053e", + "0x12071220160750140f074f070512070512124f051212124e1605053e050505", + "0x4f074a0516120f054f050f051412124f05120f124a054f054d054d12124f05", + "0x5471243054f0547054a1221054f0545052012124f051207121d0521454707", + "0x54f053c0521123c054f05121d12124f0512071212280512451241054f0521", + "0x12071235055128054f074105431241054f052905471243054f051d054a1229", + "0xf07281244054f054405291244054f0506053c1206054f0528054112124f05", + "0x55074f074305161200054f0500051412124f051207125405535200074f0744", + "0x12124f0556054412124f0555050612124f05123512124f0512071258055756", + "0x755125a054f055a0529125a054f0512541259054f05125212124f05520500", + "0x125e054f055d0559125d054f055b5c0758125c054f051256125b054f055a59", + "0x5e054f055e055c1207054f0507055b1214054f0514055a1200054f05000514", + "0x54f05125d12124f0558050612124f05123512124f051207125e0714000f05", + "0x12124f05120712646307626160074f075f14004d5f125f054f055f055e125f", + "0x67054f056705291267054f05666507631266054f0512611265054f05520560", + "0x5690560126b054f05125212124f0512071257056a6968074f076760072812", + "0x56612124f052c0565126e2c074f056d0564126d054f056c6b0755126c054f", + "0x5a1268054f056805141271054f057005681270054f056f0567126f054f056e", + "0x120712710761680f0571054f0571055c1207054f0507055b1261054f056105", + "0x5737207551273054f057305291273054f0512691272054f05125212124f05", + "0x5705141277054f057605591276054f05747507581275054f0512561274054f", + "0x570f0577054f0577055c1207054f0507055b1261054f0561055a1257054f05", + "0x1279054f0512571278054f05125212124f0552050012124f05120712770761", + "0x54f057a7b0758127b054f051256127a054f05797807551279054f05790529", + "0x4f0507055b1264054f0564055a1263054f05630514127d054f057c0559127c", + "0x1412124f0543050612124f051207127d0764630f057d054f057d055c120705", + "0x4f0543050612124f0535056b12124f05120712127f051245127e054f055405", + "0x291281054f05126c1280054f05125212124f051235127e054f050f05141212", + "0x6a054f05828307581283054f0512561282054f05818007551281054f058105", + "0x54f0507055b1214054f0514055a127e054f057e05141284054f056a055912", + "0x125212124f054d056d12124f051207128407147e0f0584054f0584055c1207", + "0x12561287054f05868507551286054f058605291286054f0512571285054f05", + "0x5a1216054f05160514128a054f058905591289054f05878807581288054f05", + "0x120f058a0720160f058a054f058a055c1207054f0507055b1220054f052005", + "0x124d070512434544120f164544" + ], + "sierra_program_debug_info": { + "type_names": [ + [0, "RangeCheck"], + [ + 1, + "Const" + ], + [2, "Const"], + [3, "Const"], + [4, "Array"], + [5, "Snapshot>"], + [6, "core::array::Span::"], + [7, "Tuple>"], + [8, "Const"], + [9, "BuiltinCosts"], + [10, "System"], + [11, "core::panics::Panic"], + [12, "Tuple>"], + [13, "core::panics::PanicResult::<(core::array::Span::,)>"], + [14, "Const"], + [15, "BoundedInt<0, 79228162514264337593543950335>"], + [16, "Unit"], + [17, "Box"], + [18, "core::option::Option::>"], + [19, "felt252"], + [20, "GasBuiltin"] + ], + "libfunc_names": [ + [0, "revoke_ap_tracking"], + [1, "withdraw_gas"], + [2, "branch_align"], + [3, "struct_deconstruct>"], + [4, "enable_ap_tracking"], + [5, "store_temp"], + [6, "array_snapshot_pop_front"], + [7, "enum_init>, 0>"], + [8, "store_temp>>"], + [9, "store_temp>>"], + [10, "jump"], + [11, "struct_construct"], + [12, "enum_init>, 1>"], + [13, "enum_match>>"], + [14, "unbox"], + [15, "rename"], + [16, "store_temp"], + [17, "downcast>"], + [18, "disable_ap_tracking"], + [19, "drop>>"], + [20, "drop>"], + [21, "drop>"], + [22, "array_new"], + [ + 23, + "const_as_immediate>" + ], + [24, "array_append"], + [25, "struct_construct"], + [26, "struct_construct>>"], + [27, "enum_init,)>, 1>"], + [28, "store_temp"], + [29, "store_temp"], + [30, "store_temp,)>>"], + [31, "get_builtin_costs"], + [32, "store_temp"], + [33, "withdraw_gas_all"], + [34, "upcast, felt252>"], + [35, "const_as_immediate>"], + [36, "felt252_add"], + [37, "snapshot_take>"], + [38, "drop>"], + [39, "struct_construct>"], + [40, "struct_construct>>"], + [41, "enum_init,)>, 0>"], + [ + 42, + "const_as_immediate>" + ], + [43, "const_as_immediate>"], + [44, "drop"], + [ + 45, + "const_as_immediate>" + ], + [46, "drop>"] + ], + "user_func_names": [[0, "test_u96::test_u96::__wrapper__TestU96__test_u96"]] + }, + "contract_class_version": "0.1.0", + "entry_points_by_type": { + "EXTERNAL": [ + { + "selector": "0x1853d8ddb27dca06517f780f15cc4dcc7d1c02edae57fec4b58627bbf65aaaa", + "function_idx": 0 + } + ], + "L1_HANDLER": [], + "CONSTRUCTOR": [] + }, + "abi": [ + { + "type": "impl", + "name": "TestU96", + "interface_name": "test_u96::ITestU96" + }, + { + "type": "interface", + "name": "test_u96::ITestU96", + "items": [ + { + "type": "function", + "name": "test_u96", + "inputs": [ + { + "name": "inp", + "type": "core::internal::bounded_int::BoundedInt::<0, 79228162514264337593543950335>" + } + ], + "outputs": [ + { + "type": "core::internal::bounded_int::BoundedInt::<0, 79228162514264337593543950335>" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "test_u96::test_u96::Event", + "kind": "enum", + "variants": [] + } + ] +} diff --git a/__tests__/cairov24onward.test.ts b/__tests__/cairov24onward.test.ts index 9898109d8..267b1bf65 100644 --- a/__tests__/cairov24onward.test.ts +++ b/__tests__/cairov24onward.test.ts @@ -208,7 +208,7 @@ describe('Cairo v2.4 onwards', () => { }); }); - describe('Cairo2.6.0 Sierra1.5.0', () => { + describe('Cairo v2.6.0 Sierra1.5.0', () => { test('declare Sierra 1.5.0', async () => { const declare260Response = await account.declareIfNot({ contract: contracts.C260.sierra, @@ -375,4 +375,36 @@ describe('Cairo v2.4 onwards', () => { await expect(nonZeroContract.call('send_nonZero_u256', [myU512])).rejects.toThrow(); }); }); + + describe('Cairo v2.8.2 u96', () => { + let u96Contract: Contract; + + beforeAll(async () => { + const { deploy } = await account.declareAndDeploy({ + contract: contracts.U96.sierra, + casm: contracts.U96.casm, + }); + u96Contract = new Contract(contracts.U96.sierra.abi, deploy.contract_address, account); + }); + + test('u96 compile', async () => { + const myU96: bigint = 2n ** 90n; + const expectedValue = '1237940039285380274899124224'; + const myCalldata1 = CallData.compile([myU96]); + expect(myCalldata1).toEqual([expectedValue]); + const myCallData = new CallData(u96Contract.abi); + const myCalldata = myCallData.compile('test_u96', { + inp: myU96, + }); + expect(myCalldata).toEqual([expectedValue]); + const myCall = u96Contract.populate('test_u96', { inp: myU96 }); + expect(myCall.calldata).toEqual([expectedValue]); + }); + + test('u96 call', async () => { + const value = 2n ** 80n; + const res0 = await u96Contract.call('test_u96', [value]); + expect(res0).toBe(value + 1n); + }); + }); }); diff --git a/__tests__/config/fixtures.ts b/__tests__/config/fixtures.ts index 73bb0253e..68e5f674c 100644 --- a/__tests__/config/fixtures.ts +++ b/__tests__/config/fixtures.ts @@ -75,6 +75,7 @@ const compiledContracts = { }, 'starknetId' ), + U96: 'cairo282/u96', }; export const contracts = mapContractSets(compiledContracts); diff --git a/__tests__/utils/calldata/cairo.test.ts b/__tests__/utils/calldata/cairo.test.ts index 4b7aaf7f7..8e42bcee9 100644 --- a/__tests__/utils/calldata/cairo.test.ts +++ b/__tests__/utils/calldata/cairo.test.ts @@ -26,6 +26,7 @@ import { getAbiContractVersion, tuple, felt, + isTypeU96, } from '../../../src/utils/calldata/cairo'; import { ETH_ADDRESS, Literal, Uint, type ContractVersion, NON_ZERO_PREFIX } from '../../../src'; import { @@ -326,3 +327,15 @@ describe('felt', () => { expect(felts).toEqual(['1952805748', '256', '1234']); }); }); + +describe('u96', () => { + test('should return true if given type is u96', () => { + expect( + isTypeU96('core::internal::bounded_int::BoundedInt::<0, 79228162514264337593543950335>') + ).toEqual(true); + }); + + test('should return false if given type is not u96', () => { + expect(isTypeU96('core::bool')).toEqual(false); + }); +}); diff --git a/src/types/calldata.ts b/src/types/calldata.ts index de9a53aaa..2a5f32ab5 100644 --- a/src/types/calldata.ts +++ b/src/types/calldata.ts @@ -24,6 +24,7 @@ export const Literal = { ClassHash: 'core::starknet::class_hash::ClassHash', ContractAddress: 'core::starknet::contract_address::ContractAddress', Secp256k1Point: 'core::starknet::secp256k1::Secp256k1Point', + U96: 'core::internal::bounded_int::BoundedInt::<0, 79228162514264337593543950335>', } as const; export type Literal = ValuesType; diff --git a/src/utils/calldata/cairo.ts b/src/utils/calldata/cairo.ts index 253db4055..d0534918a 100644 --- a/src/utils/calldata/cairo.ts +++ b/src/utils/calldata/cairo.ts @@ -141,6 +141,15 @@ export const isTypeBytes31 = (type: string) => type === 'core::bytes_31::bytes31 */ export const isTypeByteArray = (type: string) => type === 'core::byte_array::ByteArray'; +/** + * Checks if the given type is equal to the u96 type + * + * @param {string} type - The type to check. + * @returns - True if the given type is equal to u96, false otherwise. + */ +export const isTypeU96 = (type: string) => + type === 'core::internal::bounded_int::BoundedInt::<0, 79228162514264337593543950335>'; + export const isTypeSecp256k1Point = (type: string) => type === Literal.Secp256k1Point; export const isCairo1Type = (type: string) => type.includes('::'); diff --git a/src/utils/calldata/propertyOrder.ts b/src/utils/calldata/propertyOrder.ts index a6d046cdc..550c7ecae 100644 --- a/src/utils/calldata/propertyOrder.ts +++ b/src/utils/calldata/propertyOrder.ts @@ -15,6 +15,7 @@ import { isTypeSecp256k1Point, isTypeStruct, isTypeTuple, + isTypeU96, } from './cairo'; import { CairoCustomEnum, @@ -65,6 +66,9 @@ export default function orderPropsByAbi( if (isTypeByteArray(abiType)) { return unorderedItem; } + if (isTypeU96(abiType)) { + return unorderedItem; + } if (isTypeSecp256k1Point(abiType)) { return unorderedItem; } diff --git a/src/utils/calldata/validate.ts b/src/utils/calldata/validate.ts index 1ce4bc277..eac8198a4 100644 --- a/src/utils/calldata/validate.ts +++ b/src/utils/calldata/validate.ts @@ -159,6 +159,13 @@ const validateUint = (parameter: any, input: AbiEntry) => { ); break; } + case Literal.U96: { + assert( + param >= 0n && param <= 2n ** 96n - 1n, + `Validate: arg ${input.name} must be ${input.type} : a 96 bits number.` + ); + break; + } default: break; diff --git a/www/docs/guides/define_call_message.md b/www/docs/guides/define_call_message.md index 967007bf3..460dd4712 100644 --- a/www/docs/guides/define_call_message.md +++ b/www/docs/guides/define_call_message.md @@ -21,7 +21,7 @@ Cairo has 2 versions, involving 2 types of data: - **Cairo 0**: here, everything is felt, an integer on 251 bits. Available: array, struct, tuple, named tuple, or a mix of these elements. -- **Cairo 1**: with plethora of literal types: u8, u16, u32, usize, u64, u128, felt252, u256, bool, address, eth address, classHash. +- **Cairo 1**: with plethora of literal types: u8, u16, u32, usize, u64, u96, u128, felt252, u256, bool, address, eth address, classHash. Available: array, struct, tuple, bytes31, byteArray, enums or a mix of these elements. Starknet.js is compatible with both versions. @@ -49,7 +49,7 @@ const decimals: BigNumberish = 18; If your Cairo smart contract is waiting for a: -### felt, u8, u16, u32, usize, u64, u128, felt252, ContractAddress, EthAddress, ClassHash +### felt, u8, u16, u32, usize, u64, u96, u128, felt252, ContractAddress, EthAddress, ClassHash Starknet is waiting for a felt. You can send to Starknet.js methods: bigNumberish. @@ -538,21 +538,21 @@ const amount = res.amount; const amount = myContract.call(...); ``` -| Type in Cairo 1 | Cairo 1 code | Type expected in JS/TS | JS/TS function to recover data | -| --------------------------------------------------------- | ---------------------------------- | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| u8, u16, u32, usize, u64, u128, felt252, address | `func get_v()->u128` | bigint | `const res: bigint = myContract.call(...` | -| | | string representing an hex number | `const res=myContract.call(...`
`const address: string = num.toHex(res);` | -| u8, u16, u32, usize | `func get_v() -> u16` | number (53 bits max) | `const res=myContract.call(...`
`const total: number = Number(res)` | -| u256 (255 bits max) | `func get_v() -> u256` | bigint | `const res: bigint = myContract.call(...` | -| u512 (512 bits max) | `func get_v() -> u512` | bigint | `const res: bigint = myContract.call(...` | -| array of u8, u16, u32, usize, u64, u128, felt252, address | `func get_v() -> Array` | bigint[] | `const res: bigint[] = myContract.call(...` | -| bytes31 (31 ASCII characters max) | `func get_v() -> bytes31` | string | `const res: string = myContract.call(...` | -| felt252 (31 ASCII characters max) | `func get_v() -> felt252` | string | `const res = myContract.call(...`
`const title:string = shortString.decodeShortstring(res);` | -| longString | `func get_v() -> Array` | string | `const res=myContract.call(...`
`const longString = res.map( (shortStr: bigint) => { return shortString.decodeShortString( num.toHex( shortStr)) }).join("");` | -| ByteArray | `func get_v() -> ByteArray` | string | `const res: string = myContract.call(...` | -| Tuple | `func get_v() -> (felt252, u8)` | Object {"0": bigint, "1": bigint} | `const res = myContract.call(...`
`const res0: bigint = res["0"];`
`const results: bigint[] = Object.values(res)` | -| Struct | ` func get_v() -> MyStruct` | MyStruct = { account: bigint, amount: bigint} | `const res: MyStruct = myContract.call(...` | -| complex array | `func get_v() -> Array` | MyStruct[] | `const res: MyStruct[] = myContract.call(...` | +| Type in Cairo 1 | Cairo 1 code | Type expected in JS/TS | JS/TS function to recover data | +| -------------------------------------------------------------- | ---------------------------------- | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| u8, u16, u32, usize, u64, u96, u128, felt252, address | `func get_v()->u128` | bigint | `const res: bigint = myContract.call(...` | +| | | string representing an hex number | `const res=myContract.call(...`
`const address: string = num.toHex(res);` | +| u8, u16, u32, usize | `func get_v() -> u16` | number (53 bits max) | `const res=myContract.call(...`
`const total: number = Number(res)` | +| u256 (255 bits max) | `func get_v() -> u256` | bigint | `const res: bigint = myContract.call(...` | +| u512 (512 bits max) | `func get_v() -> u512` | bigint | `const res: bigint = myContract.call(...` | +| array of u8, u16, u32, usize, u64, u96, u128, felt252, address | `func get_v() -> Array` | bigint[] | `const res: bigint[] = myContract.call(...` | +| bytes31 (31 ASCII characters max) | `func get_v() -> bytes31` | string | `const res: string = myContract.call(...` | +| felt252 (31 ASCII characters max) | `func get_v() -> felt252` | string | `const res = myContract.call(...`
`const title:string = shortString.decodeShortstring(res);` | +| longString | `func get_v() -> Array` | string | `const res=myContract.call(...`
`const longString = res.map( (shortStr: bigint) => { return shortString.decodeShortString( num.toHex( shortStr)) }).join("");` | +| ByteArray | `func get_v() -> ByteArray` | string | `const res: string = myContract.call(...` | +| Tuple | `func get_v() -> (felt252, u8)` | Object {"0": bigint, "1": bigint} | `const res = myContract.call(...`
`const res0: bigint = res["0"];`
`const results: bigint[] = Object.values(res)` | +| Struct | ` func get_v() -> MyStruct` | MyStruct = { account: bigint, amount: bigint} | `const res: MyStruct = myContract.call(...` | +| complex array | `func get_v() -> Array` | MyStruct[] | `const res: MyStruct[] = myContract.call(...` | If you don't know if your Contract object is interacting with a Cairo 0 or a Cairo 1 contract, you have these methods: