Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c85e3fe
Add supported APIs for Rooch Network on Testnet and Mainnet
xlassix Jan 16, 2025
4e8fe52
Update notification gas allocation for specific addresses
xlassix Jan 16, 2025
932cd9b
update unit test to use bearer env var
rsoury Jan 20, 2025
7562183
Merge pull request #17 from usherlabs/updates
xlassix Jan 22, 2025
f0d2376
Update orchestrator function addresses in ROOCH.md file
xlassix Jan 22, 2025
f6aa368
Update notification gas allocation for specific endpoint
xlassix Jan 22, 2025
3c23515
Add migration scripts for creating and updating indexes
xlassix Jan 22, 2025
11955ee
Refactor verity_test_foreign_module::example_caller module
xlassix Jan 23, 2025
0dbc604
Update verity_test_foreign_module address in Move.toml
xlassix Jan 23, 2025
ec721e0
Add handling for minimum gas limit error in oracles move
xlassix Jan 23, 2025
cc56668
Merge pull request #16 from usherlabs/feature/notify
rsoury Jan 27, 2025
e1589a6
Implement request deduplication and jsonata usage
xlassix Feb 4, 2025
056210d
Update gas allocation amounts to reflect new values
xlassix Feb 4, 2025
e049d32
Merge pull request #19 from usherlabs/LABS-1044
rsoury Feb 4, 2025
5b9fa71
Refactor data pick handling in API handler
xlassix Feb 5, 2025
5053cb6
Merge pull request #20 from usherlabs/LAB-1044-fix
rsoury Feb 5, 2025
80c7790
Set max gas limit for transaction execution
xlassix Feb 5, 2025
c9861d6
Disable pretty log styling in logger configuration
xlassix Feb 6, 2025
7357a50
Update function addresses and payload length
xlassix Feb 9, 2025
88fb365
Merge pull request #21 from usherlabs/LABS-1047
rsoury Feb 10, 2025
e4766d9
[oracles] Upgrade GlobalParams to GlobalParamsV2
jolestar Feb 11, 2025
3f7ed33
Merge pull request #22 from jolestar/upgrade_global_params
xlassix Feb 15, 2025
6834b69
Refactor oracle registry to use Table structure
xlassix Feb 16, 2025
38f67c6
Merge pull request #24 from usherlabs/LABS-1053
rsoury Feb 17, 2025
d45e77a
[Oracles] Add new_request_by_signer functions
jolestar Mar 2, 2025
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
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,42 @@ yarn dev
# or
pnpm dev
```


## Supported APIs on Testnet and Mainnet for Rooch Network

### Twitter/X API
- User Endpoint: `https://api.x.com/2/users/` and `https://api.x.com/2/tweets/`
```bash
# Example: Get user followers count
rooch move run --function 0x0d6144b074dd19a9ff581abd5bf7815a39222c8b3ac68ce5938c9d9723544e08::example_caller::request_data \
--sender-account default \
--args 'string:https://api.x.com/2/users/by/username/elonmusk?user.fields=public_metrics' \
--args 'string:GET' \
--args 'string:{}' \
--args 'string:{}' \
--args 'string:.data.public_metrics.followers_count' \
--args 'address:<orchestrator_address>' \
--args 'u256:50000000'
```

### OpenAI API
- Chat Completions: `https://api.openai.com/v1/chat/completions`
```bash
# Example: Simple GPT request
rooch move run --function 0x0d6144b074dd19a9ff581abd5bf7815a39222c8b3ac68ce5938c9d9723544e08::example_caller::request_data \
--sender-account default \
--args 'string:https://api.openai.com/v1/chat/completions' \
--args 'string:POST' \
--args 'string:{}' \
--args 'string:{
"model": "gpt-4",
"messages": [{"role": "user", "content": "Say this is a test!"}],
"temperature": 0.7
}' \
--args 'string:.choices[].message.content' \
--args 'address:<orchestrator_address>' \
--args 'u256:50000000'
```

Note: Replace `<oracle_address>` and `<orchestrator_address>` with your actual deployed addresses.
36 changes: 18 additions & 18 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,24 @@ services:
volumes:
- postgres-db-data:/var/lib/postgresql/data

orchestrator:
build:
dockerfile: ./orch.dockerfile
context: .
image: orchestrator:move
container_name: verity-move-orchestrator
environment:
DATABASE_URL: ${DATABASE_URL}
networks:
- verify-network
depends_on:
postgres_db:
condition: service_healthy
command: >
sh -c "
npx prisma migrate deploy &&
pnpm run start
"
# orchestrator:
# build:
# dockerfile: ./orch.dockerfile
# context: .
# image: orchestrator:move
# container_name: verity-move-orchestrator
# environment:
# DATABASE_URL: ${DATABASE_URL}
# networks:
# - verify-network
# depends_on:
# postgres_db:
# condition: service_healthy
# command: >
# sh -c "
# npx prisma migrate deploy &&
# pnpm run start
# "

volumes:
postgres-db-data:
Expand Down
31 changes: 16 additions & 15 deletions docs/ROOCH.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Navigate to the `rooch` directory, build the contracts for development, publish
```bash
cd rooch
rooch move build --dev
rooch move publish --named-addresses verity_test_foreign_module=default,verity=default --sender default
rooch move publish --named-addresses verity=default --sender default
cd ..
```

Expand Down Expand Up @@ -103,19 +103,19 @@ Additional steps for managing supported orchestrator URL
- To add URL

```bash
rooch move run --function 0x27e46e033da11c4d1f986081877e80cefb2b29dec1c559c97c3ccf12e910aba7::registry::add_supported_url --sender-account <orchestrator_address> --args 'string:https://api.x.com/2/users/' --args 'u256:400000' --args 'u64:0' --args 'u256:0' --args 'u256:0'
rooch move run --function 0xf1290fb0e7e1de7e92e616209fb628970232e85c4c1a264858ff35092e1be231::registry::add_supported_url --sender-account 0x694cbe655b126e9e6a997e86aaab39e538abf30a8c78669ce23a98740b47b65d --args 'string:https://api.openai.com/v1/chat/completions' --args 'u256:50000' --args 'u64:40' --args 'u256:4000' --args 'u256:5000'
```

- to remove URLs

```bash
rooch move run --function 0x27e46e033da11c4d1f986081877e80cefb2b29dec1c559c97c3ccf12e910aba7::registry::remove_supported_url --sender-account <orchestrator_address> --args 'string:api.twitter.com/2/users/'
rooch move run --function 0xf1290fb0e7e1de7e92e616209fb628970232e85c4c1a264858ff35092e1be231::registry::remove_supported_url --sender-account <orchestrator_address> --args 'string:https://api.twitter.com/2/users/'
```

- To view supported URLS

```bash
rooch move view --function <oracle_address>::registry::get_supported_urls --args 'address:<orchestrator_address>'
rooch move view --function 0xf1290fb0e7e1de7e92e616209fb628970232e85c4c1a264858ff35092e1be231::registry::get_supported_urls --args 'address:0x694cbe655b126e9e6a997e86aaab39e538abf30a8c78669ce23a98740b47b65d'
```


Expand All @@ -142,40 +142,41 @@ rooch move run --function <contractAddress>::example_caller::request_data --sen
Here's an example of requesting the Twitter Followers Count on a Local Rooch Node:

```bash
rooch move run --function 0x0d6144b074dd19a9ff581abd5bf7815a39222c8b3ac68ce5938c9d9723544e08::example_caller::request_data --sender-account default --args 'string:https://api.x.com/2/users/by/username/elonmusk?user.fields=public_metrics' --args 'string:GET' --args 'string:{}' --args 'string:{}' --args 'string:.data.public_metrics.followers_count' --args 'address:0x694cbe655b126e9e6a997e86aaab39e538abf30a8c78669ce23a98740b47b65d' --args 'u256:50000000'
rooch move run --function 0xf1290fb0e7e1de7e92e616209fb628970232e85c4c1a264858ff35092e1be231::example_caller::request_data --sender-account default --args 'string:https://api.x.com/2/users/by/username/elonmusk?user.fields=public_metrics' --args 'string:GET' --args 'string:{}' --args 'string:{}' --args 'string:.data.public_metrics.followers_count' --args 'address:0x694cbe655b126e9e6a997e86aaab39e538abf30a8c78669ce23a98740b47b65d' --args 'u256:50000'
```
or
```bash
rooch move run --function 0x0d6144b074dd19a9ff581abd5bf7815a39222c8b3ac68ce5938c9d9723544e08::example_caller::request_data --sender-account default --args 'string:https://api.openai.com/v1/chat/completions' --args 'string:POST' --args 'string:{}' --args 'string:{
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": "Say this is a test!"}],
"temperature": 0.7
}' --args 'string:.choices[].message.content' --args 'address:0x694cbe655b126e9e6a997e86aaab39e538abf30a8c78669ce23a98740b47b65d' --args 'u256:50000000'
rooch move run --function 0xf1290fb0e7e1de7e92e616209fb628970232e85c4c1a264858ff35092e1be231::example_caller::request_data --sender-account default --args 'string:https://api.openai.com/v1/chat/completions' --args 'string:POST' --args 'string:{}' --args 'string:{"model": "gpt-4o-mini", "messages": [{"role": "user", "content": "Say this is a test!"}],"temperature": 0.7}' --args 'string:.choices[].message.content' --args 'address:0x694cbe655b126e9e6a997e86aaab39e538abf30a8c78669ce23a98740b47b65d' --args 'u256:50000000'
```

To check the state of the response object on a local Rooch node, use the following command:

```bash
rooch state -a /object/0x7a01ddf194f8a1c19212d56f747294352bf2e5cf23e6e10e64937aa1955704b0
```


Additionally,
For notification calls you can allocated an portion form escrow for notification per fulfilment Request(Recommended 1Rgas for the first fulfilment).
```bash
rooch move run --function 0xf1290fb0e7e1de7e92e616209fb628970232e85c4c1a264858ff35092e1be231::oracles::update_notification_gas_allocation --sender-account default --args 'address:0x27e46e033da11c4d1f986081877e80cefb2b29dec1c559c97c3ccf12e910aba7' --args 'string:example_caller::receive_data' --args 'u256:10000000'
```

#### Step 10: Manage Escrow balance

- To view balance

```bash
rooch move view --function 0x0d6144b074dd19a9ff581abd5bf7815a39222c8b3ac68ce5938c9d9723544e08::oracles::get_user_balance --args 'address:<your_address>'
rooch move view --function 0xf1290fb0e7e1de7e92e616209fb628970232e85c4c1a264858ff35092e1be231::oracles::get_user_balance --args 'address:<your_address>'
```

- To withdraw Balance
```bash
rooch move run --function 0x0d6144b074dd19a9ff581abd5bf7815a39222c8b3ac68ce5938c9d9723544e08::oracles::withdraw_from_escrow --args 'u256:<amount>'
rooch move run --function 0xf1290fb0e7e1de7e92e616209fb628970232e85c4c1a264858ff35092e1be231::oracles::withdraw_from_escrow --args 'u256:<amount>'
```

- To Deposit
```bash
rooch move run --function 0x0d6144b074dd19a9ff581abd5bf7815a39222c8b3ac68ce5938c9d9723544e08::oracles::deposit_to_escrow --args 'u256:<amount>'
rooch move run --function 0xf1290fb0e7e1de7e92e616209fb628970232e85c4c1a264858ff35092e1be231::oracles::deposit_to_escrow --args 'u256:<amount>'
```

To confirm the `Request` Object State, use the Object ID generated from the initial transaction to query the state of the response object.
Expand All @@ -186,7 +187,7 @@ This allows you to verify that the request was processed successfully and that t
An example of requesting the Twitter Followers Count on a Rooch Testnet:

```bash
rooch move run --function 0x0d6144b074dd19a9ff581abd5bf7815a39222c8b3ac68ce5938c9d9723544e08::example_caller::request_data --sender-account default --args 'string:https://api.x.com/2/users/by/username/elonmusk?user.fields=public_metrics' --args 'string:GET' --args 'string:{}' --args 'string:{}' --args 'string:.data.public_metrics.followers_count' --args 'address:0x694cbe655b126e9e6a997e86aaab39e538abf30a8c78669ce23a98740b47b65d'
rooch move run --function 0xf1290fb0e7e1de7e92e616209fb628970232e85c4c1a264858ff35092e1be231::example_caller::request_data --sender-account default --args 'string:https://api.x.com/2/users/by/username/elonmusk?user.fields=public_metrics' --args 'string:GET' --args 'string:{}' --args 'string:{}' --args 'string:.data.public_metrics.followers_count' --args 'address:0x694cbe655b126e9e6a997e86aaab39e538abf30a8c78669ce23a98740b47b65d'
```

To check the state of the response object on testnet, devnet, or mainnet,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- CreateTable
CREATE TABLE "Keeper" (
"id" TEXT NOT NULL,
"chain" TEXT NOT NULL DEFAULT 'ROOCH-testnet',
"module" TEXT NOT NULL,
"privateKey" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updateAt" TIMESTAMP(3) NOT NULL,

CONSTRAINT "Keeper_pkey" PRIMARY KEY ("id")
);

-- CreateIndex
CREATE INDEX "Keeper_chain_module_idx" ON "Keeper"("chain", "module");
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
Warnings:

- A unique constraint covering the columns `[chain,module]` on the table `Keeper` will be added. If there are existing duplicate values, this will fail.

*/
-- DropIndex
DROP INDEX "Keeper_chain_module_idx";

-- CreateIndex
CREATE UNIQUE INDEX "Keeper_chain_module_key" ON "Keeper"("chain", "module");
13 changes: 13 additions & 0 deletions orchestrator/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,17 @@ model Events{
updateAt DateTime @updatedAt

@@index([eventHandleId, eventSeq,chain])
}

model Keeper{
id String @id @default(cuid())
chain String @default("ROOCH-testnet")
module String
privateKey String

createdAt DateTime @default(now())
updateAt DateTime @updatedAt

@@unique([chain, module])

}
19 changes: 8 additions & 11 deletions orchestrator/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,15 @@ import { log } from "./logger";

env.rooch.chainId.map((chain) => {
const rooch = new RoochIndexer(env.rooch.privateKey, chain, env.rooch.oracleAddress);
new CronJob(
"*/15 * * * *",
() => {
rooch.sendUnfulfilledRequests();
},
null,
false,
);
new CronJob(
let running = false;
const job = new CronJob(
env.rooch.indexerCron,
() => {
rooch.run();
async () => {
if (!running) {
running = true;
await rooch.run();
running = false;
}
},
null,
true,
Expand Down
17 changes: 16 additions & 1 deletion orchestrator/src/indexer/aptos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ export default class AptosIndexer extends Indexer {
})
.filter((elem) => elem != null);


const data: any[] = _temp.map((elem) => ({
...elem.data,
notify: decodeNotifyValue(elem.data.notify?.value?.vec?.at(0) ?? ""),
Expand All @@ -162,6 +161,22 @@ export default class AptosIndexer extends Indexer {
}
}

async isPreviouslyExecuted(data: ProcessedRequestAdded<any>) {
const aptosConfig = new AptosConfig({ network: Network.TESTNET });
const aptos = new Aptos(aptosConfig);
const view_request = await aptos.view({
payload: {
function: `${this.oracleAddress}::oracles::get_response_status`,
functionArguments: [data.request_id],
},
});
if (view_request[0] !== 0) {
log.debug({ message: `Request: ${data.request_id} as already been processed` });
return true;
}
return false;
}

/**
* Sends a fulfillment transaction to the Aptos Oracles Contract.
*
Expand Down
26 changes: 17 additions & 9 deletions orchestrator/src/indexer/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export abstract class Indexer {
// Abstract: Implementation To fetch Data
abstract fetchRequestAddedEvents<T>(cursor: null | number | string): Promise<ProcessedRequestAdded<T>[]>;

abstract isPreviouslyExecuted<T>(data: ProcessedRequestAdded<T>): Promise<boolean>;

// Abstract: Implementation to send Fulfillment blockchain fulfillment Request
/**
* Sends a fulfillment transaction to on-chain Contract.
Expand Down Expand Up @@ -116,18 +118,24 @@ export abstract class Indexer {
for (let i = 0; i < newRequestsEvents.length; i++) {
try {
const event = newRequestsEvents[i];
const data = await this.processRequestAddedEvent(event);

log.info({ data });
if (!(await this.isPreviouslyExecuted(event))) {
const data = await this.processRequestAddedEvent(event);

log.info({ data });

if (data) {
try {
await this.sendFulfillment(event, data.status, JSON.stringify(data.message));
await this.save(event, data, RequestStatus.SUCCESS);
} catch (err: any) {
log.error({ err: err.message });
await this.save(event, data, RequestStatus.FAILED);
if (data) {
try {
await this.sendFulfillment(event, data.status, JSON.stringify(data.message));
await this.save(event, data, RequestStatus.SUCCESS);
} catch (err: any) {
log.error({ err: err.message });
await this.save(event, data, RequestStatus.FAILED);
}
}
} else {
log.debug({ message: `Request: ${event.request_id} as already been processed` });
await this.save(event, {}, RequestStatus.SUCCESS);
}
} catch (error) {
console.error(`Error processing event ${i}:`, error);
Expand Down
Loading
Loading