From 9b5d6e425befba1c4f134057080dbd4dc8c071de Mon Sep 17 00:00:00 2001 From: Lucas Tortora Date: Wed, 11 Dec 2024 14:54:00 -0300 Subject: [PATCH 1/6] fix(devx): Move access time and using events to move overview section --- docs/content/sidebars/developer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/content/sidebars/developer.js b/docs/content/sidebars/developer.js index e8ac1eb1bb5..d1500f346fc 100644 --- a/docs/content/sidebars/developer.js +++ b/docs/content/sidebars/developer.js @@ -57,7 +57,6 @@ const developer = [ label: 'Typescript SDK', href: '/references/ts-sdk/typescript', }, - 'developer/iota-101/using-events', ], }, { @@ -70,6 +69,8 @@ const developer = [ 'developer/iota-101/move-overview/init', 'developer/iota-101/move-overview/visibility', 'developer/iota-101/move-overview/entry-functions', + 'developer/iota-101/using-events', + 'developer/iota-101/access-time', { type: 'category', label: 'Structs and Abilities', @@ -107,7 +108,6 @@ const developer = [ 'developer/iota-101/move-overview/patterns/id-pointer', ], }, - 'developer/iota-101/access-time', 'developer/iota-101/move-overview/conventions', ], }, From aaa1ebb8e11982725a931a962a3b0d97466234c0 Mon Sep 17 00:00:00 2001 From: Lucas Tortora Date: Wed, 11 Dec 2024 14:54:14 -0300 Subject: [PATCH 2/6] feat(devx) update using events guide --- .../developer/iota-101/using-events.mdx | 146 ++++++++++++------ 1 file changed, 102 insertions(+), 44 deletions(-) diff --git a/docs/content/developer/iota-101/using-events.mdx b/docs/content/developer/iota-101/using-events.mdx index f808f9e1e07..bd240f6045e 100644 --- a/docs/content/developer/iota-101/using-events.mdx +++ b/docs/content/developer/iota-101/using-events.mdx @@ -28,19 +28,20 @@ An event object in IOTA consists of the following attributes: - `bcs`: Binary canonical serialization value. - `timestampMs`: Unix epoch timestamp in milliseconds. -## Exploring Available Events +### Exploring Available Events -To subscribe to on-chain events, you first need to identify which events are available. While you can easily track events emitted by your own code, discovering events from external packages can be more challenging. The IOTA RPC provides the [`queryEvents`](/iota-api-ref#iotax_queryevents) method, which allows you to query on-chain packages and obtain a list of events you can subscribe to. +To [subscribe to on-chain events](#subscriging-to-events), you first need to identify which events are available. While you can easily track events emitted by your own code, discovering events from external packages can be more challenging. The IOTA RPC provides the [`queryEvents`](/iota-api-ref#iotax_queryevents) method, which allows you to query on-chain packages and obtain a list of events you can subscribe to. -## Applying Event Filters +### Applying Event Filters -When targeting specific events for querying or subscribing, you can use filters to refine your results. Although the filtering options for querying and subscribing are similar, there are notable differences to be aware of. +When targeting specific events for [querying](#query-events) or [subscribing](#subscriging-to-events), you can use [filters](#filtering-events) to refine your results. Although the filtering options for querying and subscribing are similar, there are notable differences to be aware of. ## Emitting Events in Move To emit events from your Move modules, you need to use the [`iota::event`](../../references/framework/iota-framework/event.mdx) module. Emitting events allows external applications to subscribe and respond to specific on-chain activities. + First, import the `event` module in your Move code: ```move @@ -49,57 +50,104 @@ use iota::event; Then, within your function, you can emit an event using the [`emit`](../../references/framework/iota-framework/event.mdx#function-emit) function. For example: -```move -/// Take coin from `DonutShop` and transfer it to tx sender. -/// Requires authorization with `ShopOwnerCap`. -public fun collect_profits( _: &ShopOwnerCap, shop: &mut DonutShop, ctx: &mut TxContext ) { - let amount = balance::value(&shop.balance); - let profits = coin::take(&mut shop.balance, amount, ctx); - // simply create new type instance and emit it. - event::emit(ProfitsCollected { amount }); - transfer::public_transfer(profits, tx_context::sender(ctx)); -} +```move file=/examples/trading/contracts/escrow/sources/lock.move#L42-L63 ``` -## Subscribing to Events +## Querying Events + +### IOTA RPC + +The IOTA RPC provides a [queryEvents](../../references/iota-api-ref#iotax_queryEvents) method to query on-chain packages and return available events. As an example, the following `curl` command queries the Deepbook package on Mainnet for a specific type of event: + +```sh +curl -X POST https://api.testnet.iota.cafe:443 \ +-H "Content-Type: application/json" \ +-d '{ + "jsonrpc": "2.0", + "id": 1, + "method": "iotax_queryEvents", + "params": [ + { + "MoveModule": { + "package": "0x0000000000000000000000000000000000000000000000000000000000000002", + "module": "display", + "type": "0x0000…0002::display::Display<0xba68…286b::testnet_nft::TestnetNFT>" + } + }, + null, + 3, + false + ] +}' +``` -To react to events emitted by Move modules, you need to subscribe to them. -IOTA full nodes support event subscriptions via JSON-RPC notifications over WebSocket. You can interact with the [RPC directly][iotax_subscribeEvent](/iota-api-ref#iotax_subscribeevent), [iotax_subscribeTransaction](/iota-api-ref#iotax_subscribetransaction) or use an SDK like the [IOTA TypeScript SDK](../../references/ts-sdk/typescript/index.mdx). +The TypeScript SDK provides a wrapper for the `iotax_queryEvents` method: [`client.queryEvents`](../../references/ts-sdk/api/client/classes/IotaClient#queryevents). -The following excerpt from one of the examples uses the TypeScript SDK to create an asynchronous subscription to the filter identified in the filter. +### Rust -```move -let unsubscribe = await provider.subscribeEvent({ - filter: { }, - onMessage: (event) => { - console.log("subscribeEvent", JSON.stringify(event, null, 2)) +You can use the following as an example on how to query for events using the `query_events` function. You should update +the `PACKAGE_ID_CONST` with a package of your choice. + +```rust +use iota_sdk::{rpc_types::EventFilter, types::Identifier, IotaClientBuilder}; + +const PACKAGE_ID_CONST: &str = ""; + +#[tokio::main] +async fn main() -> Result<(), anyhow::Error> { + let iota_testnet = IotaClientBuilder::default() + .build("https://api.testnet.iota.cafe:443") + .await?; + + let events = iota_testnet + .event_api() + .query_events( + EventFilter::MoveModule { + package: PACKAGE_ID_CONST.parse()?, + module: Identifier::new("dev_trophy")?, + }, + None, + None, + false, + ) + .await?; + + for event in events.data { + println!("Event: {:?}", event.parsed_json); } -}); + + Ok(()) +} ``` -Move smart contracts can call other smart contracts that emit events. For example, `0x107a::nft` calls the `0x2::display::new_with_fields` smart contract and emits a `0x2::display::DisplayCreated` event. Note that using package and transaction module to query for `0x2::display` misses the following event even though it is actually an event the `0x2` package emits. The current workaround for this issue is to know all the `packageId`s you care about and search those in the `queryEvent` call. +### Query Events with GraphQL -```json -{ - "id": { - "txDigest": "DrZmtQDDCUKooLzFCi29VhUB4w6AT8phCsT9d62BAf8g", - "eventSeq": "0" - }, - "packageId": "0x000000000000000000000000000000000000000000000000000000000000107a", - "transactionModule": "nft", - "sender": "0x0000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2::display::DisplayCreated<0x107a::nft::Nft>", - "parsedJson": { - "id": "0xa12d72c159d57d4c7f540b2b9e985327628d856b20c1d6cdfd3028a2a605abfe" - }, - "bcs": "CFbAeqXAwwkyTxUD36FtzTGEcMGrVj4zgcTR1G7AaRjb", - "timestampMs": "1521456213521" -} +You can use GraphQL to query events instead of JSON RPC. The following example queries are in the +[`iota-graphql-rpc` crate](https://github.com/iotaledger/iota/tree/develop/crates/iota-graphql-rpc/examples/event_connection) in the IOTA repo. + +#### Event Connection + +```graphql file=/crates/iota-graphql-rpc/examples/event_connection/event_connection.graphql +``` + +#### Filter Events By Sender + +```graphql file=/crates/iota-graphql-rpc/examples/event_connection/filter_by_sender.graphql +``` + +#### Filter Events By Emitting Package and Type + +```graphql file=/crates/iota-graphql-rpc/examples/event_connection/filter_by_sender.graphql ``` -## Examples +:::tip + +The [TypeScript SDK](../../references/ts-sdk/api/graphql/classes/IotaGraphQLClient) provides functionality to +interact with the IOTA GraphQL service. -### Subscribe to Event +::: + +## Subscribing to Events This example leverages the IOTA TypeScript SDK to subscribe to events the package with ID `` emits. Each time the event fires, the code displays the response to the console. @@ -199,9 +247,19 @@ subscribeEvent { +## Monitoring Events + +Firing events is not very useful in a vacuum. You also need the ability to respond to those events. +There are two methods from which to choose when you need to monitor on-chain events: +- Incorporate a [custom indexer](../advanced/custom-indexer.mdx) to take advantage of IOTA's micro-data ingestion framework. +- Poll the IOTA network on a schedule to query events. + +Using a custom indexer provides a near-real time monitoring of events, so is most useful when your project requires immediate reaction to the firing of events. Polling the network is most useful when the events you're monitoring don't fire often or the need to act on those events are not immediate. The following section provides a polling example. + + ## Filtering Events -You can filter events when querying or subscribing to receive only the events you are interested in. +You can filter events when [querying](#querying-events) or [subscribing](#subscribing-to-events) to receive only the events you are interested in. :::info From f355a8bc1c930860fab7ab46810713a074e72e8b Mon Sep 17 00:00:00 2001 From: Lucas Tortora Date: Wed, 11 Dec 2024 15:02:28 -0300 Subject: [PATCH 3/6] fix(devx) Add tabs, remove headers --- .../developer/iota-101/using-events.mdx | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/docs/content/developer/iota-101/using-events.mdx b/docs/content/developer/iota-101/using-events.mdx index bd240f6045e..a10d9d792d1 100644 --- a/docs/content/developer/iota-101/using-events.mdx +++ b/docs/content/developer/iota-101/using-events.mdx @@ -55,9 +55,10 @@ Then, within your function, you can emit an event using the [`emit`](../../refer ## Querying Events -### IOTA RPC + -The IOTA RPC provides a [queryEvents](../../references/iota-api-ref#iotax_queryEvents) method to query on-chain packages and return available events. As an example, the following `curl` command queries the Deepbook package on Mainnet for a specific type of event: + +The IOTA RPC provides a [`queryEvents`](../../references/iota-api-ref#iotax_queryEvents) method to query on-chain packages and return available events. As an example, the following `curl` command queries the Deepbook package on Mainnet for a specific type of event: ```sh curl -X POST https://api.testnet.iota.cafe:443 \ @@ -81,9 +82,11 @@ curl -X POST https://api.testnet.iota.cafe:443 \ }' ``` -The TypeScript SDK provides a wrapper for the `iotax_queryEvents` method: [`client.queryEvents`](../../references/ts-sdk/api/client/classes/IotaClient#queryevents). +The TypeScript SDK provides a wrapper for the `iotax_queryEvents` method: +[`client.queryEvents`](../../references/ts-sdk/api/client/classes/IotaClient#queryevents). -### Rust + + You can use the following as an example on how to query for events using the `query_events` function. You should update the `PACKAGE_ID_CONST` with a package of your choice. @@ -119,8 +122,8 @@ async fn main() -> Result<(), anyhow::Error> { Ok(()) } ``` - -### Query Events with GraphQL + + You can use GraphQL to query events instead of JSON RPC. The following example queries are in the [`iota-graphql-rpc` crate](https://github.com/iotaledger/iota/tree/develop/crates/iota-graphql-rpc/examples/event_connection) in the IOTA repo. @@ -147,6 +150,10 @@ interact with the IOTA GraphQL service. ::: + + + + ## Subscribing to Events This example leverages the IOTA TypeScript SDK to subscribe to events the package with ID `` emits. Each time the event fires, the code displays the response to the console. @@ -154,8 +161,6 @@ This example leverages the IOTA TypeScript SDK to subscribe to events the packag -### Rust - See [Rust SDK](../../references/rust-sdk.mdx). ```rust @@ -180,8 +185,6 @@ async fn main() -> Result<()> { -### TypeScript - To create the event subscription, you can use a basic Node.js app. You need the [IOTA TypeScript SDK](../../references/ts-sdk/typescript/index.mdx), so install the module using `npm install @iota/iota-sdk` at the root of your project. In your TypeScript code, import `JsonRpcProvider` and a connection from the library. ```ts From d4e3852dc6d893ff8cd017f840eb061e4c51b621 Mon Sep 17 00:00:00 2001 From: Lucas Tortora Date: Wed, 11 Dec 2024 15:27:18 -0300 Subject: [PATCH 4/6] fix(devx) make link absolute --- docs/content/developer/iota-101/using-events.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/developer/iota-101/using-events.mdx b/docs/content/developer/iota-101/using-events.mdx index a10d9d792d1..098608f61bb 100644 --- a/docs/content/developer/iota-101/using-events.mdx +++ b/docs/content/developer/iota-101/using-events.mdx @@ -58,7 +58,7 @@ Then, within your function, you can emit an event using the [`emit`](../../refer -The IOTA RPC provides a [`queryEvents`](../../references/iota-api-ref#iotax_queryEvents) method to query on-chain packages and return available events. As an example, the following `curl` command queries the Deepbook package on Mainnet for a specific type of event: +The IOTA RPC provides a [`queryEvents`](/iota-api-ref#iotax_queryEvents) method to query on-chain packages and return available events. As an example, the following `curl` command queries the Deepbook package on Mainnet for a specific type of event: ```sh curl -X POST https://api.testnet.iota.cafe:443 \ From ea36faa3f9c0e319d1c848f9bc39b5124f3e0ffb Mon Sep 17 00:00:00 2001 From: Lucas Tortora Date: Wed, 11 Dec 2024 18:19:10 -0300 Subject: [PATCH 5/6] fix links --- docs/content/developer/iota-101/using-events.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/content/developer/iota-101/using-events.mdx b/docs/content/developer/iota-101/using-events.mdx index 098608f61bb..825d7c09ab8 100644 --- a/docs/content/developer/iota-101/using-events.mdx +++ b/docs/content/developer/iota-101/using-events.mdx @@ -30,11 +30,11 @@ An event object in IOTA consists of the following attributes: ### Exploring Available Events -To [subscribe to on-chain events](#subscriging-to-events), you first need to identify which events are available. While you can easily track events emitted by your own code, discovering events from external packages can be more challenging. The IOTA RPC provides the [`queryEvents`](/iota-api-ref#iotax_queryevents) method, which allows you to query on-chain packages and obtain a list of events you can subscribe to. +To [subscribe to on-chain events](#subscribing-to-events), you first need to identify which events are available. While you can easily track events emitted by your own code, discovering events from external packages can be more challenging. The IOTA RPC provides the [`queryEvents`](/iota-api-ref#iotax_queryevents) method, which allows you to query on-chain packages and obtain a list of events you can subscribe to. ### Applying Event Filters -When targeting specific events for [querying](#query-events) or [subscribing](#subscriging-to-events), you can use [filters](#filtering-events) to refine your results. Although the filtering options for querying and subscribing are similar, there are notable differences to be aware of. +When targeting specific events for [querying](#querying-events) or [subscribing](#subscribing-to-events), you can use [filters](#filtering-events) to refine your results. Although the filtering options for querying and subscribing are similar, there are notable differences to be aware of. ## Emitting Events in Move @@ -58,7 +58,7 @@ Then, within your function, you can emit an event using the [`emit`](../../refer -The IOTA RPC provides a [`queryEvents`](/iota-api-ref#iotax_queryEvents) method to query on-chain packages and return available events. As an example, the following `curl` command queries the Deepbook package on Mainnet for a specific type of event: +The IOTA RPC provides a [`queryEvents`](/iota-api-ref#iotax_queryevents) method to query on-chain packages and return available events. As an example, the following `curl` command queries the Deepbook package on Mainnet for a specific type of event: ```sh curl -X POST https://api.testnet.iota.cafe:443 \ From 6b3232fa0d0ed78b18a20e7a716c4c3b8bb6c495 Mon Sep 17 00:00:00 2001 From: Lucas Tortora <85233773+lucas-tortora@users.noreply.github.com> Date: Mon, 16 Dec 2024 11:34:47 -0300 Subject: [PATCH 6/6] Update docs/content/developer/iota-101/using-events.mdx Co-authored-by: vivekjain23 <165671934+vivekjain23@users.noreply.github.com> --- docs/content/developer/iota-101/using-events.mdx | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/content/developer/iota-101/using-events.mdx b/docs/content/developer/iota-101/using-events.mdx index 825d7c09ab8..5e6182ddc78 100644 --- a/docs/content/developer/iota-101/using-events.mdx +++ b/docs/content/developer/iota-101/using-events.mdx @@ -41,7 +41,6 @@ When targeting specific events for [querying](#querying-events) or [subscribing] To emit events from your Move modules, you need to use the [`iota::event`](../../references/framework/iota-framework/event.mdx) module. Emitting events allows external applications to subscribe and respond to specific on-chain activities. - First, import the `event` module in your Move code: ```move