From 114a33fe6e2eb76b59c59a160c9ccf07e0170d1e Mon Sep 17 00:00:00 2001 From: JordiParraCrespo Date: Fri, 10 Mar 2023 11:24:29 +0100 Subject: [PATCH 01/14] fix loading cells --- src/module/common/service/CkbSdkService.ts | 2 +- .../component/core/DAOAccountCard/DAOCard.tsx | 2 +- src/module/sdk/core/wallet.service.ts | 5 ++-- .../transaction/query/useGetTransactions.ts | 2 +- .../core/AccountCard/AccountCard.tsx | 4 ++-- .../wallet/hook/useServiceInstanceCreation.ts | 24 +++++++++++++------ src/module/wallet/state/WalletState.ts | 11 ++++++++- 7 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/module/common/service/CkbSdkService.ts b/src/module/common/service/CkbSdkService.ts index 6f70f8297..3c9db32e4 100644 --- a/src/module/common/service/CkbSdkService.ts +++ b/src/module/common/service/CkbSdkService.ts @@ -62,7 +62,7 @@ export class CKBSDKService { chain: Chain, mnemonic: string, walletState?: WalletState, - onSync?: (walletState: WalletState) => Promise, + onSync?: (walletState?: WalletState) => Promise, onSyncStart?: () => void, ) { this.connectionService = chain === "testnet" ? testnetConnectionService : mainnetConnectionService; diff --git a/src/module/dao/component/core/DAOAccountCard/DAOCard.tsx b/src/module/dao/component/core/DAOAccountCard/DAOCard.tsx index e6876c925..92c057951 100644 --- a/src/module/dao/component/core/DAOAccountCard/DAOCard.tsx +++ b/src/module/dao/component/core/DAOAccountCard/DAOCard.tsx @@ -10,7 +10,7 @@ const DAOCard = ({ wallet, style }: WalletComponentCardProps) => { const { data: { estimated_apc = "0.0000" } = {}, isLoading: loadingDao } = useGetDaoInfo(); const { data: { freeBalance = 0 } = {}, isLoading: balanceLoading } = useGetBalance(); - const loading = daoBalanceLoading || loadingDao || balanceLoading; + const loading = daoBalanceLoading || loadingDao || balanceLoading || wallet.synchronizingCells; return ( diff --git a/src/module/sdk/core/wallet.service.ts b/src/module/sdk/core/wallet.service.ts index 413404ccc..56d6ff97b 100644 --- a/src/module/sdk/core/wallet.service.ts +++ b/src/module/sdk/core/wallet.service.ts @@ -59,7 +59,7 @@ export class WalletService { private lastHashBlock!: string; private accountCellsMap: cellMapI = {}; private accountTransactionMap: transactionMapI = {}; - private onSync!: (walletState: WalletState) => Promise; + private onSync!: (walletState?: WalletState) => Promise; private onSyncStart!: () => void; private synchronizing = false; @@ -67,7 +67,7 @@ export class WalletService { connectionService: ConnectionService, mnemo: string, walletState?: WalletState, - onSync?: (walletState: WalletState) => Promise, + onSync?: (walletState?: WalletState) => Promise, onSyncStart?: () => void, ) { if (!WalletService.validateMnemonic(mnemo)) { @@ -190,6 +190,7 @@ export class WalletService { } } + if (this.onSync) this.onSync(); const allAddresses = this.getAllAddresses(); for (let i = 0; i < keysArr.length && i < lumosTxsArr.length && i < addressesArr.length; i += 1) { const address = addressesArr[i]; diff --git a/src/module/transaction/query/useGetTransactions.ts b/src/module/transaction/query/useGetTransactions.ts index c9300096b..a472ca960 100644 --- a/src/module/transaction/query/useGetTransactions.ts +++ b/src/module/transaction/query/useGetTransactions.ts @@ -28,7 +28,7 @@ const useGetTransactions = ({ index, filter }: UseGetTransactionsOptions = {}) = return filter ? [...uncommitedTransactions, ...filteredTransacations].filter(filter) : [...uncommitedTransactions, ...filteredTransacations]; - }, [uncommitedTransactions, transactions, filter]); + }, [uncommitedTransactions, transactions.length, filter]); return { data: txs, diff --git a/src/module/wallet/component/core/AccountCard/AccountCard.tsx b/src/module/wallet/component/core/AccountCard/AccountCard.tsx index aa63f155f..14bb474f6 100644 --- a/src/module/wallet/component/core/AccountCard/AccountCard.tsx +++ b/src/module/wallet/component/core/AccountCard/AccountCard.tsx @@ -9,13 +9,13 @@ import AccountCardButtons from "module/wallet/component/core/AccountCard/Account import useCkbConversion from "module/common/hook/useCkbConversion"; const AccountCard = ({ wallet, style }: WalletComponentCardProps): JSX.Element => { - const { index, synchronizing } = wallet; + const { index, synchronizingCells } = wallet; const { fiat } = useRecoilValue(settingsState); const { data: { freeBalance = 0 } = {}, isLoading: isBalanceLoading } = useGetBalance(index); const [showFiat, setCurrencyMode] = useState(false); const { value: balanceInFiat } = useCkbConversion(freeBalance.toString(), fiat); - const isLoading = synchronizing || isBalanceLoading; + const isLoading = synchronizingCells || isBalanceLoading; const changeCurrencyMode = () => { impactAsync(ImpactFeedbackStyle.Medium); diff --git a/src/module/wallet/hook/useServiceInstanceCreation.ts b/src/module/wallet/hook/useServiceInstanceCreation.ts index 0a27b4e0c..8d43c8f61 100644 --- a/src/module/wallet/hook/useServiceInstanceCreation.ts +++ b/src/module/wallet/hook/useServiceInstanceCreation.ts @@ -18,18 +18,28 @@ const useServiceInstanceCreation = (): (( return async (index, mnemonic, testnetInitialState, mainnetInitialState) => { if (!serviceInstancesMap.has(index)) { const stringMnemonic = mnemonic.join(" "); - const onSync = async (chain: Chain, walletState: WalletState) => { - await WalletStorage.setInitialState(index, chain, walletState); + + const onSync = async (chain: Chain, walletState?: WalletState) => { invalidateWalletQueries(index, chain); - setWalletState((state) => ({ - ...state, - wallets: state.wallets.map((w) => (w.index === index ? { ...w, initialState: walletState, synchronizing: false } : w)), - })); + if (walletState) { + await WalletStorage.setInitialState(index, chain, walletState); + setWalletState((state) => ({ + ...state, + wallets: state.wallets.map((w) => + w.index === index ? { ...w, initialState: walletState, synchronizing: false } : w, + ), + })); + } else { + setWalletState((state) => ({ + ...state, + wallets: state.wallets.map((w) => (w.index === index ? { ...w, synchronizingCells: false } : w)), + })); + } }; const onSyncStart = () => { setWalletState((state) => ({ ...state, - wallets: state.wallets.map((w) => (w.index === index ? { ...w, synchronizing: true } : w)), + wallets: state.wallets.map((w) => (w.index === index ? { ...w, synchronizing: true, synchronizingCells: true } : w)), })); }; serviceInstancesMap.set(index, { diff --git a/src/module/wallet/state/WalletState.ts b/src/module/wallet/state/WalletState.ts index b88a1d383..0b01cde67 100644 --- a/src/module/wallet/state/WalletState.ts +++ b/src/module/wallet/state/WalletState.ts @@ -4,7 +4,16 @@ import { CKBSDKService } from "module/common/service/CkbSdkService"; export const serviceInstancesMap = new Map(); -export type Wallet = Omit & { synchronizing?: boolean }; +export type Wallet = Omit & { + /** + * Main loading state. Apart from the cells, it also loads the transactions + */ + synchronizing?: boolean; + /** + * Loading the cells to cpmpute the CKBalance, the DAOBalance, tokens + */ + synchronizingCells?: boolean; +}; export interface WalletState { hasWallet: boolean; From 9b5c39e98433271e8c6a1f9192797e2a6e09db22 Mon Sep 17 00:00:00 2001 From: JordiParraCrespo Date: Fri, 10 Mar 2023 11:28:59 +0100 Subject: [PATCH 02/14] tsx secuencials --- src/module/sdk/core/wallet.service.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/module/sdk/core/wallet.service.ts b/src/module/sdk/core/wallet.service.ts index 56d6ff97b..a0d6e9759 100644 --- a/src/module/sdk/core/wallet.service.ts +++ b/src/module/sdk/core/wallet.service.ts @@ -194,8 +194,11 @@ export class WalletService { const allAddresses = this.getAllAddresses(); for (let i = 0; i < keysArr.length && i < lumosTxsArr.length && i < addressesArr.length; i += 1) { const address = addressesArr[i]; - const promises = lumosTxsArr[i].map((tx) => this.transactionService.getTransactionFromLumosTx(tx, address, allAddresses)); - const transactions = await Promise.all(promises); + const transactions: Transaction[] = []; + + for (const tx of lumosTxsArr[i]) { + transactions.push(await this.transactionService.getTransactionFromLumosTx(tx, address, allAddresses)); + } // Update transactions const currentTxs: Transaction[] = this.accountTransactionMap[keysArr[i]] || []; From cad3b23a006b57cf9fc4d479246e7d87fd942375 Mon Sep 17 00:00:00 2001 From: JordiParraCrespo Date: Fri, 10 Mar 2023 14:14:56 +0100 Subject: [PATCH 03/14] finish fix --- src/module/sdk/core/assets/nft.service.ts | 1 - src/module/sdk/core/wallet.service.ts | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/module/sdk/core/assets/nft.service.ts b/src/module/sdk/core/assets/nft.service.ts index 630d8f4d0..4381c3e08 100644 --- a/src/module/sdk/core/assets/nft.service.ts +++ b/src/module/sdk/core/assets/nft.service.ts @@ -150,7 +150,6 @@ export class NftService { nodeUrl: this.connection.getCKBUrl(), indexerUrl: this.connection.getIndexerUrl(), }); - this.logger.info("NftService initialized"); } else if (!this.nftSdk) { while (!this.nftSdk) { await sleep(100); diff --git a/src/module/sdk/core/wallet.service.ts b/src/module/sdk/core/wallet.service.ts index a0d6e9759..5d5ca80a2 100644 --- a/src/module/sdk/core/wallet.service.ts +++ b/src/module/sdk/core/wallet.service.ts @@ -197,7 +197,8 @@ export class WalletService { const transactions: Transaction[] = []; for (const tx of lumosTxsArr[i]) { - transactions.push(await this.transactionService.getTransactionFromLumosTx(tx, address, allAddresses)); + const finalTx = await this.transactionService.getTransactionFromLumosTx(tx, address, allAddresses); + transactions.push(finalTx); } // Update transactions @@ -335,7 +336,6 @@ export class WalletService { getTransactions(): Transaction[] { const sortedTxs = [...Object.values(this.accountTransactionMap)].flat(1).sort((txa, txb) => txa.blockNumber! - txb.blockNumber!); - // Remove equal transactions for (let i = 0; i < sortedTxs.length; i += 1) { let j = i + 1; From 9fca8a9a6d57e5e3d7248bf51d2fc5610aa844c7 Mon Sep 17 00:00:00 2001 From: JordiParraCrespo Date: Tue, 14 Mar 2023 07:50:57 +0100 Subject: [PATCH 04/14] add token amount --- src/module/common/service/CkbSdkService.ts | 22 +++++++---------- .../common/service/CkbSdkService.types.ts | 3 ++- src/module/sdk/core/assets/nft.service.ts | 24 +++++++++++-------- src/module/sdk/core/transaction.service.ts | 9 +++++-- src/module/sdk/core/wallet.service.ts | 2 +- .../TransactionDetailsHeader.tsx | 2 +- .../TransactionsList/TransactionsList.tsx | 1 + .../TransactionAmount/TransactionAmount.tsx | 13 ++++++++-- .../TransactionCard/TransactionCard.tsx | 4 ++-- .../TransactionLabel/hooks/useGetTxLabel.ts | 6 +++-- .../WalletsBackupAdvise.tsx | 9 ++++--- .../AssetSelectDisplay/AssetValueDisplay.tsx | 5 +++- 12 files changed, 62 insertions(+), 38 deletions(-) diff --git a/src/module/common/service/CkbSdkService.ts b/src/module/common/service/CkbSdkService.ts index 3c9db32e4..24603dbf1 100644 --- a/src/module/common/service/CkbSdkService.ts +++ b/src/module/common/service/CkbSdkService.ts @@ -71,7 +71,14 @@ export class CKBSDKService { static getFullTransactionFromTransaction(transaction: Transaction): FullTransaction { if ([TransactionType.RECEIVE_TOKEN, TransactionType.SEND_TOKEN].includes(transaction.type) && transaction.scriptType) { - return { ...transaction, token: getTokenTypeFromScript(transaction.scriptType).tokenName }; + const tokenType = getTokenTypeFromScript(transaction.scriptType); + return { + ...transaction, + token: { + type: tokenType, + amount: transaction.tokenAmount || 0, + }, + }; } return transaction; } @@ -89,19 +96,8 @@ export class CKBSDKService { } getTransactions(): FullTransaction[] { - const fullTxs: FullTransaction[] = []; const transactions = this.wallet.getTransactions(); - for (const tx of transactions) { - if ([TransactionType.RECEIVE_TOKEN, TransactionType.SEND_TOKEN].includes(tx.type) && tx.scriptType) { - const tokenIndex = getTokenIndexTypeFromScript(tx.scriptType); - if (tokenIndex !== -1) { - fullTxs.push({ ...tx, token: getTokenTypeFromIndex(tokenIndex).tokenName }); - } - } else { - fullTxs.push(tx); - } - } - return fullTxs; + return transactions.map((tx) => CKBSDKService.getFullTransactionFromTransaction(tx)); } async getTransaction(txHash: string): Promise { diff --git a/src/module/common/service/CkbSdkService.types.ts b/src/module/common/service/CkbSdkService.types.ts index d01419b41..9d7e00c82 100644 --- a/src/module/common/service/CkbSdkService.types.ts +++ b/src/module/common/service/CkbSdkService.types.ts @@ -1,4 +1,5 @@ import { DAOUnlockableAmount, FeeRate, Nft, Transaction } from "ckb-peersyst-sdk"; +import { TokenAmount } from "module/token/types"; export type Chain = "mainnet" | "testnet"; @@ -37,5 +38,5 @@ export interface WithdrawOrUnlockParams { } export interface FullTransaction extends Transaction { - token?: string; + token?: TokenAmount; } diff --git a/src/module/sdk/core/assets/nft.service.ts b/src/module/sdk/core/assets/nft.service.ts index 4381c3e08..ed1c184aa 100644 --- a/src/module/sdk/core/assets/nft.service.ts +++ b/src/module/sdk/core/assets/nft.service.ts @@ -32,7 +32,7 @@ export interface MNft { total: number; } -const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); +export const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); export enum NftTypes { nrc721 = "nrc721", @@ -144,16 +144,20 @@ export class NftService { } async initialize() { - if (!this.nftSdk && !this.initializing) { - this.initializing = true; - this.nftSdk = await NrcSdk.initialize({ - nodeUrl: this.connection.getCKBUrl(), - indexerUrl: this.connection.getIndexerUrl(), - }); - } else if (!this.nftSdk) { - while (!this.nftSdk) { - await sleep(100); + try { + if (!this.nftSdk && !this.initializing) { + this.initializing = true; + this.nftSdk = await NrcSdk.initialize({ + nodeUrl: this.connection.getCKBUrl(), + indexerUrl: this.connection.getIndexerUrl(), + }); + } else if (!this.nftSdk) { + while (!this.nftSdk) { + await sleep(100); + } } + } catch (error) { + this.logger.error(error); } } diff --git a/src/module/sdk/core/transaction.service.ts b/src/module/sdk/core/transaction.service.ts index 6733a6672..cff1878bc 100644 --- a/src/module/sdk/core/transaction.service.ts +++ b/src/module/sdk/core/transaction.service.ts @@ -1,5 +1,5 @@ import { ScriptConfig } from "@ckb-lumos/config-manager"; -import { Cell, commons, hd, helpers, Script, utils, HashType } from "@ckb-lumos/lumos"; +import { Cell, commons, hd, helpers, Script, utils, HashType, Header } from "@ckb-lumos/lumos"; import { sealTransaction, TransactionSkeletonType } from "@ckb-lumos/helpers"; import { TransactionWithStatus, values, core, WitnessArgs } from "@ckb-lumos/base"; import { TransactionCollector as TxCollector } from "@ckb-lumos/ckb-indexer"; @@ -7,7 +7,7 @@ import { Reader, normalizers } from "@ckb-lumos/toolkit"; import { CKBIndexerQueryOptions } from "@ckb-lumos/ckb-indexer/src/type"; import { ConnectionService } from "./connection.service"; import { Logger } from "../utils/logger"; -import { Nft, NftService } from "./assets/nft.service"; +import { Nft, NftService, sleep } from "./assets/nft.service"; const { ScriptValue } = values; @@ -35,6 +35,7 @@ export interface Transaction { blockHash?: string; blockNumber?: number; timestamp?: Date; + tokenAmount?: number; } export enum TransactionStatus { @@ -157,6 +158,7 @@ export class TransactionService { let outputIndex = null; let receiveAmount = 0; + let tokenAmount: undefined | number = undefined; const outputs: DataRow[] = lumosTx.transaction.outputs.map((output, index) => { const outputAddress = this.connection.getAddressFromLock(output.lock); if (allAddresses.includes(outputAddress)) { @@ -210,6 +212,7 @@ export class TransactionService { scriptType = outputType!; if (TransactionService.isScriptTypeScript(scriptType, this.connection.getConfig().SCRIPTS.SUDT!)) { type = !isReceive ? TransactionType.SEND_TOKEN : TransactionType.RECEIVE_TOKEN; + tokenAmount = data || 0; } else if (TransactionService.isScriptTypeScript(scriptType, this.connection.getConfig().SCRIPTS.DAO!)) { if (data === 0) { type = TransactionType.DEPOSIT_DAO; @@ -227,6 +230,7 @@ export class TransactionService { scriptType = inputType!; if (TransactionService.isScriptTypeScript(scriptType, this.connection.getConfig().SCRIPTS.SUDT!)) { type = !isReceive ? TransactionType.SEND_TOKEN : TransactionType.RECEIVE_TOKEN; + tokenAmount = 0; } else if (await this.nftService.isScriptNftScript(scriptType)) { type = !isReceive ? TransactionType.SEND_NFT : TransactionType.RECEIVE_NFT; } else { @@ -242,6 +246,7 @@ export class TransactionService { type: type!, scriptType: scriptType!, amount, + tokenAmount, }; if (lumosTx.tx_status.block_hash) { const header = await this.connection.getBlockHeaderFromHash(lumosTx.tx_status.block_hash); diff --git a/src/module/sdk/core/wallet.service.ts b/src/module/sdk/core/wallet.service.ts index 5d5ca80a2..d46a9db1d 100644 --- a/src/module/sdk/core/wallet.service.ts +++ b/src/module/sdk/core/wallet.service.ts @@ -7,7 +7,7 @@ import { CKBBalance, CKBService } from "./assets/ckb.service"; import { DAOBalance, DAOService, DAOStatistics, DAOUnlockableAmount } from "./dao/dao.service"; import { Cell, Script } from "@ckb-lumos/lumos"; import { QueryOptions } from "@ckb-lumos/base"; -import { Nft, NftService } from "./assets/nft.service"; +import { Nft, NftService, sleep } from "./assets/nft.service"; import { Logger } from "../utils/logger"; export enum AddressScriptType { diff --git a/src/module/transaction/component/core/TransactionDetailsModal/TransactionDetailsHeader.tsx b/src/module/transaction/component/core/TransactionDetailsModal/TransactionDetailsHeader.tsx index 07f7e9903..b26e76333 100644 --- a/src/module/transaction/component/core/TransactionDetailsModal/TransactionDetailsHeader.tsx +++ b/src/module/transaction/component/core/TransactionDetailsModal/TransactionDetailsHeader.tsx @@ -21,7 +21,7 @@ const TransactionDetailsHeader = ({ transaction }: TransactionDetailsHeaderProps - {showAmount && } + {showAmount && } {timestamp && {formattedDate}} diff --git a/src/module/transaction/component/core/TransactionsList/TransactionsList.tsx b/src/module/transaction/component/core/TransactionsList/TransactionsList.tsx index b0b633837..4bf97f3b6 100644 --- a/src/module/transaction/component/core/TransactionsList/TransactionsList.tsx +++ b/src/module/transaction/component/core/TransactionsList/TransactionsList.tsx @@ -6,6 +6,7 @@ import EmptyTransactionsList from "../../feedback/EmptyTransactionsList/EmptyTra const TransactionsList = (): JSX.Element => { const { data = [], isLoading, refetch } = useGetTransactions({ filter: (tx) => isSupportedTransaction(tx.type) }); + return ( { type: FullTransaction["type"]; + token?: FullTransaction["token"]; amount: BalanceProps["balance"]; } -const TransactionAmount = ({ type, amount, ...rest }: TransactionAmountProps): JSX.Element => { +const TransactionAmount = ({ type, amount, token, ...rest }: TransactionAmountProps): JSX.Element => { const action = transactionTypeToBalanceAction(type); const isPrimary = action === "add"; - return ; + return ( + + ); }; export default TransactionAmount; diff --git a/src/module/transaction/component/display/TransactionCard/TransactionCard.tsx b/src/module/transaction/component/display/TransactionCard/TransactionCard.tsx index 45c2f7a2b..8d06f2e87 100644 --- a/src/module/transaction/component/display/TransactionCard/TransactionCard.tsx +++ b/src/module/transaction/component/display/TransactionCard/TransactionCard.tsx @@ -19,7 +19,7 @@ const TransactionCard = ({ transaction }: TransactionCardProps): JSX.Element => const { showModal } = useModal(); const { fiat } = useRecoilValue(settingsState); const { convertBalance } = useCkbConversion(); - const { timestamp, amount, type, token = "token", status } = transaction; + const { timestamp, amount, type, token, status } = transaction; const showAmount = type !== TransactionType.SEND_NFT && type !== TransactionType.RECEIVE_NFT; const formatDate = useFormatDate(); const formattedDate = formatDate(timestamp); @@ -37,7 +37,7 @@ const TransactionCard = ({ transaction }: TransactionCardProps): JSX.Element => variant="body3Regular" type={type} amount={amount} - units={token} + token={token} style={{ maxWidth: "50%" }} /> )} diff --git a/src/module/transaction/component/display/TransactionLabel/hooks/useGetTxLabel.ts b/src/module/transaction/component/display/TransactionLabel/hooks/useGetTxLabel.ts index 5b5bf47dd..0a1369451 100644 --- a/src/module/transaction/component/display/TransactionLabel/hooks/useGetTxLabel.ts +++ b/src/module/transaction/component/display/TransactionLabel/hooks/useGetTxLabel.ts @@ -13,10 +13,12 @@ export const useGetTxLabel = (): ((tx: FullTransaction) => string) => { return translate("CKB_received"); } case TransactionType.SEND_TOKEN: { - return translate("token_sent", { token: token ? token : "token" }); + const tokenName = token?.type ? token.type.tokenName : "token"; + return translate("token_sent", { token: tokenName }); } case TransactionType.RECEIVE_TOKEN: { - return translate("token_received", { token: token ? token : "token" }); + const tokenName = token?.type ? token.type.tokenName : "token"; + return translate("token_received", { token: tokenName }); } case TransactionType.SEND_NFT: { return translate("sent_nft"); diff --git a/src/module/wallet/component/core/WalletsBackupModal/WalletsBackupAdvise/WalletsBackupAdvise.tsx b/src/module/wallet/component/core/WalletsBackupModal/WalletsBackupAdvise/WalletsBackupAdvise.tsx index ad9a4e5f9..d5c93e99b 100644 --- a/src/module/wallet/component/core/WalletsBackupModal/WalletsBackupAdvise/WalletsBackupAdvise.tsx +++ b/src/module/wallet/component/core/WalletsBackupModal/WalletsBackupAdvise/WalletsBackupAdvise.tsx @@ -6,6 +6,7 @@ import { useState } from "react"; import { WalletsBackupAdviseImage } from "module/wallet/component/core/WalletsBackupModal/WalletsBackupAdvise/WalletBackupAdvise.styles"; import { notes } from "images"; import { useTranslate } from "module/common/hook/useTranslate"; +import Container from "module/common/component/display/Container/Container"; export interface WalletsBackupAdvise { onWalletSelected: (index: number) => void; @@ -19,9 +20,11 @@ const WalletsBackupAdvise = ({ onWalletSelected }: WalletsBackupAdvise): JSX.Ele - - {translate("backup_wallet_advise_text")} - + + + {translate("backup_wallet_advise_text")} + + {type === AssetType.NFT && ( @@ -23,7 +26,7 @@ export const AssetValueDisplay = ({ ...rest }: AssetValueDisplayProps): JSX.Elem )} {type === AssetType.FT && ( - + )} {type === AssetType.NATIVE_TOKEN && } From 447a603b95a7880937325c1f65bfafade9871f56 Mon Sep 17 00:00:00 2001 From: JordiParraCrespo Date: Tue, 14 Mar 2023 08:47:58 +0100 Subject: [PATCH 05/14] Improve full tx dto --- src/module/common/service/CkbSdkService.ts | 6 ++--- .../common/service/CkbSdkService.types.ts | 5 +++-- src/module/sdk/core/assets/nft.service.ts | 22 ++++++++----------- src/module/sdk/core/wallet.service.ts | 2 +- .../TransactionDetailsHeader.tsx | 2 +- .../TransactionAmount/TransactionAmount.tsx | 20 ++++++----------- .../TransactionCard/TransactionCard.tsx | 15 ++++--------- .../TransactionLabel/hooks/useGetTxLabel.ts | 6 ++--- 8 files changed, 29 insertions(+), 49 deletions(-) diff --git a/src/module/common/service/CkbSdkService.ts b/src/module/common/service/CkbSdkService.ts index 24603dbf1..b0726a2d2 100644 --- a/src/module/common/service/CkbSdkService.ts +++ b/src/module/common/service/CkbSdkService.ts @@ -74,10 +74,8 @@ export class CKBSDKService { const tokenType = getTokenTypeFromScript(transaction.scriptType); return { ...transaction, - token: { - type: tokenType, - amount: transaction.tokenAmount || 0, - }, + token: tokenType.tokenName, + tokenType, }; } return transaction; diff --git a/src/module/common/service/CkbSdkService.types.ts b/src/module/common/service/CkbSdkService.types.ts index 9d7e00c82..de76de83d 100644 --- a/src/module/common/service/CkbSdkService.types.ts +++ b/src/module/common/service/CkbSdkService.types.ts @@ -1,5 +1,5 @@ import { DAOUnlockableAmount, FeeRate, Nft, Transaction } from "ckb-peersyst-sdk"; -import { TokenAmount } from "module/token/types"; +import { TokenAmount, TokenType } from "module/token/types"; export type Chain = "mainnet" | "testnet"; @@ -38,5 +38,6 @@ export interface WithdrawOrUnlockParams { } export interface FullTransaction extends Transaction { - token?: TokenAmount; + token?: string; //CKB or tokenName + tokenType?: TokenType; } diff --git a/src/module/sdk/core/assets/nft.service.ts b/src/module/sdk/core/assets/nft.service.ts index ed1c184aa..8e9decdbd 100644 --- a/src/module/sdk/core/assets/nft.service.ts +++ b/src/module/sdk/core/assets/nft.service.ts @@ -144,20 +144,16 @@ export class NftService { } async initialize() { - try { - if (!this.nftSdk && !this.initializing) { - this.initializing = true; - this.nftSdk = await NrcSdk.initialize({ - nodeUrl: this.connection.getCKBUrl(), - indexerUrl: this.connection.getIndexerUrl(), - }); - } else if (!this.nftSdk) { - while (!this.nftSdk) { - await sleep(100); - } + if (!this.nftSdk && !this.initializing) { + this.initializing = true; + this.nftSdk = await NrcSdk.initialize({ + nodeUrl: this.connection.getCKBUrl(), + indexerUrl: this.connection.getIndexerUrl(), + }); + } else if (!this.nftSdk) { + while (!this.nftSdk) { + await sleep(100); } - } catch (error) { - this.logger.error(error); } } diff --git a/src/module/sdk/core/wallet.service.ts b/src/module/sdk/core/wallet.service.ts index d46a9db1d..5d5ca80a2 100644 --- a/src/module/sdk/core/wallet.service.ts +++ b/src/module/sdk/core/wallet.service.ts @@ -7,7 +7,7 @@ import { CKBBalance, CKBService } from "./assets/ckb.service"; import { DAOBalance, DAOService, DAOStatistics, DAOUnlockableAmount } from "./dao/dao.service"; import { Cell, Script } from "@ckb-lumos/lumos"; import { QueryOptions } from "@ckb-lumos/base"; -import { Nft, NftService, sleep } from "./assets/nft.service"; +import { Nft, NftService } from "./assets/nft.service"; import { Logger } from "../utils/logger"; export enum AddressScriptType { diff --git a/src/module/transaction/component/core/TransactionDetailsModal/TransactionDetailsHeader.tsx b/src/module/transaction/component/core/TransactionDetailsModal/TransactionDetailsHeader.tsx index b26e76333..61923b727 100644 --- a/src/module/transaction/component/core/TransactionDetailsModal/TransactionDetailsHeader.tsx +++ b/src/module/transaction/component/core/TransactionDetailsModal/TransactionDetailsHeader.tsx @@ -21,7 +21,7 @@ const TransactionDetailsHeader = ({ transaction }: TransactionDetailsHeaderProps - {showAmount && } + {showAmount && } {timestamp && {formattedDate}} diff --git a/src/module/transaction/component/display/TransactionAmount/TransactionAmount.tsx b/src/module/transaction/component/display/TransactionAmount/TransactionAmount.tsx index 006963014..80f8b6c0a 100644 --- a/src/module/transaction/component/display/TransactionAmount/TransactionAmount.tsx +++ b/src/module/transaction/component/display/TransactionAmount/TransactionAmount.tsx @@ -2,25 +2,19 @@ import Balance from "module/wallet/component/display/Balance/Balance"; import { BalanceProps } from "module/wallet/component/display/Balance/Balance.types"; import { FullTransaction } from "module/common/service/CkbSdkService.types"; import transactionTypeToBalanceAction from "./utils/transactionTypeToBalanceAction"; +import { BNToNumber } from "module/common/utils/BalanceOperations/utils/BNtoNumber"; export interface TransactionAmountProps extends Omit { - type: FullTransaction["type"]; - token?: FullTransaction["token"]; - amount: BalanceProps["balance"]; + transaction: FullTransaction; } -const TransactionAmount = ({ type, amount, token, ...rest }: TransactionAmountProps): JSX.Element => { +const TransactionAmount = ({ transaction, ...rest }: TransactionAmountProps): JSX.Element => { + const { type, token, amount, tokenAmount, tokenType } = transaction; const action = transactionTypeToBalanceAction(type); const isPrimary = action === "add"; - return ( - - ); + const finalAmount = tokenType ? BNToNumber(tokenAmount || 0, tokenType.decimals) : amount; + + return ; }; export default TransactionAmount; diff --git a/src/module/transaction/component/display/TransactionCard/TransactionCard.tsx b/src/module/transaction/component/display/TransactionCard/TransactionCard.tsx index 8d06f2e87..b4f68613d 100644 --- a/src/module/transaction/component/display/TransactionCard/TransactionCard.tsx +++ b/src/module/transaction/component/display/TransactionCard/TransactionCard.tsx @@ -19,8 +19,9 @@ const TransactionCard = ({ transaction }: TransactionCardProps): JSX.Element => const { showModal } = useModal(); const { fiat } = useRecoilValue(settingsState); const { convertBalance } = useCkbConversion(); - const { timestamp, amount, type, token, status } = transaction; + const { timestamp, amount, type, status } = transaction; const showAmount = type !== TransactionType.SEND_NFT && type !== TransactionType.RECEIVE_NFT; + const showFiat = type === TransactionType.SEND_NATIVE_TOKEN || type === TransactionType.RECEIVE_NATIVE_TOKEN; const formatDate = useFormatDate(); const formattedDate = formatDate(timestamp); const amountInFiat = convertBalance(amount.toString()); @@ -32,15 +33,7 @@ const TransactionCard = ({ transaction }: TransactionCardProps): JSX.Element => - {showAmount && ( - - )} + {showAmount && } {timestamp ? ( @@ -53,7 +46,7 @@ const TransactionCard = ({ transaction }: TransactionCardProps): JSX.Element => {status !== TransactionStatusEnum.COMMITTED ? ( ) : ( - showAmount && ( + showFiat && ( string) => { return translate("CKB_received"); } case TransactionType.SEND_TOKEN: { - const tokenName = token?.type ? token.type.tokenName : "token"; - return translate("token_sent", { token: tokenName }); + return translate("token_sent", { token: token ? token : "token" }); } case TransactionType.RECEIVE_TOKEN: { - const tokenName = token?.type ? token.type.tokenName : "token"; - return translate("token_received", { token: tokenName }); + return translate("token_received", { token: token ? token : "token" }); } case TransactionType.SEND_NFT: { return translate("sent_nft"); From b5ce7850c85687a72131537c8fd122fd22b5feb4 Mon Sep 17 00:00:00 2001 From: JordiParraCrespo Date: Tue, 14 Mar 2023 08:59:34 +0100 Subject: [PATCH 06/14] Lint and improve token amount --- src/module/common/service/CkbSdkService.types.ts | 2 +- src/module/sdk/core/transaction.service.ts | 4 ++-- .../TransactionDetailsHeader.tsx | 6 ++---- .../display/TransactionAmount/TransactionAmount.tsx | 11 ++++++++++- .../display/TransactionCard/TransactionCard.tsx | 3 +-- .../WalletsBackupAdvise/WalletsBackupAdvise.tsx | 1 - 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/module/common/service/CkbSdkService.types.ts b/src/module/common/service/CkbSdkService.types.ts index de76de83d..a6a4aec02 100644 --- a/src/module/common/service/CkbSdkService.types.ts +++ b/src/module/common/service/CkbSdkService.types.ts @@ -1,5 +1,5 @@ import { DAOUnlockableAmount, FeeRate, Nft, Transaction } from "ckb-peersyst-sdk"; -import { TokenAmount, TokenType } from "module/token/types"; +import { TokenType } from "module/token/types"; export type Chain = "mainnet" | "testnet"; diff --git a/src/module/sdk/core/transaction.service.ts b/src/module/sdk/core/transaction.service.ts index cff1878bc..28c484181 100644 --- a/src/module/sdk/core/transaction.service.ts +++ b/src/module/sdk/core/transaction.service.ts @@ -1,5 +1,5 @@ import { ScriptConfig } from "@ckb-lumos/config-manager"; -import { Cell, commons, hd, helpers, Script, utils, HashType, Header } from "@ckb-lumos/lumos"; +import { Cell, commons, hd, helpers, Script, utils, HashType } from "@ckb-lumos/lumos"; import { sealTransaction, TransactionSkeletonType } from "@ckb-lumos/helpers"; import { TransactionWithStatus, values, core, WitnessArgs } from "@ckb-lumos/base"; import { TransactionCollector as TxCollector } from "@ckb-lumos/ckb-indexer"; @@ -7,7 +7,7 @@ import { Reader, normalizers } from "@ckb-lumos/toolkit"; import { CKBIndexerQueryOptions } from "@ckb-lumos/ckb-indexer/src/type"; import { ConnectionService } from "./connection.service"; import { Logger } from "../utils/logger"; -import { Nft, NftService, sleep } from "./assets/nft.service"; +import { Nft, NftService } from "./assets/nft.service"; const { ScriptValue } = values; diff --git a/src/module/transaction/component/core/TransactionDetailsModal/TransactionDetailsHeader.tsx b/src/module/transaction/component/core/TransactionDetailsModal/TransactionDetailsHeader.tsx index 61923b727..60aa2cf98 100644 --- a/src/module/transaction/component/core/TransactionDetailsModal/TransactionDetailsHeader.tsx +++ b/src/module/transaction/component/core/TransactionDetailsModal/TransactionDetailsHeader.tsx @@ -3,7 +3,6 @@ import { Col, Typography } from "@peersyst/react-native-components"; import TransactionLabel from "module/transaction/component/display/TransactionLabel/TransactionLabel"; import TransactionAmount from "module/transaction/component/display/TransactionAmount/TransactionAmount"; import { FullTransaction } from "module/common/service/CkbSdkService.types"; -import { TransactionType } from "ckb-peersyst-sdk"; import useFormatDate from "module/common/hook/useFormatDate"; export interface TransactionDetailsHeaderProps { @@ -11,8 +10,7 @@ export interface TransactionDetailsHeaderProps { } const TransactionDetailsHeader = ({ transaction }: TransactionDetailsHeaderProps): JSX.Element => { - const { type, amount, token, timestamp } = transaction; - const showAmount = type !== TransactionType.SEND_NFT && type !== TransactionType.RECEIVE_NFT; + const { type, timestamp } = transaction; const formatDate = useFormatDate(); const formattedDate = formatDate(timestamp); @@ -21,7 +19,7 @@ const TransactionDetailsHeader = ({ transaction }: TransactionDetailsHeaderProps - {showAmount && } + {timestamp && {formattedDate}} diff --git a/src/module/transaction/component/display/TransactionAmount/TransactionAmount.tsx b/src/module/transaction/component/display/TransactionAmount/TransactionAmount.tsx index 80f8b6c0a..9b46e4a67 100644 --- a/src/module/transaction/component/display/TransactionAmount/TransactionAmount.tsx +++ b/src/module/transaction/component/display/TransactionAmount/TransactionAmount.tsx @@ -3,6 +3,7 @@ import { BalanceProps } from "module/wallet/component/display/Balance/Balance.ty import { FullTransaction } from "module/common/service/CkbSdkService.types"; import transactionTypeToBalanceAction from "./utils/transactionTypeToBalanceAction"; import { BNToNumber } from "module/common/utils/BalanceOperations/utils/BNtoNumber"; +import { TransactionType } from "ckb-peersyst-sdk"; export interface TransactionAmountProps extends Omit { transaction: FullTransaction; @@ -13,8 +14,16 @@ const TransactionAmount = ({ transaction, ...rest }: TransactionAmountProps): JS const action = transactionTypeToBalanceAction(type); const isPrimary = action === "add"; const finalAmount = tokenType ? BNToNumber(tokenAmount || 0, tokenType.decimals) : amount; + const showAmount = + (type !== TransactionType.SEND_NFT && type !== TransactionType.RECEIVE_NFT) || (tokenType && tokenAmount === undefined); - return ; + return ( + <> + {showAmount && ( + + )} + + ); }; export default TransactionAmount; diff --git a/src/module/transaction/component/display/TransactionCard/TransactionCard.tsx b/src/module/transaction/component/display/TransactionCard/TransactionCard.tsx index b4f68613d..62ebd6143 100644 --- a/src/module/transaction/component/display/TransactionCard/TransactionCard.tsx +++ b/src/module/transaction/component/display/TransactionCard/TransactionCard.tsx @@ -20,7 +20,6 @@ const TransactionCard = ({ transaction }: TransactionCardProps): JSX.Element => const { fiat } = useRecoilValue(settingsState); const { convertBalance } = useCkbConversion(); const { timestamp, amount, type, status } = transaction; - const showAmount = type !== TransactionType.SEND_NFT && type !== TransactionType.RECEIVE_NFT; const showFiat = type === TransactionType.SEND_NATIVE_TOKEN || type === TransactionType.RECEIVE_NATIVE_TOKEN; const formatDate = useFormatDate(); const formattedDate = formatDate(timestamp); @@ -33,7 +32,7 @@ const TransactionCard = ({ transaction }: TransactionCardProps): JSX.Element => - {showAmount && } + {timestamp ? ( diff --git a/src/module/wallet/component/core/WalletsBackupModal/WalletsBackupAdvise/WalletsBackupAdvise.tsx b/src/module/wallet/component/core/WalletsBackupModal/WalletsBackupAdvise/WalletsBackupAdvise.tsx index d5c93e99b..0396f8d39 100644 --- a/src/module/wallet/component/core/WalletsBackupModal/WalletsBackupAdvise/WalletsBackupAdvise.tsx +++ b/src/module/wallet/component/core/WalletsBackupModal/WalletsBackupAdvise/WalletsBackupAdvise.tsx @@ -1,5 +1,4 @@ import { Col, Row, Typography } from "@peersyst/react-native-components"; -import Card from "module/common/component/surface/Card/Card"; import CountdownButton from "module/common/component/input/CountdownButton/CountdownButton"; import WalletSelector from "module/wallet/component/input/WalletSelector/WalletSelector"; import { useState } from "react"; From 07d777236a841885fb1c23d4c163b08cb2f40fa3 Mon Sep 17 00:00:00 2001 From: JordiParraCrespo Date: Tue, 14 Mar 2023 09:01:56 +0100 Subject: [PATCH 07/14] tx service --- src/module/sdk/core/transaction.service.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/module/sdk/core/transaction.service.ts b/src/module/sdk/core/transaction.service.ts index 28c484181..27e9d9331 100644 --- a/src/module/sdk/core/transaction.service.ts +++ b/src/module/sdk/core/transaction.service.ts @@ -230,7 +230,6 @@ export class TransactionService { scriptType = inputType!; if (TransactionService.isScriptTypeScript(scriptType, this.connection.getConfig().SCRIPTS.SUDT!)) { type = !isReceive ? TransactionType.SEND_TOKEN : TransactionType.RECEIVE_TOKEN; - tokenAmount = 0; } else if (await this.nftService.isScriptNftScript(scriptType)) { type = !isReceive ? TransactionType.SEND_NFT : TransactionType.RECEIVE_NFT; } else { From 42dc88d5d729e30cc241d0903cc71cd4a54ae4a7 Mon Sep 17 00:00:00 2001 From: JordiParraCrespo Date: Tue, 14 Mar 2023 09:36:56 +0100 Subject: [PATCH 08/14] fix testing --- test/__mocks__/transaction.ts | 9 +++++++ .../TransactionAmount.spec.tsx | 25 ++++++++++--------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/test/__mocks__/transaction.ts b/test/__mocks__/transaction.ts index 276a54675..cc2eee674 100644 --- a/test/__mocks__/transaction.ts +++ b/test/__mocks__/transaction.ts @@ -1,5 +1,6 @@ import { TransactionStatus, TransactionType } from "ckb-peersyst-sdk"; import { FullTransaction } from "module/common/service/CkbSdkService.types"; +import { token } from "./CKBSdk"; export const transaction: FullTransaction = { status: TransactionStatus.COMMITTED, @@ -13,6 +14,14 @@ export const transaction: FullTransaction = { timestamp: new Date(2022, 0, 29), }; +export const txWithTokenAmount: FullTransaction = { + ...transaction, + tokenAmount: token.amount, + tokenType: token.type, + token: token.type.tokenName, + type: TransactionType.SEND_TOKEN, +}; + export const sentTransaction: FullTransaction = { status: TransactionStatus.COMMITTED, type: TransactionType.SEND_NATIVE_TOKEN, diff --git a/test/unit/src/module/transaction/component/display/TransactionAmount/TransactionAmount.spec.tsx b/test/unit/src/module/transaction/component/display/TransactionAmount/TransactionAmount.spec.tsx index 1b4e88e7f..173a5890c 100644 --- a/test/unit/src/module/transaction/component/display/TransactionAmount/TransactionAmount.spec.tsx +++ b/test/unit/src/module/transaction/component/display/TransactionAmount/TransactionAmount.spec.tsx @@ -3,26 +3,27 @@ import TransactionAmount from "module/transaction/component/display/TransactionA import { TransactionType } from "ckb-peersyst-sdk"; import { config } from "config"; import { ACTION_LABEL } from "module/wallet/component/display/Balance/utils/actionLabels"; +import { transaction, txWithTokenAmount } from "mocks/transaction"; +import { BNToNumber } from "module/common/utils/BalanceOperations/utils/BNtoNumber"; describe("TransactionAmount tests", () => { test("Renders add", () => { const screen = render( - , + , ); expect(screen.getByText(ACTION_LABEL["add"] + "100 " + config.tokenName)).toBeDefined(); - screen.rerender(); - expect(screen.getByText(ACTION_LABEL["add"] + "100 " + config.tokenName)).toBeDefined(); - screen.rerender(); - expect(screen.getByText(ACTION_LABEL["add"] + "100 " + config.tokenName)).toBeDefined(); - screen.rerender(); - expect(screen.getByText(ACTION_LABEL["add"] + "100 " + config.tokenName)).toBeDefined(); }); test("Renders display", () => { - const screen = render(); - expect(screen.getByText("100 " + config.tokenName)).toBeDefined(); - screen.rerender(); - expect(screen.getByText("100 " + config.tokenName)).toBeDefined(); - screen.rerender(); + const screen = render(); expect(screen.getByText("100 " + config.tokenName)).toBeDefined(); }); + test("Renders tokenAmount", () => { + const screen = render(); + screen.debug(); + expect( + screen.getByText( + BNToNumber(txWithTokenAmount.tokenAmount || 0, txWithTokenAmount.tokenType?.decimals) + " " + txWithTokenAmount.token, + ), + ).toBeDefined(); + }); }); From 84964db9ed020eac49a2f9e6c550f541bcdf70ab Mon Sep 17 00:00:00 2001 From: Joan Grau Date: Tue, 14 Mar 2023 11:28:23 +0100 Subject: [PATCH 09/14] add token amount in special case like minting --- src/module/sdk/core/transaction.service.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/module/sdk/core/transaction.service.ts b/src/module/sdk/core/transaction.service.ts index 27e9d9331..927e73b63 100644 --- a/src/module/sdk/core/transaction.service.ts +++ b/src/module/sdk/core/transaction.service.ts @@ -128,11 +128,13 @@ export class TransactionService { let amount = 0; let complexAmount = 0; let inputType = null; + let inputData = null; let isRealSender = false; for (let i = 0; i < lumosTx.transaction.inputs.length; i += 1) { const input = lumosTx.transaction.inputs[i]; const inputTx = await this.connection.getTransactionFromHash(input.previous_output.tx_hash); - const output = inputTx.transaction.outputs[parseInt(input.previous_output.index, 16)]; + const outputIdx = parseInt(input.previous_output.index, 16); + const output = inputTx.transaction.outputs[outputIdx]; const inputAddress = this.connection.getAddressFromLock(output.lock); inputs.push({ quantity: parseInt(output.capacity, 16) / 100000000, @@ -149,6 +151,14 @@ export class TransactionService { codeHash: output.type.code_hash, hashType: output.type.hash_type, }; + const data = inputTx.transaction.outputs_data[outputIdx]; + if (data && data !== "0x") { + if (data.length === 34) { + inputData = Number(utils.readBigUInt128LE(data)); + } else if (data.length === 18) { + inputData = Number(utils.readBigUInt64LE(data)); + } + } } } if (address === inputAddress) { @@ -230,6 +240,9 @@ export class TransactionService { scriptType = inputType!; if (TransactionService.isScriptTypeScript(scriptType, this.connection.getConfig().SCRIPTS.SUDT!)) { type = !isReceive ? TransactionType.SEND_TOKEN : TransactionType.RECEIVE_TOKEN; + if (inputData) { + tokenAmount = inputData; + } } else if (await this.nftService.isScriptNftScript(scriptType)) { type = !isReceive ? TransactionType.SEND_NFT : TransactionType.RECEIVE_NFT; } else { From b8d0d0d8bab95490c7a0fa64e8a93b243a004c81 Mon Sep 17 00:00:00 2001 From: Joan Grau Date: Tue, 14 Mar 2023 11:59:18 +0100 Subject: [PATCH 10/14] add console logs for debugging new no capacity error --- src/module/sdk/core/assets/ckb.service.ts | 5 +++++ src/module/sdk/core/wallet.service.ts | 3 +++ 2 files changed, 8 insertions(+) diff --git a/src/module/sdk/core/assets/ckb.service.ts b/src/module/sdk/core/assets/ckb.service.ts index 652e74fa9..b9bfd8269 100644 --- a/src/module/sdk/core/assets/ckb.service.ts +++ b/src/module/sdk/core/assets/ckb.service.ts @@ -44,6 +44,8 @@ export class CKBService { if (amount < this.transferCellSize) { throw new Error("Minimum transfer (cell) value is 61 CKB"); } + console.log("Inside ckb.service::transferFromCells cells length:", cells.length); + console.log("Inside ckb.service::transferFromCells config obj:", this.connection.getConfigAsObject()); let txSkeleton = TransactionSkeleton({ cellProvider: this.connection.getEmptyCellProvider() }); @@ -61,10 +63,13 @@ export class CKBService { // Inject capacity txSkeleton = this.transactionService.addSecp256CellDep(txSkeleton); + console.log("Inside ckb.service::transferFromCells added deps TxSkeleton:", JSON.stringify(txSkeleton)); txSkeleton = this.transactionService.injectCapacity(txSkeleton, amount, cells); + console.log("Inside ckb.service::transferFromCells injected capacity from cells TxSkeleton:", JSON.stringify(txSkeleton)); // Pay fee txSkeleton = await common.payFeeByFeeRate(txSkeleton, fromAddresses, feeRate, undefined, this.connection.getConfigAsObject()); + console.log("Inside ckb.service::transferFromCells paid fee TxSkeleton:", JSON.stringify(txSkeleton)); // Get signing private keys const signingPrivKeys = this.transactionService.extractPrivateKeys(txSkeleton, fromAddresses, privateKeys); diff --git a/src/module/sdk/core/wallet.service.ts b/src/module/sdk/core/wallet.service.ts index 5d5ca80a2..5a2f595ae 100644 --- a/src/module/sdk/core/wallet.service.ts +++ b/src/module/sdk/core/wallet.service.ts @@ -373,9 +373,12 @@ export class WalletService { } async sendTransaction(amount: bigint, mnemo: string, to: string, feeRate: FeeRate = FeeRate.NORMAL): Promise { + console.log("Inside wallet.service::sendTransaction params:", amount, mnemo, to, feeRate); await this.synchronize(); const addresses = this.getAllAddresses(); + console.log("Inside wallet.service::sendTransaction addresses:", addresses.length, addresses); const privateKeys = this.getAllPrivateKeys(mnemo); + console.log("Inside wallet.service::sendTransaction pKey length:", privateKeys.length); return this.ckbService.transferFromCells(this.getCells(), addresses, to, amount, privateKeys, feeRate); } From 727f6c335664c646c39cae2772ba88abf6258e5e Mon Sep 17 00:00:00 2001 From: JordiParraCrespo Date: Tue, 14 Mar 2023 12:21:14 +0100 Subject: [PATCH 11/14] remove locks --- src/module/sdk/core/assets/ckb.service.ts | 5 ----- src/module/sdk/core/wallet.service.ts | 3 --- 2 files changed, 8 deletions(-) diff --git a/src/module/sdk/core/assets/ckb.service.ts b/src/module/sdk/core/assets/ckb.service.ts index b9bfd8269..652e74fa9 100644 --- a/src/module/sdk/core/assets/ckb.service.ts +++ b/src/module/sdk/core/assets/ckb.service.ts @@ -44,8 +44,6 @@ export class CKBService { if (amount < this.transferCellSize) { throw new Error("Minimum transfer (cell) value is 61 CKB"); } - console.log("Inside ckb.service::transferFromCells cells length:", cells.length); - console.log("Inside ckb.service::transferFromCells config obj:", this.connection.getConfigAsObject()); let txSkeleton = TransactionSkeleton({ cellProvider: this.connection.getEmptyCellProvider() }); @@ -63,13 +61,10 @@ export class CKBService { // Inject capacity txSkeleton = this.transactionService.addSecp256CellDep(txSkeleton); - console.log("Inside ckb.service::transferFromCells added deps TxSkeleton:", JSON.stringify(txSkeleton)); txSkeleton = this.transactionService.injectCapacity(txSkeleton, amount, cells); - console.log("Inside ckb.service::transferFromCells injected capacity from cells TxSkeleton:", JSON.stringify(txSkeleton)); // Pay fee txSkeleton = await common.payFeeByFeeRate(txSkeleton, fromAddresses, feeRate, undefined, this.connection.getConfigAsObject()); - console.log("Inside ckb.service::transferFromCells paid fee TxSkeleton:", JSON.stringify(txSkeleton)); // Get signing private keys const signingPrivKeys = this.transactionService.extractPrivateKeys(txSkeleton, fromAddresses, privateKeys); diff --git a/src/module/sdk/core/wallet.service.ts b/src/module/sdk/core/wallet.service.ts index 5a2f595ae..5d5ca80a2 100644 --- a/src/module/sdk/core/wallet.service.ts +++ b/src/module/sdk/core/wallet.service.ts @@ -373,12 +373,9 @@ export class WalletService { } async sendTransaction(amount: bigint, mnemo: string, to: string, feeRate: FeeRate = FeeRate.NORMAL): Promise { - console.log("Inside wallet.service::sendTransaction params:", amount, mnemo, to, feeRate); await this.synchronize(); const addresses = this.getAllAddresses(); - console.log("Inside wallet.service::sendTransaction addresses:", addresses.length, addresses); const privateKeys = this.getAllPrivateKeys(mnemo); - console.log("Inside wallet.service::sendTransaction pKey length:", privateKeys.length); return this.ckbService.transferFromCells(this.getCells(), addresses, to, amount, privateKeys, feeRate); } From 51cad7e15aced61d00d47790d98da1bd9d94101c Mon Sep 17 00:00:00 2001 From: Joan Grau Date: Tue, 14 Mar 2023 13:03:46 +0100 Subject: [PATCH 12/14] split token cell if amount is enough to not block ckbs --- src/module/sdk/core/transaction.service.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/module/sdk/core/transaction.service.ts b/src/module/sdk/core/transaction.service.ts index 927e73b63..ec7d1e887 100644 --- a/src/module/sdk/core/transaction.service.ts +++ b/src/module/sdk/core/transaction.service.ts @@ -446,9 +446,19 @@ export class TransactionService { } if (changeCapacity > BigInt(0)) { + let splitFlag = false; + changeCell.cell_output.capacity = "0x" + changeCapacity.toString(16); if (changeAmount > 0) { changeCell.data = utils.toBigUInt128LE(changeAmount.toString()); + + const changeCellMin = helpers.minimalCellCapacityCompatible(changeCell).toBigInt(); + const changeCellNoSudtMin = helpers.minimalCellCapacityCompatible(changeCellWithoutSudt).toBigInt(); + if (changeCapacity >= changeCellMin + changeCellNoSudtMin) { + changeCell.cell_output.capacity = "0x" + changeCellMin.toString(16); + changeCellWithoutSudt.cell_output.capacity = "0x" + (changeCapacity - changeCellMin).toString(16); + splitFlag = true; + } } txSkeleton = txSkeleton.update("outputs", (outputs) => outputs.push(changeCell)); @@ -460,6 +470,9 @@ export class TransactionService { }); }); } + if (splitFlag) { + txSkeleton = txSkeleton.update("outputs", (outputs) => outputs.push(changeCellWithoutSudt)); + } } return txSkeleton; From 03c96e13184959f710123d642195f12f92bc946d Mon Sep 17 00:00:00 2001 From: JordiParraCrespo Date: Tue, 14 Mar 2023 13:32:07 +0100 Subject: [PATCH 13/14] fix tokens --- src/module/sdk/core/transaction.service.ts | 12 +++++++++++- .../display/TransactionAmount/TransactionAmount.tsx | 10 +++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/module/sdk/core/transaction.service.ts b/src/module/sdk/core/transaction.service.ts index 927e73b63..eb47147c7 100644 --- a/src/module/sdk/core/transaction.service.ts +++ b/src/module/sdk/core/transaction.service.ts @@ -167,6 +167,7 @@ export class TransactionService { } let outputIndex = null; + let tokensDestinationsIndex: number[] = []; let receiveAmount = 0; let tokenAmount: undefined | number = undefined; const outputs: DataRow[] = lumosTx.transaction.outputs.map((output, index) => { @@ -176,6 +177,11 @@ export class TransactionService { if (output.type) { outputIndex = index; } + } else if (output.type) { + const outputScriptType = { args: output.type.args, codeHash: output.type.code_hash, hashType: output.type.hash_type }; + if (TransactionService.isScriptTypeScript(outputScriptType, this.connection.getConfig().SCRIPTS.SUDT!)) { + tokensDestinationsIndex.push(index); + } } if (inputAddresses.includes(outputAddress)) { complexAmount += parseInt(output.capacity, 16) / 100000000; @@ -222,7 +228,11 @@ export class TransactionService { scriptType = outputType!; if (TransactionService.isScriptTypeScript(scriptType, this.connection.getConfig().SCRIPTS.SUDT!)) { type = !isReceive ? TransactionType.SEND_TOKEN : TransactionType.RECEIVE_TOKEN; - tokenAmount = data || 0; + if (type === TransactionType.RECEIVE_TOKEN) { + tokenAmount = data || 0; + } else { + tokenAmount = tokensDestinationsIndex.reduce((acc, outputIndex) => (acc += outputs[outputIndex].data || 0), 0); + } } else if (TransactionService.isScriptTypeScript(scriptType, this.connection.getConfig().SCRIPTS.DAO!)) { if (data === 0) { type = TransactionType.DEPOSIT_DAO; diff --git a/src/module/transaction/component/display/TransactionAmount/TransactionAmount.tsx b/src/module/transaction/component/display/TransactionAmount/TransactionAmount.tsx index 9b46e4a67..b9b1d01d0 100644 --- a/src/module/transaction/component/display/TransactionAmount/TransactionAmount.tsx +++ b/src/module/transaction/component/display/TransactionAmount/TransactionAmount.tsx @@ -16,11 +16,19 @@ const TransactionAmount = ({ transaction, ...rest }: TransactionAmountProps): JS const finalAmount = tokenType ? BNToNumber(tokenAmount || 0, tokenType.decimals) : amount; const showAmount = (type !== TransactionType.SEND_NFT && type !== TransactionType.RECEIVE_NFT) || (tokenType && tokenAmount === undefined); + const decimals = tokenType ? Math.min(Math.min(finalAmount.toString().split(".")[1]?.length, tokenType.decimals), 6) : undefined; return ( <> {showAmount && ( - + )} ); From 787e9caa6975a27e567b214954de32625795d349 Mon Sep 17 00:00:00 2001 From: JordiParraCrespo Date: Tue, 14 Mar 2023 13:40:12 +0100 Subject: [PATCH 14/14] fix lint --- src/module/sdk/core/transaction.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module/sdk/core/transaction.service.ts b/src/module/sdk/core/transaction.service.ts index f3c03e5e2..2761f075f 100644 --- a/src/module/sdk/core/transaction.service.ts +++ b/src/module/sdk/core/transaction.service.ts @@ -167,7 +167,7 @@ export class TransactionService { } let outputIndex = null; - let tokensDestinationsIndex: number[] = []; + const tokensDestinationsIndex: number[] = []; let receiveAmount = 0; let tokenAmount: undefined | number = undefined; const outputs: DataRow[] = lumosTx.transaction.outputs.map((output, index) => {