{"id":24418803,"url":"https://github.com/firstbatchxyz/dria-oracle-sdk","last_synced_at":"2025-10-04T07:58:52.247Z","repository":{"id":269344093,"uuid":"880695247","full_name":"firstbatchxyz/dria-oracle-sdk","owner":"firstbatchxyz","description":"A decentralized, transparent, and permissionless framework for executing LLM tasks and AI applications.","archived":false,"fork":false,"pushed_at":"2025-03-04T09:53:35.000Z","size":228,"stargazers_count":8,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-08-25T07:43:44.126Z","etag":null,"topics":["base","ethereum","oracle","sdk","ts"],"latest_commit_sha":null,"homepage":"https://npmjs.com/package/dria-oracle-sdk","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/firstbatchxyz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-10-30T07:22:53.000Z","updated_at":"2025-03-14T11:22:13.000Z","dependencies_parsed_at":"2024-12-22T22:24:41.078Z","dependency_job_id":"54f8c450-45ca-4fcd-b5d6-1ee110c01bb3","html_url":"https://github.com/firstbatchxyz/dria-oracle-sdk","commit_stats":null,"previous_names":["firstbatchxyz/dria-oracle-sdk"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/firstbatchxyz/dria-oracle-sdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/firstbatchxyz%2Fdria-oracle-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/firstbatchxyz%2Fdria-oracle-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/firstbatchxyz%2Fdria-oracle-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/firstbatchxyz%2Fdria-oracle-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/firstbatchxyz","download_url":"https://codeload.github.com/firstbatchxyz/dria-oracle-sdk/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/firstbatchxyz%2Fdria-oracle-sdk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278283510,"owners_count":25961311,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-04T02:00:05.491Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["base","ethereum","oracle","sdk","ts"],"created_at":"2025-01-20T09:13:52.739Z","updated_at":"2025-10-04T07:58:52.233Z","avatar_url":"https://github.com/firstbatchxyz.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/firstbatchxyz/.github/refs/heads/master/branding/dria-logo-square.svg\" alt=\"logo\" width=\"168\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ch1 align=\"center\"\u003e\n    Dria Oracle SDK\n  \u003c/h1\u003e\n  \u003cp align=\"center\"\u003e\n    \u003ci\u003eA decentralized, transparent, and permissionless framework for executing LLM tasks and AI applications.\u003c/i\u003e\n  \u003c/p\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://opensource.org/licenses/MIT\" target=\"_blank\"\u003e\n        \u003cimg alt=\"License: MIT\" src=\"https://img.shields.io/badge/license-MIT-7CB9E8.svg\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://www.npmjs.com/package/dria-oracle-sdk\" target=\"_blank\"\u003e\n        \u003cimg alt=\"NPM\" src=\"https://img.shields.io/npm/v/dria-oracle-sdk?logo=npm\u0026color=CB3837\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://discord.gg/dria\" target=\"_blank\"\u003e\n        \u003cimg alt=\"Discord\" src=\"https://dcbadge.vercel.app/api/server/dria?style=flat\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n- [x] **Transparency**: _Everything_ happens on-chain, if you don't see it on the block-explorer it didn't happen.\n- [x] **Ease of Use**: SDK has an intuitive interface to integrate LLMs into your application, be it AI-driven workflows or autonomous agents.\n- [x] **Decentralized \u0026 Permissionless**: _Anyone_ can run an [Oracle Node](https://github.com/firstbatchxyz/dria-oracle-node), including you!\n- [x] **Validations**: Validator nodes validate \u0026 give score to each result, ensuring high-quality generations.\n- [x] **Diverse LLM Support**: Oracles support 50+ LLMs, you can pick specific models for your request.\n- [x] **Multi-step Tasks**: Oracles can refer to previous tasks, and keep a conversation history on-chain.\n\n**See more [here](https://firstbatch.notion.site/dria-oracle-sdk)!**\n\n## Installation\n\nDria Oracle SDK is an [NPM package](https://www.npmjs.com/package/dria-oracle-sdk), which can be installed with any of the following:\n\n```sh\nnpm  i   dria-oracle-sdk\nyarn add dria-oracle-sdk\npnpm add dria-oracle-sdk\n```\n\nThe SDK makes use of Arweave as well for large inputs \u0026 outputs to save gas, and this depends on a peer dependency:\n\n```sh\npnpm add @irys/sdk\n```\n\n## Usage\n\nUsing Oracle SDK, the following happens when you make a request:\n\n- The request is recorded on-chain \u0026 this event is picked up by Oracle nodes.\n- Oracles compete to respond with their results \u0026 solve a small hash-based proof-of-work.\n- Once the requested amount of generations are made, validator oracles give a score on each of them to assess their quality, while also doing proof-of-work themselves.\n- Once the requested amount of validations are made, you can read the highest-score generation from the contract.\n\n### Setup\n\nWe use [Viem](https://viem.sh/) to connect with blockchains. Provide the two Viem clients as input:\n\n```ts\nimport { Oracle, ArweaveStorage } from \"dria-oracle-sdk\";\nimport { createPublicClient, createWalletClient, http } from \"viem\";\n\n// wallet client for \"write\" operations\nconst walletClient = createWalletClient({\n  account: privateKeyToAccount(SECRET_KEY),\n  transport: http(RPC_URL),\n  chain,\n});\n// public client for \"read\" operations\nconst publicClient = createPublicClient({\n  transport: http(RPC_URL),\n  chain,\n});\n\n// arweave storage\nconst storage = new ArweaveStorage();\n\n// create the oracle sdk\nconst oracle = new Oracle(\n  {\n    public: publicClient,\n    wallet: walletClient,\n  },\n  storage\n);\n```\n\nThen, initialize the SDK by connecting to the Coordinator contract at the given address:\n\n```ts\nawait oracle.init(coordinatorAddress);\n```\n\n### Using Arweave\n\nAs you may have noticed, we have written `const storage = new ArweaveStorage();` above. This is because we save from gas costs by writing large strings to Arweave and storing its transaction id instead of the string itself within the contract.\nIf you omit Arweave by not passing this argument to the `Oracle` constructor, Arweave messages will not be downloaded automatically, nor large values will not be uploaded.\n\nIn a contract, if we see a stringified object such as `{ arweave: \"tx-id-here\"}` then this belongs to an Arweave transaction.\nOracle nodes can understand this, and read the actual content from Arweave. Even further, they can write their results to Arweave the same way, from which the SDK understands and downloads the output!\nIn short, there are two types of operations:\n\n- **Read**: It is enough to pass in the `ArweaveStorage` instance as shown above to the `Oracle` constructor.\n\n```ts\nconst storage = new ArweaveStorage();\n```\n\n- **Write**: To be able to upload to Arweave as the SDK user, you must provide an `ArweaveWallet` type object. The SDK tolerates to some byte-length, i.e. it will not use Arweave if the input is not large enough; this is configurable.\n\n```ts\nconst storage = new ArweaveStorage();\nconst wallet = JSON.parse(fs.readFileSync(\"./path/to/wallet.json\", \"utf-8\")) as ArweaveWallet;\n\nconst byteLimit = 2048; // default 1024\nstorage.init(wallet, byteLimit);\n```\n\n### Approving for Fees\n\nBefore we make a request, we must make sure that we have enough allowance to the coordinator contract so that it can pay the oracle fees.\nYou can check the allowance, and approve tokens if required with the following snippet:\n\n```ts\nconst allowance = await oracle.allowance();\nif (allowance === 0n) {\n  // you can omit `amount` as well to make an infinite approval\n  const amount = parseEther(\"1.0\");\n  const txHash = await oracle.approve(amount);\n  console.log({ txHash });\n}\n```\n\n### Making a Request\n\nWe are now ready to make a request. Within a request, we simply provide the input as-is, along with the models to be used:\n\n```ts\nconst input = \"What is 2+2?\";\nconst models = [\"gpt-4o-mini\"]; // or just \"*\" for any model\nconst txHash = await oracle.request(input, models);\n```\n\nWhen this transaction is mined, a `taskid` will be assigned to it by the contract. A taskId start from 1 and simply increments for each request; however, we cant be sure of its value until our request is mined. For this reason, we follow our `request` with this function:\n\n```ts\nconst taskId = await oracle.waitRequest(txHash);\n```\n\nWith the request made \u0026 its task id known, we can sit back for a while and wait for the **generator** and **validator** oracles to finish their jobs. First, generator oracles will work to answer until the requested number of generations are met. After that, the validations will take place and each generation will take a score from each validator. Once the requested number of validations are met as well, the last validator computes the final scores \u0026 distributes fees accordingly.\n\nTo wait for this programmatically, we can provide the task id and wait until all this is completed with the `wait` function:\n\n```ts\nawait oracle.wait(taskId);\n```\n\nWhen we return from `wait` without any errors, we are sure that the request has been completed.\n\n### Custom Task Parameters\n\nWhen calling `request`, you can provide optional parameters:\n\n- `protocol`: Protocol is a string that should fit `bytes32` of Solidity, which identifies your application. Can be omitted, defaults to SDK protocol.\n- `taskParameters`: An object that defines `difficulty`, `numGenerations` and `numValidations`.\n  - `difficulty` defines the proof-of-work difficulty for the oracles, increasing this exponentially rises the oracle fee.\n  - `numGenerations` is the number of generation you expect.\n  - `numValidations` is the number of validations you expect for each generation.\n\nHere is an example:\n\n```ts\nconst txHash = await oracle.request(input, models, {\n  protocol: \"my-app/0.1.0\",\n  taskParameters: {\n    difficulty: 4,\n    numGenerations: 3,\n    numValidations: 2,\n  },\n});\n```\n\n### Reading the Best Response\n\nTo read the best (i.e. highest score) response to a request, we have the `read` function:\n\n```ts\nconst response = await oracle.read(taskId);\nconst { output, metadata } = response;\n```\n\nThis function also handles downloading the actual values from Arweave, if the responder nodes have used it to save from gas. Note that you must have passed in the `ArweaveStorage` instance to the `Oracle` constructor for this to work.\n\n### Reading All Responses\n\nIf you are interested in reading all generations, you can use:\n\n```ts\nconst responses = await oracle.getResponses(taskId);\n```\n\nThis returns you an array of raw responses. You can fetch the actual values from Arweave using the `processResponse` function:\n\n```ts\nfor (const responseRaw of responses) {\n  const response = await oracle.processResponse(responseRaw);\n  // console.log ...\n}\n```\n\n### Reading Validations\n\nIf you are interested in reading all validations, you can use:\n\n```ts\nconst validations = await oracle.getValidations(taskId);\n```\n\nThis returns you an array of raw responses. You can fetch the actual values from Arweave using the `processResponse` function:\n\n```ts\nfor (const validationRaw of validations) {\n  const validation = await oracle.processValidation(validationRaw);\n  // console.log ...\n}\n```\n\n### Reading Task Events\n\nIf you want to fetch `taskId`s for a given protocol, you can filter contract events with:\n\n```ts\nconst events = await oracle.getTaskEvents({\n  protocol: stringToBytes32(\"my-protocol/0.1.0\"),\n  status: TaskStatus.Completed,\n});\n```\n\nYou can then use other functions with the returned `taskId`s.\n\n## Examples\n\nWe have several examples that demonstrate making a request, following it up with another request, and view an existing request!\nYou can examine the code there, or try them out yourself.\n\nFirst, go to [`examples`](./examples/) directory and install packages there:\n\n```sh\ncd examples\nnpm install\n```\n\nPrepare the environment by copying `.env.example` as `.env`, and fill out your `SECRET_KEY` and `RPC_URL`.\nThe examples use Base Sepolia network, so make sure your RPC URL belongs to that network.\n\n\u003e [!WARNING]\n\u003e\n\u003e Make sure you have enough ETH and WETH as well, to pay for the fees.\n\n### Making a Request\n\nLet's make a request now. Simply call `./request.mjs` with a single argument, that is your prompt.\n\n```sh\nnode ./request.mjs \u003cyour-input-here\u003e\n# node ./request.mjs \"What is 2+2?\"\n# node ./request.mjs \"Who created you?\"\n# node ./request.mjs \"Tell me a joke\"\n```\n\nThe script will print your request, and the best generation along with validations to the screen. It will also print the task id, which identifies\nyour request for the coordinator contract.\n\n### Following up a Request\n\nOracle's can \"follow up\" on an existing message, similar to how ChatGPT works with context! Check your task id from the previous example, and try to follow it\nup with another question using the `./chat.mjs` script:\n\n```sh\nnode ./chat.mjs \u003cyour-input-here\u003e \u003ctask-id-here\u003e\n# node ./chat.mjs \"how many words are there in my previous message?\" 4\n# node ./chat.mjs \"what are we talking about in our last conversation?\" 123\n# node ./chat.mjs \"what is the multiplication of the numbers in your previous messages\" 1337\n```\n\nYou can keep following up the chat messages on and on, as the oracle writes the entire history for each chat message!\n\n### Viewing a Request\n\nYou can view the request, its generations and validations for any task id with the `./view.mjs` script:\n\n```sh\nnode ./view.mjs \u003ctask-id\u003e\n# node ./view.mjs 1\n```\n\n## Testing\n\nTests use the live environment, so make sure you have some balance in your wallets. To run them:\n\n```sh\npnpm test\n```\n\n## Contracts\n\n### Base Mainnet\n\n| Contract    | Address                                                                                                                      |\n| ----------- | ---------------------------------------------------------------------------------------------------------------------------- |\n| Registry    | [`7645eef691ad9dc0f29b6abfc73cca4c8be44051`](https://base.blockscout.com/address/0x7645eef691ad9dc0f29b6abfc73cca4c8be44051) |\n| Coordinator | [`17b6d1eddcd5f9ca19bb2ffed2f3deb6bd74bd20`](https://base.blockscout.com/address/0x17b6d1eddcd5f9ca19bb2ffed2f3deb6bd74bd20) |\n\n### Base Sepolia Testnet\n\n| Contract    | Address                                                                                                                              |\n| ----------- | ------------------------------------------------------------------------------------------------------------------------------------ |\n| Registry    | [`408d245a853137e44a2465d5c66061f97582eae9`](https://base-sepolia.blockscout.com/address/0x408d245a853137e44a2465d5c66061f97582eae9) |\n| Coordinator | [`13f977bde221b470d3ae055cde7e1f84debfe202`](https://base-sepolia.blockscout.com/address/0x13f977bde221b470d3ae055cde7e1f84debfe202) |\n\n## License\n\nWe are using [MIT](./LICENSE) license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffirstbatchxyz%2Fdria-oracle-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffirstbatchxyz%2Fdria-oracle-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffirstbatchxyz%2Fdria-oracle-sdk/lists"}