Get fees to claims
This commit is contained in:
@@ -209,6 +209,44 @@ export class AccountClient extends AuthorizedApiBase {
|
||||
}
|
||||
return Promise.resolve<Account[]>(null as any);
|
||||
}
|
||||
|
||||
account_GetGmxClaimableSummary(name: string): Promise<GmxClaimableSummary> {
|
||||
let url_ = this.baseUrl + "/Account/{name}/gmx-claimable-summary";
|
||||
if (name === undefined || name === null)
|
||||
throw new Error("The parameter 'name' must be defined.");
|
||||
url_ = url_.replace("{name}", encodeURIComponent("" + name));
|
||||
url_ = url_.replace(/[?&]$/, "");
|
||||
|
||||
let options_: RequestInit = {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Accept": "application/json"
|
||||
}
|
||||
};
|
||||
|
||||
return this.transformOptions(options_).then(transformedOptions_ => {
|
||||
return this.http.fetch(url_, transformedOptions_);
|
||||
}).then((_response: Response) => {
|
||||
return this.processAccount_GetGmxClaimableSummary(_response);
|
||||
});
|
||||
}
|
||||
|
||||
protected processAccount_GetGmxClaimableSummary(response: Response): Promise<GmxClaimableSummary> {
|
||||
const status = response.status;
|
||||
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
|
||||
if (status === 200) {
|
||||
return response.text().then((_responseText) => {
|
||||
let result200: any = null;
|
||||
result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as GmxClaimableSummary;
|
||||
return result200;
|
||||
});
|
||||
} else if (status !== 200 && status !== 204) {
|
||||
return response.text().then((_responseText) => {
|
||||
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
|
||||
});
|
||||
}
|
||||
return Promise.resolve<GmxClaimableSummary>(null as any);
|
||||
}
|
||||
}
|
||||
|
||||
export class BacktestClient extends AuthorizedApiBase {
|
||||
@@ -2703,6 +2741,50 @@ export interface Chain {
|
||||
chainId?: number;
|
||||
}
|
||||
|
||||
export interface GmxClaimableSummary {
|
||||
claimableFundingFees?: FundingFeesData | null;
|
||||
claimableUiFees?: UiFeesData | null;
|
||||
rebateStats?: RebateStatsData | null;
|
||||
summary?: SummaryData | null;
|
||||
}
|
||||
|
||||
export interface FundingFeesData {
|
||||
totalLongUsdc?: number;
|
||||
totalShortUsdc?: number;
|
||||
totalUsdc?: number;
|
||||
markets?: { [key: string]: FundingFeesMarketData; } | null;
|
||||
}
|
||||
|
||||
export interface FundingFeesMarketData {
|
||||
claimableFundingAmountLong?: number;
|
||||
claimableFundingAmountShort?: number;
|
||||
}
|
||||
|
||||
export interface UiFeesData {
|
||||
totalUsdc?: number;
|
||||
markets?: { [key: string]: UiFeesMarketData; } | null;
|
||||
}
|
||||
|
||||
export interface UiFeesMarketData {
|
||||
claimableUiFeeAmount?: number;
|
||||
}
|
||||
|
||||
export interface RebateStatsData {
|
||||
totalRebateUsdc?: number;
|
||||
discountUsdc?: number;
|
||||
volume?: number;
|
||||
tier?: number;
|
||||
rebateFactor?: number;
|
||||
discountFactor?: number;
|
||||
}
|
||||
|
||||
export interface SummaryData {
|
||||
totalClaimableUsdc?: number;
|
||||
hasFundingFees?: boolean;
|
||||
hasUiFees?: boolean;
|
||||
hasRebates?: boolean;
|
||||
}
|
||||
|
||||
export interface Backtest {
|
||||
id: string;
|
||||
finalPnl: number;
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
import {useMemo, useState} from 'react'
|
||||
import {AccountClient, GmxClaimableSummary} from '../../../generated/ManagingApi'
|
||||
import useApiUrlStore from '../../../app/store/apiStore'
|
||||
import {Table} from '../../../components/mollecules'
|
||||
|
||||
function AccountFee() {
|
||||
const [accountName, setAccountName] = useState('')
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [data, setData] = useState<GmxClaimableSummary | null>(null)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const { apiUrl } = useApiUrlStore()
|
||||
|
||||
const handleFetch = async () => {
|
||||
if (!accountName.trim()) {
|
||||
setError('Please enter an account name')
|
||||
return
|
||||
}
|
||||
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
|
||||
try {
|
||||
const accountClient = new AccountClient({}, apiUrl)
|
||||
const result = await accountClient.account_GetGmxClaimableSummary(accountName.trim())
|
||||
setData(result)
|
||||
} catch (err: any) {
|
||||
setError(err.message || 'Failed to fetch GMX claimable summary')
|
||||
setData(null)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
// Table columns for all sections
|
||||
const dataColumns = useMemo(
|
||||
() => [
|
||||
{
|
||||
Header: 'Type',
|
||||
accessor: 'type',
|
||||
},
|
||||
{
|
||||
Header: 'Amount (USDC)',
|
||||
accessor: 'amount',
|
||||
},
|
||||
],
|
||||
[]
|
||||
)
|
||||
|
||||
// Funding fees table data
|
||||
const fundingFeesData = useMemo(() => {
|
||||
if (!data?.claimableFundingFees) return []
|
||||
|
||||
return [
|
||||
{
|
||||
type: 'Total Funding Fees',
|
||||
amount: `$${data.claimableFundingFees.totalUsdc?.toFixed(2) || '0.00'}`,
|
||||
},
|
||||
]
|
||||
}, [data])
|
||||
|
||||
// UI fees table data
|
||||
const uiFeesData = useMemo(() => {
|
||||
if (!data?.claimableUiFees) return []
|
||||
|
||||
return [
|
||||
{
|
||||
type: 'Total UI Fees',
|
||||
amount: `$${data.claimableUiFees.totalUsdc?.toFixed(2) || '0.00'}`,
|
||||
},
|
||||
]
|
||||
}, [data])
|
||||
|
||||
// Rebate stats table data
|
||||
const rebateStatsData = useMemo(() => {
|
||||
if (!data?.rebateStats) return []
|
||||
|
||||
return [
|
||||
{
|
||||
type: 'Total Rebate USDC',
|
||||
amount: `$${data.rebateStats.totalRebateUsdc?.toFixed(2) || '0.00'}`,
|
||||
},
|
||||
{
|
||||
type: 'Discount USDC',
|
||||
amount: `$${data.rebateStats.discountUsdc?.toFixed(2) || '0.00'}`,
|
||||
},
|
||||
{
|
||||
type: 'Rebate Factor',
|
||||
amount: (data.rebateStats.rebateFactor || 0).toFixed(4),
|
||||
},
|
||||
{
|
||||
type: 'Discount Factor',
|
||||
amount: (data.rebateStats.discountFactor || 0).toFixed(4),
|
||||
},
|
||||
]
|
||||
}, [data])
|
||||
|
||||
// Calculate total claimable for display
|
||||
const totalClaimable = useMemo(() => {
|
||||
if (!data) return 0
|
||||
const fundingTotal = data.claimableFundingFees?.totalUsdc || 0
|
||||
const uiTotal = data.claimableUiFees?.totalUsdc || 0
|
||||
return fundingTotal + uiTotal
|
||||
}, [data])
|
||||
|
||||
return (
|
||||
<div className="p-6">
|
||||
<h2 className="text-2xl font-bold mb-6">GMX Account Fees</h2>
|
||||
|
||||
{/* Input Section */}
|
||||
<div className="mb-6 flex gap-4 items-end">
|
||||
<div className="form-control">
|
||||
<label className="label">
|
||||
<span className="label-text">Account Name</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Enter account name"
|
||||
className="input input-bordered w-full max-w-xs"
|
||||
value={accountName}
|
||||
onChange={(e) => setAccountName(e.target.value)}
|
||||
disabled={loading}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
className={`btn btn-primary ${loading ? 'loading' : ''}`}
|
||||
onClick={handleFetch}
|
||||
disabled={loading}
|
||||
>
|
||||
{loading ? 'Fetching...' : 'Fetch'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Error Display */}
|
||||
{error && (
|
||||
<div className="alert alert-error mb-6">
|
||||
<div>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m-2 2" />
|
||||
</svg>
|
||||
<span>{error}</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Results Section */}
|
||||
{data && (
|
||||
<div className="space-y-8">
|
||||
{/* Total Summary */}
|
||||
<div className="stats shadow">
|
||||
<div className="stat">
|
||||
<div className="stat-title">Total Claimable</div>
|
||||
<div className="stat-value text-primary">${totalClaimable.toFixed(2)}</div>
|
||||
<div className="stat-desc">Combined funding fees and UI fees</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Funding Fees Section */}
|
||||
{data.claimableFundingFees && (data.claimableFundingFees.totalUsdc ?? 0) > 0 && (
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold mb-4">Funding Fees</h3>
|
||||
<Table
|
||||
columns={dataColumns}
|
||||
data={fundingFeesData}
|
||||
showPagination={false}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* UI Fees Section */}
|
||||
{data.claimableUiFees && (data.claimableUiFees.totalUsdc ?? 0) > 0 && (
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold mb-4">UI Fees</h3>
|
||||
<Table
|
||||
columns={dataColumns}
|
||||
data={uiFeesData}
|
||||
showPagination={false}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Rebate Stats Section */}
|
||||
{data.rebateStats && ((data.rebateStats.totalRebateUsdc ?? 0) > 0 || (data.rebateStats.discountUsdc ?? 0) > 0) && (
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold mb-4">Rebate Statistics</h3>
|
||||
<Table
|
||||
columns={dataColumns}
|
||||
data={rebateStatsData}
|
||||
showPagination={false}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AccountFee
|
||||
@@ -8,6 +8,7 @@ import MoneyManagementSettings from './moneymanagement/moneyManagement'
|
||||
import Theme from './theme'
|
||||
import DefaultConfig from './defaultConfig/defaultConfig'
|
||||
import UserInfoSettings from './UserInfoSettings'
|
||||
import AccountFee from './accountFee/accountFee'
|
||||
|
||||
type TabsType = {
|
||||
label: string
|
||||
@@ -33,18 +34,23 @@ const tabs: TabsType = [
|
||||
label: 'Account Settings',
|
||||
},
|
||||
{
|
||||
Component: Theme,
|
||||
Component: AccountFee,
|
||||
index: 4,
|
||||
label: 'Account Fee',
|
||||
},
|
||||
{
|
||||
Component: Theme,
|
||||
index: 5,
|
||||
label: 'Theme',
|
||||
},
|
||||
{
|
||||
Component: DefaultConfig,
|
||||
index: 5,
|
||||
index: 6,
|
||||
label: 'Quick Start Config',
|
||||
},
|
||||
{
|
||||
Component: HealthChecks,
|
||||
index: 6,
|
||||
index: 7,
|
||||
label: 'Health Checks',
|
||||
},
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user