@fedimint/core-web 0.1.0 → 0.1.2

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 (78) hide show
  1. package/README.md +20 -9
  2. package/index.d.ts +1 -0
  3. package/index.js +15 -0
  4. package/package.json +12 -35
  5. package/dist/dts/FedimintWallet.d.ts +0 -51
  6. package/dist/dts/FedimintWallet.d.ts.map +0 -1
  7. package/dist/dts/WalletDirector.d.ts +0 -78
  8. package/dist/dts/WalletDirector.d.ts.map +0 -1
  9. package/dist/dts/index.d.ts +0 -4
  10. package/dist/dts/index.d.ts.map +0 -1
  11. package/dist/dts/services/BalanceService.d.ts +0 -15
  12. package/dist/dts/services/BalanceService.d.ts.map +0 -1
  13. package/dist/dts/services/FederationService.d.ts +0 -13
  14. package/dist/dts/services/FederationService.d.ts.map +0 -1
  15. package/dist/dts/services/LightningService.d.ts +0 -48
  16. package/dist/dts/services/LightningService.d.ts.map +0 -1
  17. package/dist/dts/services/MintService.d.ts +0 -23
  18. package/dist/dts/services/MintService.d.ts.map +0 -1
  19. package/dist/dts/services/RecoveryService.d.ts +0 -13
  20. package/dist/dts/services/RecoveryService.d.ts.map +0 -1
  21. package/dist/dts/services/WalletService.d.ts +0 -13
  22. package/dist/dts/services/WalletService.d.ts.map +0 -1
  23. package/dist/dts/services/index.d.ts +0 -7
  24. package/dist/dts/services/index.d.ts.map +0 -1
  25. package/dist/dts/transport/TransportClient.d.ts +0 -55
  26. package/dist/dts/transport/TransportClient.d.ts.map +0 -1
  27. package/dist/dts/transport/index.d.ts +0 -3
  28. package/dist/dts/transport/index.d.ts.map +0 -1
  29. package/dist/dts/transport/wasmTransport/WasmWorkerTransport.d.ts +0 -12
  30. package/dist/dts/transport/wasmTransport/WasmWorkerTransport.d.ts.map +0 -1
  31. package/dist/dts/types/index.d.ts +0 -4
  32. package/dist/dts/types/index.d.ts.map +0 -1
  33. package/dist/dts/types/transport.d.ts +0 -35
  34. package/dist/dts/types/transport.d.ts.map +0 -1
  35. package/dist/dts/types/utils.d.ts +0 -23
  36. package/dist/dts/types/utils.d.ts.map +0 -1
  37. package/dist/dts/types/wallet.d.ts +0 -241
  38. package/dist/dts/types/wallet.d.ts.map +0 -1
  39. package/dist/dts/utils/logger.d.ts +0 -24
  40. package/dist/dts/utils/logger.d.ts.map +0 -1
  41. package/dist/index.d.ts +0 -609
  42. package/dist/index.js +0 -2
  43. package/dist/index.js.map +0 -1
  44. package/dist/worker.js +0 -2
  45. package/dist/worker.js.map +0 -1
  46. package/src/FedimintWallet.test.ts +0 -73
  47. package/src/FedimintWallet.ts +0 -119
  48. package/src/WalletDirector.ts +0 -118
  49. package/src/index.ts +0 -3
  50. package/src/services/BalanceService.test.ts +0 -26
  51. package/src/services/BalanceService.ts +0 -29
  52. package/src/services/FederationService.test.ts +0 -58
  53. package/src/services/FederationService.ts +0 -216
  54. package/src/services/LightningService.test.ts +0 -265
  55. package/src/services/LightningService.ts +0 -289
  56. package/src/services/MintService.test.ts +0 -74
  57. package/src/services/MintService.ts +0 -129
  58. package/src/services/RecoveryService.ts +0 -28
  59. package/src/services/WalletService.test.ts +0 -59
  60. package/src/services/WalletService.ts +0 -50
  61. package/src/services/index.ts +0 -6
  62. package/src/test/TestFedimintWallet.ts +0 -31
  63. package/src/test/TestWalletDirector.ts +0 -14
  64. package/src/test/TestingService.ts +0 -79
  65. package/src/test/crypto.ts +0 -44
  66. package/src/test/fixtures.test.ts +0 -18
  67. package/src/test/fixtures.ts +0 -88
  68. package/src/transport/TransportClient.test.ts +0 -6
  69. package/src/transport/TransportClient.ts +0 -251
  70. package/src/transport/index.ts +0 -2
  71. package/src/transport/wasmTransport/WasmWorkerTransport.ts +0 -39
  72. package/src/transport/wasmTransport/worker.js +0 -167
  73. package/src/transport/wasmTransport/worker.test.ts +0 -90
  74. package/src/types/index.ts +0 -3
  75. package/src/types/transport.ts +0 -54
  76. package/src/types/utils.ts +0 -29
  77. package/src/types/wallet.ts +0 -298
  78. package/src/utils/logger.ts +0 -69
@@ -1,216 +0,0 @@
1
- import type {
2
- EcashTransaction,
3
- LightningTransaction,
4
- LnVariant,
5
- MintVariant,
6
- OperationKey,
7
- OperationLog,
8
- Transactions,
9
- WalletTransaction,
10
- WalletVariant,
11
- } from '../types'
12
- import { TransportClient } from '../transport'
13
-
14
- export class FederationService {
15
- constructor(private client: TransportClient) {}
16
-
17
- async getConfig() {
18
- return await this.client.rpcSingle('', 'get_config', {})
19
- }
20
-
21
- async getFederationId() {
22
- return await this.client.rpcSingle<string>('', 'get_federation_id', {})
23
- }
24
-
25
- async getInviteCode(peer: number = 0) {
26
- return await this.client.rpcSingle<string | null>('', 'get_invite_code', {
27
- peer,
28
- })
29
- }
30
-
31
- async listOperations(
32
- limit?: number,
33
- last_seen?: OperationKey,
34
- ): Promise<[OperationKey, OperationLog][]> {
35
- return await this.client.rpcSingle<[OperationKey, OperationLog][]>(
36
- '',
37
- 'list_operations',
38
- {
39
- limit: limit ?? null,
40
- last_seen: last_seen ?? null,
41
- },
42
- )
43
- }
44
-
45
- async getOperation(operationId: string) {
46
- return await this.client.rpcSingle<OperationLog | null>(
47
- '',
48
- 'get_operation',
49
- { operation_id: operationId },
50
- )
51
- }
52
-
53
- async listTransactions(
54
- limit?: number,
55
- last_seen?: OperationKey,
56
- ): Promise<Transactions[]> {
57
- const operations = await this.listOperations(limit, last_seen)
58
- return operations
59
- .filter(
60
- (item): item is [OperationKey, OperationLog] =>
61
- Array.isArray(item) && item.length === 2,
62
- )
63
- .filter(([_, op]) => {
64
- const { operation_module_kind, meta } = op
65
- const variant = meta.variant
66
- return (
67
- (operation_module_kind === 'ln' &&
68
- ((variant as LnVariant).pay || (variant as LnVariant).receive)) ||
69
- (operation_module_kind === 'mint' &&
70
- ((variant as MintVariant).spend_o_o_b ||
71
- (variant as MintVariant).reissuance)) ||
72
- (operation_module_kind === 'wallet' &&
73
- ((variant as WalletVariant).deposit ||
74
- (variant as WalletVariant).withdraw))
75
- )
76
- })
77
- .map(([key, op]) => {
78
- const timestamp = key.creation_time
79
- ? Math.round(
80
- key.creation_time.secs_since_epoch * 1000 +
81
- key.creation_time.nanos_since_epoch / 1_000_000,
82
- )
83
- : 0
84
- const operationId = key.operation_id
85
- const kind = op.operation_module_kind as 'ln' | 'mint' | 'wallet'
86
- const meta = op.meta
87
- const variant = meta.variant
88
-
89
- let outcome: string | undefined
90
- if (op.outcome && op.outcome.outcome) {
91
- if (typeof op.outcome.outcome === 'string') {
92
- outcome = op.outcome.outcome
93
- } else if (
94
- typeof op.outcome.outcome === 'object' &&
95
- op.outcome.outcome !== null
96
- ) {
97
- if ('success' in op.outcome.outcome) outcome = 'success'
98
- else if ('canceled' in op.outcome.outcome) outcome = 'canceled'
99
- else if ('claimed' in op.outcome.outcome) outcome = 'claimed'
100
- else if ('funded' in op.outcome.outcome) outcome = 'funded'
101
- else if ('awaiting_funds' in op.outcome.outcome)
102
- outcome = 'awaiting_funds'
103
- else if ('unexpected_error' in op.outcome.outcome)
104
- outcome = 'unexpected_error'
105
- else if ('created' in op.outcome.outcome) outcome = 'created'
106
- else if ('waiting_for_refund' in op.outcome.outcome)
107
- outcome = 'canceled'
108
- else if ('awaiting_change' in op.outcome.outcome)
109
- outcome = 'pending'
110
- else if ('refunded' in op.outcome.outcome) outcome = 'refunded'
111
- else if ('waiting_for_payment' in op.outcome.outcome)
112
- outcome = 'awaiting_funds'
113
- else if ('Created' in op.outcome.outcome) outcome = 'Created'
114
- else if ('Success' in op.outcome.outcome) outcome = 'Success'
115
- else if ('Refunded' in op.outcome.outcome) outcome = 'Refunded'
116
- else if ('UserCanceledProcessing' in op.outcome.outcome)
117
- outcome = 'UserCanceledProcessing'
118
- else if ('UserCanceledSuccess' in op.outcome.outcome)
119
- outcome = 'UserCanceledSuccess'
120
- else if ('UserCanceledFailure' in op.outcome.outcome)
121
- outcome = 'UserCanceledFailure'
122
- else if ('WaitingForTransaction' in op.outcome.outcome)
123
- outcome = 'pending'
124
- else if ('WaitingForConfirmation' in op.outcome.outcome)
125
- outcome = 'pending'
126
- else if ('Confirmed' in op.outcome.outcome) outcome = 'Confirmed'
127
- else if ('Claimed' in op.outcome.outcome) outcome = 'Claimed'
128
- else if ('Failed' in op.outcome.outcome) outcome = 'Failed'
129
- }
130
- }
131
-
132
- if (kind === 'ln') {
133
- const isPay = !!(variant as LnVariant).pay
134
- const txId =
135
- (variant as LnVariant).pay?.out_point.txid ||
136
- (variant as LnVariant).receive?.out_point.txid ||
137
- ''
138
- const type = (variant as LnVariant).pay ? 'send' : 'receive'
139
- const invoice =
140
- (variant as LnVariant).pay?.invoice ||
141
- (variant as LnVariant).receive?.invoice ||
142
- ''
143
- const gateway =
144
- (variant as LnVariant).pay?.gateway_id ||
145
- (variant as LnVariant).receive?.gateway_id ||
146
- ''
147
- const fee = (variant as LnVariant).pay?.fee
148
- const internalPay = (variant as LnVariant).pay?.is_internal_payment
149
- const preimage =
150
- isPay &&
151
- op.outcome?.outcome &&
152
- typeof op.outcome.outcome === 'object' &&
153
- 'success' in op.outcome.outcome
154
- ? op.outcome.outcome.success.preimage
155
- : undefined
156
-
157
- return {
158
- timestamp,
159
- operationId,
160
- kind,
161
- txId,
162
- type,
163
- invoice,
164
- internalPay,
165
- fee,
166
- gateway,
167
- outcome: outcome as LightningTransaction['outcome'],
168
- } as LightningTransaction
169
- } else if (kind === 'mint') {
170
- const txId = (variant as MintVariant).reissuance?.txid
171
- const type = (variant as MintVariant).reissuance
172
- ? 'reissue'
173
- : 'spend_oob'
174
- const amountMsats = meta.amount
175
- const notes = (variant as MintVariant).spend_o_o_b?.oob_notes
176
-
177
- return {
178
- timestamp,
179
- type,
180
- txId,
181
- outcome: outcome as EcashTransaction['outcome'],
182
- operationId,
183
- amountMsats,
184
- notes,
185
- kind,
186
- } as EcashTransaction
187
- } else if (kind === 'wallet') {
188
- const type = (variant as WalletVariant).deposit
189
- ? 'deposit'
190
- : 'withdraw'
191
- const address =
192
- (variant as WalletVariant).deposit?.address ||
193
- (variant as WalletVariant).withdraw?.address ||
194
- ''
195
- const feeRate = (variant as WalletVariant).withdraw?.fee.fee_rate
196
- .sats_per_kvb
197
- const amountMsats =
198
- (variant as WalletVariant).withdraw?.amountMsats || 0
199
-
200
- return {
201
- timestamp,
202
- type,
203
- onchainAddress: address,
204
- fee: feeRate || 0,
205
- amountMsats,
206
- outcome,
207
- kind,
208
- operationId,
209
- } as WalletTransaction
210
- }
211
- })
212
- .filter(
213
- (transaction): transaction is Transactions => transaction !== undefined,
214
- )
215
- }
216
- }
@@ -1,265 +0,0 @@
1
- import { expect } from 'vitest'
2
- import { keyPair } from '../test/crypto'
3
- import { walletTest } from '../test/fixtures'
4
-
5
- walletTest(
6
- 'createInvoice should create a bolt11 invoice',
7
- async ({ wallet }) => {
8
- expect(wallet).toBeDefined()
9
- expect(wallet.isOpen()).toBe(true)
10
-
11
- const counterBefore = wallet.testing.getRequestCounter()
12
- const invoice = await wallet.lightning.createInvoice(100, 'test')
13
- expect(invoice).toBeDefined()
14
- expect(invoice).toMatchObject({
15
- invoice: expect.any(String),
16
- operation_id: expect.any(String),
17
- })
18
- // 3 requests were made, one for the invoice, one for refreshing the
19
- // gateway cache, one for getting the gateway info
20
- expect(wallet.testing.getRequestCounter()).toBe(counterBefore + 3)
21
-
22
- // Test with expiry time
23
- await expect(
24
- wallet.lightning.createInvoice(100, 'test', 1000),
25
- ).resolves.toBeDefined()
26
- },
27
- )
28
-
29
- walletTest('createInvoice with expiry', async ({ wallet }) => {
30
- expect(wallet).toBeDefined()
31
- expect(wallet.isOpen()).toBe(true)
32
-
33
- const invoice = await wallet.lightning.createInvoice(100, 'test', 1000)
34
- expect(invoice).toBeDefined()
35
- expect(invoice).toMatchObject({
36
- invoice: expect.any(String),
37
- operation_id: expect.any(String),
38
- })
39
- })
40
-
41
- walletTest(
42
- 'listGateways should return a list of gateways',
43
- async ({ wallet }) => {
44
- expect(wallet).toBeDefined()
45
- expect(wallet.isOpen()).toBe(true)
46
-
47
- const counterBefore = wallet.testing.getRequestCounter()
48
- const gateways = await wallet.lightning.listGateways()
49
- expect(wallet.testing.getRequestCounter()).toBe(counterBefore + 1)
50
- expect(gateways).toBeDefined()
51
- expect(gateways).toMatchObject(expect.any(Array))
52
- },
53
- )
54
-
55
- walletTest(
56
- 'updateGatewayCache should update the gateway cache',
57
- async ({ wallet }) => {
58
- expect(wallet).toBeDefined()
59
- expect(wallet.isOpen()).toBe(true)
60
-
61
- const counterBefore = wallet.testing.getRequestCounter()
62
- await expect(wallet.lightning.updateGatewayCache()).resolves.toBeDefined()
63
- expect(wallet.testing.getRequestCounter()).toBe(counterBefore + 1)
64
- },
65
- )
66
-
67
- walletTest('getGateway should return a gateway', async ({ wallet }) => {
68
- expect(wallet).toBeDefined()
69
- expect(wallet.isOpen()).toBe(true)
70
-
71
- const counterBefore = wallet.testing.getRequestCounter()
72
- const gateway = await wallet.lightning.getGateway()
73
- expect(wallet.testing.getRequestCounter()).toBe(counterBefore + 1)
74
- expect(gateway).toMatchObject({
75
- api: expect.any(String),
76
- fees: expect.any(Object),
77
- gateway_id: expect.any(String),
78
- gateway_redeem_key: expect.any(String),
79
- lightning_alias: expect.any(String),
80
- mint_channel_id: expect.any(Number),
81
- node_pub_key: expect.any(String),
82
- route_hints: expect.any(Array),
83
- })
84
- })
85
-
86
- walletTest(
87
- 'payInvoice should throw on insufficient funds',
88
- async ({ wallet }) => {
89
- expect(wallet).toBeDefined()
90
- expect(wallet.isOpen()).toBe(true)
91
-
92
- const invoice = await wallet.lightning.createInvoice(100, 'test')
93
- expect(invoice).toBeDefined()
94
- expect(invoice).toMatchObject({
95
- invoice: expect.any(String),
96
- operation_id: expect.any(String),
97
- })
98
-
99
- const counterBefore = wallet.testing.getRequestCounter()
100
- // Insufficient funds
101
- try {
102
- await wallet.lightning.payInvoice(invoice.invoice)
103
- expect.unreachable('Should throw error')
104
- } catch (error) {
105
- expect(error).toBeDefined()
106
- }
107
- // 3 requests were made, one for paying the invoice, one for refreshing the
108
- // gateway cache, one for getting the gateway info
109
- expect(wallet.testing.getRequestCounter()).toBe(counterBefore + 3)
110
- },
111
- )
112
-
113
- walletTest(
114
- 'payInvoice should pay a bolt11 invoice',
115
- { timeout: 20_000 },
116
- async ({ fundedWallet }) => {
117
- expect(fundedWallet).toBeDefined()
118
- expect(fundedWallet.isOpen()).toBe(true)
119
- const initialBalance = await fundedWallet.balance.getBalance()
120
- expect(initialBalance).toBeGreaterThan(0)
121
- const externalInvoice = await fundedWallet.testing.createFaucetInvoice(1)
122
- const gatewayInfo = await fundedWallet.testing.getFaucetGatewayInfo()
123
- const payment = await fundedWallet.lightning.payInvoice(
124
- externalInvoice,
125
- gatewayInfo,
126
- )
127
- expect(payment).toMatchObject({
128
- contract_id: expect.any(String),
129
- fee: expect.any(Number),
130
- payment_type: expect.any(Object),
131
- })
132
- const finalBalance = await fundedWallet.balance.getBalance()
133
- expect(finalBalance).toBeLessThan(initialBalance)
134
- },
135
- )
136
-
137
- walletTest(
138
- 'createInvoiceTweaked should create a bolt11 invoice with a tweaked public key',
139
- async ({ wallet }) => {
140
- expect(wallet).toBeDefined()
141
- expect(wallet.isOpen()).toBe(true)
142
-
143
- // Make an ephemeral key pair
144
- const { publicKey, secretKey } = keyPair()
145
- const tweak = 1
146
-
147
- // Create an invoice paying to the tweaked public key
148
- const invoice = await wallet.lightning.createInvoiceTweaked(
149
- 1000,
150
- 'test tweaked',
151
- publicKey,
152
- tweak,
153
- )
154
- expect(invoice).toBeDefined()
155
- expect(invoice).toMatchObject({
156
- invoice: expect.any(String),
157
- operation_id: expect.any(String),
158
- })
159
- },
160
- )
161
-
162
- walletTest(
163
- 'scanReceivesForTweaks should return the operation id',
164
- async ({ wallet }) => {
165
- expect(wallet).toBeDefined()
166
- expect(wallet.isOpen()).toBe(true)
167
-
168
- // Make an ephemeral key pair
169
- const { publicKey, secretKey } = keyPair()
170
- const tweak = 1
171
-
172
- const gatewayInfo = await wallet.testing.getFaucetGatewayInfo()
173
-
174
- // Create an invoice paying to the tweaked public key
175
- const invoice = await wallet.lightning.createInvoiceTweaked(
176
- 1000,
177
- 'test tweaked',
178
- publicKey,
179
- tweak,
180
- undefined,
181
- gatewayInfo,
182
- )
183
- await expect(
184
- wallet.testing.payFaucetInvoice(invoice.invoice),
185
- ).resolves.toBeDefined()
186
-
187
- // Scan for the receive
188
- const operationIds = await wallet.lightning.scanReceivesForTweaks(
189
- secretKey,
190
- [tweak],
191
- {},
192
- )
193
- expect(operationIds).toBeDefined()
194
- expect(operationIds).toHaveLength(1)
195
-
196
- // Subscribe to claiming the receive
197
- const subscription = await wallet.lightning.subscribeLnClaim(
198
- operationIds[0],
199
- (state) => {
200
- expect(state).toBeDefined()
201
- expect(state).toMatchObject({
202
- state: 'claimed',
203
- })
204
- },
205
- )
206
- expect(subscription).toBeDefined()
207
- },
208
- )
209
-
210
- walletTest(
211
- 'subscribe_internal_pay should return state',
212
- async ({ fundedWallet }) => {
213
- expect(fundedWallet).toBeDefined()
214
- expect(fundedWallet.isOpen()).toBe(true)
215
- const initialBalance = await fundedWallet.balance.getBalance()
216
- expect(initialBalance).toBeGreaterThan(0)
217
- const externalInvoice = (
218
- await fundedWallet.lightning.createInvoice(1, 'test invoice')
219
- ).invoice
220
- const payment = await fundedWallet.lightning.payInvoice(externalInvoice)
221
- expect(payment).toMatchObject({
222
- contract_id: expect.any(String),
223
- fee: expect.any(Number),
224
- payment_type: expect.any(Object),
225
- })
226
- const finalBalance = await fundedWallet.balance.getBalance()
227
- expect(finalBalance).toBeLessThan(initialBalance)
228
- expect(payment.payment_type).toHaveProperty('internal')
229
- if ('internal' in payment.payment_type) {
230
- const id = payment.payment_type.internal
231
- await new Promise<void>((resolve, reject) => {
232
- const unsubscribe = fundedWallet.lightning.subscribeInternalPayment(
233
- id,
234
- (state) => {
235
- try {
236
- expect(state).toBeDefined()
237
- expect(state).toBe('funding')
238
- unsubscribe()
239
- resolve()
240
- } catch (err) {
241
- reject(err)
242
- }
243
- },
244
- )
245
- })
246
- } else {
247
- const id = payment.payment_type.lightning
248
- await new Promise<void>((resolve, reject) => {
249
- const unsubscribe = fundedWallet.lightning.subscribeLnPay(
250
- id,
251
- (state) => {
252
- try {
253
- expect(state).toBeDefined()
254
- expect(state).toBe('created')
255
- unsubscribe()
256
- resolve()
257
- } catch (err) {
258
- reject(err)
259
- }
260
- },
261
- )
262
- })
263
- }
264
- },
265
- )