# ERC-7683 — Cross-Chain Intents का Standard
Cross-chain bridges slow और risky हैं। Intents nई pattern हैं जो UX को drastically improve करती हैं — ERC-7683 उनका पहला standard है।
Intents क्या हैं?
Traditional (Imperative)
User specify करता है कैसे:
"Ethereum पर USDC approve करो, bridge contract को call करो,
Arbitrum पर message relay करो, destination पर mint करो"
4 transactions, 15 minutes, high gas।
Intent-Based (Declarative)
User specify करता है क्या:
"मुझे Arbitrum पर 1000 USDC चाहिए"
Filler (third party) best path ढूंढता है, execution करता है — user को instant settlement मिलता है।
ERC-7683 Core Idea
Standard interface ताकि:
Components
┌──────────┐
│ User │
└────┬─────┘
│ 1. Post intent
▼
┌─────────────────┐
│ Origin Chain │
│ CrossChainOrder │ ← ERC-7683 contract
└─────────────────┘
│
│ 2. Filler monitors
▼
┌─────────────────┐
│ Destination │
│ Settler │ ← Verifies fulfillment
└─────────────────┘
│
│ 3. Proof relayed back
▼
┌─────────────────┐
│ Origin Chain │
│ Release funds │
└─────────────────┘
CrossChainOrder Struct
struct CrossChainOrder {
address user; // Intent creator
address originToken; // Token to give
uint256 originAmount;
uint32 destinationChain;
address destinationToken;
uint256 destinationAmount;
address recipient;
uint64 deadline; // Expiry
bytes32 nonce; // Unique ID
bytes fillerData; // Filler-specific params
}
Interface
interface ICrossChainOrder {
/// @notice Post new intent
function open(CrossChainOrder calldata order) external;
/// @notice Filler claims intent
function fill(bytes32 orderId, bytes calldata fillData) external;
/// @notice Settler verifies fulfillment
function resolve(
bytes32 orderId,
bytes calldata proof
) external;
}
Example: Cross-Chain Swap
1. User Posts Intent
Ethereum पर:
contract IntentGateway is ICrossChainOrder {
mapping(bytes32 => CrossChainOrder) public orders;
function open(CrossChainOrder calldata order) external {
require(order.deadline > block.timestamp, "Expired");
bytes32 orderId = keccak256(abi.encode(order));
orders[orderId] = order;
// Lock user's tokens
IERC20(order.originToken).transferFrom(
msg.sender,
address(this),
order.originAmount
);
emit OrderOpened(orderId, order);
}
}
2. Filler Monitors + Fills
Off-chain bot:
// Listen to OrderOpened events
gateway.on("OrderOpened", async (orderId, order) => {
if (isProfitable(order)) {
// Fill on destination chain
await destinationSettler.fill(orderId, order.destinationAmount);
}
});
Arbitrum पर:
contract Settler {
function fill(bytes32 orderId, uint256 amount) external {
// Filler sends tokens to user
token.transferFrom(msg.sender, recipient, amount);
emit Filled(orderId, msg.sender);
}
}
3. Proof Relay + Settlement
Filler relays proof back to origin chain:
function resolve(bytes32 orderId, bytes calldata proof) external {
// Verify proof (Merkle, signature, storage proof)
require(verifyFill(orderId, proof), "Invalid proof");
CrossChainOrder memory order = orders[orderId];
// Release funds to filler
IERC20(order.originToken).transfer(msg.sender, order.originAmount);
delete orders[orderId];
emit Resolved(orderId);
}
Gasless Orders (via Permit2)
User sign करता है off-chain, filler gas pay करता है:
struct SignedOrder {
CrossChainOrder order;
bytes signature;
}
function openSigned(SignedOrder calldata signedOrder) external {
bytes32 hash = hashOrder(signedOrder.order);
address signer = recoverSigner(hash, signedOrder.signature);
require(signer == signedOrder.order.user, "Invalid sig");
// Permit2 transfer (no user tx needed)
permit2.transferFrom(
signedOrder.order.user,
address(this),
signedOrder.order.originAmount,
signedOrder.order.originToken
);
emit OrderOpened(hash, signedOrder.order);
}
User UX:
// 1. Sign message (free)
const signature = await wallet.signTypedData(order);
// 2. Post to filler API (free)
await fetch("https://filler.xyz/submit", {
method: "POST",
body: JSON.stringify({ order, signature })
});
// 3. Done! Filler handles rest
Real Implementations
Across Protocol
Intent-based bridge — fillers compete for orders।
// Across settler
function fillRelay(
address depositor,
address recipient,
uint256 amount,
uint32 originChainId,
bytes32 depositId
) external {
token.transferFrom(msg.sender, recipient, amount);
emit FilledRelay(depositId, msg.sender);
}
Uniswap X
Cross-chain swaps via Dutch auction intents।
struct DutchOrder {
address token;
uint256 startAmount; // Decaying price
uint256 endAmount;
uint32 decayStart;
uint32 decayEnd;
}
Fillers compete — price decays over time until someone fills।
Risks
1. Filler Griefing
Filler claims intent लेकिन fill नहीं करता:
// Mitigation: Filler stake
mapping(address => uint) public fillerStakes;
function fill(bytes32 orderId) external {
require(fillerStakes[msg.sender] >= MIN_STAKE, "Insufficient stake");
// ...
}
2. Sequencing
Multiple fillers race — front-running risk:
// Mitigation: Commit-reveal
function commitFill(bytes32 commitment) external;
function revealFill(bytes32 orderId, bytes32 secret) external;
3. Proof Availability
Origin chain need proof from destination:
Options:
- Light client (expensive)
- Optimistic relays (fraud proof window)
- Trusted oracle (centralized)
Dev Checklist
ERC-7683 integrate करते समय:
- [ ]
CrossChainOrderstruct support करें
- [ ]
open()में token locking
- [ ]
resolve()में proof verification
- [ ] Gasless orders (Permit2)
- [ ] Filler stake mechanism
- [ ] Timeout/refund logic
- [ ] Events emit करें (OrderOpened, Filled, Resolved)
Conclusion
ERC-7683 intents को interoperable बना रहा है — fillers अब multiple protocols के orders fill कर सकते हैं एक ही interface से।
Benefits:
- Instant UX (no waiting for bridge)
- Gasless for users
- Competitive pricing (fillers race)
Trade-offs:
- Filler centralization risk
- Proof verification complexity
- New attack vectors
2026 में Across, Uniswap X, और नए bridges ERC-7683 adopt कर रहे हैं। Cross-chain app build कर रहे हैं? Intent-based flow seriously consider करें।