diff --git a/.env.production.example b/.env.production.example
index 890fc854..4f1989bf 100644
--- a/.env.production.example
+++ b/.env.production.example
@@ -20,6 +20,6 @@ NEXT_PUBLIC_DIRECT_PATH_ENABLED=false
# SOROSWAP API
SOROSWAP_API_URL= # URL of the Soroswap API
-# For development use http://localhost:4000/
+# For development use http://soroswap-api:4000
SOROSWAP_API_EMAIL= # Email for Soroswap API
SOROSWAP_API_PASSWORD= # Password for Soroswap API
\ No newline at end of file
diff --git a/README.md b/README.md
index 5e75df83..26dd63da 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# 🌟 Soroswap Frontend @ Soroban Preview 10🌟
+# 🌟 Soroswap Frontend🌟
Welcome to Soroswap, a decentralized exchange (DEX) that draws inspiration from the Uniswap V2 protocol and is specifically tailored for the Soroban network.
diff --git a/src/configs/protocols.config.json b/src/configs/protocols.config.json
index c133920d..79f9dcda 100644
--- a/src/configs/protocols.config.json
+++ b/src/configs/protocols.config.json
@@ -14,6 +14,11 @@
"key": "phoenix",
"value": true,
"url": "https://docs.soroswap.finance/soroswap-aggregator/supported-amms"
+ },
+ {
+ "key": "aqua",
+ "value": true,
+ "url": "https://docs.soroswap.finance/soroswap-aggregator/supported-amms"
}
],
"testnet": [
diff --git a/src/helpers/aggregator/index.ts b/src/helpers/aggregator/index.ts
index 3aa1979c..dccd3785 100644
--- a/src/helpers/aggregator/index.ts
+++ b/src/helpers/aggregator/index.ts
@@ -5,11 +5,71 @@ export interface DexDistribution {
path: string[];
parts: number;
is_exact_in: boolean;
+ poolHashes: string[] | undefined;
+}
+
+// #[contracttype]
+// #[derive(Clone, Debug, Eq, PartialEq)]
+// pub struct DexDistribution {
+// pub protocol_id: String,
+// pub path: Vec
,
+// pub parts: u32,
+// pub bytes: Option>>
+
+// }
+
+/**
+ * Converts an optional array of Base64-encoded strings to ScVal: Option>>
+ *
+ * @param poolHashes Optional array of Base64-encoded strings representing 32-byte hashes
+ * @returns ScVal representing Option>>
+ * @throws Error if any Base64 string is invalid or does not decode to 32 bytes
+ */
+export function poolHashesToScVal(poolHashes?: string[]): xdr.ScVal {
+ // Handle undefined or empty array: return Option::None
+ if (!poolHashes || poolHashes.length === 0) {
+ console.log("🚀 ~ poolHashesToScVal ~ poolHashes:", poolHashes)
+ return nativeToScVal(null);
+
+ }
+
+ // Convert each Base64 string to ScVal (BytesN<32>)
+ const scVec: xdr.ScVal[] = poolHashes.map((base64Str) => {
+ // Basic validation for non-empty string
+ if (!base64Str || typeof base64Str !== 'string') {
+ throw new Error(`Invalid Base64 string: ${base64Str}`);
+ }
+
+ try {
+ // Decode Base64 string to Buffer
+ const buf = Buffer.from(base64Str, 'base64');
+
+ // Validate buffer length (must be 32 bytes for BytesN<32>)
+ if (buf.length !== 32) {
+ throw new Error(
+ `Expected 32 bytes, got ${buf.length} bytes for Base64 string: ${base64Str}`
+ );
+ }
+
+ // Create ScVal for BytesN<32>
+ return xdr.ScVal.scvBytes(buf);
+ } catch (e) {
+ throw new Error(`Invalid Base64 string: ${base64Str}`);
+ }
+ });
+
+ // Wrap the vector in an Option::Some
+ return xdr.ScVal.scvVec(scVec);
}
export const dexDistributionParser = (dexDistributionRaw: DexDistribution[]): xdr.ScVal => {
+ console.log("🚀 ~ dexDistributionRaw:", dexDistributionRaw)
const dexDistributionScVal = dexDistributionRaw.map((distribution) => {
return xdr.ScVal.scvMap([
+ new xdr.ScMapEntry({
+ key: xdr.ScVal.scvSymbol('bytes'),
+ val: poolHashesToScVal(distribution.poolHashes),
+ }),
new xdr.ScMapEntry({
key: xdr.ScVal.scvSymbol('parts'),
val: nativeToScVal(distribution.parts, { type: 'u32' }),
@@ -24,6 +84,7 @@ export const dexDistributionParser = (dexDistributionRaw: DexDistribution[]): xd
}),
]);
});
+ console.log("🚀 ~ dexDistributionScVal ~ dexDistributionScVal:", dexDistributionScVal)
return xdr.ScVal.scvVec(dexDistributionScVal);
};
diff --git a/src/hooks/useAggregator.tsx b/src/hooks/useAggregator.tsx
index 696a2bda..e7a902a7 100644
--- a/src/hooks/useAggregator.tsx
+++ b/src/hooks/useAggregator.tsx
@@ -8,7 +8,7 @@ const aggregatorTestnet = process.env.NEXT_PUBLIC_AGGREGATOR_ENABLED_TESTNET ===
export const setAggregatorData = async (activeChainId: string) => {
const response = await axios.get(
- `https://raw.githubusercontent.com/soroswap/aggregator/refs/heads/main/public/${activeChainId}.contracts.json`
+ `https://raw.githubusercontent.com/soroswap/aggregator/refs/heads/aqua-adapter/public/${activeChainId}.contracts.json`
).catch((error) => {
console.error('Error fetching aggregator data', error);
console.warn('No address found Aggregator is disabled');
diff --git a/src/hooks/useSwapCallback.tsx b/src/hooks/useSwapCallback.tsx
index e24ca9f5..eac194c4 100644
--- a/src/hooks/useSwapCallback.tsx
+++ b/src/hooks/useSwapCallback.tsx
@@ -9,7 +9,7 @@ import { dexDistributionParser, hasDistribution } from 'helpers/aggregator';
import { scValToJs } from 'helpers/convert';
import { formatTokenAmount } from 'helpers/format';
import { bigNumberToI128, bigNumberToU64 } from 'helpers/utils';
-import { useContext } from 'react';
+import { useContext, useEffect } from 'react';
import { InterfaceTrade, PlatformType, TradeType } from 'state/routing/types';
import { useUserSlippageToleranceWithDefault } from 'state/user/hooks';
import { useSWRConfig } from 'swr';
@@ -114,6 +114,32 @@ export function useSwapCallback(
const { mutate } = useSWRConfig();
+ // Logs de depuración para el proceso de swap
+ useEffect(() => {
+ if (trade) {
+ console.group('%c[Soroswap Debug] SwapCallback', 'color: #00aced; font-weight: bold');
+ console.log('🚀 Tipo de operación:', trade.tradeType);
+ console.log('🔄 Plataforma seleccionada:', trade.platform);
+ console.log('💰 Moneda de entrada:', trade.inputAmount?.currency.code, 'cantidad:', trade.inputAmount?.value);
+ console.log('💰 Moneda de salida:', trade.outputAmount?.currency.code, 'cantidad:', trade.outputAmount?.value);
+ console.log('⚙️ Configuración de slippage:', allowedSlippage);
+
+ if (trade.path) {
+ console.log('🛣️ Ruta de swap:', trade.path);
+ }
+
+ if (trade.distribution) {
+ console.log('📊 Distribución:', trade.distribution);
+ }
+
+ if (isUsingAggregator) {
+ console.log('🔀 Usando agregador para optimizar la ruta');
+ }
+
+ console.groupEnd();
+ }
+ }, [trade, allowedSlippage, isUsingAggregator]);
+
const doSwap = async (
simulation?: boolean,
): Promise<