Developer Integration Guide
This guide explains how to interact with xendune contracts from frontend applications or external services.
Prerequisites
- EVM-compatible wallet (MetaMask, Trust Wallet, TokenPocket)
- USDT for transactions
- ethers.js or web3.js for contract interaction
Contract ABIs
All contract ABIs are available from deployed contract source code on BscScan. Key contracts to interact with:
| Contract | Primary Use |
|---|---|
| ProductFactory | Create products, query product indexes |
| ProductFactoryReader | Read product data, pagination, search |
| C2CFactory | Create C2C trades, query trade listings |
| C2CFactoryReader | Read C2C trade data |
| DepositFactory | Create/manage merchant deposits |
| PlatformSettings | Read platform configuration |
| InviteRegistry | Register referral relationships |
Common Workflows
Buyer: Purchase Product
// 1. Approve USDT spending
await usdt.approve(productAddress, amount);
// 2. Call product contract's purchase method
// Physical/Virtual products: purchase(specIndex, quantity)
await product.purchase(0, 1);
// 3. After receiving goods, confirm receipt
await product.confirmReceive(orderId);
Seller: List Product
// 1. Ensure deposit exists
const deposit = await depositFactory.getDeposit(sellerAddress);
// 2. Create product via factory
const tx = await productFactory.createPhysicalProduct(
{ title, keyword, description }, // ProductStrings
specs, // Spec[]
images, // string[]
deliveryMethod // uint8
);
const receipt = await tx.wait();
// Get product address from ProductCreated event
Seller: Ship Order
// Physical products only
await product.shipOrder(orderId);
Read Product Data
// Get all products for a keyword
const count = await factory.getKeywordProductCount(keyword);
const products = await reader.getKeywordProducts(keyword, offset, limit);
// Get seller's active products
const active = await factory.activeProducts(sellerAddress, index);
// Get order details
const order = await product.orders(orderId);
Event Listening
Key events for UI updates:
| Event | Contract | Trigger Condition |
|---|---|---|
| ProductCreated | ProductFactory | New product listed |
| OrderCreated | Product Templates | New order |
| OrderShipped | PhysicalProductTemplate | Seller shipped |
| DeliveryConfirmed | VirtualProductTemplate | Seller delivered |
| OrderCompleted | Product Templates | Settlement completed |
| ArbitrationRequested | Product Templates | Dispute initiated |
| ArbitrationResolved | Product Templates | Dispute resolved |
USDT Approval Pattern
All purchase operations require pre-approved USDT:
const amount = ethers.parseUnits("100", 18);
await usdt.approve(contractAddress, amount);
For better UX, request a large approval amount once rather than per-transaction approvals.
Error Handling
Contract calls may revert with custom errors. Common errors:
| Error | Meaning |
|---|---|
| IsDelisted | Product delisted |
| InvalidSpec | Spec index out of range |
| InvalidQty | Quantity is 0 or exceeds stock |
| CannotBuyOwn | Buyer is seller |
| TransferFailed | USDT transfer failed |
| WrongStatus | Order not in expected status |
| NotParty | Caller not buyer or seller |
| ActiveOrder | Order in progress, cannot modify product |
Pending Withdrawals
If settlement transfer fails, funds stored in pendingWithdrawals. Query and claim:
const pending = await product.pendingWithdrawals(userAddress);
if (pending > 0) {
await product.claimPending();
}
Chat System
xendune includes an off-chain encrypted chat system:
- End-to-end encryption using wallet-derived X25519 keys
- Auto-sends order and logistics info on purchase
- Customer service channels (unencrypted for admin visibility)
- Chat backend runs on Node.js with WebSocket support