Skip to content
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

feat: Add Narval Armory Keyring Connection #2481

Open
wants to merge 1 commit into
base: develop
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
1 change: 1 addition & 0 deletions _raw/locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1371,6 +1371,7 @@
"connectHardwareWallets": "Connect Hardware Wallets",
"connectMobileWalletApps": "Connect Mobile Wallet Apps",
"connectInstitutionalWallets": "Connect Institutional Wallets",
"connectNarval": "Connect Narval",
"createNewSeedPhrase": "Create New Seed Phrase",
"importKeystore": "Import KeyStore",
"selectImportMethod": "Select Import Method",
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"@metamask/eth-sig-util": "5.1.0",
"@metamask/obs-store": "6.0.2",
"@metamask/post-message-stream": "8.1.0",
"@narval-xyz/armory-sdk": "0.7.0",
"@ngraveio/bc-ur": "1.1.6",
"@onekeyfe/hd-core": "0.3.48",
"@onekeyfe/hd-web-sdk": "0.3.27",
Expand Down
88 changes: 88 additions & 0 deletions src/background/controller/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ import {
import { appIsProd } from '@/utils/env';
import { getRecommendGas, getRecommendNonce } from './walletUtils/sign';
import { waitSignComponentAmounted } from '@/utils/signEvent';
import NarvalKeyring, {
NarvalAccount,
} from '../service/keyring/eth-narval-keyring';
import { ArmoryConfig } from '../utils/armory';

const stashKeyrings: Record<string | number, any> = {};

Expand Down Expand Up @@ -2433,6 +2437,90 @@ export class WalletController extends BaseController {
return this._setCurrentAccountFromKeyring(keyring);
};

getNarvalConnections = () => {
const keyrings: NarvalKeyring[] = keyringService.getKeyringsByType(
KEYRING_CLASS.Narval
);

return Promise.all(
keyrings.map(async (keyring) => {
const accounts = keyring.getNarvalAccounts();
const connectionId = keyring.getNarvalConnectionId();
const credentialPublicKey = keyring.getCredentialAddress();

return {
accounts,
connectionId,
credentialPublicKey,
};
})
);
};

removeNarvalConnection = async (connectionId: string) => {
const keyring = await keyringService.getNarvalKeyringByConnectionId(
connectionId
);
await keyringService.removeNarvalConnection(keyring);
return this.getNarvalConnections();
};

connectNarvalAccount = async (
config: ArmoryConfig
): Promise<{ accounts: NarvalAccount[]; connectionId: string }> => {
const buffer = Buffer.from(
ethUtil.stripHexPrefix(config.credentialPrivateKey),
'hex'
);

const error = new Error(t('background.error.invalidPrivateKey'));

try {
if (!ethUtil.isValidPrivate(buffer)) {
throw error;
}
} catch {
throw error;
}

const armoryConfig = {
...config,
credentialPrivateKey: ethUtil.addHexPrefix(config.credentialPrivateKey),
} as ArmoryConfig;

try {
// We first try to fetch the account to be sure the config is correct
const accounts = await NarvalKeyring.fetchNarvalAccounts(armoryConfig);
// If the config is correct, we save it as part of the keyrings
const keyring = await keyringService.connectNarvalAccount(armoryConfig);
const connectionId = keyring.getNarvalConnectionId();

return { accounts, connectionId };
} catch (err) {
if (['FORBIDDEN', 'FAILED'].includes(err?.message)) {
// If this error is thrown from fetchNarvalAccounts it means that the config
// is correct and we can save it as part of the keyrings
await keyringService.connectNarvalAccount(armoryConfig);
}

throw err;
}
};

fetchNarvalAccounts = async (connectionId: string) => {
const keyring = await keyringService.getNarvalKeyringByConnectionId(
connectionId
);
return keyring.fetchNarvalAccounts();
};

selectNarvalAccounts = (
connectionId: string,
accounts: NarvalAccount[]
): Promise<NarvalAccount[]> => {
return keyringService.selectNarvalAccounts(connectionId, accounts);
};

// json format is from "https://github.com/SilentCicero/ethereumjs-accounts"
// or "https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition"
// for example: https://www.myetherwallet.com/create-wallet
Expand Down
Loading