Fix swap btc + fix bot stoping
This commit is contained in:
@@ -24,7 +24,7 @@ public class SwapTokensRequest
|
||||
/// The amount to swap
|
||||
/// </summary>
|
||||
[Required]
|
||||
[Range(0.000001, double.MaxValue, ErrorMessage = "Amount must be greater than 0")]
|
||||
[Range(0.0000000000001, double.MaxValue, ErrorMessage = "Amount must be greater than 0")]
|
||||
public double Amount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -224,7 +224,7 @@ public class TradingBot : Bot, ITradingBot
|
||||
{
|
||||
// Check broker balance before running
|
||||
var balance = await ExchangeService.GetBalance(Account, false);
|
||||
if (balance < Constants.GMX.Config.MinimumPositionAmount)
|
||||
if (balance < Constants.GMX.Config.MinimumPositionAmount && Positions.All(p => p.IsFinished()))
|
||||
{
|
||||
await LogWarning(
|
||||
$"Balance on broker is below {Constants.GMX.Config.MinimumPositionAmount} USD (actual: {balance}). Stopping bot {Identifier} and saving backup.");
|
||||
|
||||
@@ -24,6 +24,14 @@ interface SwapFormInput {
|
||||
allowedSlippage: number
|
||||
}
|
||||
|
||||
interface ValidationErrorResponse {
|
||||
type: string
|
||||
title: string
|
||||
status: number
|
||||
errors: Record<string, string[]>
|
||||
traceId: string
|
||||
}
|
||||
|
||||
const SwapModal: React.FC<SwapModalProps> = ({
|
||||
isOpen,
|
||||
onClose,
|
||||
@@ -32,6 +40,7 @@ const SwapModal: React.FC<SwapModalProps> = ({
|
||||
availableAmount,
|
||||
}) => {
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [validationErrors, setValidationErrors] = useState<Record<string, string[]>>({})
|
||||
const {error, setError, handleApiErrorWithToast} = useApiError()
|
||||
const {apiUrl} = useApiUrlStore()
|
||||
const client = new AccountClient({}, apiUrl)
|
||||
@@ -62,6 +71,7 @@ const SwapModal: React.FC<SwapModalProps> = ({
|
||||
const t = new Toast(`Swapping ${form.amount} ${form.fromTicker} to ${form.toTicker} on ${account.name}`)
|
||||
setIsLoading(true)
|
||||
setError(null)
|
||||
setValidationErrors({})
|
||||
|
||||
try {
|
||||
const result = await client.account_SwapGmxTokens(
|
||||
@@ -85,16 +95,31 @@ const SwapModal: React.FC<SwapModalProps> = ({
|
||||
setError(errorMessage)
|
||||
t.update('error', `Swap failed: ${errorMessage}`)
|
||||
}
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
// Handle validation errors from API
|
||||
if (err.response?.data && typeof err.response.data === 'object') {
|
||||
const errorData = err.response.data as ValidationErrorResponse
|
||||
console.log(errorData)
|
||||
if (errorData.errors && typeof errorData.errors === 'object') {
|
||||
setValidationErrors(errorData.errors)
|
||||
const errorMessages = Object.values(errorData.errors).flat()
|
||||
const errorMessage = errorMessages.join(', ')
|
||||
setError(errorMessage)
|
||||
t.update('error', `Validation failed: ${errorMessage}`)
|
||||
} else {
|
||||
handleApiErrorWithToast(err, t)
|
||||
}
|
||||
} else {
|
||||
handleApiErrorWithToast(err, t)
|
||||
}
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
const handleFormSubmit = (e: React.FormEvent) => {
|
||||
const handleFormSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
handleSubmit(onSubmit)(e)
|
||||
await handleSubmit(onSubmit)(e)
|
||||
}
|
||||
|
||||
const modalContent = (
|
||||
@@ -120,6 +145,18 @@ const SwapModal: React.FC<SwapModalProps> = ({
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleFormSubmit}>
|
||||
{Object.keys(validationErrors).length > 0 && (
|
||||
<div className="alert alert-error mb-4">
|
||||
<div>
|
||||
<h4 className="font-bold">Validation Errors:</h4>
|
||||
{Object.entries(validationErrors).map(([field, errors]) => (
|
||||
<div key={field} className="mt-1">
|
||||
<strong>{field}:</strong> {errors.join(', ')}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="space-y-4 mb-4">
|
||||
<FormInput label="To Ticker" htmlFor="toTicker">
|
||||
<select
|
||||
@@ -147,20 +184,27 @@ const SwapModal: React.FC<SwapModalProps> = ({
|
||||
type="number"
|
||||
step="any"
|
||||
placeholder="Enter amount to swap"
|
||||
className="input input-bordered w-full mb-2"
|
||||
className={`input input-bordered w-full mb-2 ${validationErrors.Amount ? 'input-error' : ''}`}
|
||||
{...register('amount', {
|
||||
valueAsNumber: true,
|
||||
min: 0.0001,
|
||||
min: 0.00000000000001,
|
||||
max: availableAmount,
|
||||
required: true
|
||||
})}
|
||||
/>
|
||||
{validationErrors.Amount && (
|
||||
<div className="text-error text-xs mt-1">
|
||||
{validationErrors.Amount.map((error, index) => (
|
||||
<div key={index}>{error}</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<div className="w-full">
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max={availableAmount}
|
||||
step={availableAmount / 100}
|
||||
step={0.00000000000001}
|
||||
className="range range-primary w-full"
|
||||
value={watchedAmount || 0}
|
||||
onChange={(e) => {
|
||||
@@ -201,7 +245,7 @@ const SwapModal: React.FC<SwapModalProps> = ({
|
||||
type="number"
|
||||
step="0.1"
|
||||
placeholder="0.5"
|
||||
className="input input-bordered w-full"
|
||||
className={`input input-bordered w-full ${validationErrors.AllowedSlippage ? 'input-error' : ''}`}
|
||||
{...register('allowedSlippage', {
|
||||
valueAsNumber: true,
|
||||
min: 0.1,
|
||||
@@ -209,6 +253,13 @@ const SwapModal: React.FC<SwapModalProps> = ({
|
||||
value: 0.5
|
||||
})}
|
||||
/>
|
||||
{validationErrors.AllowedSlippage && (
|
||||
<div className="text-error text-xs mt-1">
|
||||
{validationErrors.AllowedSlippage.map((error, index) => (
|
||||
<div key={index}>{error}</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</FormInput>
|
||||
|
||||
{selectedOrderType === 'limit' && (
|
||||
@@ -217,9 +268,16 @@ const SwapModal: React.FC<SwapModalProps> = ({
|
||||
type="number"
|
||||
step="any"
|
||||
placeholder="Enter trigger ratio"
|
||||
className="input input-bordered w-full"
|
||||
className={`input input-bordered w-full ${validationErrors.TriggerRatio ? 'input-error' : ''}`}
|
||||
{...register('triggerRatio', {valueAsNumber: true})}
|
||||
/>
|
||||
{validationErrors.TriggerRatio && (
|
||||
<div className="text-error text-xs mt-1">
|
||||
{validationErrors.TriggerRatio.map((error, index) => (
|
||||
<div key={index}>{error}</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</FormInput>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user