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