@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.
- package/dist/dts/FedimintWallet.d.ts +56 -1
- package/dist/dts/FedimintWallet.d.ts.map +1 -1
- package/dist/dts/services/BalanceService.d.ts +2 -21
- package/dist/dts/services/BalanceService.d.ts.map +1 -1
- package/dist/dts/services/FederationService.d.ts +1 -1
- package/dist/dts/services/FederationService.d.ts.map +1 -1
- package/dist/dts/services/LightningService.d.ts +11 -2
- package/dist/dts/services/LightningService.d.ts.map +1 -1
- package/dist/dts/services/MintService.d.ts +13 -6
- package/dist/dts/services/MintService.d.ts.map +1 -1
- package/dist/dts/services/RecoveryService.d.ts +1 -1
- package/dist/dts/services/RecoveryService.d.ts.map +1 -1
- package/dist/dts/services/WalletService.d.ts +8 -0
- package/dist/dts/services/WalletService.d.ts.map +1 -0
- package/dist/dts/services/index.d.ts +1 -0
- package/dist/dts/services/index.d.ts.map +1 -1
- package/dist/dts/types/utils.d.ts +8 -1
- package/dist/dts/types/utils.d.ts.map +1 -1
- package/dist/dts/types/wallet.d.ts +20 -9
- package/dist/dts/types/wallet.d.ts.map +1 -1
- package/dist/dts/types/worker.d.ts +1 -1
- package/dist/dts/types/worker.d.ts.map +1 -1
- package/dist/dts/worker/WorkerClient.d.ts +1 -1
- package/dist/dts/worker/WorkerClient.d.ts.map +1 -1
- package/dist/index.d.ts +114 -38
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/worker.js +1 -1
- package/dist/worker.js.map +1 -1
- package/package.json +8 -8
- package/src/FedimintWallet.test.ts +13 -0
- package/src/FedimintWallet.ts +69 -0
- package/src/services/BalanceService.ts +5 -26
- package/src/services/FederationService.ts +9 -7
- package/src/services/LightningService.ts +81 -65
- package/src/services/MintService.test.ts +41 -0
- package/src/services/MintService.ts +41 -25
- package/src/services/RecoveryService.ts +9 -7
- package/src/services/WalletService.test.ts +24 -0
- package/src/services/WalletService.ts +10 -0
- package/src/services/index.ts +1 -0
- package/src/test/TestingService.ts +5 -4
- package/src/test/fixtures.ts +6 -0
- package/src/types/utils.ts +5 -1
- package/src/types/wallet.ts +39 -9
- package/src/types/worker.ts +3 -0
- package/src/worker/WorkerClient.ts +8 -9
- 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()
|
|
7
|
+
async getConfig() {
|
|
8
8
|
return await this.client.rpcSingle('', 'get_config', {})
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
async getFederationId()
|
|
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
|
|
16
|
-
return await this.client.rpcSingle('', 'get_invite_code', {
|
|
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()
|
|
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
|
-
)
|
|
22
|
+
) {
|
|
23
23
|
const gateway = gatewayInfo ?? (await this._getDefaultGatewayInfo())
|
|
24
|
-
return await this.client.rpcSingle(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
)
|
|
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
|
-
)
|
|
64
|
-
return await this.client.rpcSingle(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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()
|
|
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
|
-
)
|
|
90
|
+
) {
|
|
82
91
|
const gateway = gatewayInfo ?? (await this._getDefaultGatewayInfo())
|
|
83
|
-
return await this.client.rpcSingle(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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
|
-
)
|
|
245
|
-
return await this.client.rpcSingle
|
|
246
|
-
|
|
247
|
-
|
|
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()
|
|
252
|
-
return await this.client.rpcSingle(
|
|
263
|
+
async listGateways() {
|
|
264
|
+
return await this.client.rpcSingle<LightningGateway[]>(
|
|
265
|
+
'ln',
|
|
266
|
+
'list_gateways',
|
|
267
|
+
{},
|
|
268
|
+
)
|
|
253
269
|
}
|
|
254
270
|
|
|
255
|
-
async updateGatewayCache()
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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:
|
|
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
|
-
)
|
|
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<
|
|
70
|
+
const res = await this.client.rpcSingle<MintSpendNotesResponse>(
|
|
62
71
|
'mint',
|
|
63
72
|
'spend_notes',
|
|
64
73
|
{
|
|
65
|
-
|
|
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
|
-
|
|
81
|
-
|
|
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)
|
|
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:
|
|
104
|
+
onSuccess: (state: SpendNotesState) => void = () => {},
|
|
95
105
|
onError: (error: string) => void = () => {},
|
|
96
106
|
) {
|
|
97
|
-
|
|
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)
|
|
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()
|
|
8
|
-
return await this.client.rpcSingle(
|
|
7
|
+
async hasPendingRecoveries() {
|
|
8
|
+
return await this.client.rpcSingle<boolean>(
|
|
9
|
+
'',
|
|
10
|
+
'has_pending_recoveries',
|
|
11
|
+
{},
|
|
12
|
+
)
|
|
9
13
|
}
|
|
10
14
|
|
|
11
|
-
async waitForAllRecoveries()
|
|
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
|
-
)
|
|
19
|
-
|
|
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
|
+
}
|
package/src/services/index.ts
CHANGED
|
@@ -25,7 +25,7 @@ export class TestingService {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
async getInviteCode() {
|
|
28
|
-
const res = await fetch(
|
|
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(
|
|
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(
|
|
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(
|
|
69
|
+
const res = await fetch(`${import.meta.env.FAUCET}/invoice`, {
|
|
69
70
|
method: 'POST',
|
|
70
71
|
body: amount.toString(),
|
|
71
72
|
})
|
package/src/test/fixtures.ts
CHANGED
|
@@ -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
|
/**
|
package/src/types/utils.ts
CHANGED
|
@@ -22,4 +22,8 @@ type JSONValue =
|
|
|
22
22
|
|
|
23
23
|
type JSONObject = Record<string, JSONValue>
|
|
24
24
|
|
|
25
|
-
|
|
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 }
|