From 08a700a65a449bd902e8e65f0f924566280dd91c Mon Sep 17 00:00:00 2001 From: Artem Burakov Date: Thu, 24 Oct 2024 16:46:45 +0300 Subject: [PATCH] adds quai and qi callback functions & minor improvements --- background/main.ts | 51 ---------- background/services/chain/index.ts | 153 ++++++++++++++++------------- 2 files changed, 87 insertions(+), 117 deletions(-) diff --git a/background/main.ts b/background/main.ts index eae3b7f6..6b4ba51a 100644 --- a/background/main.ts +++ b/background/main.ts @@ -39,7 +39,6 @@ import { AddressOnNetwork, NameOnNetwork, QiCoinbaseAddress, - QiWalletBalance, } from "./accounts" import rootReducer from "./redux-slices" import { @@ -168,7 +167,6 @@ import { LocalNodeNetworkStatusEventTypes } from "./services/provider-factory/ev import NotificationsManager from "./services/notifications" import BlockService from "./services/block" import TransactionService from "./services/transactions" -import { QI } from "./constants" // This sanitizer runs on store and action data before serializing for remote // redux devtools. The goal is to end up with an object that is directly @@ -494,54 +492,6 @@ export default class Main extends BaseService { await this.store.dispatch(setNewNetworkConnectError(chainIdWithError)) } - async startQiMiningAddressBalanceChecker(): Promise { - const interval = setInterval(async () => { - const qiMiningAddresses = - await this.indexingService.getQiCoinbaseAddresses() - const allOutpoints = ( - await Promise.all( - qiMiningAddresses.map(async (qiAddress) => { - const outpoints = await this.chainService.getOutpointsForQiAddress( - qiAddress.address - ) - return outpoints.map((outpoint) => ({ - outpoint, - address: qiAddress.address, - account: qiAddress.account, - zone: Zone.Cyprus1, - })) - }) - ) - ).flat() - - if (allOutpoints.length === 0) return - - const qiWallet = await this.keyringService.getQiHDWallet() - qiWallet.importOutpoints(allOutpoints) - const serializedQiHDWallet = qiWallet.serialize() - await this.keyringService.vaultManager.add( - { qiHDWallet: serializedQiHDWallet }, - {} - ) - - const qiWalletBalance: QiWalletBalance = { - paymentCode: qiWallet.getPaymentCode(0), - network: this.chainService.selectedNetwork, - assetAmount: { - asset: QI, - amount: qiWallet.getBalanceForZone(Zone.Cyprus1), - }, - dataSource: "local", - retrievedAt: Date.now(), - } - - this.store.dispatch( - updateUtxoAccountsBalances({ balances: [qiWalletBalance] }) - ) - }, 30000) - this.qiMiningAddressBalanceChecker = interval - } - async startBalanceChecker(): Promise { const interval = setInterval(async () => { if (!walletOpen) return @@ -699,7 +649,6 @@ export default class Main extends BaseService { this.signingService.startService(), this.analyticsService.startService(), this.startBalanceChecker(), - this.startQiMiningAddressBalanceChecker(), ] await Promise.all(independentServices) diff --git a/background/services/chain/index.ts b/background/services/chain/index.ts index 2ba88d3a..a93b788a 100644 --- a/background/services/chain/index.ts +++ b/background/services/chain/index.ts @@ -3,12 +3,14 @@ /* eslint-disable import/no-cycle */ import { Contract, + isQiAddress, JsonRpcProvider, Shard, toBigInt, WebSocketProvider, Zone, } from "quais" +import { Outpoint } from "quais/lib/commonjs/transaction/utxo" import { PELAGUS_NETWORKS } from "../../constants/networks/networks" import ProviderFactory from "../provider-factory/provider-factory" import { NetworkInterface } from "../../constants/networks/networkTypes" @@ -22,7 +24,6 @@ import { QiWalletOnNetwork, } from "../../accounts" import { - AnyAsset, AnyAssetAmount, AssetTransfer, SmartContractFungibleAsset, @@ -37,12 +38,7 @@ import { sameQuaiAddress } from "../../lib/utils" import AssetDataHelper from "./utils/asset-data-helper" import KeyringService from "../keyring" import type { ValidatedAddEthereumChainParameter } from "../provider-bridge/utils" -import { Outpoint } from "quais/lib/commonjs/transaction/utxo" import { MAILBOX_INTERFACE } from "../../contracts/payment-channel-mailbox" -import { - updateAccountBalance, - updateUtxoAccountsBalances, -} from "../../redux-slices/accounts" // The number of blocks to query at a time for historic asset transfers. // Unfortunately there's no "right" answer here that works well across different @@ -273,7 +269,7 @@ export default class ChainService extends BaseService { const qiAccounts = await globalThis.main.indexingService.getQiCoinbaseAddresses() - this.subscribeOnQiBalances(this.selectedNetwork, qiAccounts) + await this.subscribeOnBalances(this.selectedNetwork, qiAccounts) } private trackSubscriptions( @@ -290,7 +286,7 @@ export default class ChainService extends BaseService { private async subscribeOnBalances( network: NetworkInterface, - accounts: AddressOnNetwork[] + accounts: AddressOnNetwork[] | QiCoinbaseAddress[] ): Promise { const { webSocketProvider } = this.providerFactory.getProvidersForNetwork( network.chainID @@ -300,71 +296,96 @@ export default class ChainService extends BaseService { logger.error("WebSocketProvider for balance subscription not found") accounts.forEach(({ address }) => { - webSocketProvider.on({ type: "balance", address }, async (balance) => { - const asset = await this.db.getBaseAssetForNetwork(network.chainID) - const accountBalance: AccountBalance = { - address, - network, - assetAmount: { - asset, - amount: balance ?? toBigInt(0), - }, - dataSource: "local", - retrievedAt: Date.now(), + webSocketProvider.on( + { type: "balance", address }, + async (balance: bigint) => { + if (isQiAddress(address)) { + await this.handleQiMiningAddressBalanceUpdate(network) + } else { + await this.handleQuaiAddressBalanceUpdate(network, address, balance) + } } - this.emitter.emit("accountsWithBalances", { - balances: [accountBalance], - addressOnNetwork: { - address, - network, - }, - }) - await this.db.addBalance(accountBalance) - }) + ) }) } - private async subscribeOnQiBalances( + async handleQuaiAddressBalanceUpdate( network: NetworkInterface, - accounts: QiCoinbaseAddress[] - ) { - const qiWallet = await this.keyringService.getQiHDWallet() - const paymentCode = qiWallet.getPaymentCode() - const { webSocketProvider } = this.providerFactory.getProvidersForNetwork( - network.chainID - ) - if (!webSocketProvider) { - logger.error("WebSocketProvider for balance subscription not found") + address: string, + balance: bigint + ): Promise { + const asset = await this.db.getBaseAssetForNetwork(network.chainID) + const accountBalance: AccountBalance = { + address, + network, + assetAmount: { + asset, + amount: balance ?? toBigInt(0), + }, + dataSource: "local", + retrievedAt: Date.now(), } + this.emitter.emit("accountsWithBalances", { + balances: [accountBalance], + addressOnNetwork: { + address, + network, + }, + }) + await this.db.addBalance(accountBalance) + } - accounts.forEach(({ address }) => { - webSocketProvider.on({ type: "balance", address }, async (balance) => { - const qiWalletBalance: QiWalletBalance = { - paymentCode, - network, - assetAmount: { - asset: QI, - amount: balance, - }, - dataSource: "local", - retrievedAt: Date.now(), - } - - this.emitter.emit("updatedQiLedgerBalance", { - balances: [qiWalletBalance], - addressOnNetwork: { - paymentCode, - network, - }, + async handleQiMiningAddressBalanceUpdate( + network: NetworkInterface + ): Promise { + const qiMiningAddresses = + await globalThis.main.indexingService.getQiCoinbaseAddresses() + const allOutpoints = ( + await Promise.all( + qiMiningAddresses.map(async (qiAddress) => { + const outpoints = await this.getOutpointsForQiAddress( + qiAddress.address + ) + return outpoints.map((outpoint) => ({ + outpoint, + address: qiAddress.address, + account: qiAddress.account, + zone: Zone.Cyprus1, + })) }) - await this.db.addQiLedgerBalance(qiWalletBalance) - await qiWallet.scan(Zone.Cyprus1) - await this.keyringService.vaultManager.add( - { qiHDWallet: qiWallet.serialize() }, - {} - ) - }) + ) + ).flat() + + if (allOutpoints.length === 0) return + + const qiWallet = await this.keyringService.getQiHDWallet() + const paymentCode = qiWallet.getPaymentCode(0) + qiWallet.importOutpoints(allOutpoints) + + const serializedQiHDWallet = qiWallet.serialize() + await this.keyringService.vaultManager.update({ + qiHDWallet: serializedQiHDWallet, + }) + + const qiWalletBalance: QiWalletBalance = { + paymentCode, + network, + assetAmount: { + asset: QI, + amount: qiWallet.getBalanceForZone(Zone.Cyprus1), + }, + dataSource: "local", + retrievedAt: Date.now(), + } + + this.emitter.emit("updatedQiLedgerBalance", { + balances: [qiWalletBalance], + addressOnNetwork: { + paymentCode, + network, + }, }) + await this.db.addQiLedgerBalance(qiWalletBalance) } private isNetworkSubscribed(network: NetworkInterface): boolean { @@ -374,7 +395,7 @@ export default class ChainService extends BaseService { public async onNewQiAccountCreated( qiCoinbaseAddress: QiCoinbaseAddress ): Promise { - this.subscribeOnQiBalances(this.selectedNetwork, [qiCoinbaseAddress]) + await this.subscribeOnBalances(this.selectedNetwork, [qiCoinbaseAddress]) } public async onNewAccountCreated( @@ -512,7 +533,7 @@ export default class ChainService extends BaseService { } async getOutpointsForQiAddress(address: string): Promise { - return await this.jsonRpcProvider.getOutpointsByAddress(address) + return this.jsonRpcProvider.getOutpointsByAddress(address) } async getLatestBaseAccountBalance({