Skip to content

Commit

Permalink
Merge branch 'main' into feat/aggregator-update
Browse files Browse the repository at this point in the history
  • Loading branch information
MattPoblete authored Aug 20, 2024
2 parents dd1bdeb + 9405ba3 commit f299dbd
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 29 deletions.
4 changes: 2 additions & 2 deletions src/components/SearchModal/CurrencySearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export function CurrencySearch({
const [searchQuery, setSearchQuery] = useState<string>('');
const debouncedQuery = useDebounce(searchQuery, 200);
const isAddressSearch = isAddress(debouncedQuery);
const { token: searchToken, needsWrapping } = useToken(debouncedQuery);
const { token: searchToken, needsWrapping, isLoading: isLoadingToken } = useToken(debouncedQuery);
const { tokensAsMap: allTokens } = useAllTokens();

const [showUserAddedTokenModal, setShowUserAddedTokenModal] = useState<boolean>(false);
Expand Down Expand Up @@ -237,7 +237,7 @@ export function CurrencySearch({
)} */}
</PaddedColumn>
<Separator />
{searchToken && !isLoading ? (
{searchToken && !isLoading && !isLoadingToken ? (
<Column style={{ padding: '20px 0', height: '100%' }}>
<CurrencyRow
currency={searchToken}
Expand Down
39 changes: 26 additions & 13 deletions src/helpers/horizon/createHorizonTransaction.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
import { SorobanContextType, useSorobanReact } from "@soroban-react/core";
import { InterfaceTrade, TradeType } from "state/routing/types";
import {Asset, TransactionBuilder, Operation, BASE_FEE} from "@stellar/stellar-sdk";
import { Asset, TransactionBuilder, Operation, BASE_FEE } from "@stellar/stellar-sdk";
import { getAmount } from "./getHorizonPath";
import BigNumber from "bignumber.js";

export const createStellarPathPayment = async (trade: InterfaceTrade, allowedSlippage:any, sorobanContext: SorobanContextType) => {
const {address, activeConnector, serverHorizon, activeChain} = sorobanContext;
if(!address || !activeConnector || !serverHorizon || !activeChain) return;
export const createStellarPathPayment = async (trade: InterfaceTrade, allowedSlippage: any, sorobanContext: SorobanContextType) => {
const { address, activeConnector, serverHorizon, activeChain } = sorobanContext;
if (!address || !activeConnector || !serverHorizon || !activeChain) return;
const amount = getAmount(trade.inputAmount?.value!);
const sourceAsset = new Asset(trade.inputAmount?.currency.code!, trade.inputAmount?.currency.issuer)
const destinationAsset = new Asset(trade.outputAmount?.currency.code!, trade.outputAmount?.currency.issuer)
const destinationAmount = getAmount(trade.outputAmount?.value!);
const account = await serverHorizon?.loadAccount(address!);
const path = trade.path?.map((asset) => {
const assetParts = asset.split(":")
if(assetParts.length == 1 && assetParts[0] == "native"){
if (assetParts.length == 1 && assetParts[0] == "native") {
return Asset.native()
}
return new Asset(assetParts[0], assetParts[1])
})
if(!account){

if (!account) {
throw new Error("Account not found")
}
let transaction;
if(!amount || !sourceAsset || !destinationAsset || !path) throw new Error("Invalid trade");
if(trade.tradeType == TradeType.EXACT_INPUT){
if (!amount || !sourceAsset || !destinationAsset || !path || !destinationAmount) throw new Error("Invalid trade");
if (trade.tradeType == TradeType.EXACT_INPUT) {
const percentageSlippage = new BigNumber(100).minus(allowedSlippage).dividedBy(100);
const destMin = new BigNumber(amount).multipliedBy(percentageSlippage).toFixed(7).toString();
const destMin = new BigNumber(destinationAmount).multipliedBy(percentageSlippage).toFixed(7).toString();
transaction = new TransactionBuilder(account, {
fee: BASE_FEE,
networkPassphrase: activeChain?.networkPassphrase
Expand All @@ -49,20 +51,31 @@ export const createStellarPathPayment = async (trade: InterfaceTrade, allowedSli
sendMax: sendMax,
destination: address,
destAsset: destinationAsset,
destAmount: amount,
destAmount: destinationAmount,
path: path
})).setTimeout(180).build();
}
const transactionXDR = transaction.toXDR();
const signedTransaction = await activeConnector?.signTransaction(transactionXDR, {
networkPassphrase: activeChain?.networkPassphrase,
});
if(!signedTransaction){
if (!signedTransaction) {
throw new Error("Couldn't sign transaction");
}
const transactionToSubmit = TransactionBuilder.fromXDR(
signedTransaction!,
activeChain?.networkPassphrase ?? '',
);
const transactionResult = await serverHorizon?.submitTransaction(transactionToSubmit);
return transactionResult;
try {
const transactionResult = await serverHorizon?.submitTransaction(transactionToSubmit);
return transactionResult;
} catch (e) {
console.log("Error", e);
// @ts-ignore
if (e.response.data.extras.result_codes.operations.includes("op_under_dest_min")) {
throw new Error("Try increasing slippage");
// @ts-ignore
}
throw e
}
}
4 changes: 2 additions & 2 deletions src/helpers/horizon/getHorizonPath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ export function getHorizonBestPath(
if (!args.amount || !args.assetFrom || !args.assetTo || !serverHorizon) return;
if (payload.tradeType === TradeType.EXACT_INPUT) {
try {
const send = serverHorizon?.strictSendPaths(args.assetFrom, args.amount, [args.assetTo])
const send = serverHorizon.strictSendPaths(args.assetFrom, args.amount, [args.assetTo])
.call().then((res) => res.records);
return send?.then((res) => {
const maxObj = res.reduce((maxObj, obj) => {
Expand All @@ -228,7 +228,7 @@ export function getHorizonBestPath(
}
} else if (payload.tradeType === TradeType.EXACT_OUTPUT) {
try {
const receive = serverHorizon?.strictReceivePaths([args.assetFrom!], args.assetTo!, args?.amount!)
const receive = serverHorizon.strictReceivePaths([args.assetTo], args.assetFrom, args.amount)
.call().then((res) => res.records);
return receive?.then((res) => {
const minObj = res.reduce((minObj, obj) => {
Expand Down
40 changes: 33 additions & 7 deletions src/hooks/tokens/useToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,44 @@ export const findToken = async (
if (!tokenAddress || tokenAddress === '') return undefined;

const classicAssetSearch = getClassicAssetSorobanAddress(tokenAddress!, sorobanContext);

const formattedAddress = isAddress(classicAssetSearch ? classicAssetSearch : tokenAddress);
if (!formattedAddress) return undefined;

const fromMap = tokensAsMap[formattedAddress];

if (fromMap) return fromMap;

const token = await getToken(sorobanContext, formattedAddress);

// const token: TokenType = {
// contract: formattedAddress,
// name: name as string,
// code: symbol as string,
// decimals,
// icon: logo,
// };

if (!token?.name || !token?.code) return undefined;

return token;
// Here from token.name we will try to understand if this is a classic asset (even if we got a soroban contracta as address).
const stellarAsset = getClassicStellarAsset(token.name);

/*
TODO: Here we might have a situation where a Soroban Contract has as name a CODE:ISSUER
We need to have a beter way to know if a soroban contract its for sure a stellar classic asset, and which.
*/
if (stellarAsset && typeof stellarAsset !== 'boolean') {
return {
issuer: stellarAsset.issuer,
contract: token.contract,
name: stellarAsset.asset,
code: stellarAsset.assetCode,
decimals: 7,
icon: '',
};
}
else {
return token
};
};

const revalidateKeysCondition = (key: any) => {
Expand Down Expand Up @@ -69,6 +94,7 @@ export function useToken(tokenAddress: string | undefined) {
const bothLoading = isLoading || isStellarClassicAssetLoading;

const needsWrapping = !data && isStellarClassicAsset;


const needsWrappingOnAddLiquidity = (!data && isStellarClassicAsset) || !name;

Expand Down
10 changes: 5 additions & 5 deletions src/hooks/useSwapCallback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ export function useSwapCallback(

const notificationMessage = `${formatTokenAmount(currencyA ?? '0')} ${trade?.inputAmount
?.currency.code} for ${formatTokenAmount(currencyB ?? '0')} ${trade?.outputAmount
?.currency.code}`;
?.currency.code}`;

sendNotification(notificationMessage, 'Swapped', SnackbarIconType.SWAP, SnackbarContext);

Expand Down Expand Up @@ -218,8 +218,8 @@ export function useSwapCallback(
currencyB += Number(values[values.length - 1]);
}

const notificationMessage = `${formatTokenAmount(currencyA)} ${trade?.inputAmount
?.currency.code} for ${formatTokenAmount(currencyB)} ${trade?.outputAmount?.currency
const notificationMessage = `${formatTokenAmount(currencyA ?? '0')} ${trade?.inputAmount
?.currency.code} for ${formatTokenAmount(currencyB ?? '0')} ${trade?.outputAmount?.currency
.code}`;

sendNotification(notificationMessage, 'Swapped', SnackbarIconType.SWAP, SnackbarContext);
Expand All @@ -238,8 +238,8 @@ export function useSwapCallback(
const result = await createStellarPathPayment(trade, allowedSlippage, sorobanContext);
const notificationMessage = `${formatTokenAmount(trade.inputAmount?.value ?? '0')} ${trade
?.inputAmount?.currency.code} for ${formatTokenAmount(
trade.outputAmount?.value ?? '0',
)} ${trade?.outputAmount?.currency.code}`;
trade.outputAmount?.value ?? '0',
)} ${trade?.outputAmount?.currency.code}`;
sendNotification(notificationMessage, 'Swapped', SnackbarIconType.SWAP, SnackbarContext);
return result!;
} catch (error: any) {
Expand Down

0 comments on commit f299dbd

Please sign in to comment.