Skip to content

Commit

Permalink
OK-24974: Nostr, WebLN DApp connect issues (#3931)
Browse files Browse the repository at this point in the history
* fix: Nostr connect modal

* fix: webln connection

* fix: Preset network
  • Loading branch information
originalix authored Dec 12, 2023
1 parent 04ba7a5 commit 270adbf
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 5 deletions.
9 changes: 8 additions & 1 deletion packages/engine/src/vaults/impl/nostr/helper/Nostr.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import * as bip39 from 'bip39';

import { getBitcoinBip32 } from '../../../utils/btcForkChain/utils';

import { NOSTR_ADDRESS_INDEX, getNostrPath } from './NostrSDK';
import {
NOSTR_ADDRESS_INDEX,
getNip19EncodedPubkey,
getNostrPath,
} from './NostrSDK';

const fixtures = [
{
Expand Down Expand Up @@ -39,6 +43,9 @@ describe('test Nostr', () => {
fixture.privateKey,
);
expect(bytesToHex(node.publicKey.slice(1, 33))).toEqual(fixture.pubkey);
expect(
getNip19EncodedPubkey(bytesToHex(node.publicKey.slice(1, 33))),
).toEqual(fixture.npub);
});
});

Expand Down
5 changes: 5 additions & 0 deletions packages/engine/src/vaults/impl/nostr/helper/NostrSDK.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ export function getNostrCredentialId(walletId: string, accountIndex: number) {
return `${walletId}--nostr--${accountIndex}`;
}

export function getNip19EncodedPubkey(pubkey: string) {
const words = bech32.toWords(Buffer.from(pubkey, 'hex'));
return bech32.encode('npub', words, 1000);
}

class Nostr {
private walletId: string;

Expand Down
49 changes: 48 additions & 1 deletion packages/kit-bg/src/providers/ProviderApiNostr.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { web3Errors } from '@onekeyfe/cross-inpage-provider-errors';
import { IInjectedProviderNames } from '@onekeyfe/cross-inpage-provider-types';

import { getNip19EncodedPubkey } from '@onekeyhq/engine/src/vaults/impl/nostr/helper/NostrSDK';
import type {
INostrRelays,
NostrEvent,
Expand All @@ -14,7 +15,10 @@ import {
backgroundClass,
providerApiMethod,
} from '@onekeyhq/shared/src/background/backgroundDecorators';
import { IMPL_LIGHTNING } from '@onekeyhq/shared/src/engine/engineConsts';
import {
IMPL_LIGHTNING,
IMPL_NOSTR,
} from '@onekeyhq/shared/src/engine/engineConsts';
import { isHdWallet } from '@onekeyhq/shared/src/engine/engineUtils';
import debugLogger from '@onekeyhq/shared/src/logger/debugLogger';

Expand Down Expand Up @@ -78,14 +82,57 @@ class ProviderApiNostr extends ProviderApiBase {
public async getPublicKey(request: IJsBridgeMessagePayload): Promise<string> {
const { walletId, networkId, accountId } = getActiveWalletAccount();
this.checkWalletSupport(walletId);
const existPubKey = await this.getNostrAccountPubKey(request);
if (existPubKey) {
return existPubKey;
}
const pubkey = await this.backgroundApi.serviceDapp.openModal({
request,
screens: [ModalRoutes.Nostr, NostrModalRoutes.GetPublicKey],
params: { walletId, networkId, accountId },
});

if (request.origin) {
this.backgroundApi.serviceDapp.saveConnectedAccounts({
site: {
origin: request.origin,
},
address: getNip19EncodedPubkey(pubkey as string),
networkImpl: IMPL_NOSTR,
});
}

return Promise.resolve(pubkey as string);
}

async getNostrAccountPubKey(request: IJsBridgeMessagePayload) {
const { walletId, networkId, accountId } = getActiveWalletAccount();
const accounts = this.backgroundApi.serviceDapp?.getActiveConnectedAccounts(
{
origin: request.origin as string,
impl: IMPL_NOSTR,
},
);
if (!accounts) {
return null;
}
const accountNpubs = accounts.map((account) => account.address);
try {
const nostrAccount =
await this.backgroundApi.serviceNostr.getNostrAccount({
walletId,
currentNetworkId: networkId,
currentAccountId: accountId,
});
if (accountNpubs.includes(nostrAccount.address)) {
return nostrAccount.pubKey;
}
return null;
} catch {
return null;
}
}

@providerApiMethod()
public async getRelays(): Promise<INostrRelays> {
const result = await this.backgroundApi.serviceNostr.getRelays();
Expand Down
35 changes: 35 additions & 0 deletions packages/kit-bg/src/providers/ProviderApiWebln.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ class ProviderApiWebln extends ProviderApiBase {
@providerApiMethod()
public async enable(request: IJsBridgeMessagePayload) {
try {
const accountEnabled = await this.getEnabledAccount(request);
if (accountEnabled) {
return { enabled: true };
}
await this.backgroundApi.serviceDapp.openConnectionModal(request);
return { enabled: true };
} catch (error) {
Expand All @@ -85,6 +89,37 @@ class ProviderApiWebln extends ProviderApiBase {
}
}

private async getEnabledAccount(request: IJsBridgeMessagePayload) {
const { networkId, accountId } = getActiveWalletAccount();
try {
const accounts =
this.backgroundApi.serviceDapp?.getActiveConnectedAccounts({
origin: request.origin as string,
impl: IMPL_LIGHTNING,
});
if (!accounts) {
return false;
}
const accountAddresses = accounts.map((account) => account.address);

const account = await this.backgroundApi.engine.getAccount(
accountId,
networkId,
);
if (account.addresses) {
const addresses = JSON.parse(account.addresses) as {
hashAddress?: string;
};
if (addresses.hashAddress) {
return accountAddresses.includes(addresses.hashAddress);
}
}
return false;
} catch {
return false;
}
}

@providerApiMethod()
public async getInfo() {
return Promise.resolve({
Expand Down
6 changes: 5 additions & 1 deletion packages/kit-bg/src/services/ServiceNetwork.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
} from '@onekeyhq/shared/src/background/backgroundDecorators';
import {
IMPL_EVM,
getSupportedFakeNetworks,
getSupportedImpls,
} from '@onekeyhq/shared/src/engine/engineConsts';
import {
Expand Down Expand Up @@ -502,7 +503,10 @@ class ServiceNetwork extends ServiceBase {
});

for (const network of presetNetworksList) {
if (getSupportedImpls().has(network.impl)) {
if (
getSupportedImpls().has(network.impl) ||
getSupportedFakeNetworks().has(network.impl)
) {
const existingStatus = dbNetworkMap[network.id];
if (typeof existingStatus !== 'undefined') {
defaultNetworkList.push([network.id, existingStatus]);
Expand Down
33 changes: 33 additions & 0 deletions packages/kit-bg/src/services/ServiceNostr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
backgroundMethod,
} from '@onekeyhq/shared/src/background/backgroundDecorators';
import { OnekeyNetwork } from '@onekeyhq/shared/src/config/networkIds';
import debugLogger from '@onekeyhq/shared/src/logger/debugLogger';

import ServiceBase from './ServiceBase';

Expand Down Expand Up @@ -64,6 +65,38 @@ export default class ServiceNostr extends ServiceBase {
return index;
}

@backgroundMethod()
async getNostrAccount({
walletId,
currentAccountId,
currentNetworkId,
}: {
walletId: string;
currentAccountId: string;
currentNetworkId: string;
}) {
const accountIndex = await this.getCurrentAccountIndex(
currentAccountId,
currentNetworkId,
);
const networkId = OnekeyNetwork.nostr;
const path = `${getNostrPath(accountIndex)}/${NOSTR_ADDRESS_INDEX}`;
const accountId = `${walletId}--${path}`;
try {
const account = await this.backgroundApi.engine.getAccount(
accountId,
networkId,
);
return account;
} catch (e) {
debugLogger.backgroundApi.error(
'Nostr: get nostr account failed: ',
accountId,
);
throw e;
}
}

@backgroundMethod()
async getOrCreateNostrAccount({
walletId,
Expand Down
12 changes: 10 additions & 2 deletions packages/shared/src/engine/engineConsts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,6 @@ const SUPPORTED_IMPLS = new Set([
IMPL_LIGHTNING,
IMPL_LIGHTNING_TESTNET,
IMPL_ALLNETWORKS,
IMPL_NOSTR,
COINTYPE_NOSTR,
]);

const PRODUCTION_IMPLS = new Set([
Expand Down Expand Up @@ -178,6 +176,15 @@ function getSupportedImpls() {
return SUPPORTED_IMPLS;
}

/**
* Protocols like Nostr are not a chain,
* but for the purpose of account derivation,
* we still treat them as a chain.
*/
function getSupportedFakeNetworks() {
return new Set([IMPL_NOSTR]);
}

export {
COINTYPE_ADA,
COINTYPE_ALGO,
Expand Down Expand Up @@ -235,6 +242,7 @@ export {
INDEX_PLACEHOLDER,
SEPERATOR,
getSupportedImpls,
getSupportedFakeNetworks,
};

// switch network default rpc to onekey rpc node
Expand Down

0 comments on commit 270adbf

Please sign in to comment.