Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.production.example
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -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.

Expand Down
5 changes: 5 additions & 0 deletions src/configs/protocols.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand Down
61 changes: 61 additions & 0 deletions src/helpers/aggregator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<Address>,
// pub parts: u32,
// pub bytes: Option<Vec<BytesN<32>>>

// }

/**
* Converts an optional array of Base64-encoded strings to ScVal: Option<Vec<BytesN<32>>>
*
* @param poolHashes Optional array of Base64-encoded strings representing 32-byte hashes
* @returns ScVal representing Option<Vec<BytesN<32>>>
* @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' }),
Expand All @@ -24,6 +84,7 @@ export const dexDistributionParser = (dexDistributionRaw: DexDistribution[]): xd
}),
]);
});
console.log("🚀 ~ dexDistributionScVal ~ dexDistributionScVal:", dexDistributionScVal)

return xdr.ScVal.scvVec(dexDistributionScVal);
};
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useAggregator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
28 changes: 27 additions & 1 deletion src/hooks/useSwapCallback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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<
Expand Down
Loading