Skip to content

Commit

Permalink
feat: cairo enum in response parser
Browse files Browse the repository at this point in the history
Squashed commit of the following:

commit ca39cb6
Author: Philippe ROSTAN <[email protected]>
Date:   Tue Jul 18 16:46:32 2023 +0200

    feat: cairo enums in response parser

commit 1589fe0
Author: Philippe ROSTAN <[email protected]>
Date:   Tue Jul 18 16:05:37 2023 +0200

    feat: add enums-response as class

commit 3253290
Author: Philippe ROSTAN <[email protected]>
Date:   Tue Jul 18 15:59:02 2023 +0200

    feat: cairo enums 1

commit 9e5b94d
Author: semantic-release-bot <[email protected]>
Date:   Tue Jul 18 08:24:48 2023 +0000

    chore(release): 5.17.0 [skip ci]

    * add FailedTransactionResponse ([994925e](994925e))
    * remedy type declaration roll-up issues ([48625f4](48625f4))
    * transaction_failure_reason ([77329b7](77329b7))

    * add Enum in contract ([515e233](515e233)), closes [#670](#670) [#665](#665) [#664](#664) [#1](#1)
    * calldata result in populate ([d44dc56](d44dc56)), closes [#675](#675) [#1](#1)
    * contractFactory Cairo1 & changed constructor signature, 0.12 test fixes ([9b44c54](9b44c54))
    * rename Failed to Rejected for transaction type ([65b1ef4](65b1ef4))

commit f4a7242
Author: Philippe ROSTAN <[email protected]>
Date:   Tue Jul 11 16:46:12 2023 +0200

    feat: calldata result in populate

    Squashed commit of the following:

    commit f7fd920
    Author: Philippe ROSTAN <[email protected]>
    Date:   Tue Jul 11 16:35:42 2023 +0200

        feat: meta-class accepts Calldata as input

    commit b2e6c29
    Author: Philippe ROSTAN <[email protected]>
    Date:   Tue Jul 11 11:14:47 2023 +0200

        fix: calldata relocated

    commit 045af8e
    Author: CI <[email protected]>
    Date:   Wed Jul 5 06:52:47 2023 +0000

        docs: generate documentation

    commit 5f308d4
    Author: Ivan Pavičić <[email protected]>
    Date:   Wed Jul 5 08:48:29 2023 +0200

        docs: added waitForTransaction section and cleanups (#675)

        * docs: added waitForTransaction section and cleanups

        * docs: grammarly

        ---------

        Co-authored-by: Toni Tabak <[email protected]>

    commit da64857
    Author: semantic-release-bot <[email protected]>
    Date:   Mon Jul 3 15:08:31 2023 +0000

        chore(release): 5.16.0 [skip ci]

        * cairo1 version2 support ([e564033](e564033))
        * extract parser from CallData and Cairo ([b7eba2a](b7eba2a))
        * parsers ([cce9029](cce9029))

    commit ff35d5f
    Author: Toni Tabak <[email protected]>
    Date:   Mon Jul 3 16:32:11 2023 +0200

        chore: cleanup

    commit 92b2be5
    Author: Toni Tabak <[email protected]>
    Date:   Mon Jul 3 14:07:45 2023 +0200

        chore: compiled files

    commit 1f365f8
    Author: Toni Tabak <[email protected]>
    Date:   Mon Jul 3 14:05:52 2023 +0200

        feat: cairo1 version2 support

    commit 5cdfdeb
    Author: Toni Tabak <[email protected]>
    Date:   Mon Jul 3 11:41:51 2023 +0200

        chore: refact

    commit 3af53bd
    Author: Toni Tabak <[email protected]>
    Date:   Fri Jun 30 16:16:21 2023 +0200

        feat: parsers

    commit 6e25aac
    Author: Toni Tabak <[email protected]>
    Date:   Fri Jun 30 16:13:14 2023 +0200

        feat: extract parser from CallData and Cairo

    commit 2cb2848
    Author: amanusk <[email protected]>
    Date:   Thu Jun 29 21:23:28 2023 +0300

        Add example of new synatx cairo contract

    commit 7e6e136
    Merge: b2e7a40 e6b861a
    Author: Philippe ROSTAN <[email protected]>
    Date:   Fri Jun 30 12:36:18 2023 +0200

        Merge pull request #1 from 0xs34n/develop

        merge

commit e097682
Author: Petar Penovic <[email protected]>
Date:   Thu Jul 6 23:59:50 2023 +0200

    fix: remedy type declaration roll-up issues

commit 50e3250
Author: Toni Tabak <[email protected]>
Date:   Tue Jul 11 13:34:24 2023 +0200

    feat: rename Failed to Rejected for transaction type

commit 60936f4
Author: Toni Tabak <[email protected]>
Date:   Mon Jul 10 14:47:16 2023 +0200

    fix: add FailedTransactionResponse

commit 2a3a821
Author: Toni Tabak <[email protected]>
Date:   Mon Jul 10 14:36:47 2023 +0200

    fix: transaction_failure_reason

commit f7cc9ca
Author: Toni Tabak <[email protected]>
Date:   Thu Jul 6 15:42:29 2023 +0200

    Update src/contract/contractFactory.ts

    Co-authored-by: Ivan Pavičić <[email protected]>

commit 269e443
Author: Toni Tabak <[email protected]>
Date:   Thu Jul 6 15:47:30 2023 +0200

    chore: cleanup

commit d4670f6
Author: Toni Tabak <[email protected]>
Date:   Thu Jul 6 12:13:07 2023 +0200

    feat: contractFactory Cairo1 & changed constructor signature, 0.12 test fixes

commit 1a08793
Author: Philippe ROSTAN <[email protected]>
Date:   Mon Jul 3 19:50:22 2023 +0200

    feat: add Enum in contract

    Squashed commit of the following:

    commit fd6064e
    Author: Philippe ROSTAN <[email protected]>
    Date:   Mon Jul 3 19:26:54 2023 +0200

        feat: merge in hellocairo2

    commit 0246933
    Author: Philippe ROSTAN <[email protected]>
    Date:   Mon Jul 3 17:21:45 2023 +0200

        feat: merge v5.16.0
        Squashed commit of the following:

        commit e5696b4
        Author: semantic-release-bot <[email protected]>
        Date:   Mon Jul 3 15:08:31 2023 +0000

            chore(release): 5.16.0 [skip ci]

            * cairo1 version2 support ([e564033](e564033))
            * extract parser from CallData and Cairo ([b7eba2a](b7eba2a))
            * parsers ([cce9029](cce9029))

        commit 3389085
        Merge: e6b861a 589c948
        Author: Toni Tabak <[email protected]>
        Date:   Mon Jul 3 17:06:08 2023 +0200

            Merge pull request #670 from 0xs34n/next-version

            Next version

        commit 589c948
        Merge: ffa6d07 03ee060
        Author: Toni Tabak <[email protected]>
        Date:   Mon Jul 3 16:38:23 2023 +0200

            Merge pull request #665 from 0xs34n/0.12.0/abi-parser

            abi parser Cario1 Version2

        commit 03ee060
        Author: Toni Tabak <[email protected]>
        Date:   Mon Jul 3 16:32:11 2023 +0200

            chore: cleanup

        commit 6c0eae2
        Author: Toni Tabak <[email protected]>
        Date:   Mon Jul 3 14:07:45 2023 +0200

            chore: compiled files

        commit e564033
        Author: Toni Tabak <[email protected]>
        Date:   Mon Jul 3 14:05:52 2023 +0200

            feat: cairo1 version2 support

        commit ffa6d07
        Merge: e6b861a 6f8164f
        Author: Toni Tabak <[email protected]>
        Date:   Mon Jul 3 11:43:42 2023 +0200

            Merge pull request #664 from amanusk/cairo_v2_example

            Add example of new synatx cairo contract

        commit cae5abd
        Author: Toni Tabak <[email protected]>
        Date:   Mon Jul 3 11:41:51 2023 +0200

            chore: refact

        commit cce9029
        Author: Toni Tabak <[email protected]>
        Date:   Fri Jun 30 16:16:21 2023 +0200

            feat: parsers

        commit b7eba2a
        Author: Toni Tabak <[email protected]>
        Date:   Fri Jun 30 16:13:14 2023 +0200

            feat: extract parser from CallData and Cairo

        commit 6f8164f
        Author: amanusk <[email protected]>
        Date:   Thu Jun 29 21:23:28 2023 +0300

            Add example of new synatx cairo contract

    commit 15c1dcc
    Author: Philippe ROSTAN <[email protected]>
    Date:   Sun Jul 2 14:36:05 2023 +0200

        feat: sierra.json with enums

    commit 7e6e136
    Merge: b2e7a40 e6b861a
    Author: Philippe ROSTAN <[email protected]>
    Date:   Fri Jun 30 12:36:18 2023 +0200

        Merge pull request #1 from 0xs34n/develop

        merge

commit 8915b03
Author: Petar Penović <[email protected]>
Date:   Mon Jul 17 12:02:34 2023 +0200

    ci: bump devnet

commit 55b7408
Author: Philippe ROSTAN <[email protected]>
Date:   Tue Jul 18 15:51:28 2023 +0200

    feat: cairo enums in response parser

commit 66b3282
Author: Philippe ROSTAN <[email protected]>
Date:   Mon Jul 17 17:44:23 2023 +0200

    feat: add enums-response as class

commit 5cb29e7
Author: Philippe ROSTAN <[email protected]>
Date:   Mon Jul 17 10:59:53 2023 +0200

    feat: cairo enums 1

commit 045af8e
Author: CI <[email protected]>
Date:   Wed Jul 5 06:52:47 2023 +0000

    docs: generate documentation

commit 5f308d4
Author: Ivan Pavičić <[email protected]>
Date:   Wed Jul 5 08:48:29 2023 +0200

    docs: added waitForTransaction section and cleanups (#675)

    * docs: added waitForTransaction section and cleanups

    * docs: grammarly

    ---------

    Co-authored-by: Toni Tabak <[email protected]>

commit da64857
Author: semantic-release-bot <[email protected]>
Date:   Mon Jul 3 15:08:31 2023 +0000

    chore(release): 5.16.0 [skip ci]

    * cairo1 version2 support ([e564033](e564033))
    * extract parser from CallData and Cairo ([b7eba2a](b7eba2a))
    * parsers ([cce9029](cce9029))

commit ff35d5f
Author: Toni Tabak <[email protected]>
Date:   Mon Jul 3 16:32:11 2023 +0200

    chore: cleanup

commit 92b2be5
Author: Toni Tabak <[email protected]>
Date:   Mon Jul 3 14:07:45 2023 +0200

    chore: compiled files

commit 1f365f8
Author: Toni Tabak <[email protected]>
Date:   Mon Jul 3 14:05:52 2023 +0200

    feat: cairo1 version2 support

commit 5cdfdeb
Author: Toni Tabak <[email protected]>
Date:   Mon Jul 3 11:41:51 2023 +0200

    chore: refact

commit 3af53bd
Author: Toni Tabak <[email protected]>
Date:   Fri Jun 30 16:16:21 2023 +0200

    feat: parsers

commit 6e25aac
Author: Toni Tabak <[email protected]>
Date:   Fri Jun 30 16:13:14 2023 +0200

    feat: extract parser from CallData and Cairo

commit 2cb2848
Author: amanusk <[email protected]>
Date:   Thu Jun 29 21:23:28 2023 +0300

    Add example of new synatx cairo contract

commit 7e6e136
Merge: b2e7a40 e6b861a
Author: Philippe ROSTAN <[email protected]>
Date:   Fri Jun 30 12:36:18 2023 +0200

    Merge pull request #1 from 0xs34n/develop

    merge
  • Loading branch information
PhilippeR26 committed Jul 18, 2023
1 parent 384db9f commit a936a11
Show file tree
Hide file tree
Showing 16 changed files with 488 additions and 16 deletions.
35 changes: 35 additions & 0 deletions __tests__/cairo1v2.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {
Account,
BigNumberish,
CairoCustomEnum,
CairoOption,
CallData,
Calldata,
CompiledSierra,
Expand Down Expand Up @@ -345,6 +347,39 @@ describe('Cairo 1 Devnet', () => {
});
});

test('CairoEnums', async () => {
type Order = {
p1: BigNumberish;
p2: BigNumberish;
};
// return a Cairo Custom Enum
const myCairoEnum: CairoCustomEnum = await cairo1Contract.my_enum_output(50);
expect(myCairoEnum.unwrap()).toEqual(3n);
expect(myCairoEnum.activeVariant()).toEqual('Error');

const myCairoEnum2: CairoCustomEnum = await cairo1Contract.my_enum_output(100);
expect(myCairoEnum2.unwrap()).toEqual(BigInt(shortString.encodeShortString('attention:100')));
expect(myCairoEnum2.activeVariant()).toEqual('Warning');

const myCairoEnum3: CairoCustomEnum = await cairo1Contract.my_enum_output(150);
const res: Order = myCairoEnum3.unwrap();
expect(res).toEqual({ p1: 1n, p2: 150n });
expect(myCairoEnum3.activeVariant()).toEqual('Response');

// return a Cairo Option
const myCairoOption: CairoOption<Order> = await cairo1Contract.option_order_output(50);
expect(myCairoOption.unwrap()).toEqual(undefined);
expect(myCairoOption.isNone()).toEqual(true);
expect(myCairoOption.isSome()).toEqual(false);

const myCairoOption2: CairoOption<Order> = await cairo1Contract.option_order_output(150);
expect(myCairoOption2.unwrap()).toEqual({ p1: 18n, p2: 150n });
expect(myCairoOption2.isNone()).toEqual(false);
expect(myCairoOption2.isSome()).toEqual(true);

// TODO : Cairo Result will be tested when Cairo >=v2.1.0 will be implemented in Starknet devnet.
});

test('myCallData.compile for Cairo 1', async () => {
const myFalseUint256 = { high: 1, low: 23456 }; // wrong order
type Order2 = {
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export * as selector from './utils/selector';
export * from './utils/address';
export * from './utils/url';
export * from './utils/calldata';
export * from './utils/calldata/enum';
export * from './utils/contract';
export * from './utils/events';

Expand Down
3 changes: 3 additions & 0 deletions src/types/cairoEnum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { CairoCustomEnum, CairoOption, CairoResult } from '../utils/calldata/enum';

export type CairoEnum = CairoCustomEnum | CairoOption<Object> | CairoResult<Object, Object>;
5 changes: 4 additions & 1 deletion src/types/contract.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { CairoEnum } from './cairoEnum';
import { BigNumberish, BlockIdentifier, Calldata, RawArgsArray, Signature } from './lib';

export type AsyncContractFunction<T = any> = (...args: ArgsOrCalldataWithOptions) => Promise<T>;
export type ContractFunction = (...args: ArgsOrCalldataWithOptions) => any;

export type Result =
| {
[key: string]: any;
}
| Result[]
| bigint
| string
| boolean;
| boolean
| CairoEnum;

export type ArgsOrCalldata = RawArgsArray | [Calldata] | Calldata;
export type ArgsOrCalldataWithOptions = ArgsOrCalldata & ContractOptions;
Expand Down
1 change: 1 addition & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export * from './lib';
export * from './provider';
export * from './signer';
export * from './typedData';
export * from './cairoEnum';

export * as RPC from './api/rpc';
export {
Expand Down
8 changes: 8 additions & 0 deletions src/types/lib/contract/abi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,12 @@ export type StructAbi = {
type: 'struct';
};

export type AbiEnums = { [name: string]: EnumAbi };
export type EnumAbi = {
variants: (AbiEntry & { offset: number })[];
name: string;
size: number;
type: 'enum';
};

type EventAbi = any;
3 changes: 2 additions & 1 deletion src/utils/calldata/cairo.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Abi, AbiStructs, BigNumberish, Uint, Uint256 } from '../../types';
import { Abi, AbiEnums, AbiStructs, BigNumberish, Uint, Uint256 } from '../../types';
import { isBigInt, isHex, isStringWholeNumber } from '../num';
import { encodeShortString, isShortString, isText } from '../shortString';
import { UINT_128_MAX, isUint256 } from '../uint256';
Expand All @@ -10,6 +10,7 @@ export const isTypeArray = (type: string) =>
export const isTypeTuple = (type: string) => /^\(.*\)$/i.test(type);
export const isTypeNamedTuple = (type: string) => /\(.*\)/i.test(type) && type.includes(':');
export const isTypeStruct = (type: string, structs: AbiStructs) => type in structs;
export const isTypeEnum = (type: string, enums: AbiEnums) => type in enums;
export const isTypeUint = (type: string) => Object.values(Uint).includes(type as Uint);
export const isTypeUint256 = (type: string) => type === 'core::integer::u256';
export const isTypeBool = (type: string) => type === 'core::bool';
Expand Down
54 changes: 54 additions & 0 deletions src/utils/calldata/enum/CairoCustomEnum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
export type CairoEnumRaw = {
[key: string]: any;
};

/**
* Class to handle Cairo custom Enum
* @param enumContent object containing the variants and its content. Example :
* {Success: 234, Warning: undefined, Error: undefined}.
* Only one variant with a value, object, array.
* @returns an instance representing a Cairo custom Enum.
* @example ```typescript
* const myCairoEnum = new CairoCustomEnum( {Success: undefined, Warning: "0x7f32ea", Error: undefined})
* ```
*/
export class CairoCustomEnum {
/**
* direct readonly access to variants of the Cairo Custom Enum.
* @returns a value of type any
* @example ```typescript
* const successValue = myCairoEnum.variant.Success;
*/
readonly variant: CairoEnumRaw;

constructor(enumContent: CairoEnumRaw) {
// TODO for request Parser : add checks of validity of enumContent
this.variant = enumContent;
}

/**
*
* @returns the content of the valid variant of a Cairo custom Enum.
*/
public unwrap(): any {
const variants = Object.entries(this.variant);
const activeVariant = variants.find((item) => typeof item[1] !== 'undefined');
if (typeof activeVariant === 'undefined') {
return undefined;
}
return activeVariant[1];
}

/**
*
* @returns the name of the valid variant of a Cairo custom Enum.
*/
public activeVariant(): string {
const variants = Object.entries(this.variant);
const activeVariant = variants.find((item) => typeof item[1] !== 'undefined');
if (typeof activeVariant === 'undefined') {
return '';
}
return activeVariant[0];
}
}
62 changes: 62 additions & 0 deletions src/utils/calldata/enum/CairoOption.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
export enum CairoOptionVariant {
Some = 0,
None = 1,
}

/**
* Class to handle Cairo Option
* @param variant CairoOptionVariant.Some or CairoOptionVariant.None
* @param someContent value of type T.
* @returns an instance representing a Cairo Option.
* @example ```typescript
* const myOption = new CairoOption<BigNumberish>(CairoOptionVariant.Some, "0x54dda8");
* ```
*/
export class CairoOption<T> {
readonly Some?: T;

readonly None?: boolean;

constructor(variant: CairoOptionVariant, someContent?: T) {
if (variant === CairoOptionVariant.Some) {
if (typeof someContent === 'undefined') {
throw new Error(
'The creation of a Cairo Option with "Some" variant needs a content as input.'
);
}
this.Some = someContent;
this.None = undefined;
} else {
this.Some = undefined;
this.None = true;
}
}

/**
*
* @returns the content of the valid variant of a Cairo custom Enum.
* If None, returns 'undefined'.
*/
public unwrap(): T | undefined {
if (this.None) {
return undefined;
}
return this.Some;
}

/**
*
* @returns true if the valid variant is 'isSome'.
*/
public isSome(): boolean {
return !(typeof this.Some === 'undefined');
}

/**
*
* @returns true if the valid variant is 'isNone'.
*/
public isNone(): boolean {
return this.None === true;
}
}
59 changes: 59 additions & 0 deletions src/utils/calldata/enum/CairoResult.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
export enum CairoResultVariant {
Ok = 0,
Err = 1,
}

/**
* Class to handle Cairo Result
* @param variant CairoResultVariant.Ok or CairoResultVariant.Err
* @param resultContent value of type T or U.
* @returns an instance representing a Cairo Result.
* @example ```typescript
* const myOption = new CairoResult<BigNumberish,CustomError>(CairoResultVariant.Ok, "0x54dda8");
* ```
*/
export class CairoResult<T, U> {
readonly Ok?: T;

readonly Err?: U;

constructor(variant: CairoResultVariant, resultContent: T | U) {
if (variant === CairoResultVariant.Ok) {
this.Ok = resultContent as T;
this.Err = undefined;
} else {
this.Ok = undefined;
this.Err = resultContent as U;
}
}

/**
*
* @returns the content of the valid variant of a Cairo Result.
*/
public unwrap(): T | U {
if (typeof this.Ok !== 'undefined') {
return this.Ok;
}
if (typeof this.Err !== 'undefined') {
return this.Err;
}
throw new Error('Both Result.Ok and .Err are undefined. Not authorized.');
}

/**
*
* @returns true if the valid variant is 'Ok'.
*/
public isOk(): boolean {
return !(typeof this.Ok === 'undefined');
}

/**
*
* @returns true if the valid variant is 'isErr'.
*/
public isErr(): boolean {
return !(typeof this.Err === 'undefined');
}
}
3 changes: 3 additions & 0 deletions src/utils/calldata/enum/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './CairoCustomEnum';
export * from './CairoOption';
export * from './CairoResult';
25 changes: 24 additions & 1 deletion src/utils/calldata/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable no-plusplus */
import {
Abi,
AbiEnums,
AbiStructs,
Args,
ArgsOrCalldata,
Expand Down Expand Up @@ -34,8 +35,11 @@ export class CallData {

protected readonly structs: AbiStructs;

protected readonly enums: AbiEnums;

constructor(abi: Abi) {
this.structs = CallData.getAbiStruct(abi);
this.enums = CallData.getAbiEnum(abi);
this.parser = createAbiParser(abi);
this.abi = this.parser.getLegacyFormat();
}
Expand Down Expand Up @@ -192,7 +196,7 @@ export class CallData {

const parsed = outputs.flat().reduce((acc, output, idx) => {
const propName = output.name ?? idx;
acc[propName] = responseParser(responseIterator, output, this.structs, acc);
acc[propName] = responseParser(responseIterator, output, this.structs, this.enums, acc);
if (acc[propName] && acc[`${propName}_len`]) {
delete acc[`${propName}_len`];
}
Expand Down Expand Up @@ -232,6 +236,25 @@ export class CallData {
);
}

/**
* Helper to extract enums from abi
* @param abi Abi
* @returns AbiEnums - enums from abi
*/
static getAbiEnum(abi: Abi): AbiEnums {
const fullEnumList = abi
.filter((abiEntry) => abiEntry.type === 'enum')
.reduce(
(acc, abiEntry) => ({
...acc,
[abiEntry.name]: abiEntry,
}),
{}
);
delete fullEnumList['core::bool'];
return fullEnumList;
}

/**
* Helper: Compile HexCalldata | RawCalldata | RawArgs
* @param rawCalldata HexCalldata | RawCalldata | RawArgs
Expand Down
Loading

0 comments on commit a936a11

Please sign in to comment.