mirror of
https://github.com/luxfi/eth-watch-keyring.git
synced 2026-10-30 16:57:56 +00:00
98 lines
2.4 KiB
TypeScript
98 lines
2.4 KiB
TypeScript
// https://github.com/MetaMask/eth-simple-keyring#the-keyring-class-protocol
|
|
import { EventEmitter } from 'events';
|
|
import { isAddress } from 'web3-utils';
|
|
import { addHexPrefix, bufferToHex } from 'ethereumjs-util';
|
|
|
|
const keyringType = 'Watch Address';
|
|
|
|
function sanitizeHex(hex: string): string {
|
|
hex = hex.substring(0, 2) === '0x' ? hex.substring(2) : hex;
|
|
if (hex === '') {
|
|
return '';
|
|
}
|
|
hex = hex.length % 2 !== 0 ? '0' + hex : hex;
|
|
return '0x' + hex;
|
|
}
|
|
|
|
class WatchKeyring extends EventEmitter {
|
|
static type = keyringType;
|
|
type = keyringType;
|
|
accounts: string[] = [];
|
|
accountToAdd = '';
|
|
|
|
constructor(opts = {}) {
|
|
super();
|
|
this.deserialize(opts);
|
|
}
|
|
|
|
serialize() {
|
|
return Promise.resolve({
|
|
accounts: this.accounts,
|
|
});
|
|
}
|
|
|
|
async deserialize(opts) {
|
|
if (opts.accounts) {
|
|
this.accounts = opts.accounts;
|
|
}
|
|
}
|
|
|
|
setAccountToAdd = (account) => {
|
|
this.accountToAdd = account;
|
|
};
|
|
|
|
addAccounts = async () => {
|
|
if (!isAddress(this.accountToAdd)) {
|
|
throw new Error("The address you're are trying to import is invalid");
|
|
}
|
|
const prefixedAddress = addHexPrefix(this.accountToAdd);
|
|
|
|
if (
|
|
this.accounts
|
|
.map((x) => x.toLowerCase())
|
|
.includes(prefixedAddress.toLowerCase())
|
|
) {
|
|
throw new Error("The address you're are trying to import is duplicated");
|
|
}
|
|
|
|
this.accounts.push(prefixedAddress);
|
|
|
|
return [prefixedAddress];
|
|
};
|
|
|
|
// pull the transaction current state, then resolve or reject
|
|
async signTransaction(address, transaction) {
|
|
// TODO: split by protocol(walletconnect, cold wallet, etc)
|
|
throw new Error('Can not sign with watch address');
|
|
}
|
|
|
|
async signPersonalMessage(address: string, message: string) {
|
|
throw new Error('Can not sign with watch address');
|
|
}
|
|
|
|
async signTypedData(address: string, data) {
|
|
throw new Error('Can not sign with watch address');
|
|
}
|
|
|
|
async getAccounts(): Promise<string[]> {
|
|
return this.accounts.slice();
|
|
}
|
|
|
|
removeAccount(address: string): void {
|
|
if (
|
|
!this.accounts.map((a) => a.toLowerCase()).includes(address.toLowerCase())
|
|
) {
|
|
throw new Error(`Address ${address} not found in watch keyring`);
|
|
}
|
|
this.accounts = this.accounts.filter(
|
|
(a) => a.toLowerCase() !== address.toLowerCase()
|
|
);
|
|
}
|
|
|
|
_normalize(buf) {
|
|
return sanitizeHex(bufferToHex(buf).toString());
|
|
}
|
|
}
|
|
|
|
export default WatchKeyring;
|