# Plugin Integration

This guide will walk you through the process of integrating your project with Curvance's plugin architecture, allowing your application to interact with Curvance's smart contracts on behalf of users.&#x20;

{% hint style="info" %}
For an in-depth exploration of the Plugin and Delegation system architecture, check out our technical documentation page: [Plugin & Delegation System](/app/developer-docs/plugin-and-delegation-system.md)
{% endhint %}

## Understanding Plugin Delegation

Curvance's plugin system enables third-party applications to perform actions on behalf of users through a secure delegation mechanism. This allows for innovative features like:

* Automated portfolio management.
* Advanced trading strategies.
* Cross-chain operations.
* Reward auto-compounding.
* Sequential action chaining.

## Code Examples

Before your application can act on behalf of users, they must explicitly authorize your contract address as a delegate. This is the critical first step in the integration process.

#### Enabling Delegation with setDelegateApproval()

Users need to call the `setDelegateApproval()` function on the appropriate Curvance contract.&#x20;

Calling `setDelegateApproval()` is called correctly with these arguments:

<table><thead><tr><th width="148.5">Type</th><th width="168.35009765625">Name</th><th>Instruction</th></tr></thead><tbody><tr><td>address</td><td>delegate</td><td>The address of your platform's contract.</td></tr><tr><td>bool</td><td>isApproved</td><td>To activate delegation of your platform, this would be <code>true</code>. </td></tr></tbody></table>

Below is an example showing how to implement this using Ethers.js 5.7 for a position that uses `PositionManagementSimple` (such as pwstETH):

```javascript
const { ethers } = require("ethers");
// Import your project's contract address
const { YourProject_Address } = require("./config/addresses");
// Import pwstETH Position Management contract address from a config file
const { pwstETH_PositionManagement_Address } = require("./config/addresses");
// Import ABI from a separate file
const { pwstETH_PositionManagement_ABI } = require("./abis/pwstETHABI");

// Connect to provider (adjust as needed for your environment)
const provider = new ethers.providers.Web3Provider(window.ethereum);
// Or for a specific RPC endpoint:
// const provider = new ethers.providers.JsonRpcProvider("YOUR_RPC_URL");

// Create signer
const signer = provider.getSigner();

// Create contract instance using imported address, ABI, and signer
const cwstETHPositionManagementContract = new ethers.Contract(
  cwstETH_PositionManagement_Address, 
  cwstETH_PositionManagement_ABI, 
  signer
);

async function approveDelegate() {
  try {
    // Call the setDelegateApproval function
    const tx = await pwstETHPositionManagementContract.setDelegateApproval(
      YourProject_Address, 
      true);
    
    console.log("Transaction submitted:", tx.hash);
    
    // Wait for transaction to be mined
    const receipt = await tx.wait();
    console.log("Transaction confirmed in block:", receipt.blockNumber);
    
    return receipt;
  } catch (error) {
    console.error("Error approving delegate:", error);
    
    // Handle specific errors
    if (error.code === 'CALL_EXCEPTION') {
      if (error.reason && error.reason.includes("PluginDelegable__DelegatingDisabled")) {
        console.error("Delegation is disabled for this account");
      } else if (error.reason && error.reason.includes("PluginDelegable_InvalidParameter")) {
        console.error("Invalid parameter: Cannot delegate to yourself");
      }
    }
    
    throw error;
  }
}
```

***

### Verification and Security Best Practices

When implementing delegation in your application:

1. **Verify delegation status:** Always check if your contract is still approved as a delegate before attempting actions by calling `isDelegate()`in the CentralRegistry contract using the following parameters:

<table><thead><tr><th width="133.76669311523438">Type</th><th width="162.066650390625">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>user</td><td>The user's address.</td></tr><tr><td>address</td><td>delegate</td><td>Your platform's contract address.</td></tr></tbody></table>

```javascript
const { ethers } = require("ethers");
// Import your project's contract address
const { YourProject_Address } = require("./config/addresses");
// Import CentralRegistry contract address from a config file
const { CentralRegistryAddress } = require("./config/addresses");
// Import ABI from a separate file
const { CentralRegistry_ABI } = require("./abis/centralRegistryABI");

// Connect to provider (adjust as needed for your environment)
const provider = new ethers.providers.Web3Provider(window.ethereum);
// Or for a specific RPC endpoint:
// const provider = new ethers.providers.JsonRpcProvider("YOUR_RPC_URL");

// Create signer
const signer = provider.getSigner();

// Create contract instance using imported address, ABI, and signer
const CentralRegistry_Contract = new ethers.Contract(
  CentralRegistryAddress, 
  CentralRegistry_ABI,
  signer
);

async function checkDelegate() {
  try {
    // Call the isDelegate function
    const isDelegate = await CentralRegistry_Contract.isDelegate(
      userAddress, 
      true);
    
    console.log("isDelegate: ", isDelegate);
    
  } catch (error) {
    console.error("Error approving delegate:", error);
    
    throw error;
  }
}
```

2. **Handle revocation:** Users can revoke delegation at any time, so design your application to gracefully handle this case.
3. **Transparent permissions:** Clearly communicate to users which actions your application will perform on their behalf.
4. **Gas optimization:** Consider batching multiple delegated actions when possible to reduce gas costs.

### Next Steps

After implementing the delegation setup, your application should:

1. Verify the delegation was successful.
2. Store the user's delegation status in your application state.
3. Implement the specific delegated actions your application needs.
4. Provide a way for users to revoke delegation if desired.

For technical support or to get your plugin featured in Curvance's ecosystem, please contact our developer relations team.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.curvance.com/app/developer-docs/quick-start-guides/plugin-integration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
