Interact with x/async
Overview
The IAsync
precompile allows calling the x/async
module from EVM smart contracts.
This article explains how to use x/async
to manage Futures. You'll learn how to call the corresponding functions of the precompile and interact with them after deploying your contract.
- For an overview of
x/async
functions, refer to Precompiles: x/async. - The precompile address is
0x0000000000000000000000000000000000000903
.
Manage Futures
Create a new Future
To create a Future, use the following code in your contract. It calls the addFuture()
function of the precompile.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
interface IAsync {
function addFuture(string calldata handler, bytes calldata input) external returns (uint64 futureId);
event CreateFuture(uint64 indexed futureId, address indexed creator, string handler);
}
contract AsyncExample {
IAsync constant ASYNC = IAsync(0x0000000000000000000000000000000000000903);
function createFuture(string calldata handler, bytes calldata input) external returns (uint64) {
return ASYNC.addFuture(handler, input);
}
}
After deploying your contract, you can interact with it by calling the createFuture()
function:
# Example using cast (foundry)
cast send --private-key $PRIVATE_KEY $CONTRACT_ADDRESS "createFuture(string,bytes)" "myHandler" "0x1234"
Query Futures
To get a list of all Futures in all states (including pending ones), use the following code in your contract. It calls the futures()
function of the precompile.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
interface IAsync {
struct TypesPageRequest {
bytes key;
uint64 offset;
uint64 limit;
bool countTotal;
bool reverse;
}
struct Future {
uint64 id;
address creator;
string handler;
bytes input;
}
struct FuturesResponse {
TypesPageResponse pagination;
FutureResponse[] futures;
}
function futures(TypesPageRequest calldata pagination, address creator)
external view returns (FuturesResponse memory response);
}
contract AsyncExample {
IAsync constant ASYNC = IAsync(0x0000000000000000000000000000000000000903);
function queryFutures(uint64 limit, address creator) external view returns (FuturesResponse memory) {
TypesPageRequest memory pagination = TypesPageRequest({
key: new bytes(0),
offset: 0,
limit: limit,
countTotal: true,
reverse: false
});
return ASYNC.futures(pagination, creator);
}
}
After deploying your contract, you can interact with it by calling the queryFutures()
function:
# Example using cast (foundry)
cast call $CONTRACT_ADDRESS "queryFutures(uint64,address)" 10 $CREATOR_ADDRESS
Query pending Futures
To get a list of all pending Futures, use the following code in your contract. It calls the pendingFutures()
function of the precompile.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
interface IAsync {
struct TypesPageRequest {
bytes key;
uint64 offset;
uint64 limit;
bool countTotal;
bool reverse;
}
struct PendingFuturesResponse {
TypesPageResponse pagination;
Future[] futures;
}
function pendingFutures(TypesPageRequest calldata pagination)
external view returns (PendingFuturesResponse memory response);
}
contract AsyncExample {
IAsync constant ASYNC = IAsync(0x0000000000000000000000000000000000000903);
function queryPendingFutures(uint64 limit) external view returns (PendingFuturesResponse memory) {
TypesPageRequest memory pagination = TypesPageRequest({
key: new bytes(0),
offset: 0,
limit: limit,
countTotal: true,
reverse: false
});
return ASYNC.pendingFutures(pagination);
}
}
After deploying your contract, you can interact with it by calling the queryPendingFutures()
function:
# Example using cast (foundry)
cast call $CONTRACT_ADDRESS "queryPendingFutures(uint64)" 10
Query a Future by ID
To query a Future by ID, use the following code in your contract. It calls the futureById()
function of the precompile.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
interface IAsync {
struct FutureByIdResponse {
FutureResponse futureResponse;
}
function futureById(uint64 futureId) external view returns (FutureByIdResponse memory response);
}
contract AsyncExample {
IAsync constant ASYNC = IAsync(0x0000000000000000000000000000000000000903);
function queryFutureById(uint64 futureId) external view returns (FutureByIdResponse memory) {
return ASYNC.futureById(futureId);
}
}
After deploying your contract, you can interact with it by calling the queryFutureById()
function:
# Example using cast (foundry)
cast call $CONTRACT_ADDRESS "queryFutureById(uint64)" 1
Example contract
Here is an example contract calling all the available x/async
functions—it implements a complete interface for interacting with the module. You can use the contract code as a starting point for your own implementations or extend it with additional functionality.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
interface IAsync {
struct TypesPageRequest {
bytes key;
uint64 offset;
uint64 limit;
bool countTotal;
bool reverse;
}
struct TypesPageResponse {
bytes nextKey;
uint64 total;
}
struct Future {
uint64 id;
address creator;
string handler;
bytes input;
}
struct FutureResponse {
Future future;
FutureVote[] votes;
FutureResult result;
}
struct FuturesResponse {
TypesPageResponse pagination;
FutureResponse[] futures;
}
struct FutureByIdResponse {
FutureResponse futureResponse;
}
struct PendingFuturesResponse {
TypesPageResponse pagination;
Future[] futures;
}
function addFuture(string calldata handler, bytes calldata input) external returns (uint64 futureId);
function futures(TypesPageRequest calldata pagination, address creator) external view returns (FuturesResponse memory response);
function pendingFutures(TypesPageRequest calldata pagination) external view returns (PendingFuturesResponse memory response);
function futureById(uint64 futureId) external view returns (FutureByIdResponse memory response);
event CreateFuture(uint64 indexed futureId, address indexed creator, string handler);
}
contract AsyncExample {
IAsync constant ASYNC = IAsync(0x0000000000000000000000000000000000000903);
// Create a new Future
function createFuture(string calldata handler, bytes calldata input) external returns (uint64) {
return ASYNC.addFuture(handler, input);
}
// Query all Futures
function queryFutures(uint64 limit, address creator) external view returns (FuturesResponse memory) {
TypesPageRequest memory pagination = TypesPageRequest({
key: new bytes(0),
offset: 0,
limit: limit,
countTotal: true,
reverse: false
});
return ASYNC.futures(pagination, creator);
}
// Query pending Futures
function queryPendingFutures(uint64 limit) external view returns (PendingFuturesResponse memory) {
TypesPageRequest memory pagination = TypesPageRequest({
key: new bytes(0),
offset: 0,
limit: limit,
countTotal: true,
reverse: false
});
return ASYNC.pendingFutures(pagination);
}
// Query a Future by ID
function queryFutureById(uint64 futureId) external view returns (FutureByIdResponse memory) {
return ASYNC.futureById(futureId);
}
}