diff --git a/README.md b/README.md
index 746f201..6a164f1 100644
--- a/README.md
+++ b/README.md
@@ -48,25 +48,26 @@ abiwan will support multiple Cairo compiler versions, but not in parallel - diff
Currently supported:
-| Abi-Wan npm | Cairo compiler |
-| ------------- | ------------- |
-| [1.0.3](https://www.npmjs.com/package/abi-wan-kanabi/v/1.0.3) | [Cairo v1.0.0](https://github.com/starkware-libs/cairo/releases/tag/v1.0.0)
[Cairo v1.1.0](https://github.com/starkware-libs/cairo/releases/tag/v1.1.0) |
+| Abi-Wan npm | Cairo compiler |
+| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| [1.0.3](https://www.npmjs.com/package/abi-wan-kanabi/v/1.0.3) | [Cairo v1.0.0](https://github.com/starkware-libs/cairo/releases/tag/v1.0.0)
[Cairo v1.1.0](https://github.com/starkware-libs/cairo/releases/tag/v1.1.0) |
+| [2.0.0](https://www.npmjs.com/package/abi-wan-kanabi/v/2.0.0) | [Cairo v2.3.0-rc0](https://github.com/starkware-libs/cairo/releases/tag/v2.3.0-rc0) |
### Build
-To use abiwan, you must first generate types from your contracts' ABI json files, for example using the helper script (deprecated):
+To use abiwan, you must first generate types from your contracts' ABI json files, you can use the helper script:
```bash
-./scripts/extract_abi.sh //.json //.json ./
+npm run generate -- --input /path/to/abi.json --output /path/to/abi.ts
```
-This will create a declaration file (.d.ts) for the abi.
+This will create a typescript file for the abi.
You can then import it in any script and you are set to go:
```typescript
-import abi from "./abi_demo.ts";
-import { call } from "./kannabi.ts";
-call(abi, "balance_of", 5n);
+import abi from "./path/to/abi";
+import { call } from "./kanabi";
+const balance = call(abi, "balance_of", 5n);
```
> If you think that we should be able to import types directly from the json files, we think so too!
@@ -78,14 +79,17 @@ call(abi, "balance_of", 5n);
npm run typecheck
```
-### Generate `test/example.ts` from `test/example.json`
+### Generate `test/example.ts`
```bash
-npm run generate -- --input test/example.json --output test/example.ts
+# First build the example project with `scarb`
+cd test/example
+scarb build
+# Then generate test/example.ts
+cd ../..
+npm run generate -- --input test/example/target/dev/example_example_contract.contract_class.json --output test/example.ts
```
-Note: `test/example.json` was generated by `starknet-compile test/example.cairo test/example.json`
-
### Demo
https://drive.google.com/file/d/1OpIgKlk-okvwJn-dkR2Pq2FvOVwlXTUJ/view?usp=sharing
@@ -96,7 +100,7 @@ Abiwan is still very young and has not yet been subject to an official release.
## Supported Cairo Types
-Abi-wan-kanabi supports all of Cairo 1 types, here's the mapping between Cairo types and Typescript types
+Abi-wan-kanabi supports all of Cairo types, here's the mapping between Cairo types and Typescript types
### Primitive Types
@@ -106,6 +110,7 @@ Abi-wan-kanabi supports all of Cairo 1 types, here's the mapping between Cairo t
| `u8 - u32` | `number \| bigint` |
| `u64 - u256` | `number \| bigint \| Uint256` |
| `ContractAddress` | `string` |
+| `ClassHash` | `string` |
| `bool` | `boolean` |
| `()` | `void` |
diff --git a/kanabi.ts b/kanabi.ts
index 2de07f1..f7c6f6b 100644
--- a/kanabi.ts
+++ b/kanabi.ts
@@ -14,6 +14,7 @@ export type CairoInt = `${'core::integer::u'}${MBits}`
export type CairoBigInt = `${'core::integer::u'}${BigMBits}`
export type CairoU256 = 'core::integer::u256'
export type CairoAddress = 'core::starknet::contract_address::ContractAddress'
+export type CairoClassHash = 'core::starknet::class_hash::ClassHash'
export type CairoFunction = 'function'
export type CairoVoid = '()'
export type CairoBool = 'core::bool'
@@ -41,6 +42,7 @@ type AbiType =
| CairoBigInt
| CairoU256
| CairoAddress
+ | CairoClassHash
| CairoBool
| CairoVoid
@@ -66,6 +68,24 @@ type AbiOutput = {
type AbiStateMutability = 'view' | 'external'
+type AbiImpl = {
+ type: 'impl'
+ name: string
+ interface_name: string
+}
+
+type AbiInterface = {
+ type: 'interface'
+ name: string
+ items: readonly AbiFunction[]
+}
+
+type AbiConstructor = {
+ type: 'constructor'
+ name: 'constructor'
+ inputs: readonly AbiParameter[]
+}
+
type AbiFunction = {
type: 'function'
name: string
@@ -74,12 +94,22 @@ type AbiFunction = {
state_mutability: AbiStateMutability
}
-type AbiEvent = {
+type AbiEventStruct = {
type: 'event'
name: string
- inputs: readonly AbiParameter[]
+ kind: 'struct'
+ members: readonly AbiParameter[]
}
+type AbiEventEnum = {
+ type: 'event'
+ name: string
+ kind: 'enum'
+ variants: readonly AbiParameter[]
+}
+
+type AbiEvent = AbiEventStruct | AbiEventEnum
+
type AbiMember = {
name: string
type: string
@@ -97,7 +127,15 @@ type AbiEnum = {
variants: readonly AbiParameter[]
}
-export type Abi = readonly (AbiFunction | AbiStruct | AbiEvent | AbiEnum)[]
+export type Abi = readonly (
+ | AbiImpl
+ | AbiInterface
+ | AbiConstructor
+ | AbiFunction
+ | AbiStruct
+ | AbiEnum
+ | AbiEvent
+)[]
/// Implement
type _BuildArgs<
@@ -135,11 +173,20 @@ export type FunctionRet<
ExtractAbiFunction['outputs'][0]['type']
>
-export type ExtractAbiFunctions = Extract<
+export type ExtractAbiImpls = Extract<
TAbi[number],
- { type: 'function' }
+ { type: 'impl' }
>
+export type ExtractAbiInterfaces = Extract<
+ TAbi[number],
+ { type: 'interface' }
+>
+
+export type ExtractAbiFunctions =
+ | Extract['items'][number], { type: 'function' }>
+ | Extract
+
export type ExtractAbiFunctionNames =
ExtractAbiFunctions['name']
@@ -187,6 +234,8 @@ type PrimitiveTypeLookup = {
[_ in CairoBigInt]: number | bigint
} & {
[_ in CairoAddress]: string
+} & {
+ [_ in CairoClassHash]: string
} & {
[_ in CairoVoid]: void
} & {
diff --git a/package.json b/package.json
index dd6a35b..22c340a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "abi-wan-kanabi",
- "version": "1.0.4",
+ "version": "2.0.0",
"description": "Abi parser for Cairo smart contracts, based on wagmi abitype",
"main": "index.js",
"bin": {
diff --git a/test/example.cairo b/test/example.cairo
deleted file mode 100644
index d69641c..0000000
--- a/test/example.cairo
+++ /dev/null
@@ -1,89 +0,0 @@
-#[contract]
-mod HelloStarknet {
- use starknet::ContractAddress;
- use starknet::get_caller_address;
-
- use core::traits::TryInto;
- use traits::Into;
- use option::OptionTrait;
- use array::ArrayTrait;
-
- #[derive(Copy, Drop, Serde)]
- enum TestEnum {
- int128: u128,
- felt: felt252,
- tuple: (u32, u32),
- }
-
- #[derive(Drop, Serde)]
- struct TestStruct {
- int128: u128,
- felt: felt252,
- tuple: (u32, u32)
- }
-
- #[event]
- fn TestEvent(from: ContractAddress, value: felt252) {}
-
- #[external]
- fn fn_felt(felt: felt252) {}
-
- #[external]
- fn fn_felt_u8_bool(felt: felt252, int8: u8, b: bool) {}
-
- #[view]
- fn fn_felt_u8_bool_out_address_felt_u8_bool(
- felt: felt252, int8: u8, boolean: bool
- ) -> (ContractAddress, felt252, u8, bool) {
- let caller = get_caller_address();
- (caller, felt, int8, boolean)
- }
-
- #[view]
- fn fn_felt_out_felt(felt: felt252) -> felt252 {
- felt
- }
-
- #[view]
- fn fn_out_simple_option() -> Option {
- Option::Some(1)
- }
-
- #[view]
- fn fn_out_nested_option() -> Option