@fedimint/core-web 0.0.10 → 0.1.0-alex-cache-wasm-build

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/dts/FedimintWallet.d.ts +56 -1
  2. package/dist/dts/FedimintWallet.d.ts.map +1 -1
  3. package/dist/dts/services/BalanceService.d.ts +2 -21
  4. package/dist/dts/services/BalanceService.d.ts.map +1 -1
  5. package/dist/dts/services/FederationService.d.ts +1 -1
  6. package/dist/dts/services/FederationService.d.ts.map +1 -1
  7. package/dist/dts/services/LightningService.d.ts +11 -2
  8. package/dist/dts/services/LightningService.d.ts.map +1 -1
  9. package/dist/dts/services/MintService.d.ts +13 -6
  10. package/dist/dts/services/MintService.d.ts.map +1 -1
  11. package/dist/dts/services/RecoveryService.d.ts +1 -1
  12. package/dist/dts/services/RecoveryService.d.ts.map +1 -1
  13. package/dist/dts/services/WalletService.d.ts +8 -0
  14. package/dist/dts/services/WalletService.d.ts.map +1 -0
  15. package/dist/dts/services/index.d.ts +1 -0
  16. package/dist/dts/services/index.d.ts.map +1 -1
  17. package/dist/dts/types/utils.d.ts +8 -1
  18. package/dist/dts/types/utils.d.ts.map +1 -1
  19. package/dist/dts/types/wallet.d.ts +20 -9
  20. package/dist/dts/types/wallet.d.ts.map +1 -1
  21. package/dist/dts/types/worker.d.ts +1 -1
  22. package/dist/dts/types/worker.d.ts.map +1 -1
  23. package/dist/dts/worker/WorkerClient.d.ts +1 -1
  24. package/dist/dts/worker/WorkerClient.d.ts.map +1 -1
  25. package/dist/index.d.ts +114 -38
  26. package/dist/index.js +1 -1
  27. package/dist/index.js.map +1 -1
  28. package/dist/worker.js +1 -1
  29. package/dist/worker.js.map +1 -1
  30. package/package.json +8 -8
  31. package/src/FedimintWallet.test.ts +13 -0
  32. package/src/FedimintWallet.ts +69 -0
  33. package/src/services/BalanceService.ts +5 -26
  34. package/src/services/FederationService.ts +9 -7
  35. package/src/services/LightningService.ts +81 -65
  36. package/src/services/MintService.test.ts +41 -0
  37. package/src/services/MintService.ts +41 -25
  38. package/src/services/RecoveryService.ts +9 -7
  39. package/src/services/WalletService.test.ts +24 -0
  40. package/src/services/WalletService.ts +10 -0
  41. package/src/services/index.ts +1 -0
  42. package/src/test/TestingService.ts +5 -4
  43. package/src/test/fixtures.ts +6 -0
  44. package/src/types/utils.ts +5 -1
  45. package/src/types/wallet.ts +39 -9
  46. package/src/types/worker.ts +3 -0
  47. package/src/worker/WorkerClient.ts +8 -9
  48. package/src/worker/worker.js +62 -0
@@ -4,19 +4,21 @@ import { WorkerClient } from '../worker'
4
4
  export class FederationService {
5
5
  constructor(private client: WorkerClient) {}
6
6
 
7
- async getConfig(): Promise<JSONValue> {
7
+ async getConfig() {
8
8
  return await this.client.rpcSingle('', 'get_config', {})
9
9
  }
10
10
 
11
- async getFederationId(): Promise<string> {
12
- return await this.client.rpcSingle('', 'get_federation_id', {})
11
+ async getFederationId() {
12
+ return await this.client.rpcSingle<string>('', 'get_federation_id', {})
13
13
  }
14
14
 
15
- async getInviteCode(peer: number): Promise<string | null> {
16
- return await this.client.rpcSingle('', 'get_invite_code', { peer })
15
+ async getInviteCode(peer: number = 0) {
16
+ return await this.client.rpcSingle<string | null>('', 'get_invite_code', {
17
+ peer,
18
+ })
17
19
  }
18
20
 
19
- async listOperations(): Promise<JSONValue[]> {
20
- return await this.client.rpcSingle('', 'list_operations', {})
21
+ async listOperations() {
22
+ return await this.client.rpcSingle<JSONValue[]>('', 'list_operations', {})
21
23
  }
22
24
  }
@@ -3,7 +3,6 @@ import type {
3
3
  CreateBolt11Response,
4
4
  GatewayInfo,
5
5
  JSONObject,
6
- JSONValue,
7
6
  LightningGateway,
8
7
  LnPayState,
9
8
  LnReceiveState,
@@ -13,21 +12,26 @@ import type {
13
12
  export class LightningService {
14
13
  constructor(private client: WorkerClient) {}
15
14
 
15
+ /** https://web.fedimint.org/core/FedimintWallet/LightningService/createInvoice#lightning-createinvoice */
16
16
  async createInvoice(
17
17
  amountMsats: number,
18
18
  description: string,
19
19
  expiryTime?: number, // in seconds
20
20
  gatewayInfo?: GatewayInfo,
21
21
  extraMeta?: JSONObject,
22
- ): Promise<CreateBolt11Response> {
22
+ ) {
23
23
  const gateway = gatewayInfo ?? (await this._getDefaultGatewayInfo())
24
- return await this.client.rpcSingle('ln', 'create_bolt11_invoice', {
25
- amount: amountMsats,
26
- description,
27
- expiry_time: expiryTime ?? null,
28
- extra_meta: extraMeta ?? {},
29
- gateway,
30
- })
24
+ return await this.client.rpcSingle<CreateBolt11Response>(
25
+ 'ln',
26
+ 'create_bolt11_invoice',
27
+ {
28
+ amount: amountMsats,
29
+ description,
30
+ expiry_time: expiryTime ?? null,
31
+ extra_meta: extraMeta ?? {},
32
+ gateway,
33
+ },
34
+ )
31
35
  }
32
36
 
33
37
  async createInvoiceTweaked(
@@ -38,9 +42,9 @@ export class LightningService {
38
42
  expiryTime?: number, // in seconds
39
43
  gatewayInfo?: GatewayInfo,
40
44
  extraMeta?: JSONObject,
41
- ): Promise<CreateBolt11Response> {
45
+ ) {
42
46
  const gateway = gatewayInfo ?? (await this._getDefaultGatewayInfo())
43
- return await this.client.rpcSingle(
47
+ return await this.client.rpcSingle<CreateBolt11Response>(
44
48
  'ln',
45
49
  'create_bolt11_invoice_for_user_tweaked',
46
50
  {
@@ -60,52 +64,63 @@ export class LightningService {
60
64
  tweakKey: string,
61
65
  indices: number[],
62
66
  extraMeta?: JSONObject,
63
- ): Promise<string[]> {
64
- return await this.client.rpcSingle('ln', 'scan_receive_for_user_tweaked', {
65
- user_key: tweakKey,
66
- indices,
67
- extra_meta: extraMeta ?? {},
68
- })
67
+ ) {
68
+ return await this.client.rpcSingle<string[]>(
69
+ 'ln',
70
+ 'scan_receive_for_user_tweaked',
71
+ {
72
+ user_key: tweakKey,
73
+ indices,
74
+ extra_meta: extraMeta ?? {},
75
+ },
76
+ )
69
77
  }
70
78
 
71
- private async _getDefaultGatewayInfo(): Promise<GatewayInfo> {
79
+ private async _getDefaultGatewayInfo() {
72
80
  await this.updateGatewayCache()
73
81
  const gateways = await this.listGateways()
74
82
  return gateways[0]?.info
75
83
  }
76
84
 
85
+ /** https://web.fedimint.org/core/FedimintWallet/LightningService/payInvoice#lightning-payinvoice-invoice-string */
77
86
  async payInvoice(
78
87
  invoice: string,
79
88
  gatewayInfo?: GatewayInfo,
80
89
  extraMeta?: JSONObject,
81
- ): Promise<OutgoingLightningPayment> {
90
+ ) {
82
91
  const gateway = gatewayInfo ?? (await this._getDefaultGatewayInfo())
83
- return await this.client.rpcSingle('ln', 'pay_bolt11_invoice', {
84
- maybe_gateway: gateway,
85
- invoice,
86
- extra_meta: extraMeta ?? {},
87
- })
92
+ return await this.client.rpcSingle<OutgoingLightningPayment>(
93
+ 'ln',
94
+ 'pay_bolt11_invoice',
95
+ {
96
+ maybe_gateway: gateway,
97
+ invoice,
98
+ extra_meta: extraMeta ?? {},
99
+ },
100
+ )
88
101
  }
89
102
 
103
+ /** https://web.fedimint.org/core/FedimintWallet/LightningService/payInvoice#lightning-payinvoicesync-invoice-string */
90
104
  async payInvoiceSync(
91
105
  invoice: string,
92
106
  timeoutMs: number = 10000,
93
107
  gatewayInfo?: GatewayInfo,
94
108
  extraMeta?: JSONObject,
95
- ): Promise<
96
- | { success: false }
97
- | {
98
- success: true
99
- data: { feeMsats: number; preimage: string }
100
- }
101
- > {
102
- return new Promise(async (resolve, reject) => {
109
+ ) {
110
+ return new Promise<
111
+ | { success: false; error?: string }
112
+ | {
113
+ success: true
114
+ data: { feeMsats: number; preimage: string }
115
+ }
116
+ >(async (resolve, reject) => {
103
117
  const { contract_id, fee } = await this.payInvoice(
104
118
  invoice,
105
119
  gatewayInfo,
106
120
  extraMeta,
107
121
  )
108
122
 
123
+ // TODO: handle error handling for other subscription statuses
109
124
  const unsubscribe = this.subscribeLnPay(contract_id, (res) => {
110
125
  if (typeof res !== 'string' && 'success' in res) {
111
126
  clearTimeout(timeoutId)
@@ -114,12 +129,14 @@ export class LightningService {
114
129
  success: true,
115
130
  data: { feeMsats: fee, preimage: res.success.preimage },
116
131
  })
132
+ } else if (typeof res !== 'string' && 'unexpected_error' in res) {
133
+ reject(new Error(res.unexpected_error.error_message))
117
134
  }
118
135
  })
119
136
 
120
137
  const timeoutId = setTimeout(() => {
121
138
  unsubscribe()
122
- reject(new Error('Timeout waiting for pay'))
139
+ resolve({ success: false, error: 'Payment timeout' })
123
140
  }, timeoutMs)
124
141
  })
125
142
  }
@@ -130,46 +147,41 @@ export class LightningService {
130
147
  onSuccess: (state: LnReceiveState) => void = () => {},
131
148
  onError: (error: string) => void = () => {},
132
149
  ) {
133
- const unsubscribe = this.client.rpcStream(
150
+ return this.client.rpcStream(
134
151
  'ln',
135
152
  'subscribe_ln_claim',
136
153
  { operation_id: operationId },
137
154
  onSuccess,
138
155
  onError,
139
156
  )
140
-
141
- return unsubscribe
142
157
  }
143
158
 
144
159
  // TODO: Document (for external payments only)
145
160
  // TODO: Make this work for BOTH internal and external payments
161
+ /** https://web.fedimint.org/core/FedimintWallet/LightningService/payInvoice#lightning-payinvoice-invoice-string */
146
162
  subscribeLnPay(
147
163
  operationId: string,
148
164
  onSuccess: (state: LnPayState) => void = () => {},
149
165
  onError: (error: string) => void = () => {},
150
166
  ) {
151
- const unsubscribe = this.client.rpcStream(
167
+ return this.client.rpcStream(
152
168
  'ln',
153
169
  'subscribe_ln_pay',
154
170
  { operation_id: operationId },
155
171
  onSuccess,
156
172
  onError,
157
173
  )
158
-
159
- return unsubscribe
160
174
  }
161
175
 
162
- async waitForPay(operationId: string): Promise<
163
- | { success: false }
164
- | {
165
- success: true
166
- data: { preimage: string }
167
- }
168
- > {
169
- return new Promise((resolve, reject) => {
176
+ /** https://web.fedimint.org/core/FedimintWallet/LightningService/payInvoice#lightning-payinvoice-invoice-string */
177
+ async waitForPay(operationId: string) {
178
+ return new Promise<
179
+ | { success: false; error?: string }
180
+ | { success: true; data: { preimage: string } }
181
+ >((resolve, reject) => {
170
182
  let unsubscribe: () => void
171
183
  const timeoutId = setTimeout(() => {
172
- reject(new Error('Timeout waiting for receive'))
184
+ resolve({ success: false, error: 'Waiting for receive timeout' })
173
185
  }, 15000)
174
186
 
175
187
  unsubscribe = this.subscribeLnPay(
@@ -193,28 +205,24 @@ export class LightningService {
193
205
  })
194
206
  }
195
207
 
196
- // TODO: Document
208
+ /** https://web.fedimint.org/core/FedimintWallet/LightningService/createInvoice#lightning-createinvoice */
197
209
  subscribeLnReceive(
198
210
  operationId: string,
199
211
  onSuccess: (state: LnReceiveState) => void = () => {},
200
212
  onError: (error: string) => void = () => {},
201
213
  ) {
202
- const unsubscribe = this.client.rpcStream(
214
+ return this.client.rpcStream(
203
215
  'ln',
204
216
  'subscribe_ln_receive',
205
217
  { operation_id: operationId },
206
218
  onSuccess,
207
219
  onError,
208
220
  )
209
-
210
- return unsubscribe
211
221
  }
212
222
 
213
- async waitForReceive(
214
- operationId: string,
215
- timeoutMs: number = 15000,
216
- ): Promise<LnReceiveState> {
217
- return new Promise((resolve, reject) => {
223
+ /** https://web.fedimint.org/core/FedimintWallet/LightningService/createInvoice#lightning-createinvoice */
224
+ async waitForReceive(operationId: string, timeoutMs: number = 15000) {
225
+ return new Promise<LnReceiveState>((resolve, reject) => {
218
226
  let unsubscribe: () => void
219
227
  const timeoutId = setTimeout(() => {
220
228
  reject(new Error('Timeout waiting for receive'))
@@ -241,18 +249,26 @@ export class LightningService {
241
249
  async getGateway(
242
250
  gatewayId: string | null = null,
243
251
  forceInternal: boolean = false,
244
- ): Promise<LightningGateway | null> {
245
- return await this.client.rpcSingle('ln', 'get_gateway', {
246
- gateway_id: gatewayId,
247
- force_internal: forceInternal,
248
- })
252
+ ) {
253
+ return await this.client.rpcSingle<LightningGateway | null>(
254
+ 'ln',
255
+ 'get_gateway',
256
+ {
257
+ gateway_id: gatewayId,
258
+ force_internal: forceInternal,
259
+ },
260
+ )
249
261
  }
250
262
 
251
- async listGateways(): Promise<LightningGateway[]> {
252
- return await this.client.rpcSingle('ln', 'list_gateways', {})
263
+ async listGateways() {
264
+ return await this.client.rpcSingle<LightningGateway[]>(
265
+ 'ln',
266
+ 'list_gateways',
267
+ {},
268
+ )
253
269
  }
254
270
 
255
- async updateGatewayCache(): Promise<JSONValue> {
271
+ async updateGatewayCache() {
256
272
  return await this.client.rpcSingle('ln', 'update_gateway_cache', {})
257
273
  }
258
274
  }
@@ -31,3 +31,44 @@ walletTest('parseNotes should parse notes', async ({ wallet }) => {
31
31
 
32
32
  await expect(wallet.mint.reissueExternalNotes('test')).rejects.toThrow()
33
33
  })
34
+
35
+ walletTest(
36
+ 'getNotesByDenomination should return empty object if wallet is empty',
37
+ async ({ wallet }) => {
38
+ expect(wallet).toBeDefined()
39
+ expect(wallet.isOpen()).toBe(true)
40
+
41
+ const notes = await wallet.mint.getNotesByDenomination()
42
+ const balance = await wallet.balance.getBalance()
43
+ expect(balance).toEqual(0)
44
+ expect(notes).toBeDefined()
45
+ expect(notes).toEqual({})
46
+ },
47
+ )
48
+
49
+ walletTest(
50
+ 'getNotesByDenomination should get notes by denomination',
51
+ async ({ fundedWallet }) => {
52
+ expect(fundedWallet).toBeDefined()
53
+ expect(fundedWallet.isOpen()).toBe(true)
54
+
55
+ const notes = await fundedWallet.mint.getNotesByDenomination()
56
+ const balance = await fundedWallet.balance.getBalance()
57
+ expect(balance).toEqual(10000)
58
+ expect(notes).toBeDefined()
59
+ expect(notes).toEqual({
60
+ '1': 2,
61
+ '1024': 3,
62
+ '128': 2,
63
+ '16': 3,
64
+ '2': 3,
65
+ '2048': 2,
66
+ '256': 3,
67
+ '32': 2,
68
+ '4': 2,
69
+ '512': 3,
70
+ '64': 2,
71
+ '8': 2,
72
+ })
73
+ },
74
+ )
@@ -5,32 +5,40 @@ import type {
5
5
  JSONValue,
6
6
  MintSpendNotesResponse,
7
7
  MSats,
8
+ NoteCountByDenomination,
8
9
  ReissueExternalNotesState,
10
+ SpendNotesState,
9
11
  } from '../types'
10
12
 
11
13
  export class MintService {
12
14
  constructor(private client: WorkerClient) {}
13
15
 
14
- async redeemEcash(notes: string): Promise<void> {
15
- await this.client.rpcSingle('mint', 'reissue_external_notes', {
16
- oob_notes: notes, // "out of band notes"
17
- extra_meta: null,
18
- })
16
+ /** https://web.fedimint.org/core/FedimintWallet/MintService/redeemEcash */
17
+ async redeemEcash(notes: string) {
18
+ return await this.client.rpcSingle<string>(
19
+ 'mint',
20
+ 'reissue_external_notes',
21
+ {
22
+ oob_notes: notes, // "out of band notes"
23
+ extra_meta: null,
24
+ },
25
+ )
19
26
  }
20
27
 
21
- async reissueExternalNotes(
22
- oobNotes: string,
23
- extraMeta: JSONObject = {},
24
- ): Promise<string> {
25
- return await this.client.rpcSingle('mint', 'reissue_external_notes', {
26
- oob_notes: oobNotes,
27
- extra_meta: extraMeta,
28
- })
28
+ async reissueExternalNotes(oobNotes: string, extraMeta: JSONObject = {}) {
29
+ return await this.client.rpcSingle<string>(
30
+ 'mint',
31
+ 'reissue_external_notes',
32
+ {
33
+ oob_notes: oobNotes,
34
+ extra_meta: extraMeta,
35
+ },
36
+ )
29
37
  }
30
38
 
31
39
  subscribeReissueExternalNotes(
32
40
  operationId: string,
33
- onSuccess: (state: JSONValue) => void = () => {},
41
+ onSuccess: (state: ReissueExternalNotesState) => void = () => {},
34
42
  onError: (error: string) => void = () => {},
35
43
  ) {
36
44
  const unsubscribe = this.client.rpcStream<ReissueExternalNotesState>(
@@ -44,6 +52,7 @@ export class MintService {
44
52
  return unsubscribe
45
53
  }
46
54
 
55
+ /** https://web.fedimint.org/core/FedimintWallet/MintService/spendNotes */
47
56
  async spendNotes(
48
57
  amountMsats: number,
49
58
  // Tells the wallet to automatically try to cancel the spend if it hasn't completed
@@ -52,17 +61,17 @@ export class MintService {
52
61
  tryCancelAfter: number | Duration = 3600 * 24, // defaults to 1 day
53
62
  includeInvite: boolean = false,
54
63
  extraMeta: JSONValue = {},
55
- ): Promise<MintSpendNotesResponse> {
64
+ ) {
56
65
  const duration =
57
66
  typeof tryCancelAfter === 'number'
58
67
  ? { nanos: 0, secs: tryCancelAfter }
59
68
  : tryCancelAfter
60
69
 
61
- const res = await this.client.rpcSingle<Array<string>>(
70
+ const res = await this.client.rpcSingle<MintSpendNotesResponse>(
62
71
  'mint',
63
72
  'spend_notes',
64
73
  {
65
- min_amount: amountMsats,
74
+ amount: amountMsats,
66
75
  try_cancel_after: duration,
67
76
  include_invite: includeInvite,
68
77
  extra_meta: extraMeta,
@@ -77,13 +86,14 @@ export class MintService {
77
86
  }
78
87
  }
79
88
 
80
- async parseNotes(oobNotes: string): Promise<MSats> {
81
- return await this.client.rpcSingle('mint', 'validate_notes', {
89
+ /** https://web.fedimint.org/core/FedimintWallet/MintService/parseEcash */
90
+ async parseNotes(oobNotes: string) {
91
+ return await this.client.rpcSingle<MSats>('mint', 'validate_notes', {
82
92
  oob_notes: oobNotes,
83
93
  })
84
94
  }
85
95
 
86
- async tryCancelSpendNotes(operationId: string): Promise<void> {
96
+ async tryCancelSpendNotes(operationId: string) {
87
97
  await this.client.rpcSingle('mint', 'try_cancel_spend_notes', {
88
98
  operation_id: operationId,
89
99
  })
@@ -91,23 +101,29 @@ export class MintService {
91
101
 
92
102
  subscribeSpendNotes(
93
103
  operationId: string,
94
- onSuccess: (state: JSONValue) => void = () => {},
104
+ onSuccess: (state: SpendNotesState) => void = () => {},
95
105
  onError: (error: string) => void = () => {},
96
106
  ) {
97
- const unsubscribe = this.client.rpcStream(
107
+ return this.client.rpcStream<SpendNotesState>(
98
108
  'mint',
99
109
  'subscribe_spend_notes',
100
110
  { operation_id: operationId },
101
111
  (res) => onSuccess(res),
102
112
  onError,
103
113
  )
104
-
105
- return unsubscribe
106
114
  }
107
115
 
108
- async awaitSpendOobRefund(operationId: string): Promise<JSONValue> {
116
+ async awaitSpendOobRefund(operationId: string) {
109
117
  return await this.client.rpcSingle('mint', 'await_spend_oob_refund', {
110
118
  operation_id: operationId,
111
119
  })
112
120
  }
121
+
122
+ async getNotesByDenomination() {
123
+ return await this.client.rpcSingle<NoteCountByDenomination>(
124
+ 'mint',
125
+ 'note_counts_by_denomination',
126
+ {},
127
+ )
128
+ }
113
129
  }
@@ -4,23 +4,25 @@ import { WorkerClient } from '../worker'
4
4
  export class RecoveryService {
5
5
  constructor(private client: WorkerClient) {}
6
6
 
7
- async hasPendingRecoveries(): Promise<boolean> {
8
- return await this.client.rpcSingle('', 'has_pending_recoveries', {})
7
+ async hasPendingRecoveries() {
8
+ return await this.client.rpcSingle<boolean>(
9
+ '',
10
+ 'has_pending_recoveries',
11
+ {},
12
+ )
9
13
  }
10
14
 
11
- async waitForAllRecoveries(): Promise<void> {
15
+ async waitForAllRecoveries() {
12
16
  await this.client.rpcSingle('', 'wait_for_all_recoveries', {})
13
17
  }
14
18
 
15
19
  subscribeToRecoveryProgress(
16
20
  onSuccess: (progress: { module_id: number; progress: JSONValue }) => void,
17
21
  onError: (error: string) => void,
18
- ): () => void {
19
- const unsubscribe = this.client.rpcStream<{
22
+ ) {
23
+ return this.client.rpcStream<{
20
24
  module_id: number
21
25
  progress: JSONValue
22
26
  }>('', 'subscribe_to_recovery_progress', {}, onSuccess, onError)
23
-
24
- return unsubscribe
25
27
  }
26
28
  }
@@ -0,0 +1,24 @@
1
+ import { expect } from 'vitest'
2
+ import { walletTest } from '../test/fixtures'
3
+ import { TxOutputSummary, WalletSummary } from '../types'
4
+
5
+ walletTest(
6
+ 'getWalletSummary should return empty object if wallet is empty',
7
+ async ({ wallet }) => {
8
+ expect(wallet).toBeDefined()
9
+ expect(wallet.isOpen()).toBe(true)
10
+
11
+ const balance = await wallet.balance.getBalance()
12
+ expect(balance).toEqual(0)
13
+
14
+ const summary = await wallet.wallet.getWalletSummary()
15
+ const expectedSummary = {
16
+ spendable_utxos: expect.any(Array<TxOutputSummary>),
17
+ unsigned_peg_out_txos: expect.any(Array<TxOutputSummary>),
18
+ unsigned_change_utxos: expect.any(Array<TxOutputSummary>),
19
+ unconfirmed_peg_out_txos: expect.any(Array<TxOutputSummary>),
20
+ unconfirmed_change_utxos: expect.any(Array<TxOutputSummary>),
21
+ } satisfies WalletSummary
22
+ expect(summary).toEqual(expect.objectContaining(expectedSummary))
23
+ },
24
+ )
@@ -0,0 +1,10 @@
1
+ import { WalletSummary } from '../types'
2
+ import { WorkerClient } from '../worker'
3
+
4
+ export class WalletService {
5
+ constructor(private client: WorkerClient) {}
6
+
7
+ async getWalletSummary(): Promise<WalletSummary> {
8
+ return await this.client.rpcSingle('wallet', 'get_wallet_summary', {})
9
+ }
10
+ }
@@ -3,3 +3,4 @@ export { BalanceService } from './BalanceService'
3
3
  export { LightningService } from './LightningService'
4
4
  export { RecoveryService } from './RecoveryService'
5
5
  export { FederationService } from './FederationService'
6
+ export { WalletService } from './WalletService'
@@ -25,7 +25,7 @@ export class TestingService {
25
25
  }
26
26
 
27
27
  async getInviteCode() {
28
- const res = await fetch('http://localhost:15243/connect-string')
28
+ const res = await fetch(`${import.meta.env.FAUCET}/connect-string`)
29
29
  if (res.ok) {
30
30
  return await res.text()
31
31
  } else {
@@ -34,7 +34,7 @@ export class TestingService {
34
34
  }
35
35
 
36
36
  private async getFaucetGatewayApi() {
37
- const res = await fetch('http://localhost:15243/gateway-api')
37
+ const res = await fetch(`${import.meta.env.FAUCET}/gateway-api`)
38
38
  if (res.ok) {
39
39
  return await res.text()
40
40
  } else {
@@ -43,6 +43,7 @@ export class TestingService {
43
43
  }
44
44
 
45
45
  async getFaucetGatewayInfo() {
46
+ await this.lightning.updateGatewayCache()
46
47
  const gateways = await this.lightning.listGateways()
47
48
  const api = await this.getFaucetGatewayApi()
48
49
  const gateway = gateways.find((g) => g.info.api === api)
@@ -53,7 +54,7 @@ export class TestingService {
53
54
  }
54
55
 
55
56
  async payFaucetInvoice(invoice: string) {
56
- const res = await fetch('http://localhost:15243/pay', {
57
+ const res = await fetch(`${import.meta.env.FAUCET}/pay`, {
57
58
  method: 'POST',
58
59
  body: invoice,
59
60
  })
@@ -65,7 +66,7 @@ export class TestingService {
65
66
  }
66
67
 
67
68
  async createFaucetInvoice(amount: number) {
68
- const res = await fetch('http://localhost:15243/invoice', {
69
+ const res = await fetch(`${import.meta.env.FAUCET}/invoice`, {
69
70
  method: 'POST',
70
71
  body: amount.toString(),
71
72
  })
@@ -8,6 +8,7 @@ import { WorkerClient } from '../worker/WorkerClient'
8
8
  export const walletTest = test.extend<{
9
9
  wallet: TestFedimintWallet
10
10
  fundedWallet: TestFedimintWallet
11
+ unopenedWallet: TestFedimintWallet
11
12
  }>({
12
13
  wallet: async ({}, use) => {
13
14
  const randomTestingId = Math.random().toString(36).substring(2, 15)
@@ -36,6 +37,11 @@ export const walletTest = test.extend<{
36
37
  await wallet.fundWallet(10_000)
37
38
  await use(wallet)
38
39
  },
40
+ unopenedWallet: async ({}, use) => {
41
+ const wallet = new TestFedimintWallet()
42
+ await wallet.initialize()
43
+ await use(wallet)
44
+ },
39
45
  })
40
46
 
41
47
  /**
@@ -22,4 +22,8 @@ type JSONValue =
22
22
 
23
23
  type JSONObject = Record<string, JSONValue>
24
24
 
25
- export { Alias, Resolve, Duration, MSats, Sats, JSONValue, JSONObject }
25
+ type Result<T, U = string> =
26
+ | { success: true; data?: T }
27
+ | { success: false; error: U }
28
+
29
+ export { Alias, Resolve, Duration, MSats, Sats, JSONValue, JSONObject, Result }