Skip to content

Commit

Permalink
add deBridge (#253)
Browse files Browse the repository at this point in the history
# Pull Request Description

## Related Issue
Fixes #123 (Add deBridge Integration)

## Changes Made
This PR adds deBridge DLN (Decentralized Liquidity Network) protocol
integration for cross-chain token transfers with the following features:
- Cross-chain token bridging between Solana and other chains
- Bridge transaction creation and execution
- Transaction status monitoring
- Chain information retrieval

## Screenshots

![Screenshot from 2025-02-07
10-04-05](https://github.com/user-attachments/assets/a5742237-f2d4-4530-832e-bf6f216d7b8b)

![Screenshot from 2025-02-07
12-25-15](https://github.com/user-attachments/assets/06e5fca2-f3bd-453e-9ca4-98caec589152)

Result:
https://app.debridge.finance/order?orderId=0xe7bda6f7756fb4211bc21b229eca52cb051269602dbbe403ca01968abf99b9ae

### Core Features
1. **Chain Information**
   - Get list of supported chains and their configurations
   - Chain IDs and names for all supported networks
   - Special handling for Solana chain (ID: 7565164)

2. **Bridge Operations**
   - Create bridge orders for cross-chain transfers
   - Execute bridge transactions
   - Check transaction status with detailed feedback
   - Support for both Solana -> EVM and EVM -> Solana transfers

3. **User Experience**
   - Clear documentation for address format requirements
   - Detailed error handling with actionable messages
   - Chain-specific considerations for token addresses
   - Status tracking for bridge transactions
  
## Implementation Details
### Tools Added
1. `getSupportedChains.ts`:
   - Retrieves list of supported chains and their configurations
   - No input required
   - Returns chain IDs and names

2. `createBridgeOrder.ts`:
   - Creates cross-chain bridge orders
   - Handles both Solana and EVM token formats
   - Returns transaction data and estimated amounts

3. `executeBridgeOrder.ts`:
   - Executes bridge transactions
   - Takes hex-encoded transaction data
   - Returns transaction signature

4. `checkTransactionStatus.ts`:
   - Checks bridge transaction status
   - Takes transaction hash or order ID
   - Returns detailed order status

### Actions Added
- `getSupportedChainsAction`
- `createBridgeOrderAction`
- `executeBridgeOrderAction`
- `checkTransactionStatusAction`

## Transaction Example
Complete bridge flow example (SOL -> ETH):
```typescript
// 1. Get supported chains
const chains = await agent.getBridgeSupportedChains();
console.log("Available chains:", chains);

// 2. Create bridge order
const orderInput = {
  srcChainId: "7565164", // Solana
  srcChainTokenIn: "11111111111111111111111111111111", // Native SOL
  srcChainTokenInAmount: "1000000000", // 1 SOL (9 decimals)
  dstChainId: "1", // Ethereum
  dstChainTokenOut: "0x0000000000000000000000000000000000000000", // ETH
  dstChainTokenOutRecipient: "0x23C279e58ddF1018C3B9D0C224534fA2a83fb1d2" // ETH recipient
};

const order = await agent.createBridgeOrder(orderInput);
console.log("Order created:", order);

// 3. Execute bridge transaction
const signature = await agent.bridge(order.tx.data);
console.log("Bridge transaction sent:", signature);

// 4. Check status
const status = await agent.checkBridgeStatus(signature);
console.log("Bridge status:", status);
  • Loading branch information
thearyanag authored Feb 8, 2025
2 parents d99bf76 + a732874 commit e2ce8e2
Show file tree
Hide file tree
Showing 25 changed files with 1,294 additions and 1 deletion.
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ Anyone - whether an SF-based AI researcher or a crypto-native builder - can brin
- Register/resolve Alldomains
- Perpetuals Trading with Adrena Protocol
- Drift Vaults, Perps, Lending and Borrowing
- Cross-chain bridging via deBridge DLN

- **Solana Blinks**
- Lending by Lulo (Best APR for USDC)
Expand Down Expand Up @@ -557,6 +558,58 @@ const signature = await agent.swap(
```

### Cross-Chain Bridge via deBridge

The Solana Agent Kit supports cross-chain token transfers using deBridge's DLN protocol. Here's how to use it:

1. Check supported chains:
```typescript
const chains = await agent.getDebridgeSupportedChains();
console.log("Available chains:", chains);
// Example output: { chains: [{ chainId: "1", chainName: "Ethereum" }, { chainId: "7565164", chainName: "Solana" }] }
```

2. Get available tokens (optional):
```typescript
const tokens = await agent.getDebridgeTokensInfo("1", "USDC"); // Search for USDC on Ethereum
console.log("Available tokens:", tokens);
// Shows tokens matching 'USDC' on the specified chain
```

3. Create bridge order (SOL -> ETH):
```typescript
const orderInput = {
srcChainId: "7565164", // Solana
srcChainTokenIn: "11111111111111111111111111111111", // Native SOL
srcChainTokenInAmount: "1000000000", // 1 SOL (9 decimals)
dstChainId: "1", // Ethereum
dstChainTokenOut: "0x0000000000000000000000000000000000000000", // ETH
dstChainTokenOutRecipient: "0x23C279e58ddF1018C3B9D0C224534fA2a83fb1d2" // ETH recipient
};
const order = await agent.createDebridgeOrder(orderInput);
console.log("Order created:", order);
// Contains transaction data and estimated amounts
```

4. Execute the bridge order:
```typescript
const signature = await agent.executeDebridgeOrder(order.tx.data);
console.log("Bridge transaction sent:", signature);
```

5. Check bridge status:
```typescript
const status = await agent.checkDebridgeTransactionStatus(signature);
console.log("Bridge status:", status);
// Shows current status: Created, Fulfilled, etc.
```

Note: When bridging between chains:
- To Solana: Use base58 addresses for recipients and token mints
- From Solana: Use EVM addresses for recipients and ERC-20 format for tokens
- Always verify addresses and amounts before executing bridge transactions

## Examples

### LangGraph Multi-Agent System
Expand Down
2 changes: 1 addition & 1 deletion guides/test_it_out.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The project includes a test script located at `test/index.ts`. To execute the te

1. **Launch the Agent**
```bash
pnpm start
pnpm test:vercel-ai
```

2. **Select Your Mode**
Expand Down
72 changes: 72 additions & 0 deletions src/actions/debridge/checkTransactionStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Action } from "../../types/action";
import { SolanaAgentKit } from "../../agent";
import { z } from "zod";
import { checkDebridgeTransactionStatus } from "../../tools/debridge";

const checkDebridgeTransactionStatusAction: Action = {
name: "DEBRIDGE_CHECK_TRANSACTION_STATUS",
similes: [
"check bridge status",
"check debridge transaction",
"get bridge status",
"bridge transaction status",
],
description:
"Check the status of a cross-chain bridge transaction on deBridge",
examples: [
[
{
input: {
txHash:
"5v6Jx3qHsNaQvPe1Cs3AooAiY2ZnutxQHNJrHw9SwJzAeaDXMaD2JYGE579CFk88jMFw4YiKqmLUc6QCAwvhjKQX",
},
output: {
status: "success",
message: "Bridge transaction status retrieved successfully",
transaction: {
hash: "5v6Jx3qHsNaQvPe1Cs3AooAiY2ZnutxQHNJrHw9SwJzAeaDXMaD2JYGE579CFk88jMFw4YiKqmLUc6QCAwvhjKQX",
explorerUrl:
"https://explorer.solana.com/tx/5v6Jx3qHsNaQvPe1Cs3AooAiY2ZnutxQHNJrHw9SwJzAeaDXMaD2JYGE579CFk88jMFw4YiKqmLUc6QCAwvhjKQX",
},
orders: [
{
status: "completed",
srcChainTxHash:
"5v6Jx3qHsNaQvPe1Cs3AooAiY2ZnutxQHNJrHw9SwJzAeaDXMaD2JYGE579CFk88jMFw4YiKqmLUc6QCAwvhjKQX",
dstChainTxHash: "0x1234567890abcdef",
orderLink:
"https://app.debridge.finance/order?orderId=0x9876543210",
},
],
},
explanation:
"Check the status of a bridge transaction from Solana to Ethereum",
},
],
],
schema: z.object({
txHash: z.string().describe("Transaction hash to check status for"),
}),
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
try {
const orders = await checkDebridgeTransactionStatus(agent, input.txHash);

return {
status: "success",
message: "Bridge transaction status retrieved successfully",
transaction: {
hash: input.txHash,
explorerUrl: `https://explorer.solana.com/tx/${input.txHash}`,
},
orders,
};
} catch (error: any) {
return {
status: "error",
message: error.message,
};
}
},
};

export default checkDebridgeTransactionStatusAction;
167 changes: 167 additions & 0 deletions src/actions/debridge/createBridgeOrder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import { z } from "zod";
import { Action } from "../../types/action";
import { createDebridgeBridgeOrder } from "../../tools/debridge/createBridgeOrder";
import { SolanaAgentKit } from "../../agent";

const createDebridgeBridgeOrderAction: Action = {
name: "DEBRIDGE_CREATE_BRIDGE_ORDER",
description:
"Create a cross-chain bridge order using deBridge to transfer tokens between chains. Returns both the transaction data and estimated amounts.",
similes: [
"create bridge order",
"bridge tokens between chains",
"setup cross-chain transfer",
"initiate token bridge",
"start bridge transaction",
"prepare bridge order",
"transfer tokens cross-chain",
],
examples: [
[
{
input: {
srcChainId: "7565164", // Solana
srcChainTokenIn: "11111111111111111111111111111111", // Native SOL
srcChainTokenInAmount: "1000000000", // 1 SOL (9 decimals)
dstChainId: "1", // Ethereum
dstChainTokenOut: "0x0000000000000000000000000000000000000000", // ETH
dstChainTokenOutRecipient:
"0x23C279e58ddF1018C3B9D0C224534fA2a83fb1d2", // ETH recipient
},
output: {
status: "success",
tx: {
data: "0x...",
to: "0x...",
value: "0",
},
estimation: {
srcChainTokenIn: {
amount: "1000000000",
tokenAddress: "11111111111111111111111111111111",
decimals: 9,
symbol: "SOL",
},
dstChainTokenOut: {
amount: "0.99",
tokenAddress: "0x0000000000000000000000000000000000000000",
decimals: 18,
symbol: "ETH",
},
fees: {
srcChainTokenIn: "0.01",
dstChainTokenOut: "0.01",
},
},
message: "Bridge order created successfully",
},
explanation:
"Create a bridge order to transfer 1 SOL from Solana to ETH on Ethereum",
},
],
],
schema: z.object({
srcChainId: z.string().describe("Source chain ID (e.g., '1' for Ethereum)"),
srcChainTokenIn: z
.string()
.describe(
"Source token address (use '0x0000000000000000000000000000000000000000' for native tokens on EVM)",
),
srcChainTokenInAmount: z
.string()
.describe("Amount of source tokens to bridge (in smallest units)"),
dstChainId: z
.string()
.describe("Destination chain ID (e.g., '7565164' for Solana)"),
dstChainTokenOut: z.string().describe("Destination token address"),
dstChainTokenOutRecipient: z
.string()
.describe("Required: Recipient address on destination chain"),
dstChainTokenOutAmount: z
.string()
.optional()
.describe(
"Optional: Expected amount of tokens to receive (default: 'auto')",
),
slippage: z
.number()
.optional()
.describe(
"Optional: Slippage tolerance in percentage (e.g., 0.5 for 0.5%)",
),
additionalTakerRewardBps: z
.number()
.optional()
.describe("Optional: Additional taker reward in basis points"),
srcIntermediaryTokenAddress: z
.string()
.optional()
.describe("Optional: Source chain intermediary token address"),
dstIntermediaryTokenAddress: z
.string()
.optional()
.describe("Optional: Destination chain intermediary token address"),
dstIntermediaryTokenSpenderAddress: z
.string()
.optional()
.describe(
"Optional: Destination chain intermediary token spender address",
),
intermediaryTokenUSDPrice: z
.number()
.optional()
.describe("Optional: USD price of intermediary token"),
srcAllowedCancelBeneficiary: z
.string()
.optional()
.describe("Optional: Fixed recipient for cancelled orders"),
referralCode: z
.number()
.optional()
.describe("Optional: Referral code for earning deBridge points"),
affiliateFeePercent: z
.number()
.optional()
.describe("Optional: Affiliate fee percentage"),
}),
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
try {
// Get the agent's wallet address
const walletAddress = agent.wallet.publicKey.toBase58();

const response = await createDebridgeBridgeOrder({
srcChainId: input.srcChainId,
srcChainTokenIn: input.srcChainTokenIn,
srcChainTokenInAmount: input.srcChainTokenInAmount,
dstChainId: input.dstChainId,
dstChainTokenOut: input.dstChainTokenOut,
dstChainTokenOutRecipient: input.dstChainTokenOutRecipient,
account: walletAddress, // Use the agent's wallet address
dstChainTokenOutAmount: input.dstChainTokenOutAmount,
slippage: input.slippage,
additionalTakerRewardBps: input.additionalTakerRewardBps,
srcIntermediaryTokenAddress: input.srcIntermediaryTokenAddress,
dstIntermediaryTokenAddress: input.dstIntermediaryTokenAddress,
dstIntermediaryTokenSpenderAddress:
input.dstIntermediaryTokenSpenderAddress,
intermediaryTokenUSDPrice: input.intermediaryTokenUSDPrice,
srcAllowedCancelBeneficiary: input.srcAllowedCancelBeneficiary,
referralCode: input.referralCode,
affiliateFeePercent: input.affiliateFeePercent,
});

return {
status: "success",
...response,
message: "Bridge order created successfully",
};
} catch (error: any) {
return {
status: "error",
message: `Failed to create bridge order: ${error.message}`,
};
}
},
};

export default createDebridgeBridgeOrderAction;
68 changes: 68 additions & 0 deletions src/actions/debridge/executeBridgeOrder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { z } from "zod";
import { Action } from "../../types/action";
import { executeDebridgeBridgeOrder } from "../../tools/debridge/executeBridgeOrder";
import { SolanaAgentKit } from "../../agent";

const executeDebridgeBridgeOrderAction: Action = {
name: "DEBRIDGE_EXECUTE_BRIDGE_ORDER",
description:
"Execute a cross-chain bridge transaction on Solana using deBridge with the transaction data from DEBRIDGE_CREATE_BRIDGE_ORDER.",
similes: [
"execute bridge transaction",
"send bridge transaction",
"submit bridge transaction",
"process bridge transaction",
"complete bridge transfer",
"finalize cross-chain transfer",
],
examples: [
[
{
input: {
transactionData:
"0x23b872dd000000000000000000000000742d35cc6634c0532925a3b844bc454e4438f44e000000000000000000000000e7351fd770a37282b91d153ee690b63579b6e837000000000000000000000000000000000000000000000000000de0b6b3a7640000",
},
output: {
status: "success",
signature:
"4jJ6UvwqzHHqKif7hKvz3JwA8qQFEAuQqFBpPgX6qHzk9UF9eBiNJSqrEEtbqzVBGZYqoAKK6hUqHP4YmwmvQsZm",
message:
"Successfully executed bridge transaction. Signature: 4jJ6...",
},
explanation:
"Execute a cross-chain bridge transaction using transaction data from DEBRIDGE_CREATE_BRIDGE_ORDER.",
},
],
],
schema: z.object({
transactionData: z
.string()
.describe(
"Transaction data obtained from DEBRIDGE_CREATE_BRIDGE_ORDER command",
),
}),
handler: async (
agent: SolanaAgentKit,
input: Record<string, any>,
): Promise<Record<string, any>> => {
try {
const signature = await executeDebridgeBridgeOrder(
agent,
input.transactionData,
);

return {
status: "success",
signature,
message: `Successfully executed bridge transaction. Signature: ${signature.slice(0, 4)}...`,
};
} catch (error: any) {
return {
status: "error",
message: `Failed to execute bridge transaction: ${error.message}`,
};
}
},
};

export default executeDebridgeBridgeOrderAction;
Loading

0 comments on commit e2ce8e2

Please sign in to comment.