diff --git a/blog/2026-02-23.md b/blog/2026-02-23.md new file mode 100644 index 00000000000..bd3a340387c --- /dev/null +++ b/blog/2026-02-23.md @@ -0,0 +1,127 @@ +--- +title: Shade Agent Framework 2.0 +authors: [pivortex] +slug: shade-agent-framework-2.0 +tags: [updates, ai, shade-agents] +hide_table_of_contents: true +--- + +The biggest update to the Shade Agent Framework has been released since launch. It aims to enable more production-ready builds, a more flexible developer experience, and it comes with significant architectural changes. + +:::danger Upgrade immediately +The previous version of the Shade Agent Framework has **known critical vulnerabilities**. You should upgrade your agent to 2.0 as soon as possible. +::: + + + +## A Shift in Mental Model + +Shade Agent 2.0 is not a small iteration. It reflects a different way of building and deploying Shade Agents. + +**Previously**, the framework leaned on global, abstract agent contracts and a separate API service. That made early development straightforward but production use harder: you had less control over contract behavior, deployment was split across env vars and flags, and the API lived in its own Docker image. + +**In Shade Agent Framework 2.0**, the **Shade Agent API** is a single TypeScript library that runs **inside your agent’s codebase** instead of a separate service. The **agent contract** is included in your repo so you can change and extend it for your use case. The **CLI** is built around a single config file and has built-in credential management, making deploy and whitelist flows are predictable and easier to script. + +The result is a framework that’s easier to reason about, easier to customize, and better suited to production. Below is a summary of the main changes for the API, CLI, and agent contract, with links to the docs so you can get started. + +--- + +## Shade Agent API + +The Shade Agent API no longer offers multi-language support. It has been consolidated into a single **TypeScript/JavaScript** library (`@neardefi/shade-agent-js`) that runs within your agent’s codebase instead of a separate Docker image. + +### How the API Has Changed + +Previously, the API was a separate Docker image (and HTTP service); you called standalone functions that talked to that service. In 2.0, you create a client in your code and use it for everything. Registration and funding now explicit methods instead of automatic on boot. + +**Before (1.x):** No client—you installed the package and called functions that hit the API internally (or HTTP in other languages): + +```ts +import { agentAccountId, agent, agentCall, agentView } from '@neardefi/shade-agent-js'; +// API assumed to be running (Docker / localhost:3140); env vars for config +``` + +**After (2.0):** One client, created once with your config: + +```ts +import { ShadeClient } from "@neardefi/shade-agent-js"; + +const agent = await ShadeClient.create({ + networkId: "testnet", + agentContractId: process.env.AGENT_CONTRACT_ID, + sponsor: { accountId: process.env.SPONSOR_ACCOUNT_ID, privateKey: process.env.SPONSOR_PRIVATE_KEY }, + rpc: provider, +}); +// Then: await agent.register(), await agent.fund(0.3), etc. +``` + +**Account ID:** Same idea, different shape, you now use the client instance and get the value directly (no response object). + +```ts +// Before: const res = await agentAccountId(); const accountId = res.accountId +const accountId = agent.accountId(); +``` + +**Balance:** Balance is now a method on the client and returns human-readable NEAR (e.g. `1` = one NEAR), not yoctoNEAR. + +```ts +// Before: const res = await agent("getBalance"); const balance = res.balance // yoctoNEAR +const balance = await agent.balance(); // human-readable, e.g. 0.3 +``` + +**Call and view:** Call and view have stayed the same but are accessible via the client instance instead of a standalone function. + +```ts +// Before: agentCall({ methodName, args, gas }) / agentView({ methodName, args }) +const result = await agent.call({ + methodName: "example_call_function", + args: { arg1: "value1", arg2: "value2" }, + gas: BigInt("300000000000000"), + deposit: "0", +}); +const viewResult = await agent.view({ + methodName: "example_view_function", + args: { arg1: "value1" }, +}); +``` + +**Request signature:** The old API had a dedicated `requestSignature({ path, payload, keyType })` helper. In 2.0, this has been deprecated, now if you want to call a function of the contract called `request_signature`, call it like any other function: + +```ts +// Before: requestSignature({ path, payload, keyType }) +const result = await agent.call({ + methodName: "request_signature", + args: { path, payload, key_type }, + deposit: "1", +}); +``` + +New methods include `agent.register()`, `agent.fund()`, `agent.isWhitelisted()`, and `agent.getAttestation()` for explicit control over registration, funding, and attestation; see the API reference for details. + +To learn how to install, configure, and use the API, see the **[Shade Agent API reference](/ai/shade-agents/reference/api)**. + +--- + +## Shade Agent CLI + +The Shade Agent CLI had a **total revamp**. Instead of being configured with a mix of environment variables and flags, it now centers on a **single `deployment.yaml` file**, with built-in credential management and command routing, taking inspiration from the NEAR CLI. + +You run `shade auth` to configure NEAR and Phala credentials, then use the commands `shade deploy` to deploy your Shade Agent, `shade plan` to preview the deployment, and `shade whitelist` to whitelist an agent's account ID. The `deployment.yaml` file drives contract deployment (including from source or WASM), measurement and PPID approval, Docker image build and publish, and deployment to Phala Cloud, so all deployment options live in one place. + +To learn how to install the CLI, use each command, and configure `deployment.yaml`, see the **[Shade Agent CLI reference](/ai/shade-agents/reference/cli)**. + +--- + +## Agent Contract + +Previously, the framework used **global agent contracts** that were abstract and easy to start with, but made production development and customization difficult. In 2.0, by default, a reference agent contract is included in the `shade-agent-template` repo, so you can edit and extend it to your needs (e.g. custom agent-gated functions, guardrails, and initialization). + +The reference agent contract also now uses a more robust external library for attestation verification (the [shade-attestation crate](https://github.com/NearDeFi/shade-agent-framework/tree/main/shade-attestation)). Instead of approving the codehash of a single Docker image, the contract now requires you to approve a set of measurements for more in-depth verification and a list of PPIDs that set the physical hardware the agent can run on. Local mode now requires you to whitelist the account ID of the agent you want to run locally, blocking any other account ID from controlling the contract for more consistent behavior when testing. + +To walk through the contract flow, initialization, attestation verification, and how to add your own agent-gated functions, see the **[Agent Contract reference](/ai/shade-agents/reference/agent-contract)**. + +--- + +## Next Steps + +Start your migration by **cloning the template** in the [quickstart](/ai/shade-agents/getting-started/quickstart/deploying) to explore the new setup. diff --git a/docs/ai/shade-agents/concepts/framework-overview.md b/docs/ai/shade-agents/concepts/framework-overview.md index b5f78fdc6fe..cf3426a0d75 100644 --- a/docs/ai/shade-agents/concepts/framework-overview.md +++ b/docs/ai/shade-agents/concepts/framework-overview.md @@ -7,126 +7,43 @@ description: "Learn about the core components of the Shade Agent Framework with import { SigsSupport } from '@site/src/components/sigsSupport'; -The Shade Agent Framework provides a suite of tools designed to simplify the development and deployment of Shade Agents. The framework abstracts away the complexities of the underlying infrastructure, allowing developers to focus on building their agent logic. In this section, you'll explore the tooling provided by the framework and examine the key components you need when building an agent. +The **Shade Agent Framework** is a platform for creating Web3 agents and off-chain services that are **verifiable**, **trust-minimized**, and **decentralized**. It leverages **on-chain signing** to allow agents to hold assets and sign transactions on most blockchains and implement strict **guardrails** to prevent unauthorized actions. ---- - -## Templates, Languages, and Architecture - -### Templates - -When starting to build with the Shade Agent Framework, it's recommended to start by forking the [Quickstart Shade Agent Template](https://github.com/NearDeFi/shade-agent-template). This template contains all the necessary files to build a Shade Agent and provides the fastest starting path. - -Additional templates can be found in our [Tutorials and Templates](../tutorials/tutorials-overview.md) section. +It includes the **Shade Agent API**, the **Shade Agent CLI**, and an **agent contract reference implementation**. The framework aims to abstract most of the underlying TEE and blockchain interactions so you can focus on building your application. -### Supported Languages - -**TypeScript/JavaScript (Recommended)** -Agents are primarily written in TypeScript/JavaScript using `shade-agent-js`, which integrates seamlessly with [chainsig.js](../../../chain-abstraction/chain-signatures/implementation.md) for building multichain transactions and deriving multichain accounts. - -**Python** -The framework also supports `shade-agent-py`, which allows you to develop agents in Python. Here is an [example](https://github.com/NearDeFi/shade-python-example/tree/main). However, note that tooling for building multichain transactions and deriving multichain accounts is not currently available in Python, so additional development work will be required for multichain use cases. +--- -**Other Languages** -Agents can be written in any language, provided you can create a Docker image for the agent. To build a Shade Agent in other languages, you can use the API directly. Learn more about this approach on the [API page](../reference/api.md). +## Architecture Overview -### Architecture Overview +A **Shade Agent** has two main parts: the **agent** (off-chain) and the **agent contract** (on-chain). The agent is a backend service that runs in a TEE (or locally in dev) and holds your business logic; it uses the Shade Agent API to register and interact with the agent contract. The agent contract is a NEAR smart contract that decides who can act as an agent (via attestations, approved measurements, and PPIDs), enforces guardrails, and gives valid agents access to on-chain signing via chain signatures (MPC signing). One agent contract can have many registered agents - for example, several instances running the same code for redundancy, or different agents for different tasks. -A Shade Agent is essentially a `backend service` that uses the Shade Agent API and runs inside a Trusted Execution Environment (TEE) instead of on a classic server. You can develop using any backend framework you prefer, expose API routes, run cron jobs, or index events and respond to them with actions. +By default, agents are deployed to Phala Cloud, but you can deploy them to other TEE providers that support Dstack. --- ## Shade Agent API -The Shade Agent API abstracts away the complexity of TEE operations and agent contract interactions. For detailed information on how the API works and how to use it across different languages, please refer to the [API page](../reference/api.md). +The Shade Agent API is a **TypeScript/JavaScript** library that connects your agent to the Shade Agent Framework. It abstracts TEE complexity and simplifies calls to the agent contract. You can learn more about the Shade Agent API on the [API page](../reference/api.md). --- ## Shade Agent CLI -The Shade Agent CLI simplifies deploying a Shade Agent. To learn more about how the CLI works and how to use it, please refer to the [CLI page](../reference/cli.md). - ---- - -## Environment Variables - -Environment variables are a crucial component of the Shade Agent Framework. They configure your Shade Agent and are passed encrypted into your agent when it goes live. To learn more about configuring environment variables in your project, please refer to the [Environment Variables page](../reference/environment-variables.md). +The Shade Agent CLI makes it easy to deploy a Shade Agent. Including building and deploying your agent contract, building and publishing your agent's Docker image, and deploying the agent to Phala Cloud. You can learn more about the Shade Agent CLI on the [CLI page](../reference/cli.md). --- -## Agent Contract - -By default, the Shade Agent CLI will deploy a generic agent contract that implements the three core functions, `approve_codehash`, `register_agent`, and `request_signature`, discussed in the introduction. This generic agent contract works for many use cases since you can register any arbitrary agent and have it request signatures for any chain - it's very flexible. +## Agent Contract Reference Implementation -There are also cases when you should develop your own `custom agent contract`. These include, but are not limited to: -1) You want to implement strict `guard rails` that prevent malicious actions, even if the TEE is somehow compromised - Review our [security considerations](../concepts/security.md#restricting-actions) for more details -2) You want to implement a custom agent registration or code hash upgradability mechanism -3) You want to build an agent that just interacts with the NEAR blockchain - -Further documentation can be found in the [custom contract section](../reference/custom-agent-contract.md). +A walkthrough of the agent contract reference implementation is available on the [Agent Contract Reference Implementation page](../reference/agent-contract.md). It contains the fundamental agent contract logic which you can use as a starting point for your own agent contract. --- -## Phala Cloud - -Phala Cloud is a cloud solution that simplifies hosting applications and agents inside Trusted Execution Environments. The Shade Agent Framework uses Phala Cloud for agent deployment. You can deploy any standard Docker application to Phala. To learn more about Phala, visit their [documentation](https://docs.phala.network/phala-cloud/what-is/what-is-phala-cloud). - -Once your agent is deployed, you can manage the deployment from the [dashboard](https://cloud.phala.network/dashboard). - -To deploy an agent to production, you'll need a Phala Cloud account. You can create one [here](https://cloud.phala.network/register). - -After deploying to Phala Cloud, monitor your deployments and delete unused ones to avoid unnecessary costs. - ---- - -## Docker - -Docker is a platform that allows you to package an application into a self-contained environment. By creating a Docker image, you can run your agent in the TEE. An agent typically consists of two Docker images (the application and the Shade Agent API), but it can include more. When building Shade Agents, it's helpful to understand how Docker works. If you're interested in learning more about Docker, please visit the [documentation](https://docs.docker.com/get-started/docker-overview/). - -You'll need to set up Docker on your machine if you do not have it already, and create an account: -- Install Docker for [Mac](https://docs.docker.com/desktop/setup/install/mac-install/) or [Linux](https://docs.docker.com/desktop/setup/install/linux/) and create an account. -- Log in to Docker, using `docker login` for Mac or `sudo docker login` for Linux. - -There are two Docker-related files included in our project: the `Dockerfile` and the `Docker Compose` file. - -### Dockerfile - -The Dockerfile tells Docker how to build and run your image. The Shade Agent CLI automatically builds your Docker image using the Dockerfile and pushes it to Docker Hub, making it accessible over the internet. - -A standard Dockerfile will: -1. Start with a `base image`, which serves as the starting point for your application (e.g., Ubuntu, Alpine, Node.js, Python pre-installed) -2. Set the working directory -3. Install system dependencies -4. Add relevant files from the project to the image (in our examples, everything within the `source folder` is included, along with the `manifest file` that lists your dependencies like the package.json or pyproject.toml) -5. Install project dependencies -6. Build the project -7. Set the environment (production, development) -8. Tell Docker how to start the application - -In most cases, you can use the Dockerfile already supplied in the template without modification. - -Here are example Dockerfiles for a [Typescript](https://github.com/NearDeFi/shade-agent-template/blob/main/Dockerfile) and [Python](https://github.com/NearDeFi/shade-python-example/blob/main/Dockerfile) agent. - -You can learn more about the Dockerfile [here](https://docs.docker.com/reference/dockerfile/) - -### Docker Compose - -The Docker Compose file (docker-compose.yaml) defines which Docker images will be included within your agent. This file is what is actually uploaded to Phala Cloud to run your agent, which pulls the specified images on boot. The compose file also specifies which environment variables are passed to the images, whether images are exposed on ports, and other configuration details. - -The images used are automatically configured when you run the Shade Agent CLI. In most cases, you can use the Docker Compose file already supplied [in the template](https://github.com/NearDeFi/shade-agent-template/blob/main/docker-compose.yaml). However, if you want to include additional Docker images in your agent or use additional environment variables for your application, you'll need to edit the Docker Compose file. - -You can learn more about the Docker Compose file [here](https://docs.docker.com/reference/compose-file/) - ---- - -## Next Steps - Now that you have an overview of the framework, here are some great sections to explore next: -1. Framework components: [API](../reference/api.md), [CLI](../reference/cli.md), and [Environment Variables](../reference/environment-variables.md) -2. [Custom Contracts](../reference/custom-agent-contract.md) - build specialized agent contracts -3. [Plugins](../reference/plugins.md) - extend your agent's capabilities -4. [Tutorials and Templates](../tutorials/tutorials-overview.md) - get up and running with different Shade Agent architectures, and use cases as quickly as possible and learn how to build apps in full -4. [Security Considerations](../concepts/security.md) - check your agent abides by best practices - +1. Framework components: [API](../reference/api.md), [CLI](../reference/cli.md), and [Agent Contract Reference Implementation](../reference/agent-contract.md). +2. [Tutorials and Templates](../tutorials/tutorials-overview.md) - get up and running with different Shade Agent architectures and use cases as quickly as possible, and learn how to build apps in full. +3. [What can you build?](../concepts/what-can-you-build.md) - learn about the different types of applications you can build with Shade Agents. +4. [Terminology](../concepts/terminology.md) - learn the key terms and concepts used in the Shade Agent Framework. +5. [Security Considerations](../concepts/security.md) - check your agent abides by best practices. \ No newline at end of file diff --git a/docs/ai/shade-agents/concepts/security.md b/docs/ai/shade-agents/concepts/security.md index 3bfc93f31e9..12056a5d642 100644 --- a/docs/ai/shade-agents/concepts/security.md +++ b/docs/ai/shade-agents/concepts/security.md @@ -2,105 +2,111 @@ id: security title: Security Considerations sidebar_label: Security Considerations -description: "Learn key security practices when deploying Shade Agents, including duplicate actions, transaction restrictions, and RPC trust." +description: "Learn key security practices when deploying Shade Agents, including preventing duplicate actions, handling failed or unsent transactions, restricting API routes, removing agent contract keys, removing local deployment, approved measurements limits, public logs, storing agent keys, public PPIDs, fixed Docker images, trusting RPCs, and verifying the state." --- -:::warning -The Shade Agent Framework is experimental and contains known critical vulnerabilities. +import { SigsSupport } from '@site/src/components/sigsSupport'; -It must not be used in production or on mainnet and is intended solely for testing and non-critical use on testnet. +:::warning +The Shade Agent Framework has not yet undergone a formal audit. No representations or warranties are made regarding security, correctness, or fitness for any purpose. Use of this software is entirely at your own risk. - -A production-ready version of the framework is currently in development. ::: -import { SigsSupport } from '@site/src/components/sigsSupport'; - -Please review this list of security considerations before deploying a Shade Agent to Mainnet. - --- ## Restricting Actions -While TEEs are considered trusted and tamper-resistant, implementing tight restrictions or `guard rails` on agent actions within the agent contract is recommended so that even if the private key to a agent was extracted funds can't be withdrew. +While TEEs are considered trusted and tamper-resistant, implementing tight restrictions or **guardrails** on agent actions within the agent contract is recommended so that even in the event a TEE is compromised and the private key to an agent is extracted, funds can't be withdrawn. You can read more about guardrails [here](terminology.md#on-chain-guardrails). -Examples of restrictions could be: -- The agent contract can only build transactions for a list of functions and smart contract addresses. -- The agent contract can only build transactions for specific chains. -- The agent contract can only build transactions that swap or send up to 0.1 ETH per 24 hours. +--- + +## Preventing Duplicate Actions + +To ensure liveness, a Shade Agent should consist of multiple identical agents hosted by different providers/on different hardware. When multiple agents are running, all agents will respond to triggers (user inputs, cron jobs, API calls, etc.). You must ensure that the Shade Agent collectively performs the desired action only **once** in response to each update. -We recommend using the [omni-transactions-rs](https://github.com/near/omni-transaction-rs) library to build transactions within your agent contract rather than in the agent. +Consider a mindshare trading agent as an example. If Solana's mindshare increases relative to NEAR, the agent would swap SOL for NEAR. With two agents running, you must ensure this swap doesn't occur twice. -Another solution is for the Shade Agent's multichain accounts to not hold funds themselves, but the accounts to be a restricted admin on a contract on the target chain. +This logic is typically best implemented within the agent contract by only allowing one agent to perform the action at a time. --- -## Secure Data Centers +## Handling Failed or Unsent Transactions -With recent exploits of TEEs, such as TEE.fail, it’s important for TEEs to have physical security by running them in secure data centers. +A successful MPC signature on a transaction payload doesn't guarantee the transaction's success or transmission. Transactions may fail for various reasons, such as network congestion, incorrect nonce, or insufficient gas. + +It's suggested you build your agent in such a way that if the transaction fails, then a new signature can be requested without allowing for more signing for the same action when the transaction is successful. -In addition to verifying agent attestations in the smart contract, it’s recommended to only allow them to register as valid agents (via whitelisting account IDs) after verifying off-chain that they are running within secure data centers (like ones provided by Phala Cloud). Proof of Cloud https://proofofcloud.org/ is an initiative to verify TEEs are running in secure facilities. +For some use cases, it may be beneficial to emit signed transactions from your agent contract, allowing anyone or an indexer to relay them if your agent fails to retrieve the result. Signed transactions can be built using [omni-transactions-rs](https://github.com/near/omni-transaction-rs). Exercise caution with unsent signatures. --- -## Duplicate Actions +## Restricting API Routes -To ensure liveness, the Shade Agent should consist of multiple identical agents hosted by different providers/on different hardware. When multiple agents are running, all agents will respond to updates (user inputs, agent pings, API updates, etc.) or will create the same action whilst running on a cron. You must ensure that the Shade Agent collectively performs the desired action only `once` in response to each update. +In the quickstart, the agent can take an API request from anyone, allowing someone to drain the funds from the agent's account and the Ethereum Sepolia account through gas expenditure. If using API routes, you need to design your agent to only perform the action when the desired condition is met or implement authentication inside the route, for example, a user has signed an action with their wallet or they are logged in from their Google account. -Consider a Kaito Mindshare Trading Agent as an example. If Solana's mindshare increases relative to NEAR, the agent would swap SOL for NEAR. With two agents running, you must ensure this swap doesn't occur twice. +--- + +## Removing Agent Contract Keys + +Before deploying your agent contract to production, you should ensure that all **access keys** to the agent contract account have been removed. Otherwise, this would allow the access key owner to withdraw the funds held by the Shade Agent. This can be done using the CLI. -This logic is typically best implemented within the agent contract or a target smart contract being interacted with. +In the agent contract reference implementation, the contract code, approved measurements, and PPID can be updated by the owner. It's recommended that the owner be a **multisig**. --- -## Failed or Unsent Transactions +## Removing Local Deployment -A successful MPC signature on a transaction payload doesn't guarantee the transaction's success or transmission. Transactions may fail for various reasons, such as network congestion, incorrect nonce, or insufficient gas. +When deploying to production, it's recommended to remove the **local deployment flow** from the agent contract entirely. Strip out the code that supports local mode (whitelist checks, default measurements, and PPID for local, and any `requires_tee: false` branches) so the contract only accepts TEE attestations. That way, there is no way to misconfigure or re-enable local mode, and no code path that trusts a whitelist instead of attestation. -We suggest you build your agent in such a way that if the transaction fails, then a new signature can be requested without allowing for signing when the transaction is successful. +--- -For some use cases, it may be beneficial to emit signed transactions from your agent contract, allowing anyone or an indexer to relay them if your agent fails to retrieve the result. Signed transactions can be built using [omni-transactions-rs](https://github.com/near/omni-transaction-rs). Exercise caution with unsent signatures. +## Approved Measurements Limits + +The attestation verification process iterates over all approved measurements and verifies that the TEE's measurements match the approved measurements. If the approved measurements list grows too large, registration could fail due to the function call running into the **gas limit**. It's recommended to limit the number of approved measurements to a reasonable number. --- -## Parallel Transactions +## Public Logs + +By default, the Shade Agent CLI deploys the agent with **public logs** enabled. You should not emit any sensitive information in the logs when this is enabled. -Building on the above, the MPC signing a transaction payload doesn't change any nonce or state on the destination chain. So if you'd like to create an agent that can issue several parallel transactions, you will have to have an intimate knowledge of the destination chain and increment nonces for the derived accounts that you're generation signatures for. +--- -This can cause a lot of issues in the EVM world, for example: Transactions can get stuck in the mempool if the nonce used is not in sequential order. A transaction with a higher nonce will remain pending if a previous transaction (with a lower nonce) hasn't been processed. +## Storing Agent Keys -If your agent frequently tries to sign multiple transactions in parallel with the MPC, then you must keep track of which transactions are successful and handle failures appropriately so that all transactions eventually are included in blocks of the destination chain. +The agent's **ephemeral keys should not be stored** anywhere, including on the host machine. This could lead to code that is not approved in the contract accessing keys that are approved in the contract. --- -## Restricting Agent API Routes +## Public PPIDs -In the quickstart, our agent can take an API request from anyone. In a lot of cases, a Shade Agent will run on a loop responding to actions or data every set time period. If using API routes, you need to design your agent to only perform the action when the desired condition is met or do some sort of verification or authentication inside the route, for example, a user has signed an action with their wallet, or they are logged in from their Google account. +All PPIDs that are approved in the agent contract are made **public**. If you are using your own hardware, consider whether you are comfortable with its PPID being public since it could be used to track your hardware. --- -## Removing Agent Contract Keys +## Fixed Docker Images -Before deploying your agent contract to production, you should ensure that all access keys to the agent contract account have been removed. Otherwise, this would allow the access key owner to withdraw the funds held by the Shade Agent. It is best practice to implement an [upgrade mechanism](../../../tutorials/examples/update.md) that is controlled by a multisig or DAO. +Never reference Docker images by `latest` (e.g. pivortex/my-first-agent:latest) in your **Docker Compose** file; this can lead to different images being loaded in the TEE for the same measurements. Always reference versions of the image you want to use via **hash** (e.g. pivortex/my-first-agent@sha256:bf3faac9793f0fb46e89a4a4a299fad69a4bfd1e26a48846b9adf43b63cb263b). --- ## Trusting RPCs -Inside an agent, it is common to want to query the state of the blockchain and perform actions based on the state. Since RPCs can lie about the state of the blockchain and do not have crypto-economic security, we suggest you design your agent to defend against this. Below are some solutions, which solution you use will differ depending on your use case and the design of your agent: +Inside an agent, it's common to want to query the state of the blockchain and perform actions based on the state. Since **RPCs can lie** about the state of the blockchain and do not have crypto-economic security, it's suggested you design your agent to defend against this. Below are some solutions, which solution you use will differ depending on your use case and the design of your agent: -#### Verifying the State +### Verifying the State -In some cases, you will be able to submit the state back to the smart contract from which the state was queried and verify that it matches the actual state. For example, take a DAO on Ethereum that uses AI to vote on proposals. When a proposal goes live, the agent indexes the proposal, makes a decision on the proposal using an LLM, and then submits the yes/no decision back to the DAO. The agent should also submit a hash of the proposal back to the DAO, so the DAO can verify that the decision was made based on the true state of the blockchain. +In some cases, you will be able to submit the state back to the smart contract from which the state was queried and verify that it matches the actual state. For example, the verifiable DAO example submits a hash of the proposal back to the DAO, so the DAO can verify that the decision was made based on the true state of the blockchain. -#### Trustless Providers +### Trustless Providers -You can use RPC providers that leverage cryptographic proofs or run in TEEs themselves to know that the result is the true state of the blockchain. +You can use RPC providers that leverage cryptographic proofs or run in TEEs themselves to know that the result mirrors the true state of the blockchain. -#### Multiple Reputable Providers +### Multiple Reputable Providers -You can use multiple reputable RPC providers (like Infura and Alchemy) and check the result across each provider to make sure they match. - +You can use multiple reputable RPC providers and check the result across each provider to make sure they match. + + diff --git a/docs/ai/shade-agents/concepts/terminology.md b/docs/ai/shade-agents/concepts/terminology.md new file mode 100644 index 00000000000..968b24494ef --- /dev/null +++ b/docs/ai/shade-agents/concepts/terminology.md @@ -0,0 +1,109 @@ +--- +id: terminology +title: Terminology +sidebar_label: Terminology +description: "Learn the key terms and concepts used in the Shade Agent Framework." +--- + +Below are the main terms and concepts used in the Shade Agent Framework. + +--- + +## Shade Agent Framework + +The **Shade Agent Framework** is a platform for creating Web3 agents and off-chain services that are **verifiable**, **trust-minimized**, and **decentralized**. It leverages **on-chain signing** to allow agents to hold assets and sign transactions on most blockchains and implement strict **guardrails** to prevent unauthorized actions. + +It includes the **Shade Agent API**, the **Shade Agent CLI**, and an **agent contract reference implementation**. The framework aims to abstract most of the underlying TEE and blockchain interactions so you can focus on building your application. + +### Shade Agent + +A **Shade Agent** is an application built using the Shade Agent Framework. See [What can you build?](./what-can-you-build.md) for some examples. + +### Agent + +In the Shade Agent Framework, an agent is a single instance of the off-chain code running inside a **TEE** (or locally in development) that uses the Shade Agent API. One agent contract can have many registered agents: they may run the same code for redundancy or different code for different tasks. + +### Agent's Account + +The agent’s account is the NEAR account ID that represents that agent on-chain. It is an **implicit account** (64-character hex) derived from the agent's **ephemeral private key**, meaning the private key and account ID are unique to the agent, and change each time the agent reboots. In local mode, you can set the agent's account ID to be **deterministic** to avoid re-whitelisting or re-funding the agent on each run. + +### Agent Contract + +The agent contract is the on-chain **NEAR smart contract** that authorizes agents via attestations and approved measurements and PPIDs, enforces guardrails, and gives valid agents access to on-chain signing. + + +### On-Chain Guardrails + +On-chain guardrails are restrictions that are enforced on the agent contract to **prevent unauthorized actions** even if the TEE is compromised. Examples include limiting transactions to specific functions, smart contracts, blockchains, or amounts. Guardrails are usually implemented using the [omni-transaction-rs](https://github.com/Omni-rs/omni-transaction-rs) library. + +### On-Chain Signing + +The agent contract can sign transactions for **most chains** via NEAR's [Chain Signatures](../../../chain-abstraction/chain-signatures.md) service, which is accessed by making cross-contract calls to the **MPC contract**. All assets and state of the Shade Agent should be tied to the agent contract, not the agent's account, since agent keys are ephemeral. + +--- + +## Environment + +### TEE + +A **Trusted Execution Environment** (TEE) is a secure part of a CPU that runs code in an isolated and protected way. Execution and state stay private, including from the host. TEEs produce cryptographic attestations that prove it's running certain code inside a genuine TEE. + +### Local + +Local mode means the agent runs on your machine (or any non-TEE environment) instead of inside a TEE. There is no real attestation, and the contract uses a whitelist of allowed account IDs instead. Use local mode for development and testing only, not for production. + +--- + +## Registration + +### Registering an Agent + +An agent **registers** with an agent contract by calling the `register_agent` method, which verifies that it has a valid attestation. On successful registration, the agent will be stored in the contract's state with its **measurements**, **PPID**, and **validity period**. + +### Whitelisted Accounts + +The whitelist is a set of **NEAR account IDs** that are allowed to register when the agent contract is in **local mode**. Because the contract cannot verify code or hardware in local mode, it instead restricts access to specific account IDs. + +### Valid Agent + +A valid agent is one that is registered with the agent contract and still has measurements and a PPID that are approved, and its registration has not expired. Valid agents can call agent-gated methods. + +### Attestation + +An attestation is a cryptographic proof produced by a TEE that the application is running inside a genuine TEE. The agent submits its attestation when registering with the agent contract, and the contract verifies that it's a genuine attestation and checks that the attestation contains a set of approved measurements and an approved PPID. + +### Measurements + +The measurements are hashes that uniquely identify the code running in the TEE, and the platform it's running on. The agent contract stores a list of approved measurements, which can be updated by the owner of the contract. There are 6 measurements: +- **MRTD**: Measures the initial setup of the trusted domain. This is constant. +- **RTMR0**: Measures the virtual hardware. This is constant for a given number of vCPUs and memory allocation. +- **RTMR1**: Measures the kernel. This is constant. +- **RTMR2**: Measures the Dstack image version. This is constant for a given Dstack image version. +- **Key Provider Digest**: Measures the key provider of the TEE. By default, Shade Agents contain Phala's key providers but don't actually use it since it uses a Chain Signatures for decentralized key management instead. This is constant for Phala's key provider. +- **App Compose Hash**: Measures the application. This is constant for a given Docker Compose file and app layer configurations. + +### PPID + +The PPID (Provisioning Platform ID) is a unique identifier of a **physical TEE machine**. Recent exploits of TEEs have been due to attackers having physical access to the machine, revealing that the physical location of the machine is important in TEE security. By setting approved PPIDs, the agent contract can ensure that only agents running on specific machines can register. You should approve PPIDs for machines known to be located in secure data centers. By default, the CLI approves all PPIDs for Phala Cloud. + +Note that on Phala Cloud, two different deployments can have the same PPID if they are running on the same server, since resources are virtualized. + +--- + +## Docker + +Docker is used in the Shade Agent Framework to deploy agents to TEEs. + +- The **Dockerfile** defines how to build a single image for your agent (dependencies, entrypoint, etc.). The CLI uses it when building the image. +- The **Docker image** is a single packaged application for your agent. +- The **Docker Compose file** defines the full application stack of the agent that runs in the TEE. It defines the images for the agent, the allowed environment variables, ports, volumes, etc. + +--- + +## Phala Cloud + +Phala Cloud is a cloud provider for hosting applications inside Trusted Execution Environments. The Shade Agent Framework uses it as its default hosting provider for agents. + +### DStack + +DStack is a framework for running and proving applications inside of Trusted Execution Environments that Phala Cloud uses. The Shade Agent Framework only supports Dstack environments either on Phala Cloud, your own hardware, or other providers. \ No newline at end of file diff --git a/docs/ai/shade-agents/concepts/using-ai.md b/docs/ai/shade-agents/concepts/using-ai.md new file mode 100644 index 00000000000..7620f15bbda --- /dev/null +++ b/docs/ai/shade-agents/concepts/using-ai.md @@ -0,0 +1,22 @@ +--- +id: ai-inference +title: AI Inference +sidebar_label: AI Inference +description: "Learn how to use AI with Shade Agents." +--- + +Your agent can call AI inference in two main ways; they have different trust assumptions and privacy guarantees. + +--- + +### NEAR AI Cloud + +NEAR AI Cloud provides **verifiable private inference** using TEEs. You get cryptographic proof that inputs stayed private and that the output was produced by the intended model. If you use NEAR AI Cloud, you should verify the TEE attestations in your agent. + +You can learn more about NEAR AI Cloud [here](https://docs.near.ai/cloud/private-inference). + +--- + +### Other Inference Providers + +You can use other inference providers like OpenAI, Anthropic, etc. However, you need to place a certain level of trust in the provider that the inputs remain private and the output was produced by the intended model. diff --git a/docs/ai/shade-agents/concepts/what-can-you-build.md b/docs/ai/shade-agents/concepts/what-can-you-build.md index 0f72cfd1d97..720851bedbc 100644 --- a/docs/ai/shade-agents/concepts/what-can-you-build.md +++ b/docs/ai/shade-agents/concepts/what-can-you-build.md @@ -14,7 +14,7 @@ Shade Agents are: - **Verifiable** - Agent code is known and executes as expected; no one can tamper with the agent. -- **Multichain** - Can hold any crypto asset and sign transactions on any chain. +- **Multichain** - Can hold any crypto asset and sign transactions on most chains. - **AI Powered** - Can verifiably access LLMs. @@ -47,7 +47,7 @@ Since Shade Agents can access off-chain data and APIs, they make great cheap, fl --- -## Smart Contracts using LLMs +## Smart Contracts Using LLMs Shade Agents allow you to access LLMs from a smart contract that lives on any chain. The LLM and agent are both running in a TEE, so one can verify that the response from the agent is actually from an LLM and its response is a function of the provided inputs. diff --git a/docs/ai/shade-agents/getting-started/introduction.md b/docs/ai/shade-agents/getting-started/introduction.md index 0f9ef265228..4aa42a45824 100644 --- a/docs/ai/shade-agents/getting-started/introduction.md +++ b/docs/ai/shade-agents/getting-started/introduction.md @@ -5,27 +5,23 @@ sidebar_label: What are Shade Agents? description: "Learn about Shade Agents - decentralized and trustless AI agents that control accounts and assets across multiple blockchains using TEEs and NEAR's decentralized key management." --- -:::warning -The Shade Agent Framework is experimental and contains known critical vulnerabilities. +import { SigsSupport } from '@site/src/components/sigsSupport'; -It must not be used in production or on mainnet and is intended solely for testing and non-critical use on testnet. +:::warning +The Shade Agent Framework has not yet undergone a formal audit. No representations or warranties are made regarding security, correctness, or fitness for any purpose. Use of this software is entirely at your own risk. - -A production-ready version of the framework is currently in development. ::: -import { SigsSupport } from '@site/src/components/sigsSupport'; - -The Shade Agent Framework allows developers to build decentralized and trustless AI agents that control accounts and assets across multiple blockchains. +The **Shade Agent Framework** is a platform for creating Web3 agents and off-chain services that are **verifiable**, **trust-minimized**, and **decentralized**. It leverages **on-chain signing** to allow agents to hold assets and sign transactions on most blockchains and implement strict **guardrails** to prevent unauthorized actions. Previous Web3 agents fall into one of two categories: -1. They are trustless and verifiable by using a trusted execution environment (TEE), but if the TEE goes down, the private keys and funds of the agent are lost. +1. They are trustless and verifiable by using a **trusted execution environment (TEE)**, but if the TEE goes down, the private keys and funds of the agent are lost. 2. The agent’s accounts are persistent, but the agents are centralized. -Shade Agents provide verifiability and non-custody by operating in TEEs, but also persistent control of accounts by using NEAR's decentralized key management. Any instance of an agent running the same code inside a TEE can access the same accounts meaning you don't need to worry about private keys being lost or exposed. +Shade Agents provide verifiability and non-custody by operating in **TEEs**, but also persistent control of accounts by using NEAR's **decentralized key management**. Any instance of an agent running the same code inside a TEE can access the same accounts, meaning you don't need to worry about private keys being lost or exposed. -Thanks to combining TEEs with the NEAR tech stack, Shade Agents can autonomously sign transactions across any chain, interact with AI models and external data sources, manage assets, and perform privacy-preserving, verifiable computations, offering the flexibility and performance of Web2 with the verifiability of Web3. +Thanks to combining TEEs with the NEAR tech stack, Shade Agents can sign transactions across most chains, interact with AI models and external data sources, manage assets, and perform privacy-preserving, verifiable computations, offering the flexibility and performance of Web2 with the verifiability of Web3. :::info Shade Agents power [Agentic Protocols](../concepts/what-can-you-build.md#agentic-protocols): a new type of decentralized application designed to be autonomous, proactive, and intelligent. @@ -33,73 +29,77 @@ Shade Agents power [Agentic Protocols](../concepts/what-can-you-build.md#agentic --- -## How do Shade Agents work? +## How Do Shade Agents Work? -Shade Agents consist of two main components: the `agent` and the `agent smart contract`. +Shade Agents consist of two main components: the **agent** and the **agent smart contract**. ![Shade Agent Architecture](/assets/docs/ai/shade-agent-stack-diagram.png) -When an agent is booted up in a TEE, the `TEE's hardware-based entropy` generates a random private key and account. This private key is exclusively used to call the agent contract, not for storing funds. +When an agent is booted up in a TEE, it generates a random **ephemeral private key** and **NEAR account**. This private key is exclusively used to call the agent contract, not for storing funds.
What is a TEE? -A trusted execution environment is a secure area of a CPU that runs code in an isolated and protected way. This means one can verify that the expected code is running and its execution is not exposed outside of the enclave. TEEs produce attestations to prove that the code is running within a TEE and that it's running the specified code. +A trusted execution environment is a secure part of a CPU that runs code in an isolated and protected way. Execution and state stay private, including from the host. TEEs produce cryptographic attestations that prove it's running certain code inside a genuine TEE.
-The agent calls the `register_agent` function on the `agent smart contract`, providing two pieces of information generated inside the TEE: -- A `remote attestation quote` (which proves it is running inside a genuine TEE). -- The Docker image's SHA256 `code hash` (to prove that the expected code is running). +The agent calls the `register_agent` function on the **agent smart contract**, providing its **attestation**. The attestation contains: +- A proof that it's running inside a **genuine TEE**. +- The [measurements](../concepts/terminology.md#measurements) of the code running in the TEE (which uniquely identifies the code and platform it's running on). -If the attestation quote is valid and the code hash matches the expected code hash of the agent (defined during the agent contract's deployment), the agent's account is approved as a valid agent inside the agent contract. +If the attestation is valid, the measurements fit the approved measurements in the contract, and it's running on a certain machine (identified by a [PPID](../concepts/terminology.md#ppid)), then the agent's account is registered inside the agent contract. -Once registered, the `agent` can call the `request_signature` function on the agent contract, enabling it to sign transactions on behalf of the Shade Agent. `request_signature` leverages [chain signatures](../../../chain-abstraction/chain-signatures.md) for decentralized key management, allowing the Shade Agent to hold assets and sign transactions on nearly any chain. +Once registered, the **agent** can call the agent-gated functions on the agent contract. An example of this is the `request_signature` function, enabling it to sign transactions on behalf of the Shade Agent. `request_signature` leverages [chain signatures](../../../chain-abstraction/chain-signatures.md) for decentralized key management, allowing the Shade Agent to hold assets and sign transactions on nearly any chain. -`Anyone` can deploy the same Docker image of the `agent` to a different TEE. Since the Docker image will have the same code hash, it can then be registered as a new valid agent, and thus gain access to signing transactions using the Shade Agent's accounts. This means the accounts are persisted across different TEE instances. To facilitate this functionality, agents are designed to be stateless. +If **anyone** deploys the same code to a different TEE with the same measurements and PPID, it can also register in the contract, and thus gain access to signing transactions using the Shade Agent's accounts. This means the accounts are persisted across different TEE instances. To facilitate this functionality, agents are designed to be stateless. --- ## Agent Contract Functions -The Agent Contract has three main functions: +The Agent Contract has four main functions: -#### Approve Code Hash +#### Approve Measurements -After the contract is deployed, a `code hash` is set to ensure that only agents running the correct code (i.e. it has the same code hash) can be registered in the agent contract. +After the contract is deployed, a set of **measurements** is set to ensure that only agents running the correct code (i.e. it has the same measurements) can be registered in the agent contract. -Developers or protocols may need to modify the code running inside agents over time. Because of this, when the contract is initialized an `owner` account ID is set. Only the owner can approve a new `code hash`. +Developers or protocols may need to modify the code running inside agents over time. Because of this, when the contract is initialized, an **owner** account ID is set. Only the owner can approve a new set of **measurements**. -The `shade-agent-cli` handles the deployment of the agent contract and automatically approves the code hash of your agent. +The **Shade Agent CLI** handles the deployment of the agent contract and automatically approves the measurements of your agent. :::tip -Upgradeability can be designed for the specific use case. Common upgrade methods include approving a new code hash through DAO voting or implementing a grace period or cool down, allowing users to withdraw funds if they're uncomfortable with the incoming code hash for the new agent. +Upgradeability can be designed for the specific use case. Common upgrade methods include approving a new set of measurements through DAO voting or implementing a grace period or cool down, allowing users to withdraw funds if they're uncomfortable with the incoming measurements for the new agent. ::: +#### Approve PPIDs + +Similar to how measurements are approved, the owner also approves a set of **PPIDs** to ensure that only agents running on specific machines can register. + #### Register Agent -The `register_agent` function verifies that the agent is running in a TEE and executing the expected code (as defined by the approved code hash). Upon successful verification, the agent's account ID becomes registered and gains access to transaction signing (request_signature). +The `register_agent` function verifies that the agent is running in a TEE, is executing the expected code (as defined by the approved measurements), and is running on a certain machine (as defined by the approved PPIDs). Upon successful verification, the agent's account ID becomes registered and gains access to agent-gated functions. -The `shade-agent-api` automatically registers the agent when booting up in the TEE. +The **Shade Agent API** makes it easy to register; just use the `agent.register()` method. #### Request Signature -The `request_signature` function serves as the gateway to access the Shade Agent's multichain accounts and sign transactions. It employs `method access control` so that only registered agents can use this function. +The `request_signature` function serves as the gateway to access the Shade Agent's multichain accounts and sign transactions. It employs **method access control** so that only registered agents can use this function. :::tip -Developers should not sign transactions from the agents themselves (except for functions on the agent contract) as these accounts will be lost if the agent goes down. The magic of Shade Agents is that the multichain accounts are tied to the agent contract, which are persistent and accessible by any instance of a valid agent. +Developers should not sign transactions from the agents themselves (except for functions on the agent contract), as these accounts will be lost if the agent goes down. The magic of Shade Agents is that the multichain accounts are tied to the agent contract, which are persistent and accessible by any instance of a valid agent. ::: -The request signature function accepts three arguments: +The `request_signature` function accepts three arguments: - The transaction `payload` - a hash of the transaction to be signed. -- The `derivation path` - a string that modifies the address on the target chain being used. Shade Agents can access a near-unlimited number of accounts, and the account being used can be changed by modifying the path. The same path will always map to the same account for a given agent contract. -- The `key version` - sets the signature scheme required for the transaction. Shade Agents can sign transactions for any blockchain using the `secp256k1` and `ed25519` signature schemes (EVM, Bitcoin, Solana, Sui, XRP, etc.). +- The derivation `path` - a string that modifies the address on the target chain being used. Shade Agents can access a near-unlimited number of accounts, and the account being used can be changed by modifying the path. The same path will always map to the same account for a given agent contract. +- The `key_type` - sets the signature scheme required for the transaction. Shade Agents can sign transactions for any blockchain using the `secp256k1` and `ed25519` signature schemes (EVM, Bitcoin, Solana, Sui, XRP, etc.). -The `shade-agent-api` exposes the `requestSignature` function to sign transactions on behalf of the Shade Agent within your agent. +The **Shade Agent API** exposes the `agent.call()` method to sign transactions on behalf of the Shade Agent within your agent. :::tip -Within agent gated functions, you can implement an additional layer of security to strictly limit the Shade Agent's actions. For example, it could be restricted to only create transactions for Solana, perform swaps but not transfers, or transfer a maximum of 1 ETH per day. +`request_signature` is only an example of an agent-gated function. You can implement any function you want on the agent contract. It's recommended to implement [on-chain guardrails](../concepts/terminology.md#on-chain-guardrails) to prevent unauthorized actions even in the case of a compromised TEE. ::: --- @@ -108,9 +108,7 @@ Within agent gated functions, you can implement an additional layer of security The agent is just a backend service that runs inside a TEE instead of a centralized server. You can run the agent on an internal cron job, respond to actions, or it can expose API routes that can be called. -Agents can be written in virtually any programming language and use any framework, as long as you can build a `Docker image` for your program. - -If you require a custom agent contract, which not all use cases do, then these are written in Rust. +Agents are written in TypeScript/JavaScript using the **Shade Agent API**, and agent contracts are written in Rust. --- diff --git a/docs/ai/shade-agents/getting-started/quickstart/components.md b/docs/ai/shade-agents/getting-started/quickstart/components.md index c026acc4017..b82847b8621 100644 --- a/docs/ai/shade-agents/getting-started/quickstart/components.md +++ b/docs/ai/shade-agents/getting-started/quickstart/components.md @@ -10,74 +10,118 @@ import { SigsSupport } from '@site/src/components/sigsSupport'; In this section, we'll explore the main components of the [quickstart template](https://github.com/NearDeFi/shade-agent-template) to understand how to develop a Shade Agent. We'll also look at how to modify the template to build an agent for your use case. - --- ## Template Structure -The template we're using is a simple Shade Agent built with Hono and written in TypeScript that acts as a verifiable ETH price oracle. It takes prices from two different APIs, takes the average, and then pushes the price to an Ethereum contract. The template also comes with a frontend to make it easier to interact with the Shade Agent. +The template we're using is a simple Shade Agent built with Hono and written in **TypeScript** that acts as a verifiable ETH price oracle. It takes prices from two different APIs, takes the average, and then pushes the price to an Ethereum contract. + +The agent has three main files: +1) [**index.ts**](https://github.com/NearDeFi/shade-agent-template/tree/main/src/index.ts) - This is the entry point that sets up the **Shade Agent Client**, **registers** the agent and defines the routes for the agent. We'll review this file in more detail in the next section. +2) [**transaction**](https://github.com/NearDeFi/shade-agent-template/tree/main/src/routes/transaction.ts) - This is where the core logic of the agent is defined. When this API is called, the agent will build a transaction payload and request a signature from the agent contract. We'll look deeper into this API route later on this page. +3) [**agentInfo**](https://github.com/NearDeFi/shade-agent-template/tree/main/src/routes/agentInfo.ts) - This API simply fetches the agent's NEAR account ID and its balance by using the `agent.accountId()` and `agent.balance()` methods from the `shade-agent-js` library. +4) [**ethAccount**](https://github.com/NearDeFi/shade-agent-template/tree/main/src/routes/ethAccount.ts) - This API returns the **Ethereum Sepolia account** that the Shade Agent uses to update the price of Ethereum in the Sepolia contract. This API is used so the user knows which account to fund for gas. + +The repo also contains an **agent contract**. We won't review the agent contract as it's the same as the reference implementation [featured here](../../reference/agent-contract.md), but we encourage you to review the reference implementation after this section. + +--- + +## Registering the Agent + +First, in the [index.ts](https://github.com/NearDeFi/shade-agent-template/tree/main/src/index.ts) file, the **Shade Agent Client** is **initialized**. + +The client is initialized with the following arguments: +- `networkId` is set to `testnet` since the agent contract was deployed to testnet. +- `agentContractId` is set to the agent contract ID and is fetched from the environment variables. +- `sponsor` is set to the sponsor account details from the environment variables. It is used later to fund the agent. +- `derivationPath` is set to the sponsor's private key from the environment variables. For local deployment, this derives a deterministic account ID for the agent, making testing easier (for TEE deployment, this does nothing as ignored). The derivation path needs to be random and private; a private key fulfills this criterion well. + + -The project has three different APIs: -1) [**agentAccount**](https://github.com/NearDeFi/shade-agent-template/blob/main/src/routes/agentAccount.ts) - This API simply fetches the agent's NEAR account ID and its balance by using the `agentAccountId` and `agent("getBalance")` functions from the `shade-agent-js` library. -2) [**ethAccount**](https://github.com/NearDeFi/shade-agent-template/blob/main/src/routes/ethAccount.ts) - This API returns the `Ethereum Sepolia account` that the Shade Agent uses to update the price of Ethereum in the Sepolia contract. This API is used so the user knows which account to fund for gas. -3) [**transaction**](https://github.com/NearDeFi/shade-agent-template/blob/main/src/routes/transaction.ts) - This is where the core logic of the agent is defined. When this API is called, the agent will build and sign a transaction. We'll look deeper into this API route in the next part. +Next, the agent is **funded** with 0.3 NEAR via the `sponsor` account using the `agent.fund()` method. This is done to ensure the agent has enough NEAR to pay for gas when sending transactions. + + + +After this, the agent **registers** itself with the agent contract. To make it easier for local deployment, a loop is started that checks if the agent is whitelisted; if not, it will wait for 10 seconds and try again until it's whitelisted, at which point the agent will register. + + + +Since registrations expire (every 7 days by default), an interval is set to **re-register** the agent every 6 days. + + + +The agent is now registered and ready to sign transactions. --- ## Signing Transactions -In the [transaction API Route](https://github.com/NearDeFi/shade-agent-template/blob/main/src/routes/transaction.ts), the `requestSignature` function from the `shade-agent-js` library is used to sign a transaction. +In the [transaction API Route](https://github.com/NearDeFi/shade-agent-template/tree/main/src/routes/transaction.ts), the `agent.call()` method from the `shade-agent-js` library is used to call a function on the agent contract. -In this example, we're signing a transaction to call an Ethereum contract to update the stored price of ETH. First, we retrieve the price of ETH (in this example, the function queries two different APIs and calculates the average). +In this example, the agent is calling the `request_signature` function on the agent contract. This function takes a transaction payload for nearly any blockchain and requests a signature via [Chain Signatures](../../../../chain-abstraction/chain-signatures/implementation.md). Here, we're signing a transaction to call an Ethereum contract to update the stored price of ETH. First, we retrieve the price of ETH (in this example, the function queries two different APIs and calculates the average). - -Next, we build the `transaction payload` to be signed. To do this, we're using the `chainsig.js` library. +Next, we build the **transaction payload** to be signed. To do this, we're using the `chainsig.js` library. Using this library, we: -1. `Derive the Ethereum address` that will be sending the transaction. This function takes the agent contract account ID since this is the predecessor account that is calling the Chain Signatures [MPC contract](https://github.com/Near-One/mpc/tree/main/libs/chain-signatures/contract), and a path. The path can be whatever string you like, different paths will derive different addresses. +1. **Derive the Ethereum address** that will be sending the transaction. This function takes the agent contract account ID since this is the predecessor account that is calling the Chain Signatures [MPC contract](https://github.com/Near-One/mpc/tree/main/libs/chain-signatures/contract), and a path. The path can be whatever string you like; different paths will derive different addresses. 2. Create the `data`. This is what action we're performing, in this case, a function call to update the price in the contract. -3. `Build the transaction and the transaction payload` by inputting the derived address, the target Ethereum smart contract, and the data. +3. **Build the transaction and the transaction payload** by inputting the derived address, the target Ethereum smart contract, and the data. - + -Once we have the payload (also known as the hash), we can call the `requestSignature` function to sign the transaction. We specify the `keyType` as `Ecdsa` as we're signing for a blockchain that uses the `secp256k1` signature scheme. +Once we have the payload (also known as the hash), we can call the `request_signature` function on the agent contract to sign the transaction. We specify the `keyType` as `Ecdsa` as we're signing for a blockchain that uses the **secp256k1** signature scheme. - + -The result is the `signature`. +The result is the **signature**. We then attach the signature to the Ethereum transaction and broadcast it to the target network. - + --- -## Using Different Chains +## Modifying This Template + +### Using Different Chains -We set up a chain adapter for Ethereum Sepolia in the [Ethereum.ts](https://github.com/NearDeFi/shade-agent-template/blob/main/src/utils/ethereum.ts) file using the `chainsig.js` library. This library allows us to easily construct transaction payloads to be signed by the agent. +We set up a **chain adapter** for Ethereum Sepolia in the [Ethereum.ts](https://github.com/NearDeFi/shade-agent-template/tree/main/src/utils/ethereum.ts) file using the `chainsig.js` library. This library allows us to easily construct transaction payloads to be signed by the agent. - -You can set up chain adapters for a variety of chains, including EVM, Bitcoin, NEAR, Solana, SUI, XRP, Cosmos, and more to allow your agent to interact with multiple different chains. You can see a full list of the chains currently supported [here](https://github.com/NearDeFi/chainsig.js/tree/main?tab=readme-ov-file#supported-chains), but feel free to contribute any chain that is not yet supported. +You can set up chain adapters for a variety of chains, including NEAR, EVM, Bitcoin, Solana, SUI, XRP, and Cosmos, to allow your agent to interact with multiple different chains. You can see a full list of the chains currently supported [here](https://github.com/NearDeFi/chainsig.js/tree/main?tab=readme-ov-file#supported-chains), but feel free to contribute any chain that is not yet supported. + +Implementation details differ slightly from chain to chain; as such, we recommend you review our [chain signature docs](../../../../chain-abstraction/chain-signatures/implementation.md). Note that step 3 of requesting a signature is different; we use the `agent.call()` method from `shade-agent-js` instead. + +If you are using a chain that uses the **ed25519** signature scheme (NEAR, Solana, SUI, Aptos, etc.), you should specify the `keyType` as `Eddsa` when calling `request_signature`. -Implementation details differ slightly from chain to chain; as such, we recommend you review our [chain signature docs](../../../../chain-abstraction/chain-signatures/implementation.md). Note that step 3 of requesting a signature is different; we use the `requestSignature` function from `shade-agent-js` instead. +### Implementing Guardrails -If you are using a chain that uses the `ed25519` signature scheme (NEAR, Solana, SUI, Aptos, etc.), you should specify the `keyType` as `Eddsa` when calling `requestSignature`. +As you move into production, it's recommended to implement on-chain guardrails in your agent contract to prevent malicious actions even if the TEE is compromised. You can read more about guardrails [here](../../concepts/terminology.md#on-chain-guardrails). --- ## Next Steps -Now that you've explored the basics of Shade Agents, we recommend diving deeper into the [framework overview](../../concepts/framework-overview.md) to understand the core concepts needed for building production-ready Shade Agents. +Now that you've explored the basics of Shade Agents, we recommend diving deeper into the [framework overview](../../concepts/framework-overview.md) to understand the core components for building production-ready Shade Agents. \ No newline at end of file diff --git a/docs/ai/shade-agents/getting-started/quickstart/deploying.md b/docs/ai/shade-agents/getting-started/quickstart/deploying.md index 64f7b5aee11..34f708d95dc 100644 --- a/docs/ai/shade-agents/getting-started/quickstart/deploying.md +++ b/docs/ai/shade-agents/getting-started/quickstart/deploying.md @@ -5,87 +5,79 @@ sidebar_label: Deploying an Agent description: "Learn how to quickly deploy your first Shade Agent." --- -:::warning -The Shade Agent Framework is experimental and contains known critical vulnerabilities. - -It must not be used in production or on mainnet and is intended solely for testing and non-critical use on testnet. - -No representations or warranties are made regarding security, correctness, or fitness for any purpose. Use of this software is entirely at your own risk. - -A production-ready version of the framework is currently in development. -::: - import { TryDemo } from '@site/src/components/TryDemo'; import { SigsSupport } from '@site/src/components/sigsSupport'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -In this section, we'll walk you through deploying a Shade Agent. The Shade Agent Framework abstracts the complexities of creating a agent by removing TEE specific code and handling the deployment of the agent contract under hood. +:::warning +The Shade Agent Framework has not yet undergone a formal audit. -The [template](https://github.com/NearDeFi/shade-agent-template) we're using is a simple Shade Agent built with Hono and written in TypeScript that acts as a verifiable ETH price oracle. It fetches the price of Eth from two different APIs, takes the average, and then pushes the price to an Ethereum contract. +No representations or warranties are made regarding security, correctness, or fitness for any purpose. Use of this software is entirely at your own risk. +::: - +In this section, we'll walk you through **deploying** a Shade Agent. + +The [template](https://github.com/NearDeFi/shade-agent-template) we're using is a simple Shade Agent built with Hono and written in **TypeScript** that acts as a verifiable ETH price oracle. It fetches the price of Eth from two different APIs, takes the average, and then pushes the price to an Ethereum contract. We'll cover two deployment scenarios: 1. **Local Development**: Running the agent locally for rapid testing and development. 2. **TEE Deployment**: Running the agent in a real Trusted Execution Environment (TEE). -On the [next page](./components.md), you'll see how to edit this agent for your specific use case. +On the [next page](./components.md), you'll see how the key components of the agent work and how to edit this agent for your specific use case. --- ## Prerequisites -- Install NEAR and Shade Agent tooling: +- Install the **Shade Agent CLI**: ```bash - # Install the NEAR CLI - curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/near-cli-rs/releases/latest/download/near-cli-rs-installer.sh | sh - - # Install the Shade Agent CLI npm i -g @neardefi/shade-agent-cli ``` -- Create a `NEAR testnet account` and record the account name and `seed phrase`: - - ```bash - export ACCOUNT_ID=example-name.testnet - near account create-account sponsor-by-faucet-service $ACCOUNT_ID autogenerate-new-keypair save-to-keychain network-config testnet create - ``` +- Set up **Docker** if you have not already: - replacing `example-name.testnet` with a unique account Id. + - **Install** Docker for [Mac](https://docs.docker.com/desktop/setup/install/mac-install/) or [Linux](https://docs.docker.com/desktop/setup/install/linux/) and create an account. -- Set up Docker if you have not already: + - **Log in** to Docker, using `docker login` for Mac or `sudo docker login` for Linux. - - Install Docker for [Mac](https://docs.docker.com/desktop/setup/install/mac-install/) or [Linux](https://docs.docker.com/desktop/setup/install/linux/) and create an account. - - - Log in to Docker, using `docker login` for Mac or `sudo docker login` for Linux. - -- Set up a free Phala Cloud account at https://cloud.phala.network/register, then get an API key from https://cloud.phala.network/dashboard/tokens. +- Set up a free **Phala Cloud** account at https://cloud.phala.network/register, then get an API key from https://cloud.phala.network/dashboard/tokens.
What is a Phala Cloud -Phala Cloud is a cloud service that supports hosting applications in a TEE. It makes it easy to run an agent in TEE. +Phala Cloud is a cloud service that supports hosting applications in TEEs. It makes it easy to run an agent in TEE.
--- -## Set up +## Set Up -- First, `clone` the [template](https://github.com/NearDeFi/shade-agent-template). +- First, **clone** the [template](https://github.com/NearDeFi/shade-agent-template): ```bash git clone https://github.com/NearDeFi/shade-agent-template cd shade-agent-template ``` -- Rename the `.env.development.local.example` file name to `.env.development.local` and configure your environment variables. +- Set up **NEAR** and **Phala** credentials in the CLI: + + ```bash + shade auth set all testnet create-new + ``` + +- Set a unique `agent_contract.contract_id` (e.g. example-contract-123.testnet) and fill in your `build_docker_image.tag` (e.g. pivortex/my-first-agent) in the `deployment.yaml` file. + +- Create a `.env` file and configure your environment variables. + +```env +AGENT_CONTRACT_ID= Set this to the agent contract ID you set in the deployment.yaml file +SPONSOR_ACCOUNT_ID= Set this to the NEAR account ID generated by the CLI +SPONSOR_PRIVATE_KEY= Set this to the private key generated by the CLI +``` - Start up Docker: @@ -111,7 +103,7 @@ Phala Cloud is a cloud service that supports hosting applications in a TEE. It m -- Install dependencies +- Install dependencies: ```bash npm i @@ -121,17 +113,17 @@ Phala Cloud is a cloud service that supports hosting applications in a TEE. It m ## Local Development -- Make sure the `NEXT_PUBLIC_contractId` prefix is set to `ac-proxy.` followed by your NEAR accountId. +- Make sure `environment` is set to `local` in the `deployment.yaml` file. - In one terminal, run the Shade Agent CLI: ```bash - shade-agent-cli + shade deploy ``` - The CLI on Linux may prompt you to enter your `sudo password`. + On Linux, the CLI may prompt you to enter your **sudo password**. -- In another terminal, start your app: +- Then, start your app: ```bash npm run dev @@ -139,47 +131,55 @@ Phala Cloud is a cloud service that supports hosting applications in a TEE. It m Your app will start on http://localhost:3000 +- Lastly, you need to **whitelist** the agent in the agent contract (only needed for local development). In another terminal, run: + + ```bash + shade whitelist + ``` + + Enter the agent account ID displayed when starting the app. + --- ## TEE Deployment -- Change the `NEXT_PUBLIC_contractId` prefix to `ac-sandbox.` followed by your NEAR accountId. +- Change the `environment` to `TEE` in the `deployment.yaml` file. - Run the Shade Agent CLI ```bash - shade-agent-cli + shade deploy ``` - The CLI on Linux may prompt you to enter your `sudo password`. + The CLI on Linux may prompt you to enter your **sudo password**. - The last `URL` the CLI outputs is the URL of your app. If your application is not working, head over to your App on the Phala Dashboard and review the logs. +The CLI will output the URL of your app. - After deploying to Phala Cloud, monitor your deployments and delete unused ones to avoid unnecessary costs. You can manage your deployments from the[dashboard](https://cloud.phala.network/dashboard). +After deploying to Phala Cloud, monitor your deployments and delete unused ones to avoid unnecessary costs. You can manage your deployments from the[dashboard](https://cloud.phala.network/dashboard). --- ## Interacting with the Agent -You can interact with your agent via the APIs directly or via a lightweight frontend contained in this repo. +You can interact with your agent via the APIs directly or via the frontend contained in this repo. ### Direct For Phala deployments, swap localhost:3000 for your deployment URL. -- Get the Agent account ID and its balance: +- Get information about the agent: ``` - http://localhost:3000/api/agent-account + http://localhost:3000/api/agent-info ``` - Get the derived Ethereum Sepolia price pusher account ID and its balance (you will need to fund this account): ``` - http://localhost:3000/api/eth-account + http://localhost:3000/api/eth-info ``` -- Send a transaction through the agent to update the price of Eth: +- Request the agent to update the price of Eth: ``` http://localhost:3000/api/transaction @@ -195,7 +195,9 @@ npm i npm run dev ``` -To use the frontend with your Phala deployment change the `API_URL` to Phala URL in your [config.js](https://github.com/NearDeFi/shade-agent-template/blob/main/frontend/src/config.js) file. +To use the frontend with your Phala deployment, change the `API_URL` to the Phala URL in your [config.js](https://github.com/NearDeFi/shade-agent-template/tree/main/frontend/src/config.js) file. + +In the frontend, you can review the approved **measurements** and **PPID** in the contract and details of the registered agents. --- diff --git a/docs/ai/shade-agents/reference/agent-contract.md b/docs/ai/shade-agents/reference/agent-contract.md new file mode 100644 index 00000000000..08aa988c285 --- /dev/null +++ b/docs/ai/shade-agents/reference/agent-contract.md @@ -0,0 +1,301 @@ +--- +id: agent-contract +title: Agent Contract +sidebar_label: Agent Contract +description: "Review the agent contract template for the Shade Agent Framework." +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import { Github } from "@site/src/components/UI/Codetabs"; + +The **agent contract** is the on-chain component of the Shade Agent Framework. It handles agent registration, measurement, and PPID approval, and enforces that only valid agents can call specific methods. + +On this page, you'll walk through the key components of the reference agent contract and how to implement your own **agent-gated functions**. You may need to change other parts of the contract depending on your use case. The full source lives in the [shade-agent-template](https://github.com/NearDeFi/shade-agent-template/tree/2.0/agent-contract) repo. + +--- + +## Flow + +High-level flow: +- The owner deploys and initializes the contract. +- The owner approves measurements and PPIDs. +- Each agent calls `register_agent` with a valid attestation. +- Valid agents can then call agent-gated methods. + +--- + +## Initialization + +The `new` method initializes the contract and takes four arguments (the CLI can initialize the contract with defaults): +- **`requires_tee`**: Whether the contract runs in local or TEE mode. This switches the behavior of the contract so you can move easily between local and TEE deployments. +- **`attestation_expiration_time_ms`**: How long a registration stays valid for after an agent registers. +- **`owner_id`**: The account ID allowed to call owner-only methods. The owner should usually be a multisig. +- **`mpc_contract_id`**: The Chain Signatures MPC contract that the agent contract will call for multichain signing. + +On initialization, the rest of the contract state is set to empty. + + + +If your contract needs additional state, add it in the init method and extend the `Contract` struct accordingly. + +--- + +## Measurements, PPID, Whitelist, and Agent Management + +The **owner** of the contract can manage the approved measurements, PPIDs, whitelist, and agents. + +### Measurements + +The `approved_measurements` decide what code an agent is allowed to run. The CLI will approve a set of measurements for your agent when run. You can learn more about measurements [here](../concepts/terminology.md#measurements). + +The owner controls which measurements are approved and can add or remove them over time. A typical agent code upgrade flow is: approve a new set of measurements, allow a transition period (e.g. a week) so operators can update agents to run the new code, then remove the old measurements. + + + +### PPID + +The `approved_ppids` decide which physical TEE CPUs an agent may run on. The CLI will approve a list of default PPIDs when run. You can learn more about PPID [here](../concepts/terminology.md#ppid). + + + +### Agent + +Agents become authorized by calling `register_agent`; the owner can also remove an agent at any time. Use removal to clean up invalid agents or to revoke access if a TEE were to become compromised. + + + +:::note +A removed agent can re-register by calling `register_agent` with a valid attestation. +::: + +### Whitelist + +The **whitelist** applies only in **local mode**. It defines which account IDs may call **agent-gated methods**, since in local mode, the contract cannot verify that an agent is running approved code. Use `shade whitelist` in the CLI to add an account. You can learn more about whitelisting [here](../concepts/terminology.md#whitelisted-accounts). + + + +--- + +## Register Agent + +Agents register by calling `register_agent`. The method checks that the agent has a valid attestation via `verify_attestation`; if it passes, the agent is stored with its measurements, PPID, and validity period (determined by `attestation_expiration_time_ms`). + +An agent must attach 0.00486 NEAR to cover its own storage cost in the contract. If you change how much data is stored per agent, update the `STORAGE_BYTES_TO_REGISTER` constant accordingly. + + + +By default, an agent that provides a valid attestation can register. Meaning that anyone may be able to run an agent and register. Depending on your use case, you may want to add additional restrictions to an agent, for example, an allow-list of accounts, proof of a shared secret, or a limit of one agent per contract. + +### Verify Attestation + +`verify_attestation` decides if an agent is allowed to register. Its behavior depends on whether the contract is in TEE or local mode. + +#### TEE Mode + +In TEE mode (`requires_tee = true`), the method accepts the agent only if it supplies a valid attestation, which is checked using the `verify` function provided by the [shade-attestation crate](https://github.com/NearDeFi/shade-agent-framework/tree/main/shade-attestation), which takes the list of approved measurements and PPIDs, the current timestamp (in seconds), and the expected `report_data`. + + + +The attestation’s **report data** must contain the NEAR account ID of the agent. This binds the attestation to the same TEE where the agent’s key was created to prevent replay of valid attestations. Report data is passed as **bytes**. + + + +#### Local Mode + +In local mode (`requires_tee = false`), the method approves the agent if the caller is whitelisted and the mock measurements and PPID are approved in the contract. No real attestation is verified. + + + +--- + +## Require Valid Agent + +You can restrict methods so only valid agents can call them using the helper `require_valid_agent`. An agent that registered earlier may no longer be valid. To gate a method: call `require_valid_agent`, and if it returns `Some(promise)`, execute the promise. + + + +:::caution Handle the promise +You must execute the promise returned by `require_valid_agent` when it is `Some(promise)`; otherwise, the invalid agent can still call the function. +::: + +`require_valid_agent` first loads the agent from storage; if the caller is not registered, it panics. + + + +It then checks whether the agent is still valid. It's valid if its registration has not expired (determined by `attestation_expiration_time_ms`), its measurements are still in the approved set, and its PPID is still approved. + + + + + + + + + + + + + + + +If the agent is valid, then the function will return `None`. If the agent is invalid, it will be removed from the map of agents, an event will be emitted detailing the reasons for removal, and a promise will be returned from the function that will call `fail_on_invalid_agent` in the next block. + + + +The promise calls `fail_on_invalid_agent`, which panics in the next block. Panicking in the next block (rather than the current one) ensures the agent is removed from storage; panicking in the current block would revert that removal. + + + +--- + +## Your Functions + +The template includes an example `request_signature` function. It allows a **valid agent** to request a signature for a transaction payload from the MPC contract, so you can sign transactions for most chains. You can learn more about singing transactions for different chains in the [chain signatures documentation](../../../chain-abstraction/chain-signatures/implementation). + + + +You should implement your own **agent-gated functions** in this `your_functions.rs` file, following the same pattern: call `require_valid_agent`, then run your logic. + +:::tip On chain guardrails +A key part of the Shade Agent Framework is the ability to implement **on-chain guardrails**. This gives protection against unauthorized actions - even if the TEE is compromised. It's strongly recommended that you build actions within the agent contract rather than in the agent itself, for example, using the [omni-transaction-rs](https://github.com/Omni-rs/omni-transaction-rs) library. +::: + +--- + +## Building the Contract + +Usually, you build and deploy with the **Shade Agent CLI**: `shade deploy`. To build the contract manually, use the following command: + + + + + + For Linux, you can compile the contract directly with [cargo near](https://github.com/near/cargo-near/releases/latest). + + + ```bash + cargo near build non-reproducible-wasm --no-abi + ``` + + + + + + Because of a required dependency in the shade-attestation crate, agent contracts cannot be built on Mac machines. You can build the contract inside a Docker container using the following command: + + ```bash + docker run --rm -v "$(pwd)":/workspace pivortex/near-builder@sha256:cdffded38c6cff93a046171269268f99d517237fac800f58e5ad1bcd8d6e2418 cargo near build non-reproducible-wasm --no-abi + ``` + + If you would like to build the image yourself, you can use [this Dockerfile](https://github.com/NearDeFi/shade-agent-framework/blob/main/contract-builder/Dockerfile). + + + + + +:::note +The `--no-abi` flag is used to build the contract without an ABI. This is required because the shade-attestation crate currently doesn't support ABI generation. +::: + +--- + +## Calling Methods + +The **Shade Agent CLI** calls the main contract methods when you run `shade deploy`, but it does not cover every method. For methods the CLI doesn’t support, use the [NEAR CLI](../../../../tools/near-cli) or create scripts using the [NEAR API](../../../../tools/near-api). \ No newline at end of file diff --git a/docs/ai/shade-agents/reference/api.md b/docs/ai/shade-agents/reference/api.md index 270a9177891..72212828bb5 100644 --- a/docs/ai/shade-agents/reference/api.md +++ b/docs/ai/shade-agents/reference/api.md @@ -1,524 +1,207 @@ --- id: api -title: Shade Agent API -sidebar_label: Shade Agent API -description: "Learn how to use the Shade Agent API." ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import {Github, Language} from "@site/src/components/UI/Codetabs" - -The Shade Agent API abstracts away the complexity of the TEE and interacting with the agent contract to help you build a Shade Agent quickly. - +title: Shade Agent API +sidebar_label: Shade Agent API +description: "Use the Shade Agent API (TypeScript/JavaScript) to connect your agent to the Shade Agent Framework" --- ## API Overview -The API is packaged as a Docker image and included in your agent when it's uploaded to Phala Cloud. The API is accessible internally by default on port 3140, but it's not accessible from outside the TEE. - -When the API image boots up, it will automatically derive the agent's NEAR account (a random [implicit account](https://near-docs-pr-2740.onrender.com/protocol/account-id#implicit-address)), fund it with 0.3 NEAR from the NEAR_ACCOUNT_ID specified in the environment variables, and registers the agent in the agent contract. - -The API can be used in any language, but API wrappers are maintained in TypeScript/JavaScript and Python. It's recommended you develop in TypeScript as it has great synergies with [chainsig.js](../../../chain-abstraction/chain-signatures/implementation.md) for building multichain transactions. +**Shade Agent API** is a **TypeScript/JavaScript** library that connects your agent to the Shade Agent Framework. It abstracts TEE complexity and simplifies calls to the agent contract. The same API works locally and inside a TEE; its behavior differs slightly by environment, but the interface stays the same. --- -## Setup +## Installation - +```bash +npm install @neardefi/shade-agent-js +``` - - - ```bash - npm install @neardefi/shade-agent-js - ``` - - - - - - ```bash - pip install shade-agent-py - ``` - - - - +--- - You can use the Shade Agent API directly with any language that supports HTTP requests. The base API endpoints change depending on your deployment: +## Initializing the Client - **Local Development:** - ``` - http://localhost:3140/api/agent - ``` +Sets up the client with the desired configuration. - **Production (TEE):** - ``` - http://shade-agent-api:3140/api/agent - ``` +```ts +import { ShadeClient } from "@neardefi/shade-agent-js"; - All endpoints expect `POST` requests with JSON payloads and return JSON responses. +const agent = await ShadeClient.create({ + networkId: "testnet", // or "mainnet" + agentContractId: process.env.AGENT_CONTRACT_ID, // example-agent-contract.testnet + sponsor: { + accountId: process.env.SPONSOR_ACCOUNT_ID, // example-sponsor.testnet + privateKey: process.env.SPONSOR_PRIVATE_KEY, // ed25519:4vKz... + }, + rpc: provider, + numKeys: 10, + derivationPath: process.env.SPONSOR_PRIVATE_KEY, // ed25519:4vKz... +}); +``` - If you're running your API on a port other than 3140, you should amend the base URL accordingly. +### **Arguments** - +All arguments are optional. Omitting some makes certain methods unavailable. - +| Argument | Description | +|----------|-------------| +| `networkId` | The NEAR network: `mainnet` or `testnet` (defaults to testnet). | +| `agentContractId` | The account ID of your agent contract that your agent will interact with. | +| `sponsor` | The account details of a sponsor account to fund the agent. | +| `rpc` | A [near-api-js provider](https://near.github.io/near-api-js/modules/providers.html) object used by the client (defaults to a basic RPC provider based on the network). | +| `numKeys` | The number of key pairs the agent has (1–100, defaults to 1). More keys increase transaction throughput; the client rotates through them when signing transactions. | +| `derivationPath` | A string used to derive deterministic agent account IDs when running locally. Lets you avoid re-whitelisting and re-funding the agent on each run. Use a unique secret (e.g. a private key). If two agents share the same derivation path, they get the same account ID and could control contracts they are not authorized for. | --- ## Agent Account ID -Fetches the NEAR account ID of the agent. - - +Returns the ephemeral NEAR account ID of the agent. - - - ```ts - import { agentAccountId } from '@neardefi/shade-agent-js'; - - const res = await agentAccountId(); - const accountId = res.accountId - ``` - - - - - - - ```py - from shade_agent import agent_account_id - - res = await agent_account_id() - account_id = res["account_id"] - ``` - - - - - - **POST /getAccountId** - - Request body - ```json - {} - ``` - - Response - ```json - { - "accountId": "14bc8ee18f2d1ef51e7d581bdd96797804c56247733defdae67ad41314686fd7" - } - ``` - - - - +```ts +const accountId = agent.accountId(); +``` --- -## Agent Info - -Fetches the code hash and checksum for the agent. -- The `code hash` is the code hash of the app image running inside the agent. -- The `checksum` is produced by the TEEs attestation and represents that the agent is registered. - -This function will only return the details once the agent has successfully registered in the agent contract. When running the API locally, it will only return the code hash, and not the checksum. - - - - - - ```ts - import { agentInfo } from '@neardefi/shade-agent-js'; - - const res = await agentInfo(); - const codehash = res.codehash - const checksum = res.checksum - ``` - - - - - - - ```py - from shade_agent import agent_info - - res = await agent_info() - codehash = res["codehash"] - checksum = res["checksum"] - ``` - - - - - - **POST /view** - - Request body - ```json - { - "methodName": "get_agent", - "args": { - "account_id": "14bc8ee18f2d1ef51e7d581bdd96797804c56247733defdae67ad41314686fd7" - } - } - ``` - - Response - ```json - { - "codehash": "03bcd36d3ffb5346c9e1e0166a4c2734a9e7cceedee6f7d992499aeb7fa54ead", - "checksum": "0c32c5c598bc8a3bfec47f3d7d9a9d600c8a60e5b97d90a4c2856a7c829eb6d4" - } - ``` +## Agent Balance - +Returns the NEAR balance of the agent's account in human-readable units (e.g. 1 = one NEAR). If the account does not exist, it returns 0. - +```ts +const balance = await agent.balance(); +``` --- -## Agent Balance - -Fetches the NEAR balance of the agent's account in yoctoNEAR (1 NEAR = 10^24 yoctoNEAR). +## Fund Agent - +Transfers NEAR from the configured sponsor account to the agent's account. - - - ```ts - import { agent } from '@neardefi/shade-agent-js'; +```ts +await agent.fund(0.3); // 0.3 NEAR +``` - const res = await agent("getBalance"); - const balance = res.balance - ``` - +Requires `sponsor` in config. - +--- - +## Check Whitelist - ```py - from shade_agent import agent - - res = await agent("getBalance") - balance = res["balance"] - ``` +Checks whether the agent's account is whitelisted for local mode. - +```ts +const whitelisted = await agent.isWhitelisted(); +``` - +**TEE vs local:** +- TEE: Always returns `null`. +- Local: Returns `true` if the agent is whitelisted, `false` otherwise. - **POST /getBalance** +Requires `agentContractId` in config. - Request body - ```json - {} - ``` +--- - Response - ```json - { - "balance": "203436730084671139765003" - } - ``` +## Register Agent - +Registers the agent's account in the agent contract. Returns `true` on success, throws on failure. - +```ts +await agent.register(); +``` ---- +**TEE vs local:** +- TEE: Registers with a real attestation. +- Local: Registers with a mock attestation. -## Request Signature - -Requests a signature from the Shade Agent for a multichain account (by calling request_signature on the agent contract). It has three arguments: -- **path** - A string that decides which account the signature is for. The path can be set to anything, and by changing the path, you produce a signature for a different account. -- **payload** - The hash of the transaction to be signed, given as a hex string. -- **keyType** - The signature scheme being used to sign the payload `Ecdsa` (secp256k1) or `Eddsa` (ed25519). - -It returns the signature for the transaction. - - - - - - ```ts - import { requestSignature } from '@neardefi/shade-agent-js'; - - const res = await requestSignature({ - path: "ethereum-1", - payload: "cf80cd8a...", - keyType: "Ecdsa", // Or "Eddsa" - }); - ``` - -
- Response - - For `Ecdsa`, the function returns the components of the signature as hex strings. Note that to get `r`, remove the first two hex characters from `big_r`. - - ```typescript - { - scheme: 'Secp256k1', - big_r: { - affine_point: '03D537AFFD52BE9AF0DA6CF41B573F4BE065434AEE2D25A500BC730C06E7EB2AF1' - }, - s: { - scalar: '3470037EB46DC6D1921900B635785290184EC980CFEC7109EB103B5698D4F725' - }, - recovery_id: 0 - } - ``` - - For `Eddsa`, the function returns the whole signature as a 64-byte array. - - ```typescript - { - scheme: 'Ed25519', - signature: [ - 5, 105, 30, 208, 192, 39, 154, 105, 252, 20, 132, - 64, 247, 207, 223, 127, 197, 43, 30, 145, 164, 224, - 1, 45, 240, 28, 155, 218, 204, 5, 136, 111, 238, - 40, 120, 122, 249, 166, 193, 174, 120, 94, 177, 39, - 179, 193, 170, 117, 37, 36, 155, 38, 72, 24, 118, - 235, 187, 110, 129, 26, 186, 7, 0, 8 - ] - } - ``` - - If you're using the chainsig.js library, you don't need to worry about the format of these responses since the library handles it. - -
- -
- - - - ```py - from shade_agent import request_signature - - res = await request_signature( - path="ethereum-1", - payload="cf80cd8a...", - key_type="Ecdsa", # Or "Eddsa" - ) - ``` - -
- Response - - For `Ecdsa`, the function returns the components of the signature as hex strings. Note that to get `r`, remove the first two hex characters from `big_r`. - - ```python - { - 'scheme': 'Secp256k1', - 'big_r': { - 'affine_point': '03D537AFFD52BE9AF0DA6CF41B573F4BE065434AEE2D25A500BC730C06E7EB2AF1' - }, - 's': { - 'scalar': '3470037EB46DC6D1921900B635785290184EC980CFEC7109EB103B5698D4F725' - }, - 'recovery_id': 0 - } - ``` - - For `Eddsa`, the function returns the whole signature as a 64-byte array. - - ```python - { - 'scheme': 'Ed25519', - 'signature': [ - 5, 105, 30, 208, 192, 39, 154, 105, 252, 20, 132, - 64, 247, 207, 223, 127, 197, 43, 30, 145, 164, 224, - 1, 45, 240, 28, 155, 218, 204, 5, 136, 111, 238, - 40, 120, 122, 249, 166, 193, 174, 120, 94, 177, 39, - 179, 193, 170, 117, 37, 36, 155, 38, 72, 24, 118, - 235, 187, 110, 129, 26, 186, 7, 0, 8 - ] - } - ``` - -
- -
- - - - **POST /call** - - Request body - ```json - { - "methodName": "request_signature", - "args": { - "path": "ethereum-1", - "payload": "cf80cd8a...", - "key_type": "Ecdsa" - } - } - ``` - -
- Response - - For `Ecdsa`, the function returns the components of the signature as hex strings. Note that to get `r`, remove the first two hex characters from `big_r`. - - ```json - { - "scheme": "Secp256k1", - "big_r": { - "affine_point": "03D537AFFD52BE9AF0DA6CF41B573F4BE065434AEE2D25A500BC730C06E7EB2AF1" - }, - "s": { - "scalar": "3470037EB46DC6D1921900B635785290184EC980CFEC7109EB103B5698D4F725" - }, - "recovery_id": 0 - } - ``` - - For `Eddsa`, the function returns the whole signature as a 64-byte array. - - ```json - { - "scheme": "Ed25519", - "signature": [ - 5, 105, 30, 208, 192, 39, 154, 105, 252, 20, 132, - 64, 247, 207, 223, 127, 197, 43, 30, 145, 164, 224, - 1, 45, 240, 28, 155, 218, 204, 5, 136, 111, 238, - 40, 120, 122, 249, 166, 193, 174, 120, 94, 177, 39, - 179, 193, 170, 117, 37, 36, 155, 38, 72, 24, 118, - 235, 187, 110, 129, 26, 186, 7, 0, 8 - ] - } - ``` - -
- -
- -
+Requires `agentContractId` in config. --- -## Agent Call +## Call Agent Contract -Makes a function call to the agent contract from the agent. This is used for custom contracts when you want to call a function other than request_signature. It returns the result of the function call. +Calls a **change function** on the agent contract (uses gas, can change state). Returns the call result or throws. - +```ts +const result = await agent.call({ + methodName: "example_call_function", + args: { arg1: "value1", arg2: "value2" }, + gas: BigInt("300000000000000"), // Optional + deposit: "0", // Optional +}); +``` - - - ```ts - import { agentCall } from '@neardefi/shade-agent-js'; +Requires `agentContractId` in config. - const res = await agentCall({ - methodName: "example_call_method", - args: { - arg1: "Value1", - arg2: "Value2", - }, - gas: "30000000000000", // Optional - }) - ``` - - +--- - +## View Agent Contract - ```py - from shade_agent import agent_call +Calls a **view function** on the agent contract (no gas, read-only). Returns the call result or throws. - res = await agent_call({ - "methodName": "example_call_method", - "args": { - "arg1": "Value1", - "arg2": "Value2", - }, - "gas": "30000000000000", # Optional - }) - ``` +```ts +const result = await agent.view({ + methodName: "example_view_function", + args: { arg1: "value1", arg2: "value2" }, +}); +``` - +Requires `agentContractId` in config. - +--- - **POST /call** +## Get Attestation - Request body - ```json - { - "methodName": "example_call_method", - "args": { - "arg1": "value1", - "arg2": "value2" - }, - "gas": "30000000000000" // Optional - } - ``` +Returns the attestation in the format the agent contract expects. - +```ts +const attestation = await agent.getAttestation(); +``` - - +**TEE vs local:** +- TEE: Returns a real attestation. +- Local: Returns a mock attestation. --- -## Agent View +## Get Private Keys -Makes a function call to a view method (a method that does not require gas) on the agent contract. It returns the result of the function call. +Returns the agent's ephemeral private keys. Useful for when wanting to use other NEAR tooling (e.g. near-api-js) or for other operations like encrypting messages. - +:::danger +Never log, expose, or store these keys. Doing so allows registered keys to be used outside of verified code (the keys can execute any operation not authorized by the measurements). Do not hold funds or important state with these keys — they are ephemeral and lost if the TEE reboots. +::: - - - ```ts - import { agentView } from '@neardefi/shade-agent-js'; +```ts +const keys = agent.getPrivateKeys({ acknowledgeRisk: true }); +``` - const res = await agentView({ - methodName: "example_view_method", - args: { - arg1: "value1", - arg2: "value2", - }, - }) - ``` - - - - +--- - ```py - from shade_agent import agent_view +## Utilities - res = await agent_view({ - "methodName": "example_view_method", - "args": { - "arg1": "value1", - "arg2": "value2", - }, - }) - ``` +### sanitize - +Aims to redact private keys from strings, objects, or Errors. Use before logging. - +```ts +import { sanitize } from "@neardefi/shade-agent-js"; +console.error(sanitize(someError)); +``` - **POST /view** +:::warning +Sanitize redacts common key patterns, but can't catch every case or other sensitive data. Add your own sanitization where needed so no sensitive data is emitted from the TEE. +::: - Request body - ```json - { - "methodName": "example_view_method", - "args": { - "arg1": "value1", - "arg2": "value2" - } - } - ``` +### toThrowable - +Returns an error with a sanitized message. Use when rethrowing. - \ No newline at end of file +```ts +import { toThrowable } from "@neardefi/shade-agent-js"; +try { + await client.register(); +} catch (e) { + throw toThrowable(e); +} +``` \ No newline at end of file diff --git a/docs/ai/shade-agents/reference/cli.md b/docs/ai/shade-agents/reference/cli.md index 19d3ca1cadb..6fd2fa02a0a 100644 --- a/docs/ai/shade-agents/reference/cli.md +++ b/docs/ai/shade-agents/reference/cli.md @@ -2,129 +2,216 @@ id: cli title: Shade Agent CLI sidebar_label: Shade Agent CLI -description: "Learn about the Shade Agent CLI and how to use it to deploy Shade Agents." +description: "Use the Shade Agent CLI to deploy your Shade Agent." --- -The [Shade Agent CLI](https://github.com/NearDeFi/shade-agent-cli/tree/main) makes it simple to deploy a Shade Agent. +The **Shade Agent CLI** makes it easy to deploy a Shade Agent. It includes building and deploying your agent contract, building and publishing your agent's Docker image, and deploying the agent to Phala Cloud. The CLI revolves around a `deployment.yaml` file that configures how your Shade Agent will be deployed. --- -## CLI Overview +## Installation -Under the hood, the CLI: -- Builds and publishes the Docker Image for your agent app, and modifies your environment variables and docker-compose.yaml to match your new image hash -- Creates the agent contract account, deploys the agent contract to it, and initializes it with the NEAR_ACCOUNT_ID as the owner -- Approves the image code hashes for your agent (app and API image) -- Deploys the agent to a TEE on Phala Cloud +```bash +npm install -g @neardefi/shade-agent-cli +``` --- -## Local vs Production +## Commands -The `NEXT_PUBLIC_contractId` in your environment variables prefix should be set to `ac-proxy.` for local development and `ac-sandbox.` for TEE deployment. +### Deploy -For local deployment, the CLI works a little differently: -- No Docker Image is built or published for your agent app -- An agent contract that doesn't require agent registration is deployed instead (since locally, you cannot produce a valid TEE attestation) -- The API image is hosted locally instead of deploying anything to a TEE +Deploys your Shade Agent with the configuration as defined by the `deployment.yaml` file. ---- +```bash +shade deploy +``` -## Installation +Must be executed in the same directory as your `deployment.yaml` file. + +### Plan + +Generates a preview of how your Shade Agent will be deployed as defined by the `deployment.yaml` file. ```bash -npm i -g @neardefi/shade-agent-cli +shade plan ``` ---- +Must be executed in the same directory as your `deployment.yaml` file. -## Usage +### Whitelist -The Shade Agent CLI is a single command that runs the CLI with standard configurations. Run the command within the root of your project. +Whitelists a specified agent's account ID in the agent contract as defined by the `deployment.yaml` file. This is only relevant for local mode. ```bash -shade-agent-cli +shade whitelist ``` -Your project root must contain your `.env.development.local`, `Dockerfile` and `docker-compose.yaml` files. +Must be executed in the same directory as your `deployment.yaml` file. + +### Auth + +Configure **NEAR** and **Phala** credentials required for deploying your Shade Agent. Must be run before using the `deploy` or `whitelist` commands. + +```bash +shade auth +``` --- -## Flags -The CLI includes various flags to configure deployment options and disable specific components. If you require further customizability when deploying your agent, you can disable the relevant components using flags and complete those steps manually with native tools: [Docker CLI](https://docs.docker.com/reference/cli/docker/), [NEAR CLI](https://docs.near.org/tools/near-cli), and [Phala CLI](https://docs.phala.network/phala-cloud/phala-cloud-cli/overview) +## deployment.yaml Reference + +CLI configurations are read from a single `deployment.yaml` file in the project root. The following sections describe what each key configures. + +### Top-Level Keys + +| Key | Required | Description | +|-----|----------|-------------| +| **environment** | Yes |`local` or `TEE`. Controls whether the agent runs locally or in a Phala TEE. | +| **network** | Yes | `testnet` or `mainnet`. Controls whether the agent contract is on NEAR testnet or mainnet. | +| **docker_compose_path** | Yes if TEE | Path to the Docker Compose file (e.g. `./docker-compose.yaml`). Used for building the Docker image and deploying your application to a TEE. | +| **agent_contract** | Yes | Agent contract configuration. See [agent_contract](#agent_contract) for more details. | +| **approve_measurements** | No | If enabled, sets allowed measurements in the agent contract. | +| **approve_ppids** | No | If enabled, sets allowed PPIDs in the agent contract.| +| **build_docker_image** | No (TEE only) | If enabled and environment is TEE, builds a new Docker image for your agent, publishes it, and updates the Docker Compose with the new image. | +| **deploy_to_phala** | No (TEE only) | If enabled and environment is TEE, deploys the Docker Compose to Phala Cloud. | +| **whitelist_agent_for_local** | No | Config for the `shade whitelist` command to whitelist an agent's account ID whilst in local mode (not used by the shade deploy command). | +| **os** | No | Override OS for tooling: `mac` or `linux`. If omitted, the CLI auto-detects from the current platform. | + +### agent_contract -- **--wasm ``** +| Key | Required | Description | +|-----|----------|-------------| +| **contract_id** | Yes | NEAR account ID for the agent contract (e.g. `example-contract-123.testnet`). Must be unused if you are deploying a new contract. | +| **deploy_custom** | No | If enabled, the CLI creates the contract account with the same private key as the account set up via `shade auth`, and deploys a new contract. If the contract account already exists, it will be deleted and recreated to remove the old contract. | - Path to a custom agent contract WASM file (e.g. `contract/near/contract.wasm`) to deploy instead of the default contract. Use this when deploying [custom contracts](./custom-agent-contract.md). +#### deploy_custom -- **--funding ``** +`agent_contract.deploy_custom` - Amount of NEAR tokens to fund the contract deployment with (e.g. `5` for 5 NEAR). Use this when deploying a custom contract. +| Key | Required | Description | +|-----|----------|-------------| +| **enabled** | No | If `false`, deploy_custom is skipped. | +| **funding_amount** | Yes | NEAR amount to fund the new contract account with, used to fund the deployment of the contract (number between 0 and 100). | +| **delete_key** | No | If `true`, the key for the contract account is deleted after deployment, locking the contract (defaults `false`). | +| **deploy_from_source** | One of three | Build the contract from source and deploy: set `enabled: true` and `source_path` to the contract directory. | +| **deploy_from_wasm** | One of three | Deploy a pre-built WASM file: set `enabled: true` and `wasm_path` to the `.wasm` file. | +| **use_global_by_hash** | One of three | Deploy using a global contract: set `enabled: true` and `global_hash` to the contract hash. | +| **init** | No | If enabled, initializes the contract via a function call. | -- **--image** +#### init - Build and push the Docker image only. Use this when you want customizability over the deployment of the agent contract. +`agent_contract.deploy_custom.init` -- **--contract** +| Key | Required | Description | +|-----|----------|-------------| +| **enabled** | No | If `false`, init is skipped. | +| **method_name** | Yes | Contract method to call (e.g. `new`). | +| **args** | Yes | Arguments to call the method with. | +| **tgas** | No | Gas for the call (default 30). | - Build and push the Docker image, and deploy the contract only. Use this when you want customizability over the contract initialization and approval of image code hashes. +Placeholders in args: -- **--phala-only** +- `` — Resolves to `true` or `false` depending on `environment`. +- `<7_DAYS>` — Resolves to 7 days in milliseconds (604800000). +- `` — Resolves to the NEAR account ID from `shade auth`. +- `` — Resolves to the default MPC contract for the selected `network` (testnet/mainnet). - Deploy the agent, specified by the current `docker-compose.yaml`, to Phala Cloud. Use this when you want to redeploy the same agent as you last deployed. +### approve_measurements -- **--no-redeploy** +| Key | Required | Description | +|-----|----------|-------------| +| **enabled** | No | If `false`, measurements are not approved. | +| **method_name** | Yes | Contract method to call (e.g. `approve_measurements`). | +| **args** | Yes | Arguments to call the method with. | +| **tgas** | No | Gas for the call (default 30). | - Skip redeploying the contract. Use when you want to deploy a new agent quicker and you don't need the agent contract redeploying. +Placeholders in args: -- **--no-build** +- `` — Resolves to real calculated measurements for the application for TEE and mock measurements for local. - Skip building and pushing the Docker image. Use this when you want to redeploy the same agent or want more control over the image build process. +### approve_ppids -- **--no-phala** +| Key | Required | Description | +|-----|----------|-------------| +| **enabled** | No | If `false`, PPIDs are not approved. | +| **method_name** | Yes | Contract method to call (e.g. `approve_ppids`). | +| **args** | Yes | Arguments to call the method with. | +| **tgas** | No | Gas for the call (default 30). | - Skip deploying the agent to Phala Cloud. Use this when you want more control over hosting the agent (e.g. deploying to a TEE with higher specs). +Placeholders in args: -- **--no-cache** +- `` — Resolves to a list of all PPIDs of devices on Phala Cloud for TEE and a mock PPID for local. - Run Docker build with --no-cache. Use this when you need clean builds or want to update cached layers (e.g. cached layers may use older packages). +### build_docker_image (TEE Only) -:::note -Some options are mutually exclusive. See error messages for details if you use conflicting flags. +| Key | Required | Description | +|-----|----------|-------------| +| **enabled** | No | If `false`, the Docker image is not built. If disabled, the CLI will use the existing Docker Compose file. | +| **tag** | Yes | Docker image tag (e.g. `username/my-first-agent`) for building and pushing. | +| **cache** | Yes | Boolean; whether to use caching in the build process. | +| **dockerfile_path** | Yes | Path to the Dockerfile to use for the build process (e.g. `./Dockerfile`). | + +### deploy_to_phala (TEE Only) + +| Key | Required | Description | +|-----|----------|-------------| +| **enabled** | No | If `false`, deployment to Phala Cloud is skipped. | +| **app_name** | Yes | Phala Cloud app (CVM) name. | +| **env_file_path** | Yes | Path to the environment variables file loaded when deploying to Phala (e.g. `./.env`). | + +### whitelist_agent_for_local (local only) + +Used by `shade whitelist`. No `enabled` flag; if the section is present, the command is available. + +| Key | Required | Description | +|-----|----------|-------------| +| **method_name** | Yes | Contract method to call (e.g. `whitelist_agent_for_local`). | +| **args** | Yes | Arguments to call the method with. | +| **tgas** | No | Gas for the call (default 30). | + +Placeholders in args: + +- `` — Replaced with the agent account ID you provide when running `shade whitelist`. + +:::info +Currently, the CLI only supports measurement calculation and Phala Cloud deployment for fixed configurations on DStack. If you need to deploy with different configurations, you can calculate the measurements and deploy to Phala by other means; you can ask for assistance with this in our [support group](https://t.me/+mrNSq_0tp4IyNzg8). + +
+ Fixed Dstack configurations + +- Dstack Version: dstack-0.5.5 +- Hardware: 1vCPU and 2GB RAM (tdx.small on Phala) +- Key Provider: Phala Key Provider + +**App compose configs** +- Pre Launch Script: v0.0.12 + +... + +- features: ["kms", "tproxy-net"], +- gateway_enabled: true, +- kms_enabled: true, +- local_key_provider_enabled: false, +- manifest_version: 2, +- name: "", +- no_instance_id: false, +- public_logs: true, +- public_sysinfo: true, +- public_tcbinfo: true, +- runner: "docker-compose", +- secure_time: false, +- storage_fs: "zfs", +- tproxy_enabled: true, + +
::: --- -## Custom RPC - -To use customs RPCs with the CLI and the API, create a file named `near-rpc.json` within your project's root and configure the RPCs you would like to use, for example: - -```json -{ - "nearRpcProviders": [ - { - "connectionInfo": { - "url": "https://neart.lava.build:443" - }, - "options": { - "retries": 3, - "backoff": 2, - "wait": 1000 - } - }, - { - "connectionInfo": { - "url": "https://test.rpc.fastnear.com" - }, - "options": { - "retries": 3, - "backoff": 2, - "wait": 1000 - } - } - ] -} -``` -If required, you can specify headers under connectionInfo. + +## Example deployment.yaml Configurations + +You can view a list of [example deployment.yaml configurations here](https://github.com/NearDeFi/shade-agent-framework/tree/main/shade-agent-cli/example-deployment-files). \ No newline at end of file diff --git a/docs/ai/shade-agents/reference/custom-agent-contract.md b/docs/ai/shade-agents/reference/custom-agent-contract.md deleted file mode 100644 index a26ffb6fb57..00000000000 --- a/docs/ai/shade-agents/reference/custom-agent-contract.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -id: custom-agent-contract -title: Custom Agent Contract -sidebar_label: Custom Agent Contract -description: "Learn how to build, deploy, and interact with custom Shade Agent contracts." ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - -In some cases, you may want to deploy a `custom agent contract`. This allows for more customizability inside the agent contract, allows you to restrict your agent to certain actions by implementing `guard rails`, and is used for building Shade Agents that interact with just NEAR. - ---- - -## Creating the Contract - -To create a custom agent contract, we recommend you fork the [sandbox contract](https://github.com/NearDeFi/shade-agent-js/tree/main/contracts/sandbox). This is the agent contract that's deployed under the hood when using the `shade-agent-cli`. For testing locally, you will need to maintain a separate similar contract that does not implement the agent registration flow; for this, you can follow the structure of the [proxy contract](https://github.com/NearDeFi/shade-agent-js/tree/main/contracts/proxy). - -Inside this contract, you will create your own functions. For building contracts on NEAR, see our [smart contract docs](../../../smart-contracts/quickstart.md). You can only develop agent contracts in Rust. - -With the quickstart template, an agent can sign any transaction. You may want to limit your agent to only be able to sign transactions for a limited set of functions or actions. For this, we recommend building your transactions inside your agent contract with the [omni-transaction-rs](https://github.com/near/omni-transaction-rs) library. In such case, you should make the `request_signature` function private. - -For developing Shade Agents that just interact with NEAR, you can remove the `request_signature` function. The agent will make function calls to the contract directly. Make sure that you restrict relevant functions to only be allowed to be called by the agent. If you want to interact with existing contracts on NEAR that do not implement agent registration, you can leverage [cross contract calls](../../../smart-contracts/anatomy/crosscontract.md). - -How you compile the contract depends on your operating system. - - - - - - For Linux, you can compile the contract directly with [cargo near](https://github.com/near/cargo-near/releases/latest). - - - ```bash - cargo near build non-reproducible-wasm - ``` - - - - - - Because of a required dependency used in the agent registration flow, agent contracts cannot easily be compiled on a Mac. We suggest you build the contract inside a Docker container. You can use this pre-configured image for compiling NEAR contracts: - - ```bash - docker run --rm -v "$(pwd)":/workspace pivortex/near-builder@sha256:cdffded38c6cff93a046171269268f99d517237fac800f58e5ad1bcd8d6e2418 cargo near build non-reproducible-wasm - ``` - - - - - ---- - -## Deploying the Custom Contract - -To deploy your agent with the custom contract, add the `--wasm` flag when using the Shade Agent CLI, specifying the path to your wasm file. Depending on the size of the wasm, you may require more NEAR to deploy the contract. This can be done using the `--funding` flag, followed by the amount of NEAR (100KB = 1 NEAR). - -Here is an example: - -```bash -shade-agent-cli --wasm contract/target/near/contract.wasm --funding 5 -``` - ---- - -## Interacting with Custom Contract - -To call a function on your custom agent contract, use the `agentCall` function provided by the Shade Agent API. Please refer to the [relevant docs](./api.md#agent-call) for calling the contract in your desired language. \ No newline at end of file diff --git a/docs/ai/shade-agents/reference/environment-variables.md b/docs/ai/shade-agents/reference/environment-variables.md deleted file mode 100644 index 9a20ab8243e..00000000000 --- a/docs/ai/shade-agents/reference/environment-variables.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -id: environment-variables -title: Environment Variables -sidebar_label: Environment Variables -description: "Learn about the required and optional environment variables as part of the Shade Agent Framework." ---- - -Environment variables are a crucial component of the Shade Agent Framework. They configure your Shade Agent and are passed encrypted into your agent when it goes live. Note that the same agent code (same Docker Compose file) can use different environment variables in different deployments. - -The environment variables file must be named `.env.development.local`. - -## Required Variables - -- **NEAR_ACCOUNT_ID** - - :::info Example - NEAR_ACCOUNT_ID=example-account.testnet - ::: - - This is the NEAR account ID used to create the agent contract's account when running the Shade Agent CLI and is used to automatically fund the agent's account on boot. You should ensure this account remains funded as you continue to deploy additional agents. - - You can create a NEAR account by using the NEAR CLI. - - Install the NEAR CLI: - - ```bash - curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/near-cli-rs/releases/latest/download/near-cli-rs-installer.sh | sh - ``` - - Create an account: - - ```bash - export ACCOUNT_ID=example-name.testnet - near account create-account sponsor-by-faucet-service $ACCOUNT_ID autogenerate-new-keypair save-to-keychain network-config testnet create - ``` - - Replace `example-name.testnet` with a unique account ID. - -- **NEAR_SEED_PHRASE** - - :::info Example - NEAR_SEED_PHRASE="book chapter unknown knife strange inherit amazing artist mixture loan rotate lyrics" - ::: - - This is the seed phrase for the NEAR_ACCOUNT_ID. When creating an account with the above command, the seed phrase will be printed to the terminal. - -- **NEXT_PUBLIC_contractId** - - :::info Examples - NEXT_PUBLIC_contractId=ac-proxy.example-account.testnet - NEXT_PUBLIC_contractId=ac-sandbox.example-account.testnet - ::: - - This is the NEAR account ID where the agent contract will be deployed when running the Shade Agent CLI. The account is automatically created when you run the Shade Agent CLI. This account must be your NEAR_ACCOUNT_ID prefixed with either `ac-proxy.` or `ac-sandbox.`, which determines whether the deployment is local or to a TEE, respectively. - -- **API_CODEHASH** - - The API_CODEHASH defines the code hash of the Shade Agent API. You only need to update this when a new API version is released. The [Quickstart Template](https://github.com/NearDeFi/shade-agent-template/blob/main/.env.development.local.example#L9) always includes the most up-to-date API code hash. - -- **APP_CODEHASH** - - The APP_CODEHASH defines the code hash of your agent. You don't need to edit this as it will be automatically updated when running the Shade Agent CLI in production. - -- **DOCKER_TAG** - - :::info Example - DOCKER_TAG=username/my-app - ::: - - The DOCKER_TAG specifies the location of your app image on Docker Hub. Edit this tag to match your Docker username in the first part, and choose any name you'd like for the second part. The CLI will automatically update the Docker tag in your docker-compose.yaml file when it runs in production. - -- **PHALA_API_KEY** - - :::info Example - PHALA_API_KEY=phak_tIhrDY0mXJMgmLLMEMoM6yBxOsjfVM-sTmXmjOF4Fks - ::: - - The PHALA_API_KEY is used to upload your agent to Phala Cloud when running the Shade Agent CLI. You can get a key [here](https://cloud.phala.network/dashboard/tokens). - -## Optional Environment Variables - -- **API_PORT** - - :::info Example - API_PORT=4000 - ::: - - The API_PORT defines which port number the Shade Agent API is exposed on. The API by default is hosted on port 3140. - -## Your Own Variables - -You should also set any additional environment variables your agent may need in the `.env.development.local` file. Remember to update your [Docker Compose](https://github.com/NearDeFi/shade-agent-template/blob/main/docker-compose.yaml#L21) file to pass these additional variables to your agent. \ No newline at end of file diff --git a/docs/ai/shade-agents/reference/plugins.md b/docs/ai/shade-agents/reference/plugins.md deleted file mode 100644 index 3d06778e8ab..00000000000 --- a/docs/ai/shade-agents/reference/plugins.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -id: plugins -title: Shade Agent Plugins -sidebar_label: Plugins -description: "Learn how to use plugins to extend Shade Agent functionality." ---- - -Docs for integrating plugins into your Shade Agent will be coming soon. - -In the meantime, please feel free to check out these links: -- Docs on using [private and verifiable inference](https://docs.near.ai/cloud/get-started/) -- An example using a [Twitter API](https://github.com/NearDeFi/shade-agent-basednames) \ No newline at end of file diff --git a/docs/ai/shade-agents/tutorials/ai-dao/dao-agent-contract.md b/docs/ai/shade-agents/tutorials/ai-dao/dao-agent-contract.md index 25bcb448088..f4e9a8dfc14 100644 --- a/docs/ai/shade-agents/tutorials/ai-dao/dao-agent-contract.md +++ b/docs/ai/shade-agents/tutorials/ai-dao/dao-agent-contract.md @@ -210,6 +210,6 @@ The contract exposes [view functions](https://github.com/NearDeFi/verifiable-ai- --- -## Next steps +## Next Steps Now that you understand the DAO agent contract implementation, continue to the [agent page](./dao-agent.md) to learn about the verifiable agent that queries the contract for pending requests and casts a vote using an LLM. \ No newline at end of file diff --git a/docs/ai/shade-agents/tutorials/ai-dao/deploying.md b/docs/ai/shade-agents/tutorials/ai-dao/deploying.md index a1d552586f6..b7ab0780148 100644 --- a/docs/ai/shade-agents/tutorials/ai-dao/deploying.md +++ b/docs/ai/shade-agents/tutorials/ai-dao/deploying.md @@ -6,13 +6,11 @@ description: "Learn how to deploy the Verifiable AI DAO Shade Agent which includ --- :::warning -The Shade Agent Framework is experimental and contains known critical vulnerabilities. - -It must not be used in production or on mainnet and is intended solely for testing and non-critical use on testnet. +The Verifiable AI DAO tutorial uses an old version of the Shade Agent Framework, which contains known critical vulnerabilities and has a different architecture. No representations or warranties are made regarding security, correctness, or fitness for any purpose. Use of this software is entirely at your own risk. -A production-ready version of the framework is currently in development. +The tutorial will be updated to use the latest version of the Shade Agent Framework in the future. ::: import Tabs from '@theme/Tabs'; diff --git a/docs/ai/shade-agents/tutorials/ai-dao/overview.md b/docs/ai/shade-agents/tutorials/ai-dao/overview.md index 8326a345c75..30d4024ac61 100644 --- a/docs/ai/shade-agents/tutorials/ai-dao/overview.md +++ b/docs/ai/shade-agents/tutorials/ai-dao/overview.md @@ -7,12 +7,15 @@ description: "A brief overview of the Verifiable AI DAO tutorial built using the import { TryDemo } from '@site/src/components/TryDemo'; -In this tutorial, you'll explore how to build a `fully verifiable AI DAO` using the Shade Agent Framework. The Verifiable AI DAO is a DAO smart contract that uses a Shade Agent with a verifiable LLM to vote on governance proposals according to its predefined manifesto, to create transparent, AI-driven governance that is decentralized and auditable from end-to-end. +:::warning +The Verifiable AI DAO tutorial uses an old version of the Shade Agent Framework, which contains known critical vulnerabilities and has a different architecture. + +No representations or warranties are made regarding security, correctness, or fitness for any purpose. Use of this software is entirely at your own risk. - +The tutorial will be updated to use the latest version of the Shade Agent Framework in the future. +::: + +In this tutorial, you'll explore how to build a `fully verifiable AI DAO` using the Shade Agent Framework. The Verifiable AI DAO is a DAO smart contract that uses a Shade Agent with a verifiable LLM to vote on governance proposals according to its predefined manifesto, to create transparent, AI-driven governance that is decentralized and auditable from end-to-end. This tutorial also serves as a `template` for building `yield and resume-based Shade Agents`. This is a smart contract that, when called, halts its execution for the verified agent to complete some logic and resume the transaction when it has a result, enabled by NEAR's asynchronous design. This pattern allows the agent and LLM become a part of the contract, enabling smart contracts with extended capabilities of a backend server that can make API calls and use LLM inference. This is especially useful when making cross-contract calls to smart contracts that use yield and resume, allowing you to receive the result in the callback - for example, an on-demand oracle. @@ -27,12 +30,11 @@ This tutorial demonstrates how key components of the Shade Agent Framework work --- -## Required knowledge +## Required Knowledge To understand this tutorial, you should have familiarity with these concepts: - [Shade Agents](../../getting-started/introduction.md) - [NEAR Smart Contracts](../../../../smart-contracts/what-is.md) -- [Custom Agent Contracts](../../reference/custom-agent-contract.md) --- diff --git a/docs/ai/shade-agents/tutorials/tutorials-overview.md b/docs/ai/shade-agents/tutorials/tutorials-overview.md index 28a33056a74..23f78b42262 100644 --- a/docs/ai/shade-agents/tutorials/tutorials-overview.md +++ b/docs/ai/shade-agents/tutorials/tutorials-overview.md @@ -15,11 +15,6 @@ This section provides tutorials and templates to help you build Shade Agents fas Explore the [Quickstart docs](../getting-started/quickstart/deploying.md) - - ### Summary The Quickstart features a verifiable Oracle secured by the Shade Agent Framework that pushes the price of ETH to a smart contract on Ethereum. @@ -41,11 +36,6 @@ The Quickstart provides a basic template for building your first multichain Shad Explore the [Verifiable AI DAO docs](./ai-dao/overview.md) - - ### Summary The Verifiable AI DAO is a DAO smart contract that uses a Shade Agent with a verifiable LLM to vote on governance proposals according to its predefined manifesto, ensuring transparent and auditable AI-driven governance decisions. diff --git a/website/sidebars.js b/website/sidebars.js index 5211eaea986..733be958c2f 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -210,6 +210,8 @@ const sidebar = { "Concepts": [ "ai/shade-agents/concepts/framework-overview", "ai/shade-agents/concepts/what-can-you-build", + "ai/shade-agents/concepts/ai-inference", + "ai/shade-agents/concepts/terminology", "ai/shade-agents/concepts/security", ] }, @@ -230,9 +232,7 @@ const sidebar = { "Reference": [ "ai/shade-agents/reference/api", "ai/shade-agents/reference/cli", - "ai/shade-agents/reference/environment-variables", - "ai/shade-agents/reference/custom-agent-contract", - "ai/shade-agents/reference/plugins", + "ai/shade-agents/reference/agent-contract", ] }, ] diff --git a/website/src/components/sigsSupport.js b/website/src/components/sigsSupport.js index 31c68804691..32ba4d56112 100644 --- a/website/src/components/sigsSupport.js +++ b/website/src/components/sigsSupport.js @@ -34,7 +34,7 @@ export function SigsSupport() { | diff --git a/website/static/assets/docs/ai/shade-agent-stack-diagram.png b/website/static/assets/docs/ai/shade-agent-stack-diagram.png index 8a6dcbebea3..2f564e21b4f 100644 Binary files a/website/static/assets/docs/ai/shade-agent-stack-diagram.png and b/website/static/assets/docs/ai/shade-agent-stack-diagram.png differ