Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules/
dist/
www/
src/
144 changes: 144 additions & 0 deletions __tests__/utils/calldataDecode.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { DecodeConfig } from '../../src/types';

import {
// Account,
BigNumberish,
CairoUint256,
// CairoCustomEnum,
// CairoOption,
// CairoOptionVariant,
// CairoResult,
// CairoResultVariant,
// CairoUint256,
// CairoUint512,
CallData,
Calldata,
// CompiledSierra,
// Contract,
// DeclareDeployUDCResponse,
RawArgsArray,
RawArgsObject,
// byteArray,
cairo,
// ec,
// hash,
// num,
// selector,
// shortString,
// stark,
// types,
// type Uint512,
} from '../../src';

import {
// compiledC1v2,
// compiledHelloSierra,
compiledComplexSierra,
} from '../config/fixtures';

const {
// uint256,
tuple,
// isCairo1Abi
} = cairo;

describe('Cairo 1', () => {
test('should correctly compile and decompile complex data structures', async () => {
type Order2 = {
p1: BigNumberish;
p2: BigNumberish[];
};

const myOrder2bis: Order2 = {
// wrong order
p2: ['abcd', '56ec'],
p1: 'smolstring',
};

const secondUint256: CairoUint256 = new CairoUint256(40000n);
const tempUint256 = { low: 23456n, high: 1n } as CairoUint256;
const thirdUint256: CairoUint256 = new CairoUint256(tempUint256);
const myFalseUint256: CairoUint256 = thirdUint256; // wrong order

const myRawArgsObject: RawArgsObject = {
// wrong order
active: true,
symbol: 'NIT',
initial_supply: myFalseUint256,
recipient: '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a',
decimals: 18,
tupoftup: tuple(tuple(34, 94), myFalseUint256),
card: myOrder2bis,
longText: 'Bug is back, for ever, here and everywhere',
array1: [100, 101, 102],
array2: [
[200, 201],
[202, 203],
[204, 205],
],
array3: [myOrder2bis, myOrder2bis],
array4: [myFalseUint256, myFalseUint256],
tuple1: tuple(secondUint256, myOrder2bis, [54, 55, 174], 59),
name: 'niceToken',
array5: [tuple(251, 40000), tuple(252, 40001)],
};

const myRawArgsArray: RawArgsArray = [
'niceToken',
'NIT',
18,
thirdUint256,
{ p1: '17', p2: ['234', '467456745457', '0x56ec'] },
'0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a',
true,
{ '0': { '0': 34, '1': 94 }, '1': thirdUint256 },
'Bug is back, for ever, here and everywhere',
['100', '101', '102'],
[
[200, 201],
[202, 203],
[204, 205],
],
[
{ p1: '17', p2: ['234', '467456745457n', '0x56ec'] },
{ p1: '17', p2: ['234', '467456745457n', '0x56ec'] },
],
[thirdUint256, thirdUint256],
{
'0': secondUint256,
'1': { p1: '17', p2: ['234', '467456745457n', '0x56ec'] },
'2': [54, 55, 56],
'3': 59,
},
[
{ '0': 251, '1': 40000 },
{ '0': 252, '1': 40001 },
],
];

const config: DecodeConfig = {
felt: String,
'core::felt252': String,
'core::integer::u8': Number,
'core::integer::u16': Number,
'core::integer::u64': Number,
'core::integer::u128': BigInt,
'core::starknet::contract_address::ContractAddress': String,
longText: String,
};

const cd: CallData = new CallData(compiledComplexSierra.abi);
const compiledDataFromObject: Calldata = cd.compile('constructor', myRawArgsObject);
const compiledDataFromArray: Calldata = cd.compile('constructor', myRawArgsArray);
const decompiledDataFromObject = cd.decompile('constructor', compiledDataFromObject, config);
const decompiledDataFromArray = cd.decompile(
'constructor',
compiledDataFromArray,
config,
true
);

expect(decompiledDataFromObject).toEqual(myRawArgsObject);
expect(decompiledDataFromArray).toEqual(myRawArgsArray);
});
});
7 changes: 7 additions & 0 deletions src/types/lib/contract/abi.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Uint256 } from '..';

/** ABI */
export type Abi = ReadonlyArray<FunctionAbi | EventAbi | StructAbi | any>;

Expand Down Expand Up @@ -56,3 +58,8 @@ export type LegacyEvent = {
data: EventEntry[];
keys: EventEntry[];
};

type JSCDataType = StringConstructor | NumberConstructor | BigIntConstructor | BooleanConstructor;
export type DecodeConfig = {
[typeName: string]: JSCDataType;
};
20 changes: 20 additions & 0 deletions src/utils/cairoDataTypes/uint256.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,24 @@ export class CairoUint256 {
toApiRequest() {
return [CairoFelt(this.low), CairoFelt(this.high)];
}

/**
* Construct CairoUint256 from calldata
* @param calldata Array of two strings representing the low and high parts of a uint256.
*/
static fromCalldata(calldata: [string, string]): CairoUint256 {
if (calldata.length !== 2) {
throw new Error(
'Calldata must contain exactly two elements for low and high parts of uint256.'
);
}

// Validate each part to ensure they are within the acceptable range.
const [low, high] = calldata;
const validatedLow = CairoUint256.validateProps(low, UINT_256_LOW_MIN.toString());
const validatedHigh = CairoUint256.validateProps(high, UINT_256_HIGH_MIN.toString());

// Construct a new instance based on the validated low and high parts.
return new CairoUint256(validatedLow.low, validatedHigh.high);
}
}
15 changes: 15 additions & 0 deletions src/utils/calldata/cairo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,21 @@ export const isTypeResult = (type: string) => type.startsWith('core::result::Res
* @returns - Returns true if the value is a valid Uint type, otherwise false.
*/
export const isTypeUint = (type: string) => Object.values(Uint).includes(type as Uint);
/**
* Retrieves the Uint enum type for the given type string.
*
* @param {string} type - The type string to check against Uint types.
* @returns {(Uint | null)} - The corresponding Uint enum value or null if not found.
*/
export const getUintType = (type: string): string | undefined => {
for (const value of Object.values(Uint)) {
if (value === type) {
return value;
}
}

return undefined;
};
// Legacy Export
/**
* Checks if the given type is `uint256`.
Expand Down
Loading