XO Wallet Integration Part IV
This commit is contained in:
@@ -11,7 +11,15 @@ import { type BlockchainUTXOs } from '../blockchain/index.js';
|
||||
import { type Activities, type BaseStore } from '../storage/index.js';
|
||||
import { EventEmitter } from '../utils/index.js';
|
||||
|
||||
import { type TokenBalances, type Address } from '@xocash/primitives';
|
||||
import {
|
||||
type TokenBalances,
|
||||
type Address,
|
||||
Bytes,
|
||||
Hasher,
|
||||
encodeExtendedJson,
|
||||
} from '@xocash/primitives';
|
||||
|
||||
export type WalletGenesisData = Record<string, unknown>;
|
||||
|
||||
export type WalletEvents = {
|
||||
shouldMonitorUpdated: boolean;
|
||||
@@ -33,32 +41,69 @@ export type WalletEvents = {
|
||||
export abstract class BaseWallet<
|
||||
WalletEventsType extends WalletEvents = WalletEvents,
|
||||
> extends EventEmitter<WalletEventsType> {
|
||||
static readonly deriveKey: (keyName: string) => Promise<Uint8Array>;
|
||||
/**
|
||||
* Derive a key to use based on the given Genesis Data.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* These keys can be used for Wallet Id's, Signing Keys, Encryption Keys and for Dapp Samdboxes.
|
||||
*/
|
||||
static deriveKey(genesisData: WalletGenesisData, keyName: string) {
|
||||
// Hash the genesis data using Hash256 and the key ("WalletID") for this derivation using Hash256.
|
||||
const genesisDataHashed = Hasher.fromUTF8(
|
||||
encodeExtendedJson(genesisData),
|
||||
).toHash256Bytes();
|
||||
const keyHashed = Hasher.fromUTF8(keyName).toHash256Bytes();
|
||||
|
||||
// Combine the hashes and do one final hash for good measure.
|
||||
return Hasher.fromBytes(
|
||||
new Uint8Array([...genesisDataHashed, ...keyHashed]),
|
||||
).toHash256Bytes();
|
||||
}
|
||||
|
||||
static deriveId(genesisData: WalletGenesisData) {
|
||||
return BaseWallet.deriveKey(genesisData, 'walletId');
|
||||
}
|
||||
|
||||
// Dependencies.
|
||||
abstract readonly activities: Activities;
|
||||
abstract readonly blockchain: WalletBlockchain;
|
||||
abstract readonly cache: BaseStore;
|
||||
|
||||
// Genesis Data.
|
||||
abstract readonly genesisData: WalletGenesisData;
|
||||
|
||||
/**
|
||||
* Get the ID for this wallet.
|
||||
*/
|
||||
abstract getId(): Promise<string>;
|
||||
|
||||
/**
|
||||
* Derive a key using secret data from this wallet.
|
||||
*/
|
||||
abstract deriveKey(keyName: string): Promise<Uint8Array>;
|
||||
async getId() {
|
||||
// NOTE: Use the cache to optimize future calls.
|
||||
return Bytes.from(
|
||||
await this.cache.getOrSet('walletId', async () =>
|
||||
BaseWallet.deriveKey(this.genesisData, 'walletId'),
|
||||
),
|
||||
).toHex();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the encryption key to use for this wallet.
|
||||
*/
|
||||
abstract getEncryptionKey(): Promise<Uint8Array>;
|
||||
async getEncryptionKey() {
|
||||
// NOTE: Use the cache to optimize future calls.
|
||||
return await this.cache.getOrSet('encryptionKey', async () =>
|
||||
BaseWallet.deriveKey(this.genesisData, 'encryptionKey'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the signing key to use for this wallet.
|
||||
*/
|
||||
abstract getSigningKey(): Promise<Uint8Array>;
|
||||
async getSigningKey() {
|
||||
// NOTE: Use the cache to optimize future calls.
|
||||
return this.cache.getOrSet('signingKey', async () =>
|
||||
BaseWallet.deriveKey(this.genesisData, 'signingKey'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start monitoring this wallet for any transaction activity.
|
||||
|
||||
Reference in New Issue
Block a user