Skip to content

[Issue-3845] Fix spam notification #3900

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: subwallet-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ALL_ACCOUNT_KEY } from '@subwallet/extension-base/constants';
import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
import { _EvmApi, _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
import { DEFAULT_YIELD_FIRST_STEP } from '@subwallet/extension-base/services/earning-service/constants';
import { createClaimNotification, createWithdrawNotifications } from '@subwallet/extension-base/services/inapp-notification-service/utils';
import { createWithdrawNotifications } from '@subwallet/extension-base/services/inapp-notification-service/utils';
import { BasePoolInfo, BaseYieldPoolMetadata, EarningRewardHistoryItem, EarningRewardItem, GenStepFunction, HandleYieldStepData, OptimalYieldPath, OptimalYieldPathParams, RequestEarlyValidateYield, ResponseEarlyValidateYield, StakeCancelWithdrawalParams, SubmitYieldJoinData, TransactionData, UnstakingInfo, YieldPoolInfo, YieldPoolMethodInfo, YieldPoolTarget, YieldPoolType, YieldPositionInfo, YieldStepBaseInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
import { formatNumber, reformatAddress } from '@subwallet/extension-base/utils';

Expand Down Expand Up @@ -131,11 +131,11 @@ export default abstract class BasePoolHandler {
await this.state.inappNotificationService.validateAndWriteNotificationsToDB(notifications, address);
}

public async createClaimNotification (claimItemInfo: EarningRewardItem, tokenInfo: _ChainAsset) {
const notification = createClaimNotification(claimItemInfo, tokenInfo);

await this.state.inappNotificationService.validateAndWriteNotificationsToDB([notification], claimItemInfo.address);
}
// public async createClaimNotification (claimItemInfo: EarningRewardItem, tokenInfo: _ChainAsset) {
// const notification = createClaimNotification(claimItemInfo, tokenInfo);
//
// await this.state.inappNotificationService.validateAndWriteNotificationsToDB([notification], claimItemInfo.address);
// }

/** Can mint when haven't enough native token (use input token for fee) */
public get isPoolSupportAlternativeFee (): boolean {
Expand All @@ -159,7 +159,7 @@ export default abstract class BasePoolHandler {
/** Subscribe pool position */
public abstract subscribePoolPosition (useAddresses: string[], callback: (rs: YieldPositionInfo) => void): Promise<VoidFunction>;
/** Get pool reward */
public abstract getPoolReward (useAddresses: string[], callback: (rs: EarningRewardItem) => void): Promise<VoidFunction>;
public abstract getPoolReward (useAddresses: string[], callback: (rs: EarningRewardItem, tokenInfo: _ChainAsset) => void): Promise<VoidFunction>;
/** Get pool reward history */
public abstract getPoolRewardHistory (useAddresses: string[], callback: (rs: EarningRewardHistoryItem) => void): Promise<VoidFunction>;
/** Get pool target */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2019-2022 @subwallet/extension-base
// SPDX-License-Identifier: Apache-2.0

import { _ChainInfo } from '@subwallet/chain-list/types';
import { _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
import { APIItemState, ExtrinsicType, NominationInfo, UnstakingInfo } from '@subwallet/extension-base/background/KoniTypes';
import { getBondedValidators, getEarningStatusByNominations, isUnstakeAll, KrestDelegateState } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
Expand Down Expand Up @@ -320,7 +320,7 @@ export default class AmplitudeNativeStakingPoolHandler extends BaseParaNativeSta

/* Get pool reward */

override async getPoolReward (useAddresses: string[], callBack: (rs: EarningRewardItem) => void): Promise<VoidFunction> {
override async getPoolReward (useAddresses: string[], callBack: (rs: EarningRewardItem, tokenInfo: _ChainAsset) => void): Promise<VoidFunction> {
let cancel = false;
const substrateApi = this.substrateApi;

Expand All @@ -346,8 +346,9 @@ export default class AmplitudeNativeStakingPoolHandler extends BaseParaNativeSta
// if (_unclaimedReward.toString() !== '0') {
// await this.createClaimNotification(earningRewardItem, this.nativeToken);
// }

callBack(earningRewardItem);
if (_unclaimedReward.toString() !== '0') {
callBack(earningRewardItem, this.nativeToken);
}
}));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2019-2022 @subwallet/extension-base
// SPDX-License-Identifier: Apache-2.0

import { _ChainAsset } from '@subwallet/chain-list/types';
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
Expand Down Expand Up @@ -46,7 +47,7 @@ export default abstract class BaseNativeStakingPoolHandler extends BasePoolHandl

/* Get pool reward */

async getPoolReward (useAddresses: string[], callBack: (rs: EarningRewardItem) => void): Promise<VoidFunction> {
async getPoolReward (useAddresses: string[], callBack: (rs: EarningRewardItem, tokenInfo: _ChainAsset) => void): Promise<VoidFunction> {
return new Promise((resolve) => resolve(noop));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2019-2022 @subwallet/extension-base
// SPDX-License-Identifier: Apache-2.0

import { _ChainInfo } from '@subwallet/chain-list/types';
import { _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
import { APIItemState, ExtrinsicType, NominationInfo } from '@subwallet/extension-base/background/KoniTypes';
import { getCommission } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
Expand Down Expand Up @@ -358,7 +358,7 @@ export default class MythosNativeStakingPoolHandler extends BaseParaStakingPoolH
/* Leave pool action */

/* Get pool reward */
override async getPoolReward (useAddresses: string[], callback: (rs: EarningRewardItem) => void): Promise<VoidFunction> {
override async getPoolReward (useAddresses: string[], callback: (rs: EarningRewardItem, tokenInfo: _ChainAsset) => void): Promise<VoidFunction> {
let cancel = false;
const substrateApi = this.substrateApi;

Expand All @@ -377,10 +377,9 @@ export default class MythosNativeStakingPoolHandler extends BaseParaStakingPoolH
};

if (_unclaimedReward.toString() !== '0') {
await this.createClaimNotification(earningRewardItem, this.nativeToken);
// await this.createClaimNotification(earningRewardItem, this.nativeToken);
callback(earningRewardItem, this.nativeToken);
}

callback(earningRewardItem);
}
}));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2019-2022 @subwallet/extension-base
// SPDX-License-Identifier: Apache-2.0

import { _ChainAsset } from '@subwallet/chain-list/types';
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
import { APIItemState, ChainType, ExtrinsicType, NominationInfo, StakingType, UnstakingInfo } from '@subwallet/extension-base/background/KoniTypes';
import { PalletNominationPoolsPoolMember } from '@subwallet/extension-base/core/substrate/types';
Expand Down Expand Up @@ -362,7 +363,7 @@ export default class NominationPoolHandler extends BasePoolHandler {

/* Get pool reward */

async getPoolReward (useAddresses: string[], callBack: (rs: EarningRewardItem) => void): Promise<VoidFunction> {
async getPoolReward (useAddresses: string[], callBack: (rs: EarningRewardItem, tokenInfo: _ChainAsset) => void): Promise<VoidFunction> {
let cancel = false;
const substrateApi = this.substrateApi;

Expand All @@ -382,11 +383,13 @@ export default class NominationPoolHandler extends BasePoolHandler {
state: APIItemState.READY
};

// if (_unclaimedReward.toString() !== '0') {
// await this.createClaimNotification(earningRewardItem, this.nativeToken);
// }

if (_unclaimedReward.toString() !== '0') {
await this.createClaimNotification(earningRewardItem, this.nativeToken);
callBack(earningRewardItem, this.nativeToken);
}

callBack(earningRewardItem);
}
}
}
Expand Down
17 changes: 13 additions & 4 deletions packages/extension-base/src/services/earning-service/service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2019-2022 @subwallet/extension-base
// SPDX-License-Identifier: Apache-2.0

import { _ChainAsset } from '@subwallet/chain-list/types';
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
import { CRON_REFRESH_CHAIN_STAKING_METADATA, CRON_REFRESH_EARNING_REWARD_HISTORY_INTERVAL, CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL } from '@subwallet/extension-base/constants';
Expand All @@ -11,6 +12,7 @@ import { _STAKING_CHAIN_GROUP } from '@subwallet/extension-base/services/earning
import BaseLiquidStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/liquid-staking/base';
import MythosNativeStakingPoolHandler from '@subwallet/extension-base/services/earning-service/handlers/native-staking/mythos';
import { EventService } from '@subwallet/extension-base/services/event-service';
import { createClaimNotification } from '@subwallet/extension-base/services/inapp-notification-service/utils';
import DatabaseService from '@subwallet/extension-base/services/storage-service/DatabaseService';
import { SWTransaction } from '@subwallet/extension-base/services/transaction-service/types';
import { BasicTxErrorType, EarningRewardHistoryItem, EarningRewardItem, EarningRewardJson, HandleYieldStepData, HandleYieldStepParams, OptimalYieldPath, OptimalYieldPathParams, RequestEarlyValidateYield, RequestStakeCancelWithdrawal, RequestStakeClaimReward, RequestYieldLeave, RequestYieldWithdrawal, ResponseEarlyValidateYield, TransactionData, ValidateYieldProcessParams, YieldPoolInfo, YieldPoolTarget, YieldPoolType, YieldPositionInfo } from '@subwallet/extension-base/types';
Expand Down Expand Up @@ -164,7 +166,6 @@ export default class EarningService implements StoppableServiceInterface, Persis
});

this.status = ServiceStatus.INITIALIZED;

await this.start();

this.handleActions();
Expand Down Expand Up @@ -663,7 +664,7 @@ export default class EarningService implements StoppableServiceInterface, Persis
});
}

public async getPoolReward (addresses: string[], callback: (result: EarningRewardItem) => void): Promise<VoidFunction> {
public async getPoolReward (addresses: string[], callback: (result: EarningRewardItem, tokenInfo: _ChainAsset) => void): Promise<VoidFunction> {
let cancel = false;

await this.eventService.waitChainReady;
Expand Down Expand Up @@ -720,13 +721,21 @@ export default class EarningService implements StoppableServiceInterface, Persis
return;
}

this.getPoolReward(addresses, (result: EarningRewardItem) => {
this.getPoolReward(addresses, (result: EarningRewardItem, tokenInfo: _ChainAsset) => {
this.updateEarningReward(result);

const notification = createClaimNotification(result, tokenInfo);

this.state.inappNotificationService.validateAndWriteNotificationsToDB([notification], result.address).catch(console.error);
}).catch(console.error);

this.earningsRewardInterval = setInterval(() => {
this.getPoolReward(addresses, (result: EarningRewardItem) => {
this.getPoolReward(addresses, (result: EarningRewardItem, tokenInfo: _ChainAsset) => {
this.updateEarningReward(result);

const notification = createClaimNotification(result, tokenInfo);

this.state.inappNotificationService.validateAndWriteNotificationsToDB([notification], result.address).catch(console.error);
}).catch(console.error);
}, CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { isSubstrateAddress } from '@subwallet/keyring';
export class InappNotificationService implements CronServiceInterface {
status: ServiceStatus;
private refeshAvailBridgeClaimTimeOut: NodeJS.Timeout | undefined;
private isLockWrite: boolean;

constructor (
private readonly dbService: DatabaseService,
Expand All @@ -31,6 +32,7 @@ export class InappNotificationService implements CronServiceInterface {
private readonly chainService: ChainService
) {
this.status = ServiceStatus.NOT_INITIALIZED;
this.isLockWrite = false;
}

async init (): Promise<void> {
Expand Down Expand Up @@ -181,26 +183,31 @@ export class InappNotificationService implements CronServiceInterface {
}

async validateAndWriteNotificationsToDB (notifications: _BaseNotificationInfo[], address: string) {
const proxyId = this.keyringService.context.belongUnifiedAccount(address) || address;
const accountName = this.keyringService.context.getCurrentAccountProxyName(proxyId);
const passNotifications: _NotificationInfo[] = [];
const [comparedNotifications, remindTimeConfig] = await Promise.all([
this.fetchNotificationsByParams({ notificationTab: NotificationTab.ALL, proxyId }),
await fetchLastestRemindNotificationTime()
]);

for (const candidateNotification of notifications) {
candidateNotification.title = candidateNotification.title.replace('{{accountName}}', accountName);

if (this.passValidateNotification(candidateNotification, comparedNotifications, remindTimeConfig)) {
passNotifications.push({
...candidateNotification,
proxyId
});
if (!this.getLockWriteStatus()) {
this.setLockWriteStatus(true);
const proxyId = this.keyringService.context.belongUnifiedAccount(address) || address;
const accountName = this.keyringService.context.getCurrentAccountProxyName(proxyId);
const passNotifications: _NotificationInfo[] = [];
const [comparedNotifications, remindTimeConfig] = await Promise.all([
this.fetchNotificationsByParams({ notificationTab: NotificationTab.ALL, proxyId }),
await fetchLastestRemindNotificationTime()
]);

for (const candidateNotification of notifications) {
candidateNotification.title = candidateNotification.title.replace('{{accountName}}', accountName);

if (this.passValidateNotification(candidateNotification, comparedNotifications, remindTimeConfig)) {
passNotifications.push({
...candidateNotification,
proxyId
});
}
}
}

await this.dbService.upsertNotifications(passNotifications);
await this.dbService.upsertNotifications(passNotifications);

this.setLockWriteStatus(false);
}
}

cronCreateBridgeClaimNotification () {
Expand Down Expand Up @@ -519,4 +526,12 @@ export class InappNotificationService implements CronServiceInterface {
migrateNotificationProxyId (proxyIds: string[], newProxyId: string, newName: string) {
this.dbService.updateNotificationProxyId(proxyIds, newProxyId, newName);
}

getLockWriteStatus () {
return this.isLockWrite;
}

setLockWriteStatus (status: boolean) {
this.isLockWrite = status;
}
}
Loading