From f63524f0defb0d294bdc5d7467cd4a02048e462b Mon Sep 17 00:00:00 2001 From: Can Kisagun Date: Mon, 8 Sep 2025 14:52:31 -0400 Subject: [PATCH 1/4] Update frontend.md updated some of the description Signed-off-by: Can Kisagun --- docs/integration/7683/frontend.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/integration/7683/frontend.md b/docs/integration/7683/frontend.md index 3667cb3e..43b66ef0 100644 --- a/docs/integration/7683/frontend.md +++ b/docs/integration/7683/frontend.md @@ -1,21 +1,21 @@ --- -id: frontend-integration -title: Frontend Integration -sidebar_label: Frontend Integration +id: aggregator-integration +title: Aggregator Integration +sidebar_label: Aggregator Integration sidebar_position: 2 --- -# Frontend Integration for ERC 7683 Intent Bridging +# Aggragator Integration for t1 Intent Bridging -This guide explains how to integrate the 7683 intent bridging mechanism into your frontend application. It covers encoding the order data, estimating gas, and executing the bridge transaction. +This guide explains how to integrate the t1 intent bridging mechanism into your frontend application. It covers encoding the order data, estimating gas, and executing the bridge transaction. ## Overview -The 7683 Intent Bridge enables cross-chain token transfers through an intent-based system. Users express their intent to bridge tokens, and fillers compete to fulfill these intents, providing better execution and potentially better rates. +The t1 Intent Bridge facilitates cross-chain token transfers using a Trusted Execution Environment (TEE) based proving system. Users express their intent to bridge tokens, and fillers compete to fulfill these intents. TEE-based xChainRead enables solvers to get repaid in less than 10 seconds, improving capital efficiency for solvers and providing better execution and rates for users. ## How it works -The 7683 Intent Bridge operates through a standardized intent protocol: +The t1 Intent Bridge operates through a standardized intent protocol that is based on ERC-7683 standard: 1. **Intent Creation**: Users create an intent specifying source and destination tokens, amounts, and execution parameters 2. **Order Encoding**: The intent is encoded according to ERC-7683 standards with proper ABI encoding From 074dff60882924985e081689bf118c334ac9895a Mon Sep 17 00:00:00 2001 From: prince Date: Tue, 9 Sep 2025 23:01:05 +0800 Subject: [PATCH 2/4] update docs with aggregator frontend --- ...{frontend.md => aggregator-integration.md} | 87 ++++++++++++++----- 1 file changed, 66 insertions(+), 21 deletions(-) rename docs/integration/7683/{frontend.md => aggregator-integration.md} (76%) diff --git a/docs/integration/7683/frontend.md b/docs/integration/7683/aggregator-integration.md similarity index 76% rename from docs/integration/7683/frontend.md rename to docs/integration/7683/aggregator-integration.md index 43b66ef0..a1f9ff5c 100644 --- a/docs/integration/7683/frontend.md +++ b/docs/integration/7683/aggregator-integration.md @@ -5,7 +5,7 @@ sidebar_label: Aggregator Integration sidebar_position: 2 --- -# Aggragator Integration for t1 Intent Bridging +# Aggregator Integration for t1 Intent Bridging This guide explains how to integrate the t1 intent bridging mechanism into your frontend application. It covers encoding the order data, estimating gas, and executing the bridge transaction. @@ -25,35 +25,74 @@ The t1 Intent Bridge operates through a standardized intent protocol that is bas ## Integration Overview -The main components of frontend integration are: +The main components of aggregator integration are: +- Querying `minAmountOut` from API - Encoding intent order data in a Solidity-compatible format. - Executing the bridge intent with custom parameters. -## Encoding Order Data +### 1. Querying minAmountOut via API + +To obtain a pre-auction bid, query the POST `${baseUrl}/preauction` API: + +```bash +curl --location 'https://{baseUrl}/preauction' \ + --header 'Content-Type: application/json' \ + --data '{ + "id": "uuid", + "srcTokenAddress": "string", + "dstTokenAddress": "string", + "srcChainId": 1, + "dstChainId": 137, + "amountIn": "1000000000000000000" + }' +``` + +Your response should look like this: + +```typescript +interface Quote { + id: string + request: { + srcChainId: number + dstChainId: number + srcTokenAddress: string + dstTokenAddress: string + amountIn: number + } + amountOut: string + solverAddress: string + timestamp: number +} +``` + +We can obtain the `amountOut` and use it as `minAmountOut` in our intent. + +### 2. Encoding Order Data To prepare the order data for execution, use the `encodeIntentOrderData` function. This ensures the `bytes` format is correctly aligned for the 7683 contract. -### IntentOrderData Type Definition +#### IntentOrderData Type Definition -```ts +```typescript export type IntentOrderData = { sender: string // padded address recipient: string // padded address inputToken: string // padded address outputToken: string // padded address amountIn: string - amountOut: string + minAmountOut: string senderNonce: number originDomain: number destinationDomain: number destinationSettler: string // padded address fillDeadline: number + closedAuction: boolean data: string // hex string like "0x" } ``` -```ts +```typescript export function encodeIntentOrderData(orderData: IntentOrderData): string { const abiCoder = ethers.utils.defaultAbiCoder const toBytes32 = (addr: string) => ethers.utils.hexZeroPad(addr, 32) @@ -71,6 +110,7 @@ export function encodeIntentOrderData(orderData: IntentOrderData): string { 'uint32', 'bytes32', 'uint32', + 'boolean', 'bytes', ], [ @@ -79,14 +119,15 @@ export function encodeIntentOrderData(orderData: IntentOrderData): string { toBytes32(orderData.inputToken), toBytes32(orderData.outputToken), orderData.amountIn, - orderData.amountOut, + orderData.minAmountOut, orderData.senderNonce, orderData.originDomain, orderData.destinationDomain, toBytes32(orderData.destinationSettler), orderData.fillDeadline, + orderData.closedAuction, orderData.data, - ] + ], ) const dynamicOffsetPrefix = '0x0000000000000000000000000000000000000000000000000000000000000020' @@ -94,7 +135,7 @@ export function encodeIntentOrderData(orderData: IntentOrderData): string { } ``` -### 2. Order Data Type Hash +### 3. Order Data Type Hash Define the EIP-712 type string and hash for the order data: @@ -106,18 +147,19 @@ export const ORDER_DATA_TYPE_STRING = 'bytes32 inputToken,' + 'bytes32 outputToken,' + 'uint256 amountIn,' + - 'uint256 amountOut,' + + 'uint256 minAmountOut,' + 'uint256 senderNonce,' + 'uint32 originDomain,' + 'uint32 destinationDomain,' + 'bytes32 destinationSettler,' + 'uint32 fillDeadline,' + + 'bool closedAuction,' + 'bytes data)' export const ORDER_DATA_TYPE_HASH = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(ORDER_DATA_TYPE_STRING)) ``` -### 3. Executing Intent Bridge +### 4. Executing Intent Bridge Here's the complete implementation for executing an intent bridge: @@ -125,17 +167,19 @@ Here's the complete implementation for executing an intent bridge: export const executeIntentBridge = async ( walletProvider: providers.ExternalProvider, walletAddress: string, + tokenInAddress: string, + tokenOutAddress: string, fromChainId: number, toChainId: number, - amount: string + amount: string, ) => { const provider = new ethers.providers.Web3Provider(walletProvider, 'any') const signer = provider.getSigner() const originChainContract = new ethers.Contract( - process.env.ORIGIN_CHAIN_7683_CONTRACT_ADDRESS, + process.env.ORIGIN_CHAIN_7683_CONTRACT_ADDRESS!, ORIGIN_CHAIN_7683_ABI, - signer + signer, ) try { @@ -145,15 +189,16 @@ export const executeIntentBridge = async ( const orderData: IntentOrderData = { sender: walletAddress, recipient: walletAddress, - inputToken: '0x0000000000000000000000000000000000000000', // Native ETH - outputToken: '0x0000000000000000000000000000000000000000', // Native ETH + inputToken: tokenInAddress, + outputToken: tokenOutAddress, amountIn: Number(amountAfterConversion).toString(), - amountOut: Number(amountAfterConversion).toString(), // Adjust amountOut based on the filler's fee + minAmountOut: Number(amountAfterConversion).toString(), // Get minAmountOut from our /preauction API senderNonce: Math.floor(Math.random() * 1e15), originDomain: fromChainId, destinationDomain: toChainId, - destinationSettler: process.env.DESTINATION_CHAIN_7683_CONTRACT_ADDRESS, + destinationSettler: process.env.DESTINATION_CHAIN_7683_CONTRACT_ADDRESS!, fillDeadline: Math.floor(Date.now() / 1000) + 24 * 60 * 60, // 24 hour deadline + closedAuction: true, data: '0x', } @@ -169,7 +214,7 @@ export const executeIntentBridge = async ( }, { value: amountAfterConversion.toBigInt(), - } + }, ) await executeIntentBridgeResult.wait() } catch (e) { @@ -178,7 +223,7 @@ export const executeIntentBridge = async ( } ``` -### Security Considerations +## Security Considerations - **Nonce Management**: Each intent uses a unique random nonce to prevent replay attacks - **Deadline Protection**: 24-hour deadline prevents indefinite pending states From 35c845882b58727c40e12b0f60b936b33f5db20d Mon Sep 17 00:00:00 2001 From: prince Date: Tue, 9 Sep 2025 23:08:03 +0800 Subject: [PATCH 3/4] updated sidebar --- sidebars.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sidebars.js b/sidebars.js index d5120257..5f821684 100644 --- a/sidebars.js +++ b/sidebars.js @@ -11,7 +11,7 @@ const sidebars = { { type: 'category', label: '7683', - items: ['integration/7683/solver-integration', 'integration/7683/frontend-integration'], + items: ['integration/7683/solver-integration', 'integration/7683/aggregator-integration'], }, ], } From e1c1561a47e8eff3de9458444ffb13c40bc7d0a3 Mon Sep 17 00:00:00 2001 From: prince Date: Tue, 9 Sep 2025 23:18:46 +0800 Subject: [PATCH 4/4] updated docs with aggreator integration --- .../7683/aggregator-integration.md | 40 ++++++++++++++----- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/docs/integration/7683/aggregator-integration.md b/docs/integration/7683/aggregator-integration.md index a1f9ff5c..0470d461 100644 --- a/docs/integration/7683/aggregator-integration.md +++ b/docs/integration/7683/aggregator-integration.md @@ -40,14 +40,23 @@ curl --location 'https://{baseUrl}/preauction' \ --header 'Content-Type: application/json' \ --data '{ "id": "uuid", - "srcTokenAddress": "string", - "dstTokenAddress": "string", + "srcTokenAddress": "0x...", + "dstTokenAddress": "0x...", "srcChainId": 1, "dstChainId": 137, "amountIn": "1000000000000000000" }' ``` +**Request Parameters:** + +- `id`: randomly generated v4 uuid +- `srcTokenAddress`: input token address +- `dstTokenAddress`: output token address +- `srcChainId`: input chain id +- `dstChainId`: output chain id +- `amountIn`: input amount in units + Your response should look like this: ```typescript @@ -164,14 +173,21 @@ export const ORDER_DATA_TYPE_HASH = ethers.utils.keccak256(ethers.utils.toUtf8By Here's the complete implementation for executing an intent bridge: ```typescript +// Define TokenInfo type +interface TokenInfo { + address: string + decimal: number +} + export const executeIntentBridge = async ( walletProvider: providers.ExternalProvider, walletAddress: string, - tokenInAddress: string, - tokenOutAddress: string, + tokenIn: TokenInfo, + tokenOut: TokenInfo, fromChainId: number, toChainId: number, amount: string, + amountOut: string, // Get this from the /preauction API response ) => { const provider = new ethers.providers.Web3Provider(walletProvider, 'any') const signer = provider.getSigner() @@ -183,22 +199,23 @@ export const executeIntentBridge = async ( ) try { - const amountAfterConversion = ethers.utils.parseUnits(amount, 18) + const amountInAfterConversion = ethers.utils.parseUnits(amount, tokenIn.decimal) + const amountOutAfterConversion = ethers.utils.parseUnits(amountOut, tokenOut.decimal) // Construct order data const orderData: IntentOrderData = { sender: walletAddress, recipient: walletAddress, - inputToken: tokenInAddress, - outputToken: tokenOutAddress, - amountIn: Number(amountAfterConversion).toString(), - minAmountOut: Number(amountAfterConversion).toString(), // Get minAmountOut from our /preauction API + inputToken: tokenIn.address, + outputToken: tokenOut.address, + amountIn: Number(amountInAfterConversion).toString(), + minAmountOut: Number(amountOutAfterConversion).toString(), // Get minAmountOut from our /preauction API senderNonce: Math.floor(Math.random() * 1e15), originDomain: fromChainId, destinationDomain: toChainId, destinationSettler: process.env.DESTINATION_CHAIN_7683_CONTRACT_ADDRESS!, fillDeadline: Math.floor(Date.now() / 1000) + 24 * 60 * 60, // 24 hour deadline - closedAuction: true, + closedAuction: true, // this will always be true if you are using our closed auction api data: '0x', } @@ -212,8 +229,9 @@ export const executeIntentBridge = async ( orderDataType: ORDER_DATA_TYPE_HASH, orderData: encodedOrderData, }, + // only if you are transferring native ETH, else remove line 233-235 { - value: amountAfterConversion.toBigInt(), + value: amountInAfterConversion.toBigInt(), }, ) await executeIntentBridgeResult.wait()