Skip to content

Commit c21153c

Browse files
committed
feat: wip tx lvl fees
1 parent 3d13273 commit c21153c

13 files changed

Lines changed: 117 additions & 28 deletions

File tree

apps/namadillo/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"@keplr-wallet/types": "^0.12.136",
1313
"@namada/chain-registry": "^1.5.2",
1414
"@namada/indexer-client": "4.0.5",
15-
"@namada/sdk-multicore": "0.23.0",
15+
"@namada/sdk-multicore": "file:.yalc/@namada/sdk-multicore",
1616
"@tailwindcss/container-queries": "^0.1.1",
1717
"@tanstack/query-core": "^5.40.0",
1818
"@tanstack/react-query": "^5.40.0",

apps/namadillo/public/config.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,12 @@
44
#masp_indexer_url = ""
55
#localnet_enabled = false
66
#fathom_site_id = ""
7+
8+
[server_fee]
9+
# tnam or znam address
10+
# target = "znam175uaqlukleyjjyfcccehp2pw3g696a57skewlv0fenldlw702gtjd6qkpjs09zxl6jafsz3e73h"
11+
target = "tnam1qrku7yxdt6d23nhe826ntukygzkfyczuu5mm0yll"
12+
# between 0 and 1
13+
percentage = 0.001
14+
# raw max value
15+
max_value = 100

apps/namadillo/src/App/Transfer/TransferModule.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -130,19 +130,19 @@ export const TransferModule = ({
130130
}, [gasConfig]);
131131

132132
const availableAmountMinusFees = useMemo(() => {
133-
if (!availableAmount || !availableAssets) return;
133+
if (!availableAmount || !availableAssets || !displayGasFee) return;
134+
let amountMinusFees = availableAmount;
134135

135-
if (
136-
!displayGasFee?.totalDisplayAmount ||
137-
// Don't subtract if the gas token is different than the selected asset:
138-
gasConfig?.gasToken !== selectedAsset?.asset.address
139-
) {
140-
return availableAmount;
136+
if (gasConfig?.gasToken === selectedAsset?.asset.address) {
137+
amountMinusFees = availableAmount
138+
.minus(displayGasFee.totalDisplayAmount)
139+
.decimalPlaces(6);
140+
}
141+
if (feeProps?.frontendFeeConfig?.percentage) {
142+
amountMinusFees = amountMinusFees
143+
.div(feeProps.frontendFeeConfig.percentage.plus(1))
144+
.decimalPlaces(6);
141145
}
142-
143-
const amountMinusFees = availableAmount
144-
.minus(displayGasFee.totalDisplayAmount)
145-
.decimalPlaces(6);
146146

147147
return BigNumber.max(amountMinusFees, 0);
148148
}, [selectedAsset?.asset.address, availableAmount, displayGasFee]);

apps/namadillo/src/atoms/integrations/services.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
} from "@namada/indexer-client";
1717
import { getIndexerApi } from "atoms/api";
1818
import { chainParametersAtom } from "atoms/chain";
19-
import { rpcUrlAtom } from "atoms/settings";
19+
import { rpcUrlAtom, serverFeeAtom } from "atoms/settings";
2020
import { queryForAck, queryForIbcTimeout } from "atoms/transactions";
2121
import BigNumber from "bignumber.js";
2222
import * as Comlink from "comlink";
@@ -73,6 +73,7 @@ export const getShieldedArgs = async (
7373
const store = getDefaultStore();
7474
const rpcUrl = store.get(rpcUrlAtom);
7575
const chain = store.get(chainParametersAtom);
76+
const serverFee = store.get(serverFeeAtom);
7677

7778
if (!chain.isSuccess) throw "Chain not loaded";
7879

@@ -91,6 +92,7 @@ export const getShieldedArgs = async (
9192
amount,
9293
destinationChannelId,
9394
chainId: chain.data.chainId,
95+
frontendFeeConfig: serverFee,
9496
},
9597
};
9698

apps/namadillo/src/atoms/settings/atoms.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { isUrlValid, sanitizeUrl } from "@namada/utils";
22
import { getCustomIndexerApi, indexerApiAtom } from "atoms/api";
33
import { chainParametersAtom, indexerRpcUrlAtom } from "atoms/chain";
4+
import BigNumber from "bignumber.js";
45
import { Getter, Setter, atom, getDefaultStore } from "jotai";
56
import { atomWithMutation, atomWithQuery } from "jotai-tanstack-query";
67
import { atomWithStorage } from "jotai/utils";
@@ -175,6 +176,19 @@ export const maspIndexerUrlAtom = atom((get) => {
175176
return "";
176177
});
177178

179+
// TODO: figure out where to have this atom
180+
export const serverFeeAtom = atom((get) => {
181+
const serverFee = get(defaultServerConfigAtom).data?.server_fee;
182+
return (
183+
serverFee && {
184+
target: serverFee.target,
185+
percentage: BigNumber(serverFee.percentage),
186+
maxValue:
187+
serverFee.max_value ? BigNumber(serverFee.max_value) : undefined,
188+
}
189+
);
190+
});
191+
178192
export const updateIndexerUrlAtom = atomWithMutation(() => {
179193
return {
180194
mutationKey: ["update-indexer-url"],

apps/namadillo/src/atoms/transfer/atoms.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,16 @@ export const createShieldingTransferAtom = atomWithMutation((get) => {
103103
gasConfig,
104104
account,
105105
memo,
106+
frontendFeeConfig,
106107
}: BuildTxAtomParams<ShieldingTransferProps>) =>
107108
createShieldingTransferTx(
108109
chain.data!,
109110
account,
110111
params,
111112
gasConfig,
112113
rpcUrl,
113-
memo
114+
memo,
115+
frontendFeeConfig
114116
),
115117
};
116118
});

apps/namadillo/src/atoms/transfer/services.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import BigNumber from "bignumber.js";
1717
import * as Comlink from "comlink";
1818
import { NamadaKeychain } from "hooks/useNamadaKeychain";
1919
import { buildTx, EncodedTxData, isPublicKeyRevealed } from "lib/query";
20-
import { Address, ChainSettings, GasConfig } from "types";
20+
import { Address, ChainSettings, FrontendFeeConfig, GasConfig } from "types";
2121
import { getSdkInstance } from "utils/sdk";
2222
import {
2323
IbcTransfer,
@@ -168,7 +168,8 @@ export const createShieldingTransferTx = async (
168168
props: ShieldingTransferProps[],
169169
gasConfig: GasConfig,
170170
rpcUrl: string,
171-
memo?: string
171+
memo?: string,
172+
frontendFeeConfig?: FrontendFeeConfig
172173
): Promise<EncodedTxData<ShieldingTransferProps> | undefined> => {
173174
const source = props[0]?.data[0]?.source;
174175
const destination = props[0]?.target;
@@ -193,6 +194,10 @@ export const createShieldingTransferTx = async (
193194
target: destination,
194195
data: [{ source, token, amount }],
195196
bparams,
197+
frontendSusFee: frontendFeeConfig && {
198+
address: frontendFeeConfig.target,
199+
amount: frontendFeeConfig.percentage.toString(),
200+
},
196201
};
197202
const msg: Shield = {
198203
type: "shield",
@@ -220,7 +225,8 @@ export const createUnshieldingTransferTx = async (
220225
gasConfig: GasConfig,
221226
rpcUrl: string,
222227
disposableSigner: GenDisposableSignerResponse,
223-
memo?: string
228+
memo?: string,
229+
frontendFeeConfig?: FrontendFeeConfig
224230
): Promise<EncodedTxData<UnshieldingTransferProps> | undefined> => {
225231
const { publicKey: signerPublicKey } = disposableSigner;
226232

@@ -247,6 +253,10 @@ export const createUnshieldingTransferTx = async (
247253
source,
248254
data: [{ target: destination, token, amount }],
249255
bparams,
256+
frontendSusFee: frontendFeeConfig && {
257+
address: frontendFeeConfig.target,
258+
amount: frontendFeeConfig.percentage.toString(),
259+
},
250260
};
251261

252262
const msg: Unshield = {
@@ -274,7 +284,8 @@ export const createIbcTx = async (
274284
gasConfig: GasConfig,
275285
rpcUrl: string,
276286
signerPublicKey: string,
277-
memo?: string
287+
memo?: string,
288+
frontendFeeConfig?: FrontendFeeConfig
278289
): Promise<EncodedTxData<IbcTransferProps>> => {
279290
let bparams: BparamsMsgValue[] | undefined;
280291
if (account.type === AccountType.Ledger) {
@@ -292,6 +303,10 @@ export const createIbcTx = async (
292303
...props[0],
293304
gasSpendingKey: props[0].gasSpendingKey,
294305
bparams,
306+
frontendSusFee: frontendFeeConfig && {
307+
address: frontendFeeConfig.target,
308+
amount: frontendFeeConfig.percentage.toString(),
309+
},
295310
};
296311

297312
// We only check if we need to reveal the public key if the gas spending key is not provided
@@ -326,7 +341,8 @@ export const createOsmosisSwapTx = async (
326341
gasConfig: GasConfig,
327342
rpcUrl: string,
328343
disposableSigner: GenDisposableSignerResponse,
329-
memo?: string
344+
memo?: string,
345+
frontendFeeConfig?: FrontendFeeConfig
330346
): Promise<EncodedTxData<OsmosisSwapProps>> => {
331347
const { publicKey: signerPublicKey } = disposableSigner;
332348

@@ -349,6 +365,10 @@ export const createOsmosisSwapTx = async (
349365
...transfer,
350366
gasSpendingKey: transfer.gasSpendingKey,
351367
bparams,
368+
frontendSusFee: frontendFeeConfig && {
369+
address: frontendFeeConfig.target,
370+
amount: frontendFeeConfig.percentage.toString(),
371+
},
352372
},
353373
};
354374
const msg: OsmosisSwap = {

apps/namadillo/src/hooks/useTransaction.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ export const useTransaction = <T,>({
147147
params,
148148
gasConfig: feeProps.gasConfig,
149149
account,
150+
frontendFeeConfig: feeProps.frontendFeeConfig,
150151
...txAdditionalParams,
151152
};
152153
const encodedTxData = await performBuildTx(variables);

apps/namadillo/src/hooks/useTransactionFee/useTransactionFee.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ import {
99
isPublicKeyRevealedAtom,
1010
} from "atoms/fees";
1111
import { tokenPricesFamily } from "atoms/prices/atoms";
12+
import { serverFeeAtom } from "atoms/settings";
1213
import BigNumber from "bignumber.js";
1314
import invariant from "invariant";
1415
import { useAtomValue } from "jotai";
1516
import { useMemo, useState } from "react";
16-
import { GasConfig } from "types";
17+
import { FrontendFeeConfig, GasConfig } from "types";
1718
import { TxKind } from "types/txKind";
1819
import { findCheapestToken } from "./internal";
1920

@@ -24,6 +25,7 @@ export type TransactionFeeProps = {
2425
gasPriceTable: GasPriceTable | undefined;
2526
onChangeGasLimit: (value: BigNumber) => void;
2627
onChangeGasToken: (value: string) => void;
28+
frontendFeeConfig?: FrontendFeeConfig;
2729
};
2830

2931
export const useTransactionFee = (
@@ -35,6 +37,7 @@ export const useTransactionFee = (
3537
const userTransparentBalances = useAtomValue(transparentBalanceAtom);
3638
const userShieldedBalances = useAtomValue(shieldedBalanceAtom);
3739
const isPublicKeyRevealed = useAtomValue(isPublicKeyRevealedAtom);
40+
const serverFee = useAtomValue(serverFeeAtom);
3841

3942
const { data: nativeToken, isLoading: isLoadingNativeToken } = useAtomValue(
4043
nativeTokenAddressAtom
@@ -137,6 +140,13 @@ export const useTransactionFee = (
137140
gasToken,
138141
};
139142

143+
// TODO: mappings
144+
const frontendFeeConfig = serverFee && {
145+
target: serverFee.target,
146+
percentage: serverFee.percentage,
147+
maxFeeInMinDenom: serverFee.maxValue,
148+
};
149+
140150
const isLoading =
141151
userTransparentBalances.isLoading ||
142152
isLoadingNativeToken ||
@@ -145,6 +155,7 @@ export const useTransactionFee = (
145155

146156
return {
147157
gasConfig,
158+
frontendFeeConfig,
148159
isLoading,
149160
gasEstimate,
150161
gasPriceTable,

apps/namadillo/src/types.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type Unique = {
2626
export type PublicKey = string;
2727

2828
export type Address = string;
29+
export type PaymentAddress = string;
2930

3031
export type BaseDenom = string;
3132

@@ -46,6 +47,12 @@ export type GasConfig = {
4647
gasToken: GasToken;
4748
};
4849

50+
export type FrontendFeeConfig = {
51+
target: Address | PaymentAddress;
52+
percentage: BigNumber;
53+
maxValue?: BigNumber;
54+
};
55+
4956
export type GasConfigToDisplay = {
5057
totalDisplayAmount: BigNumber;
5158
asset: Asset;
@@ -71,6 +78,11 @@ export type SettingsTomlOptions = {
7178
rpc_url?: string;
7279
localnet_enabled?: boolean;
7380
fathom_site_id?: string;
81+
server_fee?: {
82+
target: string;
83+
percentage: number;
84+
max_value?: number;
85+
};
7486
};
7587

7688
export type ChainParameters = {
@@ -184,6 +196,7 @@ export type BuildTxAtomParams<T> = {
184196
gasConfig: GasConfig;
185197
memo?: string;
186198
signer?: Signer;
199+
frontendFeeConfig?: FrontendFeeConfig;
187200
};
188201

189202
export type SortOptions = "asc" | "desc" | undefined;

0 commit comments

Comments
 (0)