Skip to content

Commit

Permalink
BUG: Nested events not handled (#1140)
Browse files Browse the repository at this point in the history
* test: eth signer

* test: move secp256k1Point tests in a dedicated test file

* feat: helper for  transaction receipt

* simplify extends for account class

* feat: handling of cairo u512 type

* refactor: change name of variable : GetTxReceiptResponseWithoutHelper

* fix: double lines for same imports

* fix: solve an error in validate.ts initiated by pr 1007

* fix: correction of a word in guide

* docs: validateChecksumAddress

* fix: jsdoc correction

* docs: add tsdoc in utils/address.ts

* test: add extra fees

* fix: estimateFeeBulk include skipValidate in accountInvocationsFactory

* feat: add type guard to receipt response status methods

* fix: repair i128 typed data encoding and add typed data range checks

* chore: update left over StarkNet casing

* feat: bundle resolution, module, type import for walletacc

* feat: bundle resolution, module, type import for walletaccount

* chore: fix connect import

* chore: add get-starknet-core next as dependencie

* chore: import fix

* fix: estimateMessageFee - eth address format (#1040)

* fix: estimatemessagefee eth address format

* fix: implement requests

* docs: small guides cleanup (#1048)

* docs: fix nodeUrl code typo (#1046)

* docs: small guides cleanup

---------

Co-authored-by: Joel Mun <hj923@hotmail.com>

* fix(RpcProvider): allow client to provide `specVersion` in 0.7 provider

this saves an extra call on RPC for optionally-known information (like the `chainId` case).
also fixed speck -> spec typo

* fix: remove abis parameter from signer and account execute

* feat: configure u512 and Secp256k1Point for abiwan

* chore: bump dependencies

* chore: expose data gas consumed and data gas price for 0.7 rpc

* test: Improve tests performance (#1121)

* test: fix transaction retry interval fallback for devnet tests

* test: remove test.only

* Update _test.yml (#1126)

* chore(release): 6.9.0 [skip ci]

# [6.9.0](v6.8.0...v6.9.0) (2024-05-21)

### Bug Fixes

* cannot infer ts2742 types from starknet-types@0.7 ([#1098](#1098)) ([f1c3b8e](f1c3b8e))
* remove [warning] from typedoc for external usage ([#1095](#1095)) ([195186f](195186f)), closes [#1121](#1121) [#1126](#1126)

### Features

* add type coverage ([#1120](#1120)) ([eceda5d](eceda5d))
* provider.getL1MessageHash ([#1123](#1123)) ([1489cf2](1489cf2))

### Reverts

* Revert "chore: add examples to JsDoc for transaction.ts file (#1105)" (#1108) ([59eb01e](59eb01e)), closes [#1105](#1105) [#1108](#1108)

* fix: handling of events nested in Cairo components

* fix: change names of events in tests

* refactor: change type names

* test: adapt parseUDCEvent to events namespace

* refactor: implement reviewer requests

* refactor: add spec6 types

* Revert "Merge branch 'next-version' into nested-events"

This reverts commit 4c65e9b, reversing
changes made to 7702d9c.

* fix: remove events.ts  that came back after merge

* refactor: use of external types-js lib for events types

---------

Co-authored-by: gregory <10611760+gregoryguillou@users.noreply.github.com>
Co-authored-by: Toni Tabak <tabaktoni@gmail.com>
Co-authored-by: ivpavici <ivan.pavicic@live.com>
Co-authored-by: Petar Penovic <pp@spaceshard.io>
Co-authored-by: Joel Mun <hj923@hotmail.com>
Co-authored-by: Abraham Makovetsky <avimak@gmail.com>
Co-authored-by: Haroune Mohammedi <haroune.mohammedi@quadratic-labs.com>
Co-authored-by: Dhruv Kelawala <dhruvrk2000@gmail.com>
Co-authored-by: Luka Saric <32763694+lukasaric@users.noreply.github.com>
Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net>
  • Loading branch information
11 people authored Jun 12, 2024
1 parent 223a58f commit 506402f
Show file tree
Hide file tree
Showing 12 changed files with 2,722 additions and 131 deletions.
2,243 changes: 2,243 additions & 0 deletions __mocks__/cairo/cairo260/nestedEvents.abi.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions __tests__/account.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import {
constants,
contractClassResponseToLegacyCompiledContract,
ec,
events,
extractContractHashes,
hash,
num,
parseUDCEvent,
shortString,
stark,
} from '../src';
Expand Down Expand Up @@ -537,7 +537,7 @@ describe('deploy and test Wallet', () => {

// check pre-calculated address
const txReceipt = await provider.waitForTransaction(deployment.transaction_hash);
const udcEvent = parseUDCEvent(txReceipt as any); // todo: when time fix types
const udcEvent = events.parseUDCEvent(txReceipt as any); // todo: when time fix types
expect(cleanHex(deployment.contract_address[0])).toBe(cleanHex(udcEvent.contract_address));
});

Expand All @@ -558,7 +558,7 @@ describe('deploy and test Wallet', () => {

// check pre-calculated address
const txReceipt = await provider.waitForTransaction(deployment.transaction_hash);
const udcEvent = parseUDCEvent(txReceipt as any); // todo: when time fix types
const udcEvent = events.parseUDCEvent(txReceipt as any); // todo: when time fix types
expect(cleanHex(deployment.contract_address[0])).toBe(cleanHex(udcEvent.contract_address));
});

Expand Down
194 changes: 180 additions & 14 deletions __tests__/cairo1v2.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import fs from 'node:fs';
import path from 'node:path';
import {
Account,
BigNumberish,
Expand All @@ -18,7 +20,9 @@ import {
byteArray,
cairo,
ec,
events,
hash,
json,
num,
selector,
shortString,
Expand Down Expand Up @@ -870,7 +874,7 @@ describe('Cairo 1', () => {
);
const shouldBe: types.ParsedEvents = [
{
EventRegular: {
'hello_res_events_newTypes::hello_res_events_newTypes::HelloStarknet::EventRegular': {
simpleKeyVariable,
simpleKeyStruct,
simpleKeyArray,
Expand All @@ -881,8 +885,8 @@ describe('Cairo 1', () => {
},
];
const tx = await provider.waitForTransaction(transaction_hash);
const events = eventContract.parseEvents(tx);
return expect(events).toStrictEqual(shouldBe);
const myEvents = eventContract.parseEvents(tx);
return expect(myEvents).toStrictEqual(shouldBe);
});

test('parse event returning a nested struct', async () => {
Expand All @@ -892,22 +896,22 @@ describe('Cairo 1', () => {
);
const shouldBe: types.ParsedEvents = [
{
EventNested: {
'hello_res_events_newTypes::hello_res_events_newTypes::HelloStarknet::EventNested': {
nestedKeyStruct,
nestedDataStruct,
},
},
];
const tx = await provider.waitForTransaction(transaction_hash);
const events = eventContract.parseEvents(tx);
return expect(events).toStrictEqual(shouldBe);
const myEvents = eventContract.parseEvents(tx);
return expect(myEvents).toStrictEqual(shouldBe);
});

test('parse tx returning multiple similar events', async () => {
const anotherKeyVariable = 100n;
const shouldBe: types.ParsedEvents = [
{
EventRegular: {
'hello_res_events_newTypes::hello_res_events_newTypes::HelloStarknet::EventRegular': {
simpleKeyVariable,
simpleKeyStruct,
simpleKeyArray,
Expand All @@ -917,7 +921,7 @@ describe('Cairo 1', () => {
},
},
{
EventRegular: {
'hello_res_events_newTypes::hello_res_events_newTypes::HelloStarknet::EventRegular': {
simpleKeyVariable: anotherKeyVariable,
simpleKeyStruct,
simpleKeyArray,
Expand Down Expand Up @@ -945,13 +949,13 @@ describe('Cairo 1', () => {
]);
const { transaction_hash } = await account.execute([callData1, callData2]);
const tx = await provider.waitForTransaction(transaction_hash);
const events = eventContract.parseEvents(tx);
return expect(events).toStrictEqual(shouldBe);
const myEvents = eventContract.parseEvents(tx);
return expect(myEvents).toStrictEqual(shouldBe);
});
test('parse tx returning multiple different events', async () => {
const shouldBe: types.ParsedEvents = [
{
EventRegular: {
'hello_res_events_newTypes::hello_res_events_newTypes::HelloStarknet::EventRegular': {
simpleKeyVariable,
simpleKeyStruct,
simpleKeyArray,
Expand All @@ -961,7 +965,7 @@ describe('Cairo 1', () => {
},
},
{
EventNested: {
'hello_res_events_newTypes::hello_res_events_newTypes::HelloStarknet::EventNested': {
nestedKeyStruct,
nestedDataStruct,
},
Expand All @@ -981,8 +985,170 @@ describe('Cairo 1', () => {
]);
const { transaction_hash } = await account.execute([callData1, callData2]);
const tx = await provider.waitForTransaction(transaction_hash);
const events = eventContract.parseEvents(tx);
return expect(events).toStrictEqual(shouldBe);
const myEvents = eventContract.parseEvents(tx);
return expect(myEvents).toStrictEqual(shouldBe);
});

test('parsing nested events from Cairo components', () => {
// this abi is from Sepolia contract 0x07981ea76ca241100a3e1cd4083a15a73a068b6d6a946d36042cbfc9b531baa2
// with the end from OpenZeppelin ERC20 contract (for `flat` event test)
const { abi } = json.parse(
fs
.readFileSync(
path.resolve(__dirname, `../__mocks__/cairo/cairo260/nestedEvents.abi.json`)
)
.toString('ascii')
);
const abiEvents = events.getAbiEvents(abi);
const abiStructs = CallData.getAbiStruct(abi);
const abiEnums = CallData.getAbiEnum(abi);
const rawEventNested = {
block_hash: '0x39f27ab4cd508ab99e818512b261a7e4ae01072eb4ec8bb86aeb64755f99f2c',
block_number: 69198,
data: [
'0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',
'0x4718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d',
'0x0',
'0x0',
'0x8bb2c97000',
'0x0',
'0x425615c73f000',
'0x0',
'0x0',
'0x0',
'0x0',
'0x2bfc41e4bcfdbe82d0bafe3f935dadb18b6e90be3d22ccccea1f5b10986ed53',
'0x7aab02decaf82af6fa798fe8d23de042695846ab9dae9f18331fffc518d3d36',
'0x616b697261',
'0x616b697261',
],
from_address: '0x7981ea76ca241100a3e1cd4083a15a73a068b6d6a946d36042cbfc9b531baa2',
keys: [
'0x22ea134d4126804c60797e633195f8c9aa5fd6d1567e299f4961d0e96f373ee',
'0x2e0a012a863e6b614014d113e7285b06e30d2999e42e6e03ba2ef6158b0a8f1',
'0x33e29bc9b537bae4e370559331e2bf35b434b566f41a64601b37f410f46a580',
'0x33e29bc9b537bae4e370559331e2bf35b434b566f41a64601b37f410f46a580',
],
transaction_hash: '0x4e38fcce79c115b6fe2c486e3514efc1bd4da386b91c104e97230177d0bf181',
};
const parsedEvent = events.parseEvents([rawEventNested], abiEvents, abiStructs, abiEnums);
expect(parsedEvent).toEqual([
{
'kurosawa_akira::ExchangeBalanceComponent::exchange_balance_logic_component::Trade': {
maker: 1466771120193999006693452314154095230636738457276435850562375218974960297344n,
taker: 1466771120193999006693452314154095230636738457276435850562375218974960297344n,
ticker: {
'0': 2087021424722619777119509474943472645767659996348769578120564519014510906823n,
'1': 2009894490435840142178314390393166646092438090257831307886760648929397478285n,
},
router_maker: 0n,
router_taker: 0n,
amount_base: 600000000000n,
amount_quote: 1167000000000000n,
is_sell_side: false,
is_failed: false,
is_ecosystem_book: false,
maker_hash:
1243447045605505261525562127352132336915826038411731622093247599150671261011n,
taker_hash:
3467769886575726876986429904727435956490031836678599158998056330580017888566n,
maker_source: 418413900385n,
taker_source: 418413900385n,
},
},
]);
// From component `DepositComponent`, event `Deposit` (same event name than next)
const rawEventNestedDeposit1 = {
block_hash: '0x31afd649a5042cb1855ce820708a555eab62fe6ea07a2a538fa9100cdc80383',
block_number: 69198,
data: [
'0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',
'0x33e29bc9b537bae4e370559331e2bf35b434b566f41a64601b37f410f46a580',
'0x119b74ab81c000',
'0x0',
],
from_address: '0x7981ea76ca241100a3e1cd4083a15a73a068b6d6a946d36042cbfc9b531baa2',
keys: [
'0xa1db419bdf20c7726cf74c30394c4300e5645db4e3cacaf897da05faabae03',
'0x9149d2123147c5f43d258257fef0b7b969db78269369ebcf5ebb9eef8592f2',
'0x033e29bc9b537bae4e370559331e2bf35b434b566f41a64601b37f410f46a580',
],
transaction_hash: '0x7768860d79bfb4c8463d215abea3c267899e373407c6882077f7447051c50de',
};
// From component `RouterComponent`, event `Deposit` (same event name than previous)
const rawEventNestedDeposit2 = {
block_hash: '0x39f27ab4cd508ab99e818512b261a7e4ae01072eb4ec8bb86aeb64755f99f2c',
block_number: 69198,
data: [
'0x33e29bc9b537bae4e370559331e2bf35b434b566f41a64601b37f410f46a580',
'0x119b74ab81c000',
'0x0',
],
from_address: '0x7981ea76ca241100a3e1cd4083a15a73a068b6d6a946d36042cbfc9b531baa2',
keys: [
'0x1352a17d221f274db15a49e35cc827e5106495ba85330b210632597411d5a46',
'0x9149d2123147c5f43d258257fef0b7b969db78269369ebcf5ebb9eef8592f2',
'0x33e29bc9b537bae4e370559331e2bf35b434b566f41a64601b37f410f46a580',
'0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',
],
transaction_hash: '0x2d5210e5334a83306abe6f7f5e7e65cd1feed72ad3b8e359a2f4614fa948e1d',
};
const parsedEventNestedDeposit1 = events.parseEvents(
[rawEventNestedDeposit1],
abiEvents,
abiStructs,
abiEnums
);
expect(parsedEventNestedDeposit1).toEqual([
{
'kurosawa_akira::DepositComponent::deposit_component::Deposit': {
receiver: 1466771120193999006693452314154095230636738457276435850562375218974960297344n,
token: 2087021424722619777119509474943472645767659996348769578120564519014510906823n,
funder: 1466771120193999006693452314154095230636738457276435850562375218974960297344n,
amount: 4956000000000000n,
},
},
]);
const parsedEventNestedDeposit2 = events.parseEvents(
[rawEventNestedDeposit2],
abiEvents,
abiStructs,
abiEnums
);
expect(parsedEventNestedDeposit2).toEqual([
{
'kurosawa_akira::RouterComponent::router_component::Deposit': {
router: 1466771120193999006693452314154095230636738457276435850562375218974960297344n,
token: 2087021424722619777119509474943472645767659996348769578120564519014510906823n,
funder: 1466771120193999006693452314154095230636738457276435850562375218974960297344n,
amount: 4956000000000000n,
},
},
]);

// parsing nested event with #[flat] attribute, from a Cairo component
const rawEventFlat = {
block_hash: '0x39f27ab4cd508ab99e818512b261a7e4ae01072eb4ec8bb86aeb64755f99f2c',
block_number: 69198,
data: ['0x119b74ab81c000', '0x0'],
from_address: '0x7981ea76ca241100a3e1cd4083a15a73a068b6d6a946d36042cbfc9b531baa2',
keys: [
'0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9',
'0x33e29bc9b537bae4e370559331e2bf35b434b566f41a64601b37f410f46a580',
'0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',
],
transaction_hash: '0x2da31a929a9848e9630906275a75a531e1718d4830501e10b0bccacd55f6fe0',
};
const parsedEventFlat = events.parseEvents([rawEventFlat], abiEvents, abiStructs, abiEnums);
expect(parsedEventFlat).toEqual([
{
'openzeppelin::token::erc20::erc20::ERC20Component::Transfer': {
from: 1466771120193999006693452314154095230636738457276435850562375218974960297344n,
to: 2087021424722619777119509474943472645767659996348769578120564519014510906823n,
value: 4956000000000000n,
},
},
]);
});
});

Expand Down
12 changes: 6 additions & 6 deletions __tests__/cairo1v2_typed.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ describe('Cairo 1', () => {
);
const shouldBe: types.ParsedEvents = [
{
EventRegular: {
'hello_res_events_newTypes::hello_res_events_newTypes::HelloStarknet::EventRegular': {
simpleKeyVariable,
simpleKeyStruct,
simpleKeyArray,
Expand All @@ -824,7 +824,7 @@ describe('Cairo 1', () => {
);
const shouldBe: types.ParsedEvents = [
{
EventNested: {
'hello_res_events_newTypes::hello_res_events_newTypes::HelloStarknet::EventNested': {
nestedKeyStruct,
nestedDataStruct,
},
Expand All @@ -840,7 +840,7 @@ describe('Cairo 1', () => {
const anotherKeyVariable = 100n;
const shouldBe: types.ParsedEvents = [
{
EventRegular: {
'hello_res_events_newTypes::hello_res_events_newTypes::HelloStarknet::EventRegular': {
simpleKeyVariable,
simpleKeyStruct,
simpleKeyArray,
Expand All @@ -850,7 +850,7 @@ describe('Cairo 1', () => {
},
},
{
EventRegular: {
'hello_res_events_newTypes::hello_res_events_newTypes::HelloStarknet::EventRegular': {
simpleKeyVariable: anotherKeyVariable,
simpleKeyStruct,
simpleKeyArray,
Expand Down Expand Up @@ -884,7 +884,7 @@ describe('Cairo 1', () => {
test('parse tx returning multiple different events', async () => {
const shouldBe: types.ParsedEvents = [
{
EventRegular: {
'hello_res_events_newTypes::hello_res_events_newTypes::HelloStarknet::EventRegular': {
simpleKeyVariable,
simpleKeyStruct,
simpleKeyArray,
Expand All @@ -894,7 +894,7 @@ describe('Cairo 1', () => {
},
},
{
EventNested: {
'hello_res_events_newTypes::hello_res_events_newTypes::HelloStarknet::EventNested': {
nestedKeyStruct,
nestedDataStruct,
},
Expand Down
4 changes: 2 additions & 2 deletions src/contract/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
ParsedEvents,
RawArgs,
Result,
StructAbi,
AbiStruct,
ValidateType,
} from '../types';
import assert from '../utils/assert';
Expand Down Expand Up @@ -124,7 +124,7 @@ export class Contract implements ContractInterface {

deployTransactionHash?: string;

protected readonly structs: { [name: string]: StructAbi };
protected readonly structs: { [name: string]: AbiStruct };

protected readonly events: AbiEvents;

Expand Down
3 changes: 1 addition & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export * as ec from './utils/ec';
export * as starknetId from './utils/starknetId';
export * as provider from './utils/provider';
export * as selector from './utils/hash/selector';
export * as events from './utils/events/index';
export * as events from './utils/events';
export * from './utils/responseParser';
export * from './utils/cairoDataTypes/uint256';
export * from './utils/cairoDataTypes/uint512';
Expand All @@ -42,7 +42,6 @@ export * from './utils/url';
export * from './utils/calldata';
export * from './utils/calldata/enum';
export * from './utils/contract';
export * from './utils/events';
export * from './utils/transactionReceipt';
export * as wallet from './wallet/connect';

Expand Down
Loading

0 comments on commit 506402f

Please sign in to comment.