Skip to content

Commit 7ce1b90

Browse files
authored
Merge pull request #4323 from Koniverse/koni/dev/issue-4300
[Issue-4300] Extension - Cannot signing transaction when chain connection not be initialized
2 parents 7cabfda + 3632499 commit 7ce1b90

File tree

2 files changed

+86
-44
lines changed

2 files changed

+86
-44
lines changed

packages/extension-base/src/koni/background/handlers/Extension.ts

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { _AssetRef, _AssetType, _ChainAsset, _ChainInfo, _MultiChainAsset } from
77
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
88
import { withErrorLog } from '@subwallet/extension-base/background/handlers/helpers';
99
import { createSubscription } from '@subwallet/extension-base/background/handlers/subscriptions';
10-
import { AccountExternalError, AddressBookInfo, AmountData, AmountDataWithId, AssetSetting, AssetSettingUpdateReq, BondingOptionParams, BrowserConfirmationType, CampaignBanner, CampaignData, CampaignDataType, ChainType, CronReloadRequest, CrowdloanJson, ExternalRequestPromiseStatus, ExtrinsicType, HistoryTokenPriceJSON, KeyringState, MantaPayEnableMessage, MantaPayEnableParams, MantaPayEnableResponse, MantaPaySyncState, MetadataItem, NftCollection, NftJson, NftTransactionRequest, NftTransactionResponse, PriceJson, RequestAccountCreateExternalV2, RequestAccountCreateHardwareMultiple, RequestAccountCreateHardwareV2, RequestAccountCreateWithSecretKey, RequestAccountExportPrivateKey, RequestAddInjectedAccounts, RequestApproveConnectWalletSession, RequestApproveWalletConnectNotSupport, RequestAuthorization, RequestAuthorizationBlock, RequestAuthorizationPerAccount, RequestAuthorizationPerSite, RequestAuthorizeApproveV2, RequestBondingSubmit, RequestCameraSettings, RequestCampaignBannerComplete, RequestChangeEnableChainPatrol, RequestChangeLanguage, RequestChangeMasterPassword, RequestChangePriceCurrency, RequestChangeShowBalance, RequestChangeShowZeroBalance, RequestChangeTimeAutoLock, RequestConfirmationComplete, RequestConfirmationCompleteCardano, RequestConfirmationCompleteTon, RequestConnectWalletConnect, RequestCrowdloanContributions, RequestDeleteContactAccount, RequestDisconnectWalletConnectSession, RequestEditContactAccount, RequestFindRawMetadata, RequestForgetSite, RequestFreeBalance, RequestGetHistoryTokenPriceData, RequestGetTransaction, RequestKeyringExportMnemonic, RequestMigratePassword, RequestMigrateSoloAccount, RequestMigrateUnifiedAndFetchEligibleSoloAccounts, RequestParseEvmContractInput, RequestParseTransactionSubstrate, RequestPassPhishingPage, RequestPingSession, RequestQrParseRLP, RequestQrSignEvm, RequestQrSignSubstrate, RequestRejectConnectWalletSession, RequestRejectExternalRequest, RequestRejectWalletConnectNotSupport, RequestRemoveInjectedAccounts, RequestResetWallet, RequestResolveExternalRequest, RequestSaveAppConfig, RequestSaveBrowserConfig, RequestSaveMigrationAcknowledgedStatus, RequestSaveOSConfig, RequestSaveRecentAccount, RequestSaveUnifiedAccountMigrationInProgress, RequestSettingsType, RequestSigningApprovePasswordV2, RequestStakePoolingBonding, RequestStakePoolingUnbonding, RequestSubscribeHistory, RequestSubstrateNftSubmitTransaction, RequestTuringCancelStakeCompound, RequestTuringStakeCompound, RequestUnbondingSubmit, RequestUnlockKeyring, RequestUnlockType, ResolveAddressToDomainRequest, ResolveDomainRequest, ResponseAccountCreateWithSecretKey, ResponseAccountExportPrivateKey, ResponseChangeMasterPassword, ResponseFindRawMetadata, ResponseKeyringExportMnemonic, ResponseMigratePassword, ResponseMigrateSoloAccount, ResponseMigrateUnifiedAndFetchEligibleSoloAccounts, ResponseNftImport, ResponseParseEvmContractInput, ResponseParseTransactionSubstrate, ResponseQrParseRLP, ResponseQrSignEvm, ResponseQrSignSubstrate, ResponseRejectExternalRequest, ResponseResetWallet, ResponseResolveExternalRequest, ResponseSubscribeCurrentTokenPrice, ResponseSubscribeHistory, ResponseUnlockKeyring, ShowCampaignPopupRequest, StakingJson, StakingRewardJson, StakingType, ThemeNames, TokenPriorityDetails, TransactionHistoryItem, TransactionResponse, UiSettings, ValidateNetworkRequest, ValidateNetworkResponse, ValidatorInfo } from '@subwallet/extension-base/background/KoniTypes';
10+
import { AccountExternalError, AddressBookInfo, AmountData, AmountDataWithId, AssetSetting, AssetSettingUpdateReq, BondingOptionParams, BrowserConfirmationType, CampaignBanner, CampaignData, CampaignDataType, ChainType, CronReloadRequest, CrowdloanJson, ExternalRequestPromiseStatus, ExtrinsicType, HistoryTokenPriceJSON, KeyringState, MantaPayEnableMessage, MantaPayEnableParams, MantaPayEnableResponse, MantaPaySyncState, NftCollection, NftJson, NftTransactionRequest, NftTransactionResponse, PriceJson, RequestAccountCreateExternalV2, RequestAccountCreateHardwareMultiple, RequestAccountCreateHardwareV2, RequestAccountCreateWithSecretKey, RequestAccountExportPrivateKey, RequestAddInjectedAccounts, RequestApproveConnectWalletSession, RequestApproveWalletConnectNotSupport, RequestAuthorization, RequestAuthorizationBlock, RequestAuthorizationPerAccount, RequestAuthorizationPerSite, RequestAuthorizeApproveV2, RequestBondingSubmit, RequestCameraSettings, RequestCampaignBannerComplete, RequestChangeEnableChainPatrol, RequestChangeLanguage, RequestChangeMasterPassword, RequestChangePriceCurrency, RequestChangeShowBalance, RequestChangeShowZeroBalance, RequestChangeTimeAutoLock, RequestConfirmationComplete, RequestConfirmationCompleteCardano, RequestConfirmationCompleteTon, RequestConnectWalletConnect, RequestCrowdloanContributions, RequestDeleteContactAccount, RequestDisconnectWalletConnectSession, RequestEditContactAccount, RequestFindRawMetadata, RequestForgetSite, RequestFreeBalance, RequestGetHistoryTokenPriceData, RequestGetTransaction, RequestKeyringExportMnemonic, RequestMigratePassword, RequestMigrateSoloAccount, RequestMigrateUnifiedAndFetchEligibleSoloAccounts, RequestParseEvmContractInput, RequestParseTransactionSubstrate, RequestPassPhishingPage, RequestPingSession, RequestQrParseRLP, RequestQrSignEvm, RequestQrSignSubstrate, RequestRejectConnectWalletSession, RequestRejectExternalRequest, RequestRejectWalletConnectNotSupport, RequestRemoveInjectedAccounts, RequestResetWallet, RequestResolveExternalRequest, RequestSaveAppConfig, RequestSaveBrowserConfig, RequestSaveMigrationAcknowledgedStatus, RequestSaveOSConfig, RequestSaveRecentAccount, RequestSaveUnifiedAccountMigrationInProgress, RequestSettingsType, RequestSigningApprovePasswordV2, RequestStakePoolingBonding, RequestStakePoolingUnbonding, RequestSubscribeHistory, RequestSubstrateNftSubmitTransaction, RequestTuringCancelStakeCompound, RequestTuringStakeCompound, RequestUnbondingSubmit, RequestUnlockKeyring, RequestUnlockType, ResolveAddressToDomainRequest, ResolveDomainRequest, ResponseAccountCreateWithSecretKey, ResponseAccountExportPrivateKey, ResponseChangeMasterPassword, ResponseFindRawMetadata, ResponseKeyringExportMnemonic, ResponseMigratePassword, ResponseMigrateSoloAccount, ResponseMigrateUnifiedAndFetchEligibleSoloAccounts, ResponseNftImport, ResponseParseEvmContractInput, ResponseParseTransactionSubstrate, ResponseQrParseRLP, ResponseQrSignEvm, ResponseQrSignSubstrate, ResponseRejectExternalRequest, ResponseResetWallet, ResponseResolveExternalRequest, ResponseSubscribeCurrentTokenPrice, ResponseSubscribeHistory, ResponseUnlockKeyring, ShowCampaignPopupRequest, StakingJson, StakingRewardJson, StakingType, ThemeNames, TokenPriorityDetails, TransactionHistoryItem, TransactionResponse, UiSettings, ValidateNetworkRequest, ValidateNetworkResponse, ValidatorInfo } from '@subwallet/extension-base/background/KoniTypes';
1111
import { AccountAuthType, AuthorizeRequest, MessageTypes, MetadataRequest, RequestAccountExport, RequestAuthorizeCancel, RequestAuthorizeReject, RequestCurrentAccountAddress, RequestMetadataApprove, RequestMetadataReject, RequestSigningApproveSignature, RequestSigningCancel, RequestTypes, ResponseAccountExport, ResponseAuthorizeList, ResponseType, SigningRequest, WindowOpenParams } from '@subwallet/extension-base/background/types';
1212
import { TransactionWarning } from '@subwallet/extension-base/background/warnings/TransactionWarning';
1313
import { _SUPPORT_TOKEN_PAY_FEE_GROUP, ALL_ACCOUNT_KEY, LATEST_SESSION } from '@subwallet/extension-base/constants';
@@ -2861,23 +2861,18 @@ export default class KoniExtension {
28612861
if (isJsonPayload(payload)) {
28622862
const [, chainInfo] = this.#koniState.findNetworkKeyByGenesisHash(payload.genesisHash);
28632863

2864-
const allRegistry: RegistrySource[] = [
2864+
const registries = await Promise.all([
28652865
setupApiRegistry(chainInfo, this.#koniState),
2866-
setupDatabaseRegistry(
2867-
await this.#koniState.chainService.getMetadataByHash(payload.genesisHash) as MetadataItem,
2868-
chainInfo,
2869-
payload
2870-
),
2871-
setupDappRegistry(
2872-
this.#koniState.knownMetadata.find((meta: MetadataDef) => meta.genesisHash === payload.genesisHash) as MetadataDef,
2873-
payload
2874-
)
2875-
].filter((item): item is RegistrySource => item !== null && item.registry !== undefined);
2876-
2877-
if (allRegistry.length === 0) {
2866+
setupDatabaseRegistry(chainInfo, payload, this.#koniState),
2867+
setupDappRegistry(payload, this.#koniState)
2868+
]);
2869+
2870+
const validRegistries = registries.filter((item): item is RegistrySource => !!item?.registry);
2871+
2872+
if (validRegistries.length === 0) {
28782873
registry.setSignedExtensions(payload.signedExtensions);
28792874
} else {
2880-
registry = getSuitableRegistry(allRegistry, payload);
2875+
registry = getSuitableRegistry(validRegistries, payload);
28812876
}
28822877
}
28832878

packages/extension-base/src/koni/background/utils.ts

Lines changed: 76 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import { _ChainInfo } from '@subwallet/chain-list/types';
55
import { MetadataItem } from '@subwallet/extension-base/background/KoniTypes';
6+
import { wait } from '@subwallet/extension-base/utils';
67
import { metadataExpand } from '@subwallet/extension-chains/bundle';
78
import { MetadataDef } from '@subwallet/extension-inject/types';
89

@@ -44,51 +45,97 @@ export function getSuitableRegistry (registries: RegistrySource[], payload: Sign
4445
return sortedRegistries[0].registry;
4546
}
4647

47-
export function setupApiRegistry (chainInfo: _ChainInfo | undefined, koniState: KoniState): RegistrySource | null {
48+
export async function setupApiRegistry (chainInfo: _ChainInfo | undefined, koniState: KoniState): Promise<RegistrySource | null> {
4849
if (!chainInfo) {
4950
return null;
5051
}
5152

52-
const api = koniState.getSubstrateApi(chainInfo.slug).api;
53-
const apiSpecVersion = api?.runtimeVersion.specVersion.toString();
54-
const registry = api?.registry as unknown as TypeRegistry;
53+
try {
54+
const api = koniState.getSubstrateApi(chainInfo.slug).api;
5555

56-
return {
57-
registry,
58-
specVersion: apiSpecVersion
59-
};
56+
if (!api) {
57+
return null;
58+
}
59+
60+
// Wait for the API to be ready or timeout after 1 second
61+
await Promise.race([
62+
wait(1000).then(() => {
63+
throw new Error('Timeout waiting for API to be ready');
64+
}),
65+
api.isReady
66+
]);
67+
68+
// Extract the spec version and registry
69+
const apiSpecVersion = api.runtimeVersion.specVersion.toString();
70+
const registry = api.registry as TypeRegistry;
71+
72+
return {
73+
registry,
74+
specVersion: apiSpecVersion
75+
};
76+
} catch (e) {
77+
console.error('Error in setupApiRegistry:', e);
78+
79+
return null;
80+
}
6081
}
6182

62-
export function setupDatabaseRegistry (metadata: MetadataItem, chainInfo: _ChainInfo | undefined, payload: SignerPayloadJSON): RegistrySource | null {
63-
if (!metadata || !metadata.genesisHash || !chainInfo) {
83+
export async function setupDatabaseRegistry (chainInfo: _ChainInfo | undefined, payload: SignerPayloadJSON, koniState: KoniState): Promise<RegistrySource | null> {
84+
if (!chainInfo) {
85+
console.warn('setupDatabaseRegistry: Missing chainInfo');
86+
6487
return null;
6588
}
6689

67-
const registry = new TypeRegistry();
68-
const _metadata = new Metadata(registry, metadata.hexValue);
90+
try {
91+
const metadata = await koniState.chainService.getMetadataByHash(payload.genesisHash) as MetadataItem;
6992

70-
registry.register(metadata.types);
71-
registry.setChainProperties(registry.createType('ChainProperties', metadata.tokenInfo) as unknown as ChainProperties);
72-
registry.setMetadata(_metadata, payload.signedExtensions, metadata.userExtensions);
93+
if (!metadata?.genesisHash) {
94+
console.warn('setupDatabaseRegistry: Metadata not found or invalid for genesisHash:', payload.genesisHash);
7395

74-
return {
75-
registry,
76-
specVersion: metadata.specVersion
77-
};
78-
}
96+
return null;
97+
}
98+
99+
const registry = new TypeRegistry();
100+
const _metadata = new Metadata(registry, metadata.hexValue);
101+
102+
registry.register(metadata.types);
103+
registry.setChainProperties(registry.createType('ChainProperties', metadata.tokenInfo) as unknown as ChainProperties);
104+
registry.setMetadata(_metadata, payload.signedExtensions, metadata.userExtensions);
105+
106+
return {
107+
registry,
108+
specVersion: metadata.specVersion
109+
};
110+
} catch (e) {
111+
console.error('setupDatabaseRegistry: Error setting up database registry:', e);
79112

80-
export function setupDappRegistry (metadata: MetadataDef, payload: SignerPayloadJSON): RegistrySource | null {
81-
if (!metadata || !metadata.genesisHash) {
82113
return null;
83114
}
115+
}
116+
117+
export function setupDappRegistry (payload: SignerPayloadJSON, koniState: KoniState): Promise<RegistrySource | null> {
118+
return new Promise((resolve) => {
119+
const metadata = koniState.knownMetadata.find((meta: MetadataDef) => meta.genesisHash === payload.genesisHash);
120+
121+
if (!metadata?.genesisHash) {
122+
return resolve(null);
123+
}
124+
125+
try {
126+
const expanded = metadataExpand(metadata, false);
127+
const registry = expanded.registry;
84128

85-
const expanded = metadataExpand(metadata, false);
86-
const registry = expanded.registry;
129+
registry.setSignedExtensions(payload.signedExtensions, expanded.definition.userExtensions);
87130

88-
registry.setSignedExtensions(payload.signedExtensions, expanded.definition.userExtensions);
131+
resolve({
132+
registry,
133+
specVersion: metadata.specVersion
134+
});
135+
} catch (e) {
136+
console.error('setupDappRegistry: Error setting up DApp registry:', e);
89137

90-
return {
91-
registry,
92-
specVersion: metadata.specVersion
93-
};
138+
resolve(null);
139+
}
140+
});
94141
}

0 commit comments

Comments
 (0)