Account.ts raw

   1  import { Pubkey } from '../shared'
   2  import { SignerType, SignerTypeValue } from './SignerType'
   3  
   4  /**
   5   * Credentials for different signer types
   6   */
   7  export type AccountCredentials = {
   8    ncryptsec?: string
   9    nsec?: string
  10  }
  11  
  12  /**
  13   * Account Entity
  14   *
  15   * Represents a user account in the application.
  16   * An account is identified by a public key and a signer type.
  17   *
  18   * Note: The same pubkey with different signer types are considered
  19   * different accounts (e.g., you might have nsec and nip-07 for the same key).
  20   */
  21  export class Account {
  22    private constructor(
  23      private readonly _pubkey: Pubkey,
  24      private readonly _signerType: SignerType,
  25      private readonly _credentials: AccountCredentials
  26    ) {}
  27  
  28    /**
  29     * Create a new account
  30     */
  31    static create(
  32      pubkey: Pubkey,
  33      signerType: SignerType,
  34      credentials: AccountCredentials = {}
  35    ): Account {
  36      return new Account(pubkey, signerType, { ...credentials })
  37    }
  38  
  39    /**
  40     * Create an account from raw values
  41     */
  42    static fromRaw(
  43      pubkeyHex: string,
  44      signerTypeValue: SignerTypeValue,
  45      credentials: AccountCredentials = {}
  46    ): Account {
  47      const pubkey = Pubkey.fromHex(pubkeyHex)
  48      const signerType = SignerType.fromString(signerTypeValue)
  49      return new Account(pubkey, signerType, { ...credentials })
  50    }
  51  
  52    /**
  53     * Try to create an account from raw values
  54     */
  55    static tryFromRaw(
  56      pubkeyHex: string,
  57      signerTypeValue: string,
  58      credentials: AccountCredentials = {}
  59    ): Account | null {
  60      try {
  61        const pubkey = Pubkey.tryFromString(pubkeyHex)
  62        if (!pubkey) return null
  63  
  64        const signerType = SignerType.tryFromString(signerTypeValue)
  65        if (!signerType) return null
  66  
  67        return new Account(pubkey, signerType, { ...credentials })
  68      } catch {
  69        return null
  70      }
  71    }
  72  
  73    /**
  74     * Create from legacy TAccount format
  75     */
  76    static fromLegacy(legacy: {
  77      pubkey: string
  78      signerType: SignerTypeValue
  79      ncryptsec?: string
  80      nsec?: string
  81      npub?: string
  82    }): Account | null {
  83      const pubkey = Pubkey.tryFromString(legacy.pubkey)
  84      if (!pubkey) return null
  85  
  86      const signerType = SignerType.tryFromString(legacy.signerType)
  87      if (!signerType) return null
  88  
  89      return new Account(pubkey, signerType, {
  90        ncryptsec: legacy.ncryptsec,
  91        nsec: legacy.nsec
  92      })
  93    }
  94  
  95    /**
  96     * The account's public key
  97     */
  98    get pubkey(): Pubkey {
  99      return this._pubkey
 100    }
 101  
 102    /**
 103     * The signer type used by this account
 104     */
 105    get signerType(): SignerType {
 106      return this._signerType
 107    }
 108  
 109    /**
 110     * Whether this account can sign events
 111     */
 112    get canSign(): boolean {
 113      return this._signerType.canSign
 114    }
 115  
 116    /**
 117     * Whether this is a view-only account
 118     */
 119    get isViewOnly(): boolean {
 120      return this._signerType.isViewOnly
 121    }
 122  
 123    /**
 124     * Get the ncryptsec credential (if available)
 125     */
 126    get ncryptsec(): string | undefined {
 127      return this._credentials.ncryptsec
 128    }
 129  
 130    /**
 131     * Create a unique identifier for this account
 132     * Combination of pubkey and signer type
 133     */
 134    get id(): string {
 135      return `${this._pubkey.hex}:${this._signerType.value}`
 136    }
 137  
 138    /**
 139     * Check if this is the same account (same pubkey and signer type)
 140     */
 141    equals(other: Account): boolean {
 142      return this._pubkey.equals(other._pubkey) && this._signerType.equals(other._signerType)
 143    }
 144  
 145    /**
 146     * Check if this account has the same pubkey as another
 147     */
 148    hasSamePubkey(other: Account): boolean {
 149      return this._pubkey.equals(other._pubkey)
 150    }
 151  
 152    /**
 153     * Convert to legacy TAccount format
 154     */
 155    toLegacy(): {
 156      pubkey: string
 157      signerType: SignerTypeValue
 158      ncryptsec?: string
 159      nsec?: string
 160      npub?: string
 161    } {
 162      return {
 163        pubkey: this._pubkey.hex,
 164        signerType: this._signerType.value,
 165        ncryptsec: this._credentials.ncryptsec,
 166        nsec: this._credentials.nsec,
 167        npub: this._signerType.isViewOnly ? this._pubkey.npub : undefined
 168      }
 169    }
 170  
 171    /**
 172     * Create an account pointer (pubkey + signer type, no credentials)
 173     */
 174    toPointer(): { pubkey: string; signerType: SignerTypeValue } {
 175      return {
 176        pubkey: this._pubkey.hex,
 177        signerType: this._signerType.value
 178      }
 179    }
 180  
 181    /**
 182     * For JSON serialization (excludes sensitive credentials)
 183     */
 184    toJSON(): { pubkey: string; signerType: string } {
 185      return {
 186        pubkey: this._pubkey.hex,
 187        signerType: this._signerType.value
 188      }
 189    }
 190  }
 191