Skip to content

Commit

Permalink
fix: sudt transafer
Browse files Browse the repository at this point in the history
  • Loading branch information
ByteZhang1024 committed Apr 19, 2024
1 parent 196aa74 commit eb73726
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 23 deletions.
23 changes: 22 additions & 1 deletion packages/engine/src/vaults/impl/nervos/Vault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ export default class Vault extends VaultBase {
txSkeleton = await xUDTTransafer(
txSkeleton,
from,
token,
tokenAddress,
to,
BI.from(amountValue),
Expand Down Expand Up @@ -453,6 +454,7 @@ export default class Vault extends VaultBase {
.isGreaterThan(new BigNumber(1.5 * 100000000))
) {
debugLogger.common.error('Fee is too high, transaction: ', txs);

throw new OneKeyInternalError('Fee is too high');
}

Expand Down Expand Up @@ -752,11 +754,24 @@ export default class Vault extends VaultBase {
config: Config;
tokenAddress: string;
}) {
const token = await this.engine.ensureTokenInDB(
const tokenDb = await this.engine.ensureTokenInDB(
this.networkId,
tokenAddress,
);

let token: PartialTokenInfo | undefined;
if (tokenDb) {
token = {
symbol: tokenDb.symbol,
name: tokenDb.name,
decimals: tokenDb.decimals,
};
}

if (!token) {
token = await getTokenInfo(tokenAddress, config);
}

if (!token) {
return [];
}
Expand Down Expand Up @@ -1019,7 +1034,13 @@ export default class Vault extends VaultBase {
config,
tokenAddress,
});

if (actions.length === 0 && tokenActions.length === 0) {
return await Promise.resolve(null);
}

actions = [...actions, ...tokenActions];

if (tokenActions.length > 0) {
existsToken = true;
}
Expand Down
8 changes: 5 additions & 3 deletions packages/engine/src/vaults/impl/nervos/types/TokenInfo.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export type XUDTInfoResponse = {
id: string;
type: string;
attributes: XUDTAttributes;
data: {
id: string;
type: string;
attributes: XUDTAttributes;
};
};

export type XUDTAttributes = {
Expand Down
53 changes: 38 additions & 15 deletions packages/engine/src/vaults/impl/nervos/utils/xudt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,16 @@ import {
minimalCellCapacityCompatible,
parseAddress,
} from '@ckb-lumos/helpers';
import axios from 'axios';
import BigNumber from 'bignumber.js';
import fetch from 'cross-fetch';
import { List, Set } from 'immutable';

import { getFiatEndpoint } from '../../../../endpoint';
import type { Token as IToken } from '@onekeyhq/engine/src/types/token';

import {
MinimumTransferBalanceRequiredForSendingAssetError,
OneKeyValidatorError,
} from '../../../../errors';

import { addCellDep } from './script';

Expand Down Expand Up @@ -55,6 +61,7 @@ export function packAmount(amount: BIish): HexString {
export async function transfer(
txSkeleton: TransactionSkeletonType,
fromAddress: Address,
token: IToken,
xudtToken: Token,
toAddress: Address | null | undefined,
amount: BIish,
Expand Down Expand Up @@ -215,6 +222,9 @@ export async function transfer(
let _totalCapacity = BI.from(0);
let _totalAmount = BI.from(0);

let _totalTokenCapacity = BI.from(0);
let _requiresExtraNativeToken = BI.from(0);

let done = false;
for (const { cellCollector } of cellCollectorInfos) {
for await (const inputCell of cellCollector.collect()) {
Expand Down Expand Up @@ -264,6 +274,9 @@ export async function transfer(

_totalCapacity = _totalCapacity.add(inputCapacity);
_totalAmount = _totalAmount.add(inputAmount);
if (inputCell.cellOutput.type?.args === xudtToken) {
_totalTokenCapacity = _totalTokenCapacity.add(inputCapacity);
}

const requiresAmount = _amount;

Expand All @@ -277,6 +290,7 @@ export async function transfer(
minimalCellCapacityCompatible(changeCellWithoutXudt),
);

_requiresExtraNativeToken = targetCapacity.sub(_totalTokenCapacity);
if (
_totalCapacity.gt(targetCapacity) &&
_totalAmount.gte(requiresAmount)
Expand All @@ -290,8 +304,14 @@ export async function transfer(
}
}

if (changeAmount.lt(0) || changeCapacity.lt(0)) {
throw new Error('Not enough capacity or amount in from infos!');
if (!done || changeAmount.lt(0) || changeCapacity.lt(0)) {
throw new MinimumTransferBalanceRequiredForSendingAssetError(
`${new BigNumber(amount.toString())
.shiftedBy(-token.decimals)
.toString()} ${token.symbol}`,
_requiresExtraNativeToken.div(10 ** 8).toString(),
'CKB',
);
}

const minimalChangeCellWithoutSudtCapacity = BI.from(
Expand Down Expand Up @@ -350,8 +370,8 @@ export async function getTokenInfo(
const scriptHash = utils.computeScriptHash(xudtScript);

try {
const response = await axios.get<XUDTInfoResponse>(
`${getFiatEndpoint()}/nervos/xudts/${scriptHash}`,
const response = await fetch(
`https://mainnet-api.explorer.nervos.org/api/v1/xudts/${scriptHash}`,
{
headers: {
'Content-Type': 'application/vnd.api+json',
Expand All @@ -360,15 +380,18 @@ export async function getTokenInfo(
},
);

if (
response.data.attributes.type_script.args.toLowerCase() ===
token.toLowerCase()
) {
return {
name: response.data.attributes.full_name,
symbol: response.data.attributes.symbol,
decimals: parseInt(response.data.attributes.decimal),
};
if (response.status === 200) {
const res = JSON.parse(await response.text()) as XUDTInfoResponse;
if (
res.data.attributes.type_script.args.toLowerCase() ===
token.toLowerCase()
) {
return {
name: res.data.attributes.full_name,
symbol: res.data.attributes.symbol,
decimals: parseInt(res.data.attributes.decimal),
};
}
}
} catch (error) {
// ignore
Expand Down
6 changes: 2 additions & 4 deletions packages/kit/src/views/Send/modals/PreSendAmount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
useTokenBalanceWithoutFrozen,
} from '../../../hooks/useOverview';
import { useFrozenBalance, useSingleToken } from '../../../hooks/useTokens';
import { deviceUtils } from '../../../utils/hardware';
import { wait } from '../../../utils/helper';
import {
showAccountBalanceDetailsOverlay,
Expand Down Expand Up @@ -440,10 +441,7 @@ function PreSendAmount() {
{ type: 'error' },
);
} else {
ToastManager.show(
{ title: typeof e === 'string' ? e : (e as Error).message },
{ type: 'error' },
);
deviceUtils.showErrorToast(e);
}
} finally {
setIsLoading(false);
Expand Down

0 comments on commit eb73726

Please sign in to comment.