Skip to content

Commit

Permalink
feat: cairo1 version2 support
Browse files Browse the repository at this point in the history
  • Loading branch information
tabaktoni committed Jul 3, 2023
1 parent cae5abd commit e564033
Show file tree
Hide file tree
Showing 10 changed files with 583 additions and 13 deletions.

This file was deleted.

This file was deleted.

542 changes: 542 additions & 0 deletions __tests__/cairo1v2.test.ts

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions __tests__/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ export const compiledHelloSierraCasm = readContractSierraCasm('cairo/helloSierra
export const compiledComplexSierra = readContractSierra('cairo/complexInput/complexInput');
export const compiledC1Account = readContractSierra('cairo/account/account');
export const compiledC1AccountCasm = readContractSierraCasm('cairo/account/account');
export const compiledC1v2 = readContractSierra('cairo/helloCairo2/compiled');
export const compiledC1v2Casm = readContractSierraCasm('cairo/helloCairo2/compiled');

/* Default test config based on run `starknet-devnet --seed 0` */
const DEFAULT_TEST_PROVIDER_SEQUENCER_URL = 'http://127.0.0.1:5050/';
Expand Down
4 changes: 3 additions & 1 deletion src/contract/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
} from '../types';
import assert from '../utils/assert';
import { CallData, cairo } from '../utils/calldata';
import { createAbiParser } from '../utils/calldata/parser';
import { ContractInterface } from './interface';

export const splitArgsAndOptions = (args: ArgsOrCalldataWithOptions) => {
Expand Down Expand Up @@ -151,7 +152,8 @@ export class Contract implements ContractInterface {
this.providerOrAccount = providerOrAccount;
this.callData = new CallData(abi);
this.structs = CallData.getAbiStruct(abi);
this.abi = abi;
const parser = createAbiParser(abi);
this.abi = parser.getLegacyFormat();

const options = { enumerable: true, value: {}, writable: false };
Object.defineProperties(this, {
Expand Down
4 changes: 4 additions & 0 deletions src/utils/calldata/cairo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ export const getArrayType = (type: string) => {
export function isCairo1Abi(abi: Abi): boolean {
const firstFunction = abi.find((entry) => entry.type === 'function');
if (!firstFunction) {
if (abi.find((it) => it.type === 'interface')) {
// Expected in Cairo1 version 2
return true;
}
throw new Error(`Error in ABI. No function in ABI.`);
}
if (firstFunction.inputs.length) {
Expand Down
24 changes: 16 additions & 8 deletions src/utils/calldata/requestParser.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AbiEntry, AbiStructs, BigNumberish, ParsedStruct, Tupled } from '../../types';
import { AbiEntry, AbiStructs, BigNumberish, ParsedStruct, Tupled, Uint256 } from '../../types';
import { isText, splitLongString } from '../shortString';
import {
felt,
Expand Down Expand Up @@ -54,6 +54,15 @@ function parseTuple(element: object, typeStr: string): Tupled[] {
});
}

function parseUint256(element: object | BigNumberish) {
if (typeof element === 'object') {
const { low, high } = element as Uint256;
return [felt(low as BigNumberish), felt(high as BigNumberish)];
}
const el_uint256 = uint256(element);
return [felt(el_uint256.low), felt(el_uint256.high)];
}

/**
* Deep parse of the object that has been passed to the method
*
Expand Down Expand Up @@ -84,6 +93,10 @@ function parseCalldataValue(

// checking if the passed element is struct
if (structs[type] && structs[type].members.length) {
if (isTypeUint256(type)) {
return parseUint256(element);
}

const { members } = structs[type];
const subElement = element as any;

Expand All @@ -100,14 +113,9 @@ function parseCalldataValue(
return acc.concat(parsedData);
}, [] as string[]);
}
// check if u256
// check if u256 C1v0
if (isTypeUint256(type)) {
if (typeof element === 'object') {
const { low, high } = element;
return [felt(low as BigNumberish), felt(high as BigNumberish)];
}
const el_uint256 = uint256(element);
return [felt(el_uint256.low), felt(el_uint256.high)];
return parseUint256(element);
}
if (typeof element === 'object') {
throw Error(`Parameter ${element} do not align with abi parameter ${type}`);
Expand Down
7 changes: 7 additions & 0 deletions src/utils/calldata/responseParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ function parseResponseValue(
element: { name: string; type: string },
structs: AbiStructs
): BigNumberish | ParsedStruct | boolean | any[] {
// type uint256 struct (c1v2)
if (isTypeUint256(element.type)) {
const low = responseIterator.next().value;
const high = responseIterator.next().value;
return uint256ToBN({ low, high });
}

// type struct
if (element.type in structs && structs[element.type]) {
return structs[element.type].members.reduce((acc, el) => {
Expand Down
6 changes: 6 additions & 0 deletions src/utils/calldata/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ const validateBool = (parameter: any, input: AbiEntry) => {
};

const validateStruct = (parameter: any, input: AbiEntry, structs: AbiStructs) => {
// c1v2 uint256 in struct
if (input.type === Uint.u256) {
validateUint(parameter, input);
return;
}

assert(
typeof parameter === 'object' && !Array.isArray(parameter),
`Validate: arg ${input.name} is cairo type struct (${input.type}), and should be defined as js object (not array)`
Expand Down
5 changes: 3 additions & 2 deletions src/utils/hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,14 @@ export function calculateDeployTransactionHash(
contractAddress: BigNumberish,
constructorCalldata: RawCalldata,
version: BigNumberish,
chainId: StarknetChainId
chainId: StarknetChainId,
constructorName: string = 'constructor'
): string {
return calculateTransactionHashCommon(
TransactionHashPrefix.DEPLOY,
version,
contractAddress,
getSelectorFromName('constructor'),
getSelectorFromName(constructorName),
constructorCalldata,
0,
chainId
Expand Down

0 comments on commit e564033

Please sign in to comment.