Skip to content

adding trigger content #27

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 171 additions & 0 deletions content/docs/example-trigger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
---
description: 'Integrate task triggers directly inside on-chain contracts'
sidebar: 'docs'
prev: '/docs/'
next: '/docs/trigger-monitoring/'
---

# Example: Trigger

First off -- why you would want this?
In certain situations all that is needed is a simple task being scheduled by a person, that is easily managed checking on its progress every so often.

A more advanced use would be to integrate logic for scheduling directly inside the contracts functionality, such that the contract can schedule and maintain a task. This effectively allows a contract to have a fully autonomous runtime, a decentralized automonous business appears! So, if you would like to integrate cron within a contract, here's the full CRUD example with all the cases for interacting directly. Bonus points for setting this up with a DAO :)

# Example: Cross-Crontract Cron Task Management

[View Full Source](https://github.com/Cron-Near/contracts/tree/main/examples/cross-contract)

This example shows how to setup a cross-contract implementation with croncat. The demo functionality shows an on-chain indexing of balances in a time series format. This contract allows scheduling, updating, removing & checking status.

## Contract Setup

Integration in a cross-contract setup requires 3 main things:
1. ABI Definitions
2. Methods to schedule
3. Methods to maintain

## Definitions:

You will need the following definitions for rust to be able to analyze and structure you code properly.

```rust

#[derive(BorshDeserialize, BorshSerialize, Debug, Serialize, Deserialize, PartialEq)]
#[serde(crate = "near_sdk::serde")]
pub struct Task {
pub owner_id: AccountId,
pub contract_id: AccountId,
pub function_id: String,
pub cadence: String,
pub recurring: bool,
pub total_deposit: U128,
pub deposit: U128,
pub gas: Gas,
pub arguments: Vec<u8>,
}

#[ext_contract(ext_croncat)]
pub trait ExtCroncat {
fn get_tasks(&self, offset: Option<u64>) -> (Vec<Base64VecU8>, U128);
fn get_all_tasks(&self, slot: Option<U128>) -> Vec<Task>;
fn get_task(&self, task_hash: Base64VecU8) -> Task;
fn create_task(
&mut self,
contract_id: String,
function_id: String,
cadence: String,
recurring: Option<bool>,
deposit: Option<U128>,
gas: Option<Gas>,
arguments: Option<Vec<u8>>,
) -> Base64VecU8;
fn update_task(
&mut self,
task_hash: Base64VecU8,
cadence: Option<String>,
recurring: Option<bool>,
deposit: Option<U128>,
gas: Option<Gas>,
arguments: Option<Vec<u8>>,
);
fn remove_task(&mut self, task_hash: Base64VecU8);
fn proxy_call(&mut self);
}
```

## Scheduling

Setting up a single or recurring task is very straightforward, however it can be hard to guess at the right parameters. The following is an example setup for a task the will execute a transaction to the account `crosscontract.testnet` using the method `tick` (which computes a timeseries tick) at an interveral of every 1 minute.

Key things to note:
* There is a callback shown here, it is a way to get the task hash, the main identifier for your scheduled task.
* attached deposit is used to fund the future task executions
* Parameters in this example will vary from your implementation, this is just a sample.

```rust
/// Create a new scheduled task, registering the "tick" method with croncat
///
/// ```bash
/// near call crosscontract.testnet schedule '{ "function_id": "tick", "period": "0 */1 * * * *" }' --accountId YOUR_ACCOUNT.testnet
/// ```
#[payable]
pub fn schedule(&mut self, function_id: String, period: String) -> Promise {
assert_eq!(
env::current_account_id(),
env::predecessor_account_id(),
"{}",
ERR_ONLY_OWNER
);
// NOTE: Could check that the balance supplied is enough to cover XX task calls.

ext_croncat::create_task(
env::current_account_id(),
function_id,
period,
Some(true),
Some(U128::from(NO_DEPOSIT)),
Some(GAS_FOR_TICK_CALL), // 30 Tgas
None,
&self.cron.clone().expect(ERR_NO_CRON_CONFIGURED),
env::attached_deposit(),
GAS_FOR_SCHEDULE_CALL,
)
.then(ext::schedule_callback(
&env::current_account_id(),
NO_DEPOSIT,
GAS_FOR_SCHEDULE_CALLBACK,
))
}

/// Get the task hash, and store in state
#[private]
pub fn schedule_callback(&mut self, #[callback] task_hash: Base64VecU8) {
log!("schedule_callback task_hash {:?}", &task_hash);
self.task_hash = Some(task_hash);
}
```

## Maintaining the Task

Once you've scheduled a task, its important to make sure it is funded to continue running (if your app needs it). The task hash allows you to update or get information about your task. Your contract can then know key information like how much balance is remaining on the task itself.

For a full sample of updating, removing & more: [View Full Demo Source](https://github.com/Cron-Near/contracts/tree/main/examples/cross-contract)

```rust
/// Get the task status, including remaining balance & etc.
/// Useful for automated on-chain task management! This method could be scheduled as well, and manage re-funding tasks or changing tasks on new data.
///
/// ```bash
/// near call crosscontract.testnet status
/// ```
pub fn status(&self) -> Promise {
// TODO: fix this! serialization is not working
let hash = self.task_hash.clone().expect(ERR_NO_TASK_CONFIGURED);
log!("TASK HASH: {:?} {:?} {}", &hash, serde_json::to_string(&hash).unwrap(), serde_json::to_string(&hash).unwrap());
ext_croncat::get_task(
// hash,
serde_json::to_string(&hash).unwrap().to_string(),
&self.cron.clone().expect(ERR_NO_CRON_CONFIGURED),
NO_DEPOSIT,
GAS_FOR_STATUS_CALL,
)
.then(ext::schedule_callback(
&env::current_account_id(),
NO_DEPOSIT,
GAS_FOR_STATUS_CALLBACK,
))
}

/// Get the task hash, and store in state
/// NOTE: This method helps contract understand remaining task balance, in case more is needed to continue running.
/// NOTE: This could handle things about the task, or have logic about changing the task in some way.
#[private]
pub fn status_callback(&self, #[callback] task: Option<Task>) -> Option<Task> {
// NOTE: Could check remaining balance here
// NOTE: Could have logic to another callback IF the balance is running low
task
}
```

There's a lot of information in this guide, and you've probably got questions. Do not hesitate to reach out and get help with further integrating croncat!
2 changes: 1 addition & 1 deletion content/docs/task-creation.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ next: '/docs/task-monitoring/'

Croncat tasks follow a very straight forward flow:

1. Deploy or find a contract to a NEAR blockchain
1. Deploy or find a contract to a NEAR blockchain account
2. Decide how often a contract should be called & estimate it's transaction fee needs.
3. Create the task configuration within croncat
4. Monitor the ongoing progress of the task
Expand Down
94 changes: 94 additions & 0 deletions content/docs/trigger-creation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
description: 'Create a task in croncat specifying different configuration params'
sidebar: 'docs'
prev: '/docs/'
next: '/docs/trigger-monitoring/'
---

# Trigger Creation

## Basic Flow

Croncat triggers follow a very straight forward flow:

1. Create a croncat task - [See here for setup](./task-creation.md)
2. Get the task hash for the task you own & want to trigger
3. Create the trigger with croncat
4. Monitor the ongoing progress of the trigger

## Configuration Reference

Each field within croncat serves a specific purpose, the following details show what kinds of data are acceptable. [View Source](https://github.com/CronCats/contracts/blob/main/manager/src/triggers.rs#L52-L55)

| Field | Type | Description |
| ------- | ------- | ------- |
| contract_id | AccountId | Account to direct all execution calls against |
| function_id | String | Contract method this task will be executing |
| task_hash | String | The hash of the task you own and want to trigger |
| arguments | Vec<u8> | NOTE: Only allow static pre-defined bytes, most useful for cross-contract task creation |
| | | |

## Simple Trigger Creation Example

Let's say you have a task that calls the contract "counter" that increments a storage integer. You want it to trigger every even minute by using a different contract that returns true/false before calling the increment contract.

Creating a trigger will look like this:

```bash
near call manager_v1.croncat.testnet create_trigger '{"contract_id": "view.in.testnet","function_id": "get_a_boolean","arguments":"","task_hash":"fsda1234fdas1234..."}' --accountId YOU.testnet
```

Now let's break this down a bit:

First snippet makes a call request to the "cron" manager in testnet to register a new trigger.
```bash
near call manager_v1.croncat.testnet create_trigger
```

Next we specify the contract and function getting viewed, like this:
```bash
'{"contract_id": "view.in.testnet","function_id": "get_a_boolean",
```

Then we specify the `task_hash` of this contract call:
```bash
"arguments":"","task_hash":"fsda1234fdas1234...",
```

This is completed by making sure the transaction is signed by the account that will own this trigger:
```bash
--accountId YOUR_NEAR_ACCT.testnet
```

**Important thing to note:** You will get a trigger hash upon successful creation. Save this hash as its your access to monitor and update the trigger in the future.


## How to get Trigger Hash

```bash
near view <CONTRACT_ACCOUNT> get_hash '{"contract_id": "<CONTRACT_ID>","function_id": "<FUNCTION>","cadence": "0 0 * * * *","owner_id": "<OWNER_ID>"}'
```

Example (get Task Hash from "ping" function):
```bash
near view manager_v1.croncat.testnet get_hash '{"contract_id": "jakson.pool.f863973.m0","function_id": "ping","cadence": "0 0 * * * *","owner_id": "jakson.testnet"}'
```

## Remove task

When deleting a task, all unused balance will be returned to the wallet of the task owner.


```bash
near call <CONTRACT_ACCOUNT> remove_task '{"task_hash": "r2JvrGPvDkFUuqdF4x1+L93aYKGmgp4GqXT4UAK3AE4="}' --accountId jakson.testnet
```

Example

```bash
near call manager_v1.croncat.testnet remove_task '{"task_hash": "r2JvrGPvDkFUuqdF4x1"}' --accountId <accountId>
```

## More Examples

For deeper examples of contracts & task creation, [view all examples here](/docs/examples).
Loading