Skip to content

Commit

Permalink
Merge branch 'upgrade-ui' into master-to-webapp-1.1.18
Browse files Browse the repository at this point in the history
  • Loading branch information
S2kael committed Nov 2, 2023
2 parents e68ed6a + e2e81ae commit 257a554
Show file tree
Hide file tree
Showing 34 changed files with 423 additions and 930 deletions.
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
TRANSAK_API_KEY=4b767e2c-2e01-45c9-978e-d32c6f0c8900
COINBASE_PAY_ID=1dbd2a0b94
NFT_MINTING_HOST=http://...
MARKETING_CAMPAIGN_URL=https://static-data.subwallet.app/marketing-campaigns/list.json
BRANCH_NAME=master
1 change: 0 additions & 1 deletion .github/workflows/push-koni-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ jobs:
GH_RELEASE_GITHUB_API_TOKEN: ${{ secrets.GH_PAT }}
TRANSAK_API_KEY: ${{ secrets.TRANSAK_API_KEY }}
COINBASE_PAY_ID: ${{ secrets.COINBASE_PAY_ID }}
MARKETING_CAMPAIGN_URL: https://static-data.subwallet.app/marketing-campaigns/preview.json
GH_RELEASE_FILES: master-build.zip,master-src.zip
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
REF_NAME: ${{ github.ref_name }}
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/push-master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ jobs:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
TRANSAK_API_KEY: ${{ secrets.TRANSAK_API_KEY }}
COINBASE_PAY_ID: ${{ secrets.COINBASE_PAY_ID }}
MARKETING_CAMPAIGN_URL: https://static-data.subwallet.app/marketing-campaigns/list.json
BRANCH_NAME: ${{ github.ref_name }}
run: |
yarn install --immutable | grep -v 'YN0013'
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
"@polkadot/types": "^10.9.1",
"@polkadot/util": "^12.3.2",
"@polkadot/util-crypto": "^12.3.2",
"@subwallet/chain-list": "0.2.19",
"@subwallet/chain-list": "0.2.20-beta.4",
"@subwallet/keyring": "^0.1.1",
"@subwallet/ui-keyring": "^0.1.1",
"babel-core": "^7.0.0-bridge.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/extension-base/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"@reduxjs/toolkit": "^1.9.1",
"@sora-substrate/type-definitions": "^1.17.7",
"@substrate/connect": "^0.7.26",
"@subwallet/chain-list": "0.2.19",
"@subwallet/chain-list": "0.2.20-beta.4",
"@subwallet/extension-base": "^1.1.19-0",
"@subwallet/extension-chains": "^1.1.19-0",
"@subwallet/extension-dapp": "^1.1.19-0",
Expand Down
7 changes: 6 additions & 1 deletion packages/extension-base/src/background/KoniTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { _ChainState, _EvmApi, _NetworkUpsertParams, _SubstrateApi, _ValidateCus
import { CrowdloanContributionsResponse } from '@subwallet/extension-base/services/subscan-service/types';
import { SWTransactionResponse, SWTransactionResult } from '@subwallet/extension-base/services/transaction-service/types';
import { WalletConnectNotSupportRequest, WalletConnectSessionRequest } from '@subwallet/extension-base/services/wallet-connect-service/types';
import { RequestUnlockDotCheckCanMint, RequestUnlockDotSubscribeMintedData, UnlockDotTransactionNft } from '@subwallet/extension-base/types';
import { BuyServiceInfo, BuyTokenInfo, RequestUnlockDotCheckCanMint, RequestUnlockDotSubscribeMintedData, UnlockDotTransactionNft } from '@subwallet/extension-base/types';
import { InjectedAccount, InjectedAccountWithMeta, MetadataDefBase } from '@subwallet/extension-inject/types';
import { KeyringPair$Json, KeyringPair$Meta } from '@subwallet/keyring/types';
import { KeyringOptions } from '@subwallet/ui-keyring/options/types';
Expand Down Expand Up @@ -2670,6 +2670,11 @@ export interface KoniRequestSignatures {
'pri(campaign.banner.subscribe)': [null, CampaignBanner[], CampaignBanner[]];
'pri(campaign.banner.complete)': [RequestCampaignBannerComplete, boolean];
/* Campaign */

/* Buy Service */
'pri(buyService.tokens.subscribe)': [null, Record<string, BuyTokenInfo>, Record<string, BuyTokenInfo>];
'pri(buyService.services.subscribe)': [null, Record<string, BuyServiceInfo>, Record<string, BuyServiceInfo>];
/* Buy Service */
}

export interface ApplicationMetadataType {
Expand Down
2 changes: 0 additions & 2 deletions packages/extension-base/src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,5 @@ export const IGNORE_QR_SIGNER: string[] = [];

export const XCM_MIN_AMOUNT_RATIO = 1.2;

export const MARKETING_CAMPAIGN_URL = process.env.MARKETING_CAMPAIGN_URL || '';

export * from './staking';
export * from './storage';
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import { SWTransaction, SWTransactionResponse, SWTransactionResult, TransactionE
import { WALLET_CONNECT_EIP155_NAMESPACE } from '@subwallet/extension-base/services/wallet-connect-service/constants';
import { isProposalExpired, isSupportWalletConnectChain, isSupportWalletConnectNamespace } from '@subwallet/extension-base/services/wallet-connect-service/helpers';
import { ResultApproveWalletConnectSession, WalletConnectNotSupportRequest, WalletConnectSessionRequest } from '@subwallet/extension-base/services/wallet-connect-service/types';
import { RequestUnlockDotCheckCanMint, RequestUnlockDotSubscribeMintedData } from '@subwallet/extension-base/types';
import { BuyServiceInfo, BuyTokenInfo, RequestUnlockDotCheckCanMint, RequestUnlockDotSubscribeMintedData } from '@subwallet/extension-base/types';
import { isSameAddress, reformatAddress, uniqueStringArray } from '@subwallet/extension-base/utils';
import { convertSubjectInfoToAddresses } from '@subwallet/extension-base/utils/address';
import { createTransactionFromRLP, signatureToHex, Transaction as QrTransaction } from '@subwallet/extension-base/utils/eth';
Expand Down Expand Up @@ -4207,6 +4207,58 @@ export default class KoniExtension {

/* Campaign */

/* Buy service */

private async subscribeBuyTokens (id: string, port: chrome.runtime.Port): Promise<Record<string, BuyTokenInfo>> {
const cb = createSubscription<'pri(buyService.tokens.subscribe)'>(id, port);
let ready = false;

const callback = (rs: Record<string, BuyTokenInfo>) => {
if (ready) {
cb(rs);
}
};

const subscription = this.#koniState.buyService.subscribeBuyTokens(callback);

this.createUnsubscriptionHandle(id, subscription.unsubscribe);

port.onDisconnect.addListener((): void => {
this.cancelSubscription(id);
});

await this.#koniState.eventService.waitBuyTokenReady;
ready = true;

return this.#koniState.buyService.getBuyTokens();
}

private async subscribeBuyServices (id: string, port: chrome.runtime.Port): Promise<Record<string, BuyServiceInfo>> {
const cb = createSubscription<'pri(buyService.services.subscribe)'>(id, port);
let ready = false;

const callback = (rs: Record<string, BuyServiceInfo>) => {
if (ready) {
cb(rs);
}
};

const subscription = this.#koniState.buyService.subscribeBuyServices(callback);

this.createUnsubscriptionHandle(id, subscription.unsubscribe);

port.onDisconnect.addListener((): void => {
this.cancelSubscription(id);
});

await this.#koniState.eventService.waitBuyServiceReady;
ready = true;

return this.#koniState.buyService.getBuyServices();
}

/* Buy service */

// --------------------------------------------------------------
// eslint-disable-next-line @typescript-eslint/require-await
public async handle<TMessageType extends MessageTypes> (id: string, type: TMessageType, request: RequestTypes[TMessageType], port: chrome.runtime.Port): Promise<ResponseType<TMessageType>> {
Expand Down Expand Up @@ -4723,6 +4775,13 @@ export default class KoniExtension {
case 'pri(campaign.banner.complete)':
return this.completeCampaignBanner(request as RequestCampaignBannerComplete);
/* Campaign */

/* Buy service */
case 'pri(buyService.tokens.subscribe)':
return this.subscribeBuyTokens(id, port);
case 'pri(buyService.services.subscribe)':
return this.subscribeBuyServices(id, port);
/* Buy service */
// Default
default:
throw new Error(`Unable to handle message of type ${type}`);
Expand Down
3 changes: 3 additions & 0 deletions packages/extension-base/src/koni/background/handlers/State.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { AccountJson, RequestAuthorizeTab, RequestRpcSend, RequestRpcSubscribe,
import { ALL_ACCOUNT_KEY, ALL_GENESIS_HASH, MANTA_PAY_BALANCE_INTERVAL } from '@subwallet/extension-base/constants';
import { BalanceService } from '@subwallet/extension-base/services/balance-service';
import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
import BuyService from '@subwallet/extension-base/services/buy-service';
import CampaignService from '@subwallet/extension-base/services/campaign-service';
import { ChainService } from '@subwallet/extension-base/services/chain-service';
import { _DEFAULT_MANTA_ZK_CHAIN, _MANTA_ZK_CHAIN_GROUP, _PREDEFINED_SINGLE_MODES } from '@subwallet/extension-base/services/chain-service/constants';
Expand Down Expand Up @@ -132,6 +133,7 @@ export default class KoniState {
readonly walletConnectService: WalletConnectService;
readonly mintCampaignService: MintCampaignService;
readonly campaignService: CampaignService;
readonly buyService: BuyService;

// Handle the general status of the extension
private generalStatus: ServiceStatus = ServiceStatus.INITIALIZING;
Expand All @@ -157,6 +159,7 @@ export default class KoniState {
this.migrationService = new MigrationService(this, this.eventService);
this.campaignService = new CampaignService(this);
this.mintCampaignService = new MintCampaignService(this);
this.buyService = new BuyService(this);

this.transactionService = new TransactionService(this.chainService, this.eventService, this.requestService, this.balanceService, this.historyService, this.notificationService, this.dbService, this.mintCampaignService);

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

export * from './token';
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { BuyService, SupportService } from '@subwallet/extension-base/types';

const DEFAULT_BUY_SERVICE: BuyService = { symbol: '', network: '' };

export const DEFAULT_SERVICE_INFO: Record<SupportService, BuyService> = {
transak: { ...DEFAULT_BUY_SERVICE },
banxa: { ...DEFAULT_BUY_SERVICE },
coinbase: { ...DEFAULT_BUY_SERVICE },
onramper: { ...DEFAULT_BUY_SERVICE },
moonpay: { ...DEFAULT_BUY_SERVICE }
};
114 changes: 114 additions & 0 deletions packages/extension-base/src/services/buy-service/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
// SPDX-License-Identifier: Apache-2.0

import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
import { ListBuyServicesResponse, ListBuyTokenResponse } from '@subwallet/extension-base/services/buy-service/types';
import { BuyServiceInfo, BuyTokenInfo, SupportService } from '@subwallet/extension-base/types';
import { fetchStaticData } from '@subwallet/extension-base/utils/fetchStaticData';
import { BehaviorSubject } from 'rxjs';

import { DEFAULT_SERVICE_INFO } from './constants';

export default class BuyService {
readonly #state: KoniState;

private buyTokensSubject = new BehaviorSubject<Record<string, BuyTokenInfo>>({});
private buyServicesSubject = new BehaviorSubject<Record<string, BuyServiceInfo>>({});

constructor (state: KoniState) {
this.#state = state;

this.buyTokensSubject.next({});
this.buyServicesSubject.next({});

this.fetchTokens()
.catch((e) => {
console.error('Error on fetch buy tokens', e);
this.#state.eventService.emit('buy.tokens.ready', true);
});

this.fetchServices()
.catch((e) => {
console.error('Error on fetch buy services', e);
this.#state.eventService.emit('buy.services.ready', true);
});
}

private async fetchTokens () {
const data = await fetchStaticData<ListBuyTokenResponse>('buy-token-configs');

const result: Record<string, BuyTokenInfo> = {};

for (const datum of data) {
const temp: BuyTokenInfo = {
serviceInfo: {
...DEFAULT_SERVICE_INFO
},
support: datum.support,
services: [],
slug: datum.slug,
symbol: datum.symbol,
network: datum.network
};

for (const [_service, info] of Object.entries(datum.serviceInfo)) {
const service = _service as SupportService;

if (info.isSuspended) {
continue;
}

temp.serviceInfo[service] = {
network: info.network,
symbol: info.symbol
};

temp.services.push(service);
}

if (temp.services.length) {
result[temp.slug] = temp;
}
}

this.buyTokensSubject.next(result);

this.#state.eventService.emit('buy.tokens.ready', true);
}

private async fetchServices () {
const data = await fetchStaticData<ListBuyServicesResponse>('buy-service-infos');

const result: Record<string, BuyServiceInfo> = {};

for (const datum of data) {
const { id, slug, ...info } = datum;

result[slug] = { ...info };
}

this.buyServicesSubject.next(result);

this.#state.eventService.emit('buy.services.ready', true);
}

public subscribeBuyTokens (callback: (data: Record<string, BuyTokenInfo>) => void) {
return this.buyTokensSubject.subscribe({
next: callback
});
}

public getBuyTokens () {
return this.buyTokensSubject.getValue();
}

public subscribeBuyServices (callback: (data: Record<string, BuyServiceInfo>) => void) {
return this.buyServicesSubject.subscribe({
next: callback
});
}

public getBuyServices () {
return this.buyServicesSubject.getValue();
}
}
25 changes: 25 additions & 0 deletions packages/extension-base/src/services/buy-service/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2019-2022 @subwallet/extension-koni authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { BuyService, BuyTokenInfo, SupportService } from '@subwallet/extension-base/types';

interface _BuyTokenInfo {
serviceInfo: Record<string, BuyService & { isSuspended: boolean }>;
network: string;
slug: string;
symbol: string;
support: BuyTokenInfo['support'];
}

interface _BuyServiceInfo {
id: number;
name: string;
contactUrl: string;
termUrl: string;
policyUrl: string;
url: string;
slug: SupportService;
}

export type ListBuyTokenResponse = _BuyTokenInfo[];
export type ListBuyServicesResponse = _BuyServiceInfo[];
10 changes: 2 additions & 8 deletions packages/extension-base/src/services/campaign-service/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
// SPDX-License-Identifier: Apache-2.0

import { CampaignData, CampaignDataType } from '@subwallet/extension-base/background/KoniTypes';
import { MARKETING_CAMPAIGN_URL } from '@subwallet/extension-base/constants';
import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
import { ListCampaignResponse } from '@subwallet/extension-base/services/campaign-service/types';
import { TARGET_ENV } from '@subwallet/extension-base/utils';
import axios from 'axios';
import { fetchStaticData } from '@subwallet/extension-base/utils/fetchStaticData';

import { runCampaign } from './helpers';

Expand All @@ -32,12 +31,7 @@ export default class CampaignService {
}

private async fetchCampaign () {
const response = await axios.request({
method: 'GET',
url: MARKETING_CAMPAIGN_URL
});

const respData = response.data as ListCampaignResponse;
const respData = await fetchStaticData<ListCampaignResponse>('marketing-campaigns');

const campaigns: CampaignData[] = [];

Expand Down
4 changes: 4 additions & 0 deletions packages/extension-base/src/services/event-service/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export class EventService extends EventEmitter<EventRegistry> {
public readonly waitAssetReady: Promise<boolean>;
public readonly waitMigrateReady: Promise<boolean>;
public readonly waitCampaignReady: Promise<boolean>;
public readonly waitBuyTokenReady: Promise<boolean>;
public readonly waitBuyServiceReady: Promise<boolean>;

constructor (options: { lazyTime: number } = { lazyTime: 300 }) {
super();
Expand All @@ -32,6 +34,8 @@ export class EventService extends EventEmitter<EventRegistry> {
this.waitAssetReady = this.generateWaitPromise('asset.ready');
this.waitMigrateReady = this.generateWaitPromise('migration.done');
this.waitCampaignReady = this.generateWaitPromise('campaign.ready');
this.waitBuyTokenReady = this.generateWaitPromise('buy.tokens.ready');
this.waitBuyServiceReady = this.generateWaitPromise('buy.services.ready');
}

private generateWaitPromise<T extends EventType> (eventType: T): Promise<boolean> {
Expand Down
4 changes: 4 additions & 0 deletions packages/extension-base/src/services/event-service/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ export interface EventRegistry {

'migration.done': [boolean];
'campaign.ready': [boolean];

// Buy token
'buy.tokens.ready': [boolean];
'buy.services.ready': [boolean];
}

export type EventType = keyof EventRegistry;
Expand Down
Loading

0 comments on commit 257a554

Please sign in to comment.