payment-kit 1.18.29 → 1.18.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api/src/crons/index.ts +8 -0
- package/api/src/libs/constants.ts +2 -0
- package/api/src/libs/env.ts +2 -2
- package/api/src/libs/payment.ts +9 -2
- package/api/src/queues/payment.ts +23 -2
- package/api/src/routes/payment-currencies.ts +15 -1
- package/api/src/store/models/types.ts +1 -0
- package/blocklet.yml +1 -1
- package/package.json +21 -21
- package/src/locales/en.tsx +4 -0
- package/src/locales/zh.tsx +3 -0
- package/src/pages/admin/settings/vault-config/edit-form.tsx +58 -3
- package/src/pages/admin/settings/vault-config/index.tsx +35 -1
- package/src/pages/integrations/overview.tsx +1 -1
package/api/src/crons/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
batchHandleStripeSubscriptions,
|
|
8
8
|
} from '../integrations/stripe/resource';
|
|
9
9
|
import {
|
|
10
|
+
depositVaultCronTime,
|
|
10
11
|
expiredSessionCleanupCronTime,
|
|
11
12
|
meteringSubscriptionDetectionCronTime,
|
|
12
13
|
notificationCronTime,
|
|
@@ -25,6 +26,7 @@ import { SubscriptionTrialWillEndSchedule } from './subscription-trial-will-end'
|
|
|
25
26
|
import { SubscriptionWillCanceledSchedule } from './subscription-will-canceled';
|
|
26
27
|
import { SubscriptionWillRenewSchedule } from './subscription-will-renew';
|
|
27
28
|
import { createMeteringSubscriptionDetection } from './metering-subscription-detection';
|
|
29
|
+
import { startDepositVaultQueue } from '../queues/payment';
|
|
28
30
|
|
|
29
31
|
function init() {
|
|
30
32
|
Cron.init({
|
|
@@ -99,6 +101,12 @@ function init() {
|
|
|
99
101
|
fn: () => createMeteringSubscriptionDetection(),
|
|
100
102
|
options: { runOnInit: false },
|
|
101
103
|
},
|
|
104
|
+
{
|
|
105
|
+
name: 'deposit.vault',
|
|
106
|
+
time: depositVaultCronTime,
|
|
107
|
+
fn: () => startDepositVaultQueue(),
|
|
108
|
+
options: { runOnInit: true },
|
|
109
|
+
},
|
|
102
110
|
],
|
|
103
111
|
onError: (error: Error, name: string) => {
|
|
104
112
|
logger.error('run job failed', { name, error });
|
package/api/src/libs/env.ts
CHANGED
|
@@ -8,11 +8,11 @@ export const notificationCronConcurrency: number = Number(process.env.NOTIFICATI
|
|
|
8
8
|
export const stripeInvoiceCronTime: string = process.env.STRIPE_INVOICE_CRON_TIME || '0 */30 * * * *'; // 默认每 30min 执行一次
|
|
9
9
|
export const stripePaymentCronTime: string = process.env.STRIPE_PAYMENT_CRON_TIME || '0 */20 * * * *'; // 默认每 20min 执行一次
|
|
10
10
|
export const stripeSubscriptionCronTime: string = process.env.STRIPE_SUBSCRIPTION_CRON_TIME || '0 10 */8 * * *'; // 默认每 8小时 执行一次
|
|
11
|
-
export const revokeStakeCronTime: string = process.env.REVOKE_STAKE_CRON_TIME || '0 */5 * * * *'; // 默认每 5 min
|
|
11
|
+
export const revokeStakeCronTime: string = process.env.REVOKE_STAKE_CRON_TIME || '0 */5 * * * *'; // 默认每 5 min 执行一次
|
|
12
12
|
export const daysUntilCancel: string | undefined = process.env.DAYS_UNTIL_CANCEL;
|
|
13
13
|
export const meteringSubscriptionDetectionCronTime: string =
|
|
14
14
|
process.env.METERING_SUBSCRIPTION_DETECTION_CRON_TIME || '0 0 10 * * *'; // 默认每天 10:00 执行
|
|
15
|
-
|
|
15
|
+
export const depositVaultCronTime: string = process.env.DEPOSIT_VAULT_CRON_TIME || '0 */5 * * * *'; // 默认每 5 min 执行一次
|
|
16
16
|
// sequelize 配置相关
|
|
17
17
|
export const sequelizeOptionsPoolMin: number = process.env.SEQUELIZE_OPTIONS_POOL_MIN
|
|
18
18
|
? +process.env.SEQUELIZE_OPTIONS_POOL_MIN
|
package/api/src/libs/payment.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { sign } from '@arcblock/jwt';
|
|
|
5
5
|
import { getWalletDid } from '@blocklet/sdk/lib/did';
|
|
6
6
|
import type { DelegateState, TokenLimit } from '@ocap/client';
|
|
7
7
|
import { toTxHash } from '@ocap/mcrypto';
|
|
8
|
-
import { BN, fromUnitToToken } from '@ocap/util';
|
|
8
|
+
import { BN, fromTokenToUnit, fromUnitToToken } from '@ocap/util';
|
|
9
9
|
import cloneDeep from 'lodash/cloneDeep';
|
|
10
10
|
import type { LiteralUnion } from 'type-fest';
|
|
11
11
|
|
|
@@ -24,7 +24,7 @@ import type { TPaymentCurrency } from '../store/models/payment-currency';
|
|
|
24
24
|
import { blocklet, ethWallet, wallet, getVaultAddress } from './auth';
|
|
25
25
|
import logger from './logger';
|
|
26
26
|
import { getBlockletJson, getUserOrAppInfo, OCAP_PAYMENT_TX_TYPE, resolveAddressChainTypes } from './util';
|
|
27
|
-
import { CHARGE_SUPPORTED_CHAIN_TYPES, EVM_CHAIN_TYPES } from './constants';
|
|
27
|
+
import { CHARGE_SUPPORTED_CHAIN_TYPES, VAULT_BUFFER_THRESHOLD, EVM_CHAIN_TYPES } from './constants';
|
|
28
28
|
import { getTokenByAddress } from '../integrations/arcblock/stake';
|
|
29
29
|
|
|
30
30
|
export interface SufficientForPaymentResult {
|
|
@@ -459,6 +459,13 @@ export async function checkDepositVaultAmount(paymentCurrencyId: string): Promis
|
|
|
459
459
|
return { depositAmount: '0', message: 'No amount available to deposit after calculations' };
|
|
460
460
|
}
|
|
461
461
|
|
|
462
|
+
const bufferThreshold =
|
|
463
|
+
paymentCurrency?.vault_config?.buffer_threshold ||
|
|
464
|
+
fromTokenToUnit(VAULT_BUFFER_THRESHOLD, paymentCurrency.decimal).toString();
|
|
465
|
+
if (new BN(amountToDeposit).lt(new BN(bufferThreshold))) {
|
|
466
|
+
return { depositAmount: '0', message: 'Amount to deposit is less than the buffer threshold' };
|
|
467
|
+
}
|
|
468
|
+
|
|
462
469
|
return {
|
|
463
470
|
depositAmount: amountToDeposit,
|
|
464
471
|
vaultAddress,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import isEmpty from 'lodash/isEmpty';
|
|
2
2
|
|
|
3
3
|
import { BN } from '@ocap/util';
|
|
4
|
+
import pAll from 'p-all';
|
|
4
5
|
import { ensureStakedForGas } from '../integrations/arcblock/stake';
|
|
5
6
|
import { transferErc20FromUser } from '../integrations/ethereum/token';
|
|
6
7
|
import { createEvent } from '../libs/audit';
|
|
@@ -39,7 +40,7 @@ import { ensureOverdraftProtectionInvoiceAndItems } from '../libs/invoice';
|
|
|
39
40
|
import { Lock } from '../store/models';
|
|
40
41
|
import { ensureOverdraftProtectionPrice } from '../libs/overdraft-protection';
|
|
41
42
|
import createQueue from '../libs/queue';
|
|
42
|
-
import { EVM_CHAIN_TYPES } from '../libs/constants';
|
|
43
|
+
import { CHARGE_SUPPORTED_CHAIN_TYPES, EVM_CHAIN_TYPES } from '../libs/constants';
|
|
43
44
|
|
|
44
45
|
type PaymentJob = {
|
|
45
46
|
paymentIntentId: string;
|
|
@@ -802,14 +803,16 @@ export const handlePayment = async (job: PaymentJob) => {
|
|
|
802
803
|
wallet,
|
|
803
804
|
delegator: result.delegator,
|
|
804
805
|
});
|
|
806
|
+
logger.info('PaymentIntent signed', { signed });
|
|
805
807
|
// @ts-ignore
|
|
806
808
|
const { buffer } = await client.encodeTransferV2Tx({ tx: signed });
|
|
809
|
+
logger.info('PaymentIntent buffer', { buffer, gas: getGasPayerExtra(buffer) });
|
|
807
810
|
const txHash = await client.sendTransferV2Tx(
|
|
808
811
|
// @ts-ignore
|
|
809
812
|
{ tx: signed, wallet, delegator: result.delegator },
|
|
810
813
|
getGasPayerExtra(buffer)
|
|
811
814
|
);
|
|
812
|
-
|
|
815
|
+
logger.info('PaymentIntent txHash', { txHash });
|
|
813
816
|
logger.info('PaymentIntent capture done', { id: paymentIntent.id, txHash });
|
|
814
817
|
|
|
815
818
|
await paymentIntent.update({
|
|
@@ -1022,3 +1025,21 @@ events.on('payment.queued', async (id, job, args = {}) => {
|
|
|
1022
1025
|
events.emit('payment.queued.error', { id, job, error });
|
|
1023
1026
|
}
|
|
1024
1027
|
});
|
|
1028
|
+
|
|
1029
|
+
export async function startDepositVaultQueue() {
|
|
1030
|
+
logger.debug('startDepositVaultQueue');
|
|
1031
|
+
const paymentCurrencies = (await PaymentCurrency.scope('withVaultConfig').findAll({
|
|
1032
|
+
include: [{ model: PaymentMethod, as: 'payment_method' }],
|
|
1033
|
+
})) as (PaymentCurrency & { payment_method: PaymentMethod })[];
|
|
1034
|
+
await pAll(
|
|
1035
|
+
paymentCurrencies.map((x) => {
|
|
1036
|
+
if (CHARGE_SUPPORTED_CHAIN_TYPES.includes(x.payment_method.type) && x.vault_config?.enabled === true) {
|
|
1037
|
+
depositVaultQueue.push({ id: `deposit-vault-${x.id}`, job: { currencyId: x.id } });
|
|
1038
|
+
}
|
|
1039
|
+
return async () => {};
|
|
1040
|
+
}),
|
|
1041
|
+
{
|
|
1042
|
+
concurrency: 5,
|
|
1043
|
+
}
|
|
1044
|
+
);
|
|
1045
|
+
}
|
|
@@ -8,7 +8,7 @@ import logger from '../libs/logger';
|
|
|
8
8
|
import { authenticate } from '../libs/security';
|
|
9
9
|
import { PaymentCurrency, TPaymentCurrency } from '../store/models/payment-currency';
|
|
10
10
|
import { PaymentMethod } from '../store/models/payment-method';
|
|
11
|
-
import { EVM_CHAIN_TYPES } from '../libs/constants';
|
|
11
|
+
import { VAULT_BUFFER_THRESHOLD, EVM_CHAIN_TYPES } from '../libs/constants';
|
|
12
12
|
import { ethWallet, getVaultAddress, wallet } from '../libs/auth';
|
|
13
13
|
import { resolveAddressChainTypes } from '../libs/util';
|
|
14
14
|
import { depositVaultQueue } from '../queues/payment';
|
|
@@ -215,6 +215,10 @@ router.put('/:id/deposit-vault', auth, async (req, res) => {
|
|
|
215
215
|
if (!paymentCurrency) {
|
|
216
216
|
return res.status(404).json({ error: 'Payment currency not found' });
|
|
217
217
|
}
|
|
218
|
+
const vaultAddress = await getVaultAddress();
|
|
219
|
+
if (!vaultAddress) {
|
|
220
|
+
return res.status(400).json({ error: 'Vault address not found' });
|
|
221
|
+
}
|
|
218
222
|
depositVaultQueue.push({
|
|
219
223
|
id: `deposit-vault-${paymentCurrency.id}`,
|
|
220
224
|
job: { currencyId: paymentCurrency.id },
|
|
@@ -239,6 +243,7 @@ const UpdateVaultConfigSchema = Joi.object({
|
|
|
239
243
|
enabled: Joi.boolean().required(),
|
|
240
244
|
deposit_threshold: Joi.number().greater(0).required(),
|
|
241
245
|
withdraw_threshold: Joi.number().min(0).required(),
|
|
246
|
+
buffer_threshold: Joi.number().greater(0).required(),
|
|
242
247
|
});
|
|
243
248
|
router.put('/:id/vault-config', authOwner, async (req, res) => {
|
|
244
249
|
try {
|
|
@@ -254,11 +259,20 @@ router.put('/:id/vault-config', authOwner, async (req, res) => {
|
|
|
254
259
|
return res.status(404).json({ error: 'payment currency not found' });
|
|
255
260
|
}
|
|
256
261
|
|
|
262
|
+
const vaultAddress = await getVaultAddress();
|
|
263
|
+
if (!vaultAddress) {
|
|
264
|
+
return res.status(400).json({ error: 'Vault address not found' });
|
|
265
|
+
}
|
|
266
|
+
|
|
257
267
|
const updateData: Partial<TPaymentCurrency> = {
|
|
258
268
|
vault_config: {
|
|
259
269
|
enabled: vaultConfig.enabled,
|
|
260
270
|
deposit_threshold: fromTokenToUnit(vaultConfig.deposit_threshold, paymentCurrency.decimal).toString(),
|
|
261
271
|
withdraw_threshold: fromTokenToUnit(vaultConfig.withdraw_threshold, paymentCurrency.decimal).toString(),
|
|
272
|
+
buffer_threshold: fromTokenToUnit(
|
|
273
|
+
vaultConfig.buffer_threshold || VAULT_BUFFER_THRESHOLD,
|
|
274
|
+
paymentCurrency.decimal
|
|
275
|
+
).toString(),
|
|
262
276
|
},
|
|
263
277
|
};
|
|
264
278
|
|
package/blocklet.yml
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payment-kit",
|
|
3
|
-
"version": "1.18.
|
|
3
|
+
"version": "1.18.30",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "blocklet dev --open",
|
|
6
6
|
"eject": "vite eject",
|
|
@@ -43,30 +43,30 @@
|
|
|
43
43
|
]
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@abtnode/cron": "^1.16.
|
|
47
|
-
"@arcblock/did": "^1.
|
|
46
|
+
"@abtnode/cron": "^1.16.42",
|
|
47
|
+
"@arcblock/did": "^1.20.0",
|
|
48
48
|
"@arcblock/did-auth-storage-nedb": "^1.7.1",
|
|
49
|
-
"@arcblock/did-connect": "^2.
|
|
50
|
-
"@arcblock/did-util": "^1.
|
|
51
|
-
"@arcblock/jwt": "^1.
|
|
52
|
-
"@arcblock/ux": "^2.
|
|
53
|
-
"@arcblock/validator": "^1.
|
|
54
|
-
"@blocklet/js-sdk": "^1.16.
|
|
55
|
-
"@blocklet/logger": "^1.16.
|
|
56
|
-
"@blocklet/payment-react": "1.18.
|
|
57
|
-
"@blocklet/sdk": "^1.16.
|
|
58
|
-
"@blocklet/ui-react": "^2.
|
|
49
|
+
"@arcblock/did-connect": "^2.13.1",
|
|
50
|
+
"@arcblock/did-util": "^1.20.0",
|
|
51
|
+
"@arcblock/jwt": "^1.20.0",
|
|
52
|
+
"@arcblock/ux": "^2.13.1",
|
|
53
|
+
"@arcblock/validator": "^1.20.0",
|
|
54
|
+
"@blocklet/js-sdk": "^1.16.42",
|
|
55
|
+
"@blocklet/logger": "^1.16.42",
|
|
56
|
+
"@blocklet/payment-react": "1.18.30",
|
|
57
|
+
"@blocklet/sdk": "^1.16.42",
|
|
58
|
+
"@blocklet/ui-react": "^2.13.1",
|
|
59
59
|
"@blocklet/uploader": "^0.1.82",
|
|
60
60
|
"@blocklet/xss": "^0.1.31",
|
|
61
61
|
"@mui/icons-material": "^5.16.6",
|
|
62
62
|
"@mui/lab": "^5.0.0-alpha.173",
|
|
63
63
|
"@mui/material": "^5.16.6",
|
|
64
64
|
"@mui/system": "^5.16.6",
|
|
65
|
-
"@ocap/asset": "^1.
|
|
66
|
-
"@ocap/client": "^1.
|
|
67
|
-
"@ocap/mcrypto": "^1.
|
|
68
|
-
"@ocap/util": "^1.
|
|
69
|
-
"@ocap/wallet": "^1.
|
|
65
|
+
"@ocap/asset": "^1.20.0",
|
|
66
|
+
"@ocap/client": "^1.20.0",
|
|
67
|
+
"@ocap/mcrypto": "^1.20.0",
|
|
68
|
+
"@ocap/util": "^1.20.0",
|
|
69
|
+
"@ocap/wallet": "^1.20.0",
|
|
70
70
|
"@stripe/react-stripe-js": "^2.7.3",
|
|
71
71
|
"@stripe/stripe-js": "^2.4.0",
|
|
72
72
|
"ahooks": "^3.8.0",
|
|
@@ -119,9 +119,9 @@
|
|
|
119
119
|
"web3": "^4.16.0"
|
|
120
120
|
},
|
|
121
121
|
"devDependencies": {
|
|
122
|
-
"@abtnode/types": "^1.16.
|
|
122
|
+
"@abtnode/types": "^1.16.42",
|
|
123
123
|
"@arcblock/eslint-config-ts": "^0.3.3",
|
|
124
|
-
"@blocklet/payment-types": "1.18.
|
|
124
|
+
"@blocklet/payment-types": "1.18.30",
|
|
125
125
|
"@types/cookie-parser": "^1.4.7",
|
|
126
126
|
"@types/cors": "^2.8.17",
|
|
127
127
|
"@types/debug": "^4.1.12",
|
|
@@ -167,5 +167,5 @@
|
|
|
167
167
|
"parser": "typescript"
|
|
168
168
|
}
|
|
169
169
|
},
|
|
170
|
-
"gitHead": "
|
|
170
|
+
"gitHead": "ed1753c48ee405a104cd2a0cab87cccb21e70ba8"
|
|
171
171
|
}
|
package/src/locales/en.tsx
CHANGED
|
@@ -759,6 +759,10 @@ export default flat({
|
|
|
759
759
|
enabledNo: 'Disabled',
|
|
760
760
|
depositThreshold: 'Deposit Threshold',
|
|
761
761
|
withdrawThreshold: 'Withdrawal Threshold',
|
|
762
|
+
bufferThreshold: 'Buffer Threshold',
|
|
763
|
+
bufferThresholdHelp:
|
|
764
|
+
'Only when the amount exceeding the deposit threshold reaches the buffer threshold will the collection operation be triggered.',
|
|
765
|
+
bufferThresholdInvalid: 'Buffer threshold must be greater than 0',
|
|
762
766
|
edit: 'Configure',
|
|
763
767
|
enable: 'Enable',
|
|
764
768
|
editTitle: 'Configure {currency} Vault Settings',
|
package/src/locales/zh.tsx
CHANGED
|
@@ -741,6 +741,9 @@ export default flat({
|
|
|
741
741
|
enabledNo: '未启用',
|
|
742
742
|
depositThreshold: '存入阈值',
|
|
743
743
|
withdrawThreshold: '提取阈值',
|
|
744
|
+
bufferThreshold: '差额阈值',
|
|
745
|
+
bufferThresholdHelp: '只有当超出存入阈值的金额达到差额阈值时,才会触发归集操作.',
|
|
746
|
+
bufferThresholdInvalid: '差额阈值必须大于0',
|
|
744
747
|
edit: '配置',
|
|
745
748
|
enable: '启用',
|
|
746
749
|
editTitle: '配置 {currency} 冷钱包设置',
|
|
@@ -20,9 +20,11 @@ type VaultConfigFormData = {
|
|
|
20
20
|
enabled: boolean;
|
|
21
21
|
deposit_threshold: string;
|
|
22
22
|
withdraw_threshold: string;
|
|
23
|
+
buffer_threshold: string;
|
|
23
24
|
};
|
|
24
25
|
|
|
25
|
-
const
|
|
26
|
+
const VAULT_DEPOSIT_THRESHOLD = '100';
|
|
27
|
+
const VAULT_BUFFER_THRESHOLD = '10';
|
|
26
28
|
|
|
27
29
|
const updateVaultConfig = async (currencyId: string, data: VaultConfigFormData) => {
|
|
28
30
|
const res = await api.put(`/api/payment-currencies/${currencyId}/vault-config`, data);
|
|
@@ -42,10 +44,13 @@ function EditForm({ item, onClose, onSuccess, isOwner }: EditFormProps) {
|
|
|
42
44
|
deposit_threshold:
|
|
43
45
|
item?.vault_config?.deposit_threshold && item?.vault_config?.deposit_threshold !== '0'
|
|
44
46
|
? formatBNStr(item.vault_config.deposit_threshold, item?.decimal || 18)
|
|
45
|
-
:
|
|
47
|
+
: VAULT_DEPOSIT_THRESHOLD,
|
|
46
48
|
withdraw_threshold: item?.vault_config?.withdraw_threshold
|
|
47
49
|
? formatBNStr(item.vault_config.withdraw_threshold, item?.decimal || 18)
|
|
48
50
|
: '0',
|
|
51
|
+
buffer_threshold: item?.vault_config?.buffer_threshold
|
|
52
|
+
? formatBNStr(item.vault_config.buffer_threshold, item?.decimal || 18)
|
|
53
|
+
: VAULT_BUFFER_THRESHOLD,
|
|
49
54
|
},
|
|
50
55
|
mode: 'onChange',
|
|
51
56
|
});
|
|
@@ -58,6 +63,11 @@ function EditForm({ item, onClose, onSuccess, isOwner }: EditFormProps) {
|
|
|
58
63
|
return t('admin.vaultConfig.depositThresholdHelp');
|
|
59
64
|
};
|
|
60
65
|
|
|
66
|
+
const getBufferHelperText = (error?: { message?: string }) => {
|
|
67
|
+
if (error) return error.message;
|
|
68
|
+
return t('admin.vaultConfig.bufferThresholdHelp');
|
|
69
|
+
};
|
|
70
|
+
|
|
61
71
|
// const getWithdrawHelperText = (error?: { message?: string }, threshold?: string) => {
|
|
62
72
|
// if (error) return error.message;
|
|
63
73
|
// return Number(threshold) === 0
|
|
@@ -192,7 +202,52 @@ function EditForm({ item, onClose, onSuccess, isOwner }: EditFormProps) {
|
|
|
192
202
|
},
|
|
193
203
|
}}
|
|
194
204
|
sx={{ mt: 1 }}
|
|
195
|
-
placeholder={
|
|
205
|
+
placeholder={VAULT_DEPOSIT_THRESHOLD}
|
|
206
|
+
/>
|
|
207
|
+
)}
|
|
208
|
+
/>
|
|
209
|
+
</Box>
|
|
210
|
+
|
|
211
|
+
{/* 差额阈值设置 */}
|
|
212
|
+
<Box>
|
|
213
|
+
{renderLabelWithTooltip(
|
|
214
|
+
t('admin.vaultConfig.bufferThreshold'),
|
|
215
|
+
t('admin.vaultConfig.bufferThresholdHelp')
|
|
216
|
+
)}
|
|
217
|
+
<Controller
|
|
218
|
+
name="buffer_threshold"
|
|
219
|
+
control={control}
|
|
220
|
+
rules={{
|
|
221
|
+
required: true,
|
|
222
|
+
validate: (value) => {
|
|
223
|
+
if (Number(value) <= 0) {
|
|
224
|
+
return t('admin.vaultConfig.bufferThresholdInvalid');
|
|
225
|
+
}
|
|
226
|
+
const validPrecision = formatAmountPrecisionLimit(value.toString(), locale, item.decimal || 6);
|
|
227
|
+
return validPrecision || true;
|
|
228
|
+
},
|
|
229
|
+
}}
|
|
230
|
+
render={({ field }) => (
|
|
231
|
+
<TextField
|
|
232
|
+
{...field}
|
|
233
|
+
fullWidth
|
|
234
|
+
type="number"
|
|
235
|
+
error={!!errors.buffer_threshold}
|
|
236
|
+
helperText={getBufferHelperText(errors.buffer_threshold)}
|
|
237
|
+
InputProps={{
|
|
238
|
+
endAdornment: (
|
|
239
|
+
<InputAdornment position="end">
|
|
240
|
+
<Box sx={{ display: 'flex', alignItems: 'center', ml: 1 }}>
|
|
241
|
+
<Currency logo={item.logo} name={item.symbol} />
|
|
242
|
+
</Box>
|
|
243
|
+
</InputAdornment>
|
|
244
|
+
),
|
|
245
|
+
inputProps: {
|
|
246
|
+
min: 0,
|
|
247
|
+
},
|
|
248
|
+
}}
|
|
249
|
+
sx={{ mt: 1 }}
|
|
250
|
+
placeholder={VAULT_BUFFER_THRESHOLD}
|
|
196
251
|
/>
|
|
197
252
|
)}
|
|
198
253
|
/>
|
|
@@ -203,6 +203,40 @@ export default function VaultConfig() {
|
|
|
203
203
|
},
|
|
204
204
|
},
|
|
205
205
|
},
|
|
206
|
+
{
|
|
207
|
+
label: t('admin.vaultConfig.bufferThreshold'),
|
|
208
|
+
name: 'buffer_threshold',
|
|
209
|
+
options: {
|
|
210
|
+
customBodyRenderLite: (dataIndex: number) => {
|
|
211
|
+
const item = data.list?.[dataIndex];
|
|
212
|
+
if (!item) {
|
|
213
|
+
return '-';
|
|
214
|
+
}
|
|
215
|
+
if (!item?.vault_config) {
|
|
216
|
+
return (
|
|
217
|
+
<Typography variant="body2" color="text.secondary">
|
|
218
|
+
{t('admin.vaultConfig.notConfig')}
|
|
219
|
+
</Typography>
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
return (
|
|
223
|
+
<Typography variant="body1">
|
|
224
|
+
{formatBNStr(item.vault_config?.buffer_threshold || '0', item.decimal)} {item.symbol}
|
|
225
|
+
</Typography>
|
|
226
|
+
);
|
|
227
|
+
},
|
|
228
|
+
customHeadLabelRender: () => {
|
|
229
|
+
return (
|
|
230
|
+
<Box display="flex" alignItems="center" gap={1}>
|
|
231
|
+
{t('admin.vaultConfig.bufferThreshold')}
|
|
232
|
+
<Tooltip title={t('admin.vaultConfig.bufferThresholdHelp')}>
|
|
233
|
+
<HelpOutline fontSize="small" sx={{ color: 'text.lighter' }} />
|
|
234
|
+
</Tooltip>
|
|
235
|
+
</Box>
|
|
236
|
+
);
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
},
|
|
206
240
|
// {
|
|
207
241
|
// label: t('admin.vaultConfig.withdrawThreshold'),
|
|
208
242
|
// name: 'withdraw_threshold',
|
|
@@ -289,7 +323,7 @@ export default function VaultConfig() {
|
|
|
289
323
|
) : (
|
|
290
324
|
<Link
|
|
291
325
|
key={part.content}
|
|
292
|
-
to={`${window.location.origin}/.well-known/service/admin/
|
|
326
|
+
to={`${window.location.origin}/.well-known/service/admin/operations/advanced`}
|
|
293
327
|
style={{ color: '#3b82f6' }}>
|
|
294
328
|
{part.content}
|
|
295
329
|
</Link>
|