react-native-rgb 0.2.0

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 (44) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +165 -0
  3. package/Rgb.podspec +23 -0
  4. package/android/build.gradle +80 -0
  5. package/android/gradle.properties +5 -0
  6. package/android/src/main/AndroidManifest.xml +2 -0
  7. package/android/src/main/java/com/rgb/AppConstants.kt +57 -0
  8. package/android/src/main/java/com/rgb/RgbModule.kt +1959 -0
  9. package/android/src/main/java/com/rgb/RgbPackage.kt +33 -0
  10. package/android/src/main/java/com/rgb/WalletStore.kt +49 -0
  11. package/ios/AppConstants.swift +71 -0
  12. package/ios/Rgb.h +5 -0
  13. package/ios/Rgb.mm +1740 -0
  14. package/ios/Rgb.swift +1916 -0
  15. package/ios/RgbLib.swift +7615 -0
  16. package/ios/WalletStore.swift +61 -0
  17. package/lib/module/Interfaces.js +65 -0
  18. package/lib/module/Interfaces.js.map +1 -0
  19. package/lib/module/NativeRgb.js +5 -0
  20. package/lib/module/NativeRgb.js.map +1 -0
  21. package/lib/module/RgbError.js +65 -0
  22. package/lib/module/RgbError.js.map +1 -0
  23. package/lib/module/Wallet.js +854 -0
  24. package/lib/module/Wallet.js.map +1 -0
  25. package/lib/module/index.js +39 -0
  26. package/lib/module/index.js.map +1 -0
  27. package/lib/module/package.json +1 -0
  28. package/lib/typescript/package.json +1 -0
  29. package/lib/typescript/src/Interfaces.d.ts +390 -0
  30. package/lib/typescript/src/Interfaces.d.ts.map +1 -0
  31. package/lib/typescript/src/NativeRgb.d.ts +417 -0
  32. package/lib/typescript/src/NativeRgb.d.ts.map +1 -0
  33. package/lib/typescript/src/RgbError.d.ts +28 -0
  34. package/lib/typescript/src/RgbError.d.ts.map +1 -0
  35. package/lib/typescript/src/Wallet.d.ts +648 -0
  36. package/lib/typescript/src/Wallet.d.ts.map +1 -0
  37. package/lib/typescript/src/index.d.ts +28 -0
  38. package/lib/typescript/src/index.d.ts.map +1 -0
  39. package/package.json +174 -0
  40. package/src/Interfaces.ts +376 -0
  41. package/src/NativeRgb.ts +630 -0
  42. package/src/RgbError.ts +84 -0
  43. package/src/Wallet.ts +1118 -0
  44. package/src/index.tsx +46 -0
package/ios/Rgb.swift ADDED
@@ -0,0 +1,1916 @@
1
+ import Foundation
2
+
3
+
4
+ @objc(RgbSwiftHelper)
5
+ public class RgbSwiftHelper: NSObject {
6
+
7
+ private static func getErrorClassName(_ error: Error) -> String {
8
+ if let rgbError = error as? RgbLibError {
9
+ let errorString = String(reflecting: rgbError)
10
+
11
+ if let rgbLibErrorRange = errorString.range(of: "RgbLibError.") {
12
+ let afterRgbLibError = String(errorString[rgbLibErrorRange.upperBound...])
13
+ if let parenIndex = afterRgbLibError.firstIndex(of: "(") {
14
+ return String(afterRgbLibError[..<parenIndex])
15
+ }
16
+ return afterRgbLibError
17
+ }
18
+ if let parenIndex = errorString.firstIndex(of: "(") {
19
+ let beforeParen = String(errorString[..<parenIndex])
20
+ if let lastDotIndex = beforeParen.lastIndex(of: ".") {
21
+ return String(beforeParen[beforeParen.index(after: lastDotIndex)...])
22
+ }
23
+ }
24
+ }
25
+
26
+ let errorType = String(describing: type(of: error))
27
+ if let dotIndex = errorType.lastIndex(of: ".") {
28
+ return String(errorType[errorType.index(after: dotIndex)...])
29
+ }
30
+ return errorType
31
+ }
32
+ private static func parseErrorMessage(_ error: Error) -> String {
33
+ let errorString = String(describing: error)
34
+
35
+ if let detailsRange = errorString.range(of: "details: \"") {
36
+ let afterDetails = String(errorString[detailsRange.upperBound...])
37
+ if let endQuote = afterDetails.firstIndex(of: "\"") {
38
+ return String(afterDetails[..<endQuote])
39
+ }
40
+ }
41
+
42
+ if let detailsRange = errorString.range(of: "(details: \"") {
43
+ let afterDetails = String(errorString[detailsRange.upperBound...])
44
+ if let endQuote = afterDetails.firstIndex(of: "\"") {
45
+ return String(afterDetails[..<endQuote])
46
+ }
47
+ }
48
+
49
+ return error.localizedDescription
50
+ }
51
+
52
+ private static func getNetwork(_ network: String) -> BitcoinNetwork {
53
+ switch network.uppercased() {
54
+ case "MAINNET":
55
+ return .mainnet
56
+ case "TESTNET":
57
+ return .testnet
58
+ case "TESTNET4":
59
+ return .testnet4
60
+ case "REGTEST":
61
+ return .regtest
62
+ case "SIGNET":
63
+ return .signet
64
+ default:
65
+ fatalError("Unknown BitcoinNetwork: \(network)")
66
+ }
67
+ }
68
+ @objc
69
+ public static func _generateKeys(_ bitcoinNetwork: String) -> NSDictionary {
70
+ let network: BitcoinNetwork
71
+ switch bitcoinNetwork.uppercased() {
72
+ case "MAINNET":
73
+ network = .mainnet
74
+ case "TESTNET":
75
+ network = .testnet
76
+ case "TESTNET4":
77
+ network = .testnet4
78
+ case "REGTEST":
79
+ network = .regtest
80
+ case "SIGNET":
81
+ network = .signet
82
+ default:
83
+ fatalError("Unknown BitcoinNetwork: \(bitcoinNetwork)")
84
+ }
85
+
86
+ let keys = generateKeys(bitcoinNetwork: network)
87
+ return [
88
+ "mnemonic": keys.mnemonic,
89
+ "xpub": keys.xpub,
90
+ "accountXpubVanilla": keys.accountXpubVanilla,
91
+ "accountXpubColored": keys.accountXpubColored,
92
+ "masterFingerprint": keys.masterFingerprint,
93
+ ] as NSDictionary
94
+ }
95
+
96
+ @objc
97
+ public static func _restoreKeys(_ bitcoinNetwork: String, mnemonic: String) -> NSDictionary {
98
+ let network: BitcoinNetwork
99
+ switch bitcoinNetwork.uppercased() {
100
+ case "MAINNET":
101
+ network = .mainnet
102
+ case "TESTNET":
103
+ network = .testnet
104
+ case "TESTNET4":
105
+ network = .testnet4
106
+ case "REGTEST":
107
+ network = .regtest
108
+ case "SIGNET":
109
+ network = .signet
110
+
111
+ default:
112
+ fatalError("Unknown BitcoinNetwork: \(bitcoinNetwork)")
113
+ }
114
+
115
+ do{
116
+ let keys = try restoreKeys(bitcoinNetwork: network, mnemonic: mnemonic)
117
+ return [
118
+ "mnemonic": keys.mnemonic,
119
+ "xpub": keys.xpub,
120
+ "accountXpubVanilla": keys.accountXpubVanilla,
121
+ "accountXpubColored": keys.accountXpubColored,
122
+ "masterFingerprint": keys.masterFingerprint,
123
+ ] as NSDictionary
124
+ } catch {
125
+ let errorData = [
126
+ "error": parseErrorMessage(error),
127
+ "errorCode": getErrorClassName(error)
128
+ ] as NSDictionary
129
+ return errorData
130
+ }
131
+ }
132
+
133
+ private static func getAssetSchema(_ schema: String) -> AssetSchema {
134
+ switch schema.uppercased() {
135
+ case "NIA":
136
+ return .nia
137
+ case "UDA":
138
+ return .uda
139
+ case "CFA":
140
+ return .cfa
141
+ case "IFA":
142
+ return .ifa
143
+ default:
144
+ fatalError("Unknown AssetSchema: \(schema)")
145
+ }
146
+ }
147
+
148
+ @objc(_initializeWallet:accountXpubVanilla:accountXpubColored:mnemonic:masterFingerprint:supportedSchemas:maxAllocationsPerUtxo:vanillaKeychain:)
149
+ public static func _initializeWallet(
150
+ _ network: String,
151
+ _ accountXpubVanilla: String,
152
+ _ accountXpubColored: String,
153
+ _ mnemonic: String,
154
+ _ masterFingerprint: String,
155
+ _ supportedSchemas: NSArray,
156
+ _ maxAllocationsPerUtxo: NSNumber,
157
+ _ vanillaKeychain: NSNumber
158
+ ) -> NSDictionary {
159
+ do {
160
+ // Validate inputs
161
+ guard !network.isEmpty, !accountXpubVanilla.isEmpty, !accountXpubColored.isEmpty,
162
+ !mnemonic.isEmpty, !masterFingerprint.isEmpty else {
163
+ return ["error": "All string parameters must be non-empty"] as NSDictionary
164
+ }
165
+
166
+ guard supportedSchemas.count > 0 else {
167
+ return ["error": "supportedSchemas must not be empty"] as NSDictionary
168
+ }
169
+
170
+ // Ensure AppConstants is initialized - access shared instance safely
171
+ let constants = AppConstants.shared
172
+ // Ensure initialization happens on main thread if needed
173
+ if Thread.isMainThread {
174
+ constants.ensureInitialized()
175
+ } else {
176
+ DispatchQueue.main.sync {
177
+ constants.ensureInitialized()
178
+ }
179
+ }
180
+
181
+ guard let rgbDir = constants.rgbDir else {
182
+ return ["error": "RGB directory not initialized. Call AppConstants.initContext() first."] as NSDictionary
183
+ }
184
+
185
+ let bitcoinNetwork = getNetwork(network)
186
+ var schemaList: [AssetSchema] = []
187
+ for schemaStr in supportedSchemas {
188
+ if let schemaString = schemaStr as? String {
189
+ schemaList.append(getAssetSchema(schemaString))
190
+ }
191
+ }
192
+
193
+ let walletData = WalletData(
194
+ dataDir: rgbDir.path,
195
+ bitcoinNetwork: bitcoinNetwork,
196
+ databaseType: .sqlite,
197
+ maxAllocationsPerUtxo: UInt32(maxAllocationsPerUtxo.intValue),
198
+ accountXpubVanilla: accountXpubVanilla,
199
+ accountXpubColored: accountXpubColored,
200
+ mnemonic: mnemonic,
201
+ masterFingerprint: masterFingerprint,
202
+ vanillaKeychain: UInt8(vanillaKeychain.intValue),
203
+ supportedSchemas: schemaList
204
+ )
205
+ let wallet = try Wallet(walletData: walletData)
206
+
207
+ // Ensure WalletStore is accessible
208
+ let store = WalletStore.shared
209
+ let walletId = store.create(wallet: wallet)
210
+ return ["walletId": walletId] as NSDictionary
211
+ } catch {
212
+ let errorData = [
213
+ "error": parseErrorMessage(error),
214
+ "errorCode": getErrorClassName(error)
215
+ ] as NSDictionary
216
+ return errorData
217
+ }
218
+ }
219
+
220
+ @objc(_goOnline:skipConsistencyCheck:indexerUrl:)
221
+ public static func _goOnline(
222
+ _ walletId: NSNumber,
223
+ _ skipConsistencyCheck: Bool,
224
+ _ indexerUrl: String
225
+ ) -> NSDictionary {
226
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
227
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
228
+ }
229
+
230
+ do {
231
+ let online = try session.wallet.goOnline(
232
+ skipConsistencyCheck: skipConsistencyCheck,
233
+ indexerUrl: indexerUrl
234
+ )
235
+ WalletStore.shared.setOnline(id: walletId.intValue, online: online)
236
+ return [:] as NSDictionary
237
+ } catch {
238
+ let errorData = [
239
+ "error": parseErrorMessage(error),
240
+ "errorCode": getErrorClassName(error)
241
+ ] as NSDictionary
242
+ return errorData
243
+ }
244
+ }
245
+
246
+ @objc(_getBtcBalance:skipSync:)
247
+ public static func _getBtcBalance(
248
+ _ walletId: NSNumber,
249
+ _ skipSync: Bool
250
+ ) -> NSDictionary {
251
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
252
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
253
+ }
254
+
255
+ do {
256
+ let btcBalance = try session.wallet.getBtcBalance(
257
+ online: session.online,
258
+ skipSync: skipSync
259
+ )
260
+
261
+ let vanilla: [String: NSNumber] = [
262
+ "settled": NSNumber(value: btcBalance.vanilla.settled),
263
+ "future": NSNumber(value: btcBalance.vanilla.future),
264
+ "spendable": NSNumber(value: btcBalance.vanilla.spendable)
265
+ ]
266
+
267
+ let colored: [String: NSNumber] = [
268
+ "settled": NSNumber(value: btcBalance.colored.settled),
269
+ "future": NSNumber(value: btcBalance.colored.future),
270
+ "spendable": NSNumber(value: btcBalance.colored.spendable)
271
+ ]
272
+
273
+ return [
274
+ "vanilla": vanilla,
275
+ "colored": colored
276
+ ] as NSDictionary
277
+ } catch {
278
+ let errorData = [
279
+ "error": parseErrorMessage(error),
280
+ "errorCode": getErrorClassName(error)
281
+ ] as NSDictionary
282
+ return errorData
283
+ }
284
+ }
285
+
286
+ @objc(_walletClose:)
287
+ public static func _walletClose(_ walletId: NSNumber) -> NSDictionary {
288
+ WalletStore.shared.remove(id: walletId.intValue)
289
+ return [:] as NSDictionary
290
+ }
291
+
292
+ // Helper functions for type conversions
293
+ private static func getAssignment(_ assignmentDict: NSDictionary) -> Assignment {
294
+ guard let type = assignmentDict["type"] as? String else {
295
+ fatalError("Assignment type is required")
296
+ }
297
+
298
+ switch type.uppercased() {
299
+ case "FUNGIBLE":
300
+ guard let amount = assignmentDict["amount"] as? NSNumber else {
301
+ fatalError("Amount is required for FUNGIBLE assignment")
302
+ }
303
+ return .fungible(amount: amount.uint64Value)
304
+ case "NON_FUNGIBLE":
305
+ return .nonFungible
306
+ case "INFLATION_RIGHT":
307
+ guard let amount = assignmentDict["amount"] as? NSNumber else {
308
+ fatalError("Amount is required for INFLATION_RIGHT assignment")
309
+ }
310
+ return .inflationRight(amount: amount.uint64Value)
311
+ case "REPLACE_RIGHT":
312
+ return .replaceRight
313
+ case "ANY":
314
+ return .any
315
+ default:
316
+ fatalError("Unknown Assignment type: \(type)")
317
+ }
318
+ }
319
+
320
+ private static func getRefreshFilter(_ filterDict: NSDictionary) -> RefreshFilter {
321
+ guard let statusStr = filterDict["status"] as? String else {
322
+ fatalError("RefreshFilter status is required")
323
+ }
324
+
325
+ let status: RefreshTransferStatus
326
+ switch statusStr.uppercased() {
327
+ case "WAITING_COUNTERPARTY":
328
+ status = .waitingCounterparty
329
+ case "WAITING_CONFIRMATIONS":
330
+ status = .waitingConfirmations
331
+ default:
332
+ fatalError("Unknown RefreshTransferStatus: \(statusStr)")
333
+ }
334
+
335
+ guard let incoming = filterDict["incoming"] as? Bool else {
336
+ fatalError("RefreshFilter incoming is required")
337
+ }
338
+
339
+ return RefreshFilter(status: status, incoming: incoming)
340
+ }
341
+
342
+ private static func getRecipient(_ recipientDict: NSDictionary) -> Recipient {
343
+ guard let recipientId = recipientDict["recipientId"] as? String else {
344
+ fatalError("Recipient recipientId is required")
345
+ }
346
+
347
+ guard let assignmentDict = recipientDict["assignment"] as? NSDictionary else {
348
+ fatalError("Recipient assignment is required")
349
+ }
350
+ let assignment = getAssignment(assignmentDict)
351
+
352
+ guard let transportEndpointsArray = recipientDict["transportEndpoints"] as? NSArray else {
353
+ fatalError("Recipient transportEndpoints is required")
354
+ }
355
+ var transportEndpoints: [String] = []
356
+ for endpoint in transportEndpointsArray {
357
+ if let endpointStr = endpoint as? String {
358
+ transportEndpoints.append(endpointStr)
359
+ }
360
+ }
361
+
362
+ // WitnessData is optional
363
+ let witnessData: WitnessData?
364
+ if let witnessDataDict = recipientDict["witnessData"] as? NSDictionary {
365
+ guard let amountSatValue = witnessDataDict["amountSat"] as? NSNumber else {
366
+ fatalError("WitnessData amountSat is required")
367
+ }
368
+ let amountSat = amountSatValue.uint64Value
369
+
370
+ let blinding: UInt64?
371
+ if let blindingValue = witnessDataDict["blinding"] as? NSNumber {
372
+ blinding = blindingValue.uint64Value
373
+ } else {
374
+ blinding = nil
375
+ }
376
+
377
+ witnessData = WitnessData(amountSat: amountSat, blinding: blinding)
378
+ } else {
379
+ witnessData = nil
380
+ }
381
+
382
+ return Recipient(recipientId: recipientId, witnessData: witnessData, assignment: assignment, transportEndpoints: transportEndpoints)
383
+ }
384
+
385
+ private static func balanceToDict(_ balance: Balance) -> NSDictionary {
386
+ return [
387
+ "settled": NSNumber(value: balance.settled),
388
+ "future": NSNumber(value: balance.future),
389
+ "spendable": NSNumber(value: balance.spendable)
390
+ ] as NSDictionary
391
+ }
392
+
393
+ private static func assetCfaToDict(_ asset: AssetCfa) -> NSDictionary {
394
+ var dict: [String: Any] = [
395
+ "assetId": asset.assetId,
396
+ "name": asset.name,
397
+ "precision": NSNumber(value: asset.precision),
398
+ "issuedSupply": NSNumber(value: asset.issuedSupply),
399
+ "timestamp": NSNumber(value: asset.timestamp),
400
+ "addedAt": NSNumber(value: asset.addedAt),
401
+ "balance": balanceToDict(asset.balance)
402
+ ]
403
+
404
+ if let details = asset.details {
405
+ dict["details"] = details
406
+ }
407
+
408
+ if let media = asset.media {
409
+ dict["media"] = [
410
+ "filePath": media.filePath,
411
+ "mime": media.mime
412
+ ] as NSDictionary
413
+ }
414
+
415
+ return dict as NSDictionary
416
+ }
417
+
418
+ private static func assetIfaToDict(_ asset: AssetIfa) -> NSDictionary {
419
+ var dict: [String: Any] = [
420
+ "assetId": asset.assetId,
421
+ "ticker": asset.ticker,
422
+ "name": asset.name,
423
+ "precision": NSNumber(value: asset.precision),
424
+ "initialSupply": NSNumber(value: asset.initialSupply),
425
+ "maxSupply": NSNumber(value: asset.maxSupply),
426
+ "knownCirculatingSupply": NSNumber(value: asset.knownCirculatingSupply),
427
+ "timestamp": NSNumber(value: asset.timestamp),
428
+ "addedAt": NSNumber(value: asset.addedAt),
429
+ "balance": balanceToDict(asset.balance)
430
+ ]
431
+
432
+ if let details = asset.details {
433
+ dict["details"] = details
434
+ }
435
+
436
+ if let media = asset.media {
437
+ dict["media"] = [
438
+ "filePath": media.filePath,
439
+ "mime": media.mime
440
+ ] as NSDictionary
441
+ }
442
+
443
+ if let rejectListUrl = asset.rejectListUrl {
444
+ dict["rejectListUrl"] = rejectListUrl
445
+ }
446
+
447
+ return dict as NSDictionary
448
+ }
449
+
450
+ private static func assetNiaToDict(_ asset: AssetNia) -> NSDictionary {
451
+ return [
452
+ "assetId": asset.assetId,
453
+ "ticker": asset.ticker,
454
+ "name": asset.name,
455
+ "precision": NSNumber(value: asset.precision),
456
+ "timestamp": NSNumber(value: asset.timestamp),
457
+ "addedAt": NSNumber(value: asset.addedAt),
458
+ "balance": balanceToDict(asset.balance)
459
+ ] as NSDictionary
460
+ }
461
+
462
+ private static func assetUdaToDict(_ asset: AssetUda) -> NSDictionary {
463
+ var dict: [String: Any] = [
464
+ "assetId": asset.assetId,
465
+ "ticker": asset.ticker,
466
+ "name": asset.name,
467
+ "precision": NSNumber(value: asset.precision),
468
+ "timestamp": NSNumber(value: asset.timestamp),
469
+ "addedAt": NSNumber(value: asset.addedAt),
470
+ "balance": balanceToDict(asset.balance)
471
+ ]
472
+
473
+ if let details = asset.details {
474
+ dict["details"] = details
475
+ }
476
+
477
+ return dict as NSDictionary
478
+ }
479
+
480
+ private static func operationResultToDict(_ result: OperationResult) -> NSDictionary {
481
+ return [
482
+ "txid": result.txid,
483
+ "batchTransferIdx": NSNumber(value: result.batchTransferIdx)
484
+ ] as NSDictionary
485
+ }
486
+
487
+ private static func receiveDataToDict(_ data: ReceiveData) -> NSDictionary {
488
+ var dict: [String: Any] = [
489
+ "invoice": data.invoice,
490
+ "recipientId": data.recipientId,
491
+ "batchTransferIdx": NSNumber(value: data.batchTransferIdx)
492
+ ]
493
+
494
+ if let expirationTimestamp = data.expirationTimestamp {
495
+ dict["expirationTimestamp"] = NSNumber(value: expirationTimestamp)
496
+ }
497
+
498
+ return dict as NSDictionary
499
+ }
500
+
501
+ // Wallet methods
502
+ @objc(_backup:backupPath:password:)
503
+ public static func _backup(_ walletId: NSNumber, _ backupPath: String, _ password: String) -> NSDictionary {
504
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
505
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
506
+ }
507
+
508
+ do {
509
+ try session.wallet.backup(backupPath: backupPath, password: password)
510
+ return [:] as NSDictionary
511
+ } catch {
512
+ let errorData = [
513
+ "error": parseErrorMessage(error),
514
+ "errorCode": getErrorClassName(error)
515
+ ] as NSDictionary
516
+ return errorData
517
+ }
518
+ }
519
+
520
+ @objc(_backupInfo:)
521
+ public static func _backupInfo(_ walletId: NSNumber) -> NSDictionary {
522
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
523
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
524
+ }
525
+
526
+ do {
527
+ let hasBackup = try session.wallet.backupInfo()
528
+ return ["hasBackup": NSNumber(value: hasBackup)] as NSDictionary
529
+ } catch {
530
+ let errorData = [
531
+ "error": parseErrorMessage(error),
532
+ "errorCode": getErrorClassName(error)
533
+ ] as NSDictionary
534
+ return errorData
535
+ }
536
+ }
537
+
538
+ @objc(_blindReceive:assetId:assignment:durationSeconds:transportEndpoints:minConfirmations:)
539
+ public static func _blindReceive(
540
+ _ walletId: NSNumber,
541
+ _ assetId: String?,
542
+ _ assignment: NSDictionary,
543
+ _ durationSeconds: NSNumber?,
544
+ _ transportEndpoints: NSArray,
545
+ _ minConfirmations: NSNumber
546
+ ) -> NSDictionary {
547
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
548
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
549
+ }
550
+
551
+ do {
552
+ let assignmentObj = getAssignment(assignment)
553
+ var endpoints: [String] = []
554
+ for endpoint in transportEndpoints {
555
+ if let endpointStr = endpoint as? String {
556
+ endpoints.append(endpointStr)
557
+ }
558
+ }
559
+
560
+ let receiveData = try session.wallet.blindReceive(
561
+ assetId: assetId,
562
+ assignment: assignmentObj,
563
+ durationSeconds: durationSeconds?.uint32Value,
564
+ transportEndpoints: endpoints,
565
+ minConfirmations: minConfirmations.uint8Value
566
+ )
567
+
568
+ return receiveDataToDict(receiveData)
569
+ } catch {
570
+ let errorData = [
571
+ "error": parseErrorMessage(error),
572
+ "errorCode": getErrorClassName(error)
573
+ ] as NSDictionary
574
+ return errorData
575
+ }
576
+ }
577
+
578
+ @objc(_createUtxos:upTo:num:size:feeRate:skipSync:)
579
+ public static func _createUtxos(
580
+ _ walletId: NSNumber,
581
+ _ upTo: NSNumber,
582
+ _ num: NSNumber?,
583
+ _ size: NSNumber?,
584
+ _ feeRate: NSNumber,
585
+ _ skipSync: NSNumber
586
+ ) -> NSDictionary {
587
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
588
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
589
+ }
590
+
591
+ guard let online = session.online else {
592
+ return ["error": "Wallet is not online"] as NSDictionary
593
+ }
594
+
595
+ do {
596
+ let count = try session.wallet.createUtxos(
597
+ online: online,
598
+ upTo: upTo.boolValue,
599
+ num: num?.uint8Value,
600
+ size: size?.uint32Value,
601
+ feeRate: feeRate.uint64Value,
602
+ skipSync: skipSync.boolValue
603
+ )
604
+ return ["count": NSNumber(value: count)] as NSDictionary
605
+ } catch {
606
+ let errorData = [
607
+ "error": parseErrorMessage(error),
608
+ "errorCode": getErrorClassName(error)
609
+ ] as NSDictionary
610
+ return errorData
611
+ }
612
+ }
613
+
614
+ @objc(_createUtxosBegin:upTo:num:size:feeRate:skipSync:)
615
+ public static func _createUtxosBegin(
616
+ _ walletId: NSNumber,
617
+ _ upTo: NSNumber,
618
+ _ num: NSNumber?,
619
+ _ size: NSNumber?,
620
+ _ feeRate: NSNumber,
621
+ _ skipSync: NSNumber
622
+ ) -> NSDictionary {
623
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
624
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
625
+ }
626
+
627
+ guard let online = session.online else {
628
+ return ["error": "Wallet is not online"] as NSDictionary
629
+ }
630
+
631
+ do {
632
+ let psbt = try session.wallet.createUtxosBegin(
633
+ online: online,
634
+ upTo: upTo.boolValue,
635
+ num: num?.uint8Value,
636
+ size: size?.uint32Value,
637
+ feeRate: feeRate.uint64Value,
638
+ skipSync: skipSync.boolValue
639
+ )
640
+ return ["psbt": psbt] as NSDictionary
641
+ } catch {
642
+ let errorData = [
643
+ "error": parseErrorMessage(error),
644
+ "errorCode": getErrorClassName(error)
645
+ ] as NSDictionary
646
+ return errorData
647
+ }
648
+ }
649
+
650
+ @objc(_createUtxosEnd:signedPsbt:skipSync:)
651
+ public static func _createUtxosEnd(
652
+ _ walletId: NSNumber,
653
+ _ signedPsbt: String,
654
+ _ skipSync: NSNumber
655
+ ) -> NSDictionary {
656
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
657
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
658
+ }
659
+
660
+ guard let online = session.online else {
661
+ return ["error": "Wallet is not online"] as NSDictionary
662
+ }
663
+
664
+ do {
665
+ let count = try session.wallet.createUtxosEnd(online: online, signedPsbt: signedPsbt, skipSync: skipSync.boolValue)
666
+ return ["count": NSNumber(value: count)] as NSDictionary
667
+ } catch {
668
+ let errorData = [
669
+ "error": parseErrorMessage(error),
670
+ "errorCode": getErrorClassName(error)
671
+ ] as NSDictionary
672
+ return errorData
673
+ }
674
+ }
675
+
676
+ @objc(_deleteTransfers:batchTransferIdx:noAssetOnly:)
677
+ public static func _deleteTransfers(
678
+ _ walletId: NSNumber,
679
+ _ batchTransferIdx: NSNumber?,
680
+ _ noAssetOnly: NSNumber
681
+ ) -> NSDictionary {
682
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
683
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
684
+ }
685
+
686
+ do {
687
+ let deleted = try session.wallet.deleteTransfers(
688
+ batchTransferIdx: batchTransferIdx?.int32Value,
689
+ noAssetOnly: noAssetOnly.boolValue
690
+ )
691
+ return ["deleted": NSNumber(value: deleted)] as NSDictionary
692
+ } catch {
693
+ let errorData = [
694
+ "error": parseErrorMessage(error),
695
+ "errorCode": getErrorClassName(error)
696
+ ] as NSDictionary
697
+ return errorData
698
+ }
699
+ }
700
+
701
+ @objc(_drainTo:address:destroyAssets:feeRate:)
702
+ public static func _drainTo(
703
+ _ walletId: NSNumber,
704
+ _ address: String,
705
+ _ destroyAssets: NSNumber,
706
+ _ feeRate: NSNumber
707
+ ) -> NSDictionary {
708
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
709
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
710
+ }
711
+
712
+ guard let online = session.online else {
713
+ return ["error": "Wallet is not online"] as NSDictionary
714
+ }
715
+
716
+ do {
717
+ let txid = try session.wallet.drainTo(
718
+ online: online,
719
+ address: address,
720
+ destroyAssets: destroyAssets.boolValue,
721
+ feeRate: feeRate.uint64Value
722
+ )
723
+ return ["txid": txid] as NSDictionary
724
+ } catch {
725
+ let errorData = [
726
+ "error": parseErrorMessage(error),
727
+ "errorCode": getErrorClassName(error)
728
+ ] as NSDictionary
729
+ return errorData
730
+ }
731
+ }
732
+
733
+ @objc(_drainToBegin:address:destroyAssets:feeRate:)
734
+ public static func _drainToBegin(
735
+ _ walletId: NSNumber,
736
+ _ address: String,
737
+ _ destroyAssets: NSNumber,
738
+ _ feeRate: NSNumber
739
+ ) -> NSDictionary {
740
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
741
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
742
+ }
743
+
744
+ guard let online = session.online else {
745
+ return ["error": "Wallet is not online"] as NSDictionary
746
+ }
747
+
748
+ do {
749
+ let psbt = try session.wallet.drainToBegin(
750
+ online: online,
751
+ address: address,
752
+ destroyAssets: destroyAssets.boolValue,
753
+ feeRate: feeRate.uint64Value
754
+ )
755
+ return ["psbt": psbt] as NSDictionary
756
+ } catch {
757
+ let errorData = [
758
+ "error": parseErrorMessage(error),
759
+ "errorCode": getErrorClassName(error)
760
+ ] as NSDictionary
761
+ return errorData
762
+ }
763
+ }
764
+
765
+ @objc(_drainToEnd:signedPsbt:)
766
+ public static func _drainToEnd(
767
+ _ walletId: NSNumber,
768
+ _ signedPsbt: String
769
+ ) -> NSDictionary {
770
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
771
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
772
+ }
773
+
774
+ guard let online = session.online else {
775
+ return ["error": "Wallet is not online"] as NSDictionary
776
+ }
777
+
778
+ do {
779
+ let txid = try session.wallet.drainToEnd(online: online, signedPsbt: signedPsbt)
780
+ return ["txid": txid] as NSDictionary
781
+ } catch {
782
+ let errorData = [
783
+ "error": parseErrorMessage(error),
784
+ "errorCode": getErrorClassName(error)
785
+ ] as NSDictionary
786
+ return errorData
787
+ }
788
+ }
789
+
790
+ @objc(_failTransfers:batchTransferIdx:noAssetOnly:skipSync:)
791
+ public static func _failTransfers(
792
+ _ walletId: NSNumber,
793
+ _ batchTransferIdx: NSNumber?,
794
+ _ noAssetOnly: NSNumber,
795
+ _ skipSync: NSNumber
796
+ ) -> NSDictionary {
797
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
798
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
799
+ }
800
+
801
+ guard let online = session.online else {
802
+ return ["error": "Wallet is not online"] as NSDictionary
803
+ }
804
+
805
+ do {
806
+ let failed = try session.wallet.failTransfers(
807
+ online: online,
808
+ batchTransferIdx: batchTransferIdx?.int32Value,
809
+ noAssetOnly: noAssetOnly.boolValue,
810
+ skipSync: skipSync.boolValue
811
+ )
812
+ return ["failed": NSNumber(value: failed)] as NSDictionary
813
+ } catch {
814
+ let errorData = [
815
+ "error": parseErrorMessage(error),
816
+ "errorCode": getErrorClassName(error)
817
+ ] as NSDictionary
818
+ return errorData
819
+ }
820
+ }
821
+
822
+ @objc(_finalizePsbt:signedPsbt:)
823
+ public static func _finalizePsbt(_ walletId: NSNumber, _ signedPsbt: String) -> NSDictionary {
824
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
825
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
826
+ }
827
+
828
+ do {
829
+ let finalizedPsbt = try session.wallet.finalizePsbt(signedPsbt: signedPsbt)
830
+ return ["psbt": finalizedPsbt] as NSDictionary
831
+ } catch {
832
+ let errorData = [
833
+ "error": parseErrorMessage(error),
834
+ "errorCode": getErrorClassName(error)
835
+ ] as NSDictionary
836
+ return errorData
837
+ }
838
+ }
839
+
840
+ @objc(_getAddress:)
841
+ public static func _getAddress(_ walletId: NSNumber) -> NSDictionary {
842
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
843
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
844
+ }
845
+
846
+ do {
847
+ let address = try session.wallet.getAddress()
848
+ return ["address": address] as NSDictionary
849
+ } catch {
850
+ let errorData = [
851
+ "error": parseErrorMessage(error),
852
+ "errorCode": getErrorClassName(error)
853
+ ] as NSDictionary
854
+ return errorData
855
+ }
856
+ }
857
+
858
+ @objc(_getAssetBalance:assetId:)
859
+ public static func _getAssetBalance(_ walletId: NSNumber, _ assetId: String) -> NSDictionary {
860
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
861
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
862
+ }
863
+
864
+ do {
865
+ let balance = try session.wallet.getAssetBalance(assetId: assetId)
866
+ return balanceToDict(balance)
867
+ } catch {
868
+ let errorData = [
869
+ "error": parseErrorMessage(error),
870
+ "errorCode": getErrorClassName(error)
871
+ ] as NSDictionary
872
+ return errorData
873
+ }
874
+ }
875
+
876
+ @objc(_getAssetMetadata:assetId:)
877
+ public static func _getAssetMetadata(_ walletId: NSNumber, _ assetId: String) -> NSDictionary {
878
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
879
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
880
+ }
881
+
882
+ do {
883
+ let metadata = try session.wallet.getAssetMetadata(assetId: assetId)
884
+ var dict: [String: Any] = [
885
+ "assetId": assetId,
886
+ "name": metadata.name
887
+ ]
888
+
889
+ if let ticker = metadata.ticker {
890
+ dict["ticker"] = ticker
891
+ }
892
+ if let details = metadata.details {
893
+ dict["details"] = details
894
+ }
895
+ dict["precision"] = NSNumber(value: metadata.precision)
896
+ dict["maxSupply"] = NSNumber(value: metadata.maxSupply)
897
+ dict["timestamp"] = NSNumber(value: metadata.timestamp)
898
+
899
+ return dict as NSDictionary
900
+ } catch {
901
+ let errorData = [
902
+ "error": parseErrorMessage(error),
903
+ "errorCode": getErrorClassName(error)
904
+ ] as NSDictionary
905
+ return errorData
906
+ }
907
+ }
908
+
909
+ @objc(_getFeeEstimation:blocks:)
910
+ public static func _getFeeEstimation(_ walletId: NSNumber, _ blocks: NSNumber) -> NSDictionary {
911
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
912
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
913
+ }
914
+
915
+ guard let online = session.online else {
916
+ return ["error": "Wallet is not online"] as NSDictionary
917
+ }
918
+
919
+ do {
920
+ let feeRate = try session.wallet.getFeeEstimation(online: online, blocks: blocks.uint16Value)
921
+ return ["feeRate": NSNumber(value: feeRate)] as NSDictionary
922
+ } catch {
923
+ let errorData = [
924
+ "error": parseErrorMessage(error),
925
+ "errorCode": getErrorClassName(error)
926
+ ] as NSDictionary
927
+ return errorData
928
+ }
929
+ }
930
+
931
+ @objc(_getMediaDir:)
932
+ public static func _getMediaDir(_ walletId: NSNumber) -> NSDictionary {
933
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
934
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
935
+ }
936
+
937
+ let mediaDir = session.wallet.getMediaDir()
938
+ return ["mediaDir": mediaDir] as NSDictionary
939
+ }
940
+
941
+ @objc(_getWalletData:)
942
+ public static func _getWalletData(_ walletId: NSNumber) -> NSDictionary {
943
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
944
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
945
+ }
946
+
947
+ let walletData = session.wallet.getWalletData()
948
+
949
+ let networkString: String
950
+ switch walletData.bitcoinNetwork {
951
+ case .mainnet: networkString = "MAINNET"
952
+ case .testnet: networkString = "TESTNET"
953
+ case .testnet4: networkString = "TESTNET4"
954
+ case .regtest: networkString = "REGTEST"
955
+ case .signet: networkString = "SIGNET"
956
+ }
957
+
958
+ let dbTypeString: String
959
+ switch walletData.databaseType {
960
+ case .sqlite: dbTypeString = "SQLITE"
961
+ }
962
+
963
+ var schemaStrings: [String] = []
964
+ for schema in walletData.supportedSchemas {
965
+ switch schema {
966
+ case .nia: schemaStrings.append("NIA")
967
+ case .uda: schemaStrings.append("UDA")
968
+ case .cfa: schemaStrings.append("CFA")
969
+ case .ifa: schemaStrings.append("IFA")
970
+ }
971
+ }
972
+
973
+ var dict: [String: Any] = [
974
+ "dataDir": walletData.dataDir,
975
+ "bitcoinNetwork": networkString,
976
+ "databaseType": dbTypeString,
977
+ "maxAllocationsPerUtxo": NSNumber(value: walletData.maxAllocationsPerUtxo),
978
+ "accountXpubVanilla": walletData.accountXpubVanilla,
979
+ "accountXpubColored": walletData.accountXpubColored,
980
+ "masterFingerprint": walletData.masterFingerprint,
981
+ "supportedSchemas": schemaStrings
982
+ ]
983
+
984
+ if let mnemonic = walletData.mnemonic {
985
+ dict["mnemonic"] = mnemonic
986
+ }
987
+ if let vanillaKeychain = walletData.vanillaKeychain {
988
+ dict["vanillaKeychain"] = NSNumber(value: vanillaKeychain)
989
+ }
990
+
991
+ return dict as NSDictionary
992
+ }
993
+
994
+ @objc(_getWalletDir:)
995
+ public static func _getWalletDir(_ walletId: NSNumber) -> NSDictionary {
996
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
997
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
998
+ }
999
+
1000
+ let walletDir = session.wallet.getWalletDir()
1001
+ return ["walletDir": walletDir] as NSDictionary
1002
+ }
1003
+
1004
+ @objc(_inflate:assetId:inflationAmounts:feeRate:minConfirmations:)
1005
+ public static func _inflate(
1006
+ _ walletId: NSNumber,
1007
+ _ assetId: String,
1008
+ _ inflationAmounts: NSArray,
1009
+ _ feeRate: NSNumber,
1010
+ _ minConfirmations: NSNumber
1011
+ ) -> NSDictionary {
1012
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1013
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1014
+ }
1015
+
1016
+ guard let online = session.online else {
1017
+ return ["error": "Wallet is not online"] as NSDictionary
1018
+ }
1019
+
1020
+ do {
1021
+ var amounts: [UInt64] = []
1022
+ for amount in inflationAmounts {
1023
+ if let amountNum = amount as? NSNumber {
1024
+ amounts.append(amountNum.uint64Value)
1025
+ }
1026
+ }
1027
+
1028
+ let result = try session.wallet.inflate(
1029
+ online: online,
1030
+ assetId: assetId,
1031
+ inflationAmounts: amounts,
1032
+ feeRate: feeRate.uint64Value,
1033
+ minConfirmations: minConfirmations.uint8Value
1034
+ )
1035
+
1036
+ return operationResultToDict(result)
1037
+ } catch {
1038
+ let errorData = [
1039
+ "error": parseErrorMessage(error),
1040
+ "errorCode": getErrorClassName(error)
1041
+ ] as NSDictionary
1042
+ return errorData
1043
+ }
1044
+ }
1045
+
1046
+ @objc(_inflateBegin:assetId:inflationAmounts:feeRate:minConfirmations:)
1047
+ public static func _inflateBegin(
1048
+ _ walletId: NSNumber,
1049
+ _ assetId: String,
1050
+ _ inflationAmounts: NSArray,
1051
+ _ feeRate: NSNumber,
1052
+ _ minConfirmations: NSNumber
1053
+ ) -> NSDictionary {
1054
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1055
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1056
+ }
1057
+
1058
+ guard let online = session.online else {
1059
+ return ["error": "Wallet is not online"] as NSDictionary
1060
+ }
1061
+
1062
+ do {
1063
+ var amounts: [UInt64] = []
1064
+ for amount in inflationAmounts {
1065
+ if let amountNum = amount as? NSNumber {
1066
+ amounts.append(amountNum.uint64Value)
1067
+ }
1068
+ }
1069
+
1070
+ let psbt = try session.wallet.inflateBegin(
1071
+ online: online,
1072
+ assetId: assetId,
1073
+ inflationAmounts: amounts,
1074
+ feeRate: feeRate.uint64Value,
1075
+ minConfirmations: minConfirmations.uint8Value
1076
+ )
1077
+
1078
+ return ["psbt": psbt] as NSDictionary
1079
+ } catch {
1080
+ let errorData = [
1081
+ "error": parseErrorMessage(error),
1082
+ "errorCode": getErrorClassName(error)
1083
+ ] as NSDictionary
1084
+ return errorData
1085
+ }
1086
+ }
1087
+
1088
+ @objc(_inflateEnd:signedPsbt:)
1089
+ public static func _inflateEnd(_ walletId: NSNumber, _ signedPsbt: String) -> NSDictionary {
1090
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1091
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1092
+ }
1093
+
1094
+ guard let online = session.online else {
1095
+ return ["error": "Wallet is not online"] as NSDictionary
1096
+ }
1097
+
1098
+ do {
1099
+ let result = try session.wallet.inflateEnd(online: online, signedPsbt: signedPsbt)
1100
+ return operationResultToDict(result)
1101
+ } catch {
1102
+ let errorData = [
1103
+ "error": parseErrorMessage(error),
1104
+ "errorCode": getErrorClassName(error)
1105
+ ] as NSDictionary
1106
+ return errorData
1107
+ }
1108
+ }
1109
+
1110
+ @objc(_issueAssetCfa:name:details:precision:amounts:filePath:)
1111
+ public static func _issueAssetCfa(
1112
+ _ walletId: NSNumber,
1113
+ _ name: String,
1114
+ _ details: String?,
1115
+ _ precision: NSNumber,
1116
+ _ amounts: NSArray,
1117
+ _ filePath: String?
1118
+ ) -> NSDictionary {
1119
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1120
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1121
+ }
1122
+
1123
+ do {
1124
+ var amountsList: [UInt64] = []
1125
+ for amount in amounts {
1126
+ if let amountNum = amount as? NSNumber {
1127
+ amountsList.append(amountNum.uint64Value)
1128
+ }
1129
+ }
1130
+
1131
+ let asset = try session.wallet.issueAssetCfa(
1132
+ name: name,
1133
+ details: details,
1134
+ precision: precision.uint8Value,
1135
+ amounts: amountsList,
1136
+ filePath: filePath
1137
+ )
1138
+
1139
+ return assetCfaToDict(asset)
1140
+ } catch {
1141
+ let errorData = [
1142
+ "error": parseErrorMessage(error),
1143
+ "errorCode": getErrorClassName(error)
1144
+ ] as NSDictionary
1145
+ return errorData
1146
+ }
1147
+ }
1148
+
1149
+ @objc(_issueAssetIfa:ticker:name:precision:amounts:inflationAmounts:replaceRightsNum:rejectListUrl:)
1150
+ public static func _issueAssetIfa(
1151
+ _ walletId: NSNumber,
1152
+ _ ticker: String,
1153
+ _ name: String,
1154
+ _ precision: NSNumber,
1155
+ _ amounts: NSArray,
1156
+ _ inflationAmounts: NSArray,
1157
+ _ replaceRightsNum: NSNumber,
1158
+ _ rejectListUrl: String?
1159
+ ) -> NSDictionary {
1160
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1161
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1162
+ }
1163
+
1164
+ do {
1165
+ var amountsList: [UInt64] = []
1166
+ for amount in amounts {
1167
+ if let amountNum = amount as? NSNumber {
1168
+ amountsList.append(amountNum.uint64Value)
1169
+ }
1170
+ }
1171
+
1172
+ var inflationAmountsList: [UInt64] = []
1173
+ for amount in inflationAmounts {
1174
+ if let amountNum = amount as? NSNumber {
1175
+ inflationAmountsList.append(amountNum.uint64Value)
1176
+ }
1177
+ }
1178
+
1179
+ let asset = try session.wallet.issueAssetIfa(
1180
+ ticker: ticker,
1181
+ name: name,
1182
+ precision: precision.uint8Value,
1183
+ amounts: amountsList,
1184
+ inflationAmounts: inflationAmountsList,
1185
+ replaceRightsNum: replaceRightsNum.uint8Value,
1186
+ rejectListUrl: rejectListUrl
1187
+ )
1188
+
1189
+ return assetIfaToDict(asset)
1190
+ } catch {
1191
+ let errorData = [
1192
+ "error": parseErrorMessage(error),
1193
+ "errorCode": getErrorClassName(error)
1194
+ ] as NSDictionary
1195
+ return errorData
1196
+ }
1197
+ }
1198
+
1199
+ @objc(_issueAssetNia:ticker:name:precision:amounts:)
1200
+ public static func _issueAssetNia(
1201
+ _ walletId: NSNumber,
1202
+ _ ticker: String,
1203
+ _ name: String,
1204
+ _ precision: NSNumber,
1205
+ _ amounts: NSArray
1206
+ ) -> NSDictionary {
1207
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1208
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1209
+ }
1210
+
1211
+ do {
1212
+ var amountsList: [UInt64] = []
1213
+ for amount in amounts {
1214
+ if let amountNum = amount as? NSNumber {
1215
+ amountsList.append(amountNum.uint64Value)
1216
+ }
1217
+ }
1218
+
1219
+ let asset = try session.wallet.issueAssetNia(
1220
+ ticker: ticker,
1221
+ name: name,
1222
+ precision: precision.uint8Value,
1223
+ amounts: amountsList
1224
+ )
1225
+
1226
+ return assetNiaToDict(asset)
1227
+ } catch {
1228
+ let errorData = [
1229
+ "error": parseErrorMessage(error),
1230
+ "errorCode": getErrorClassName(error)
1231
+ ] as NSDictionary
1232
+ return errorData
1233
+ }
1234
+ }
1235
+
1236
+ @objc(_issueAssetUda:ticker:name:details:precision:mediaFilePath:attachmentsFilePaths:)
1237
+ public static func _issueAssetUda(
1238
+ _ walletId: NSNumber,
1239
+ _ ticker: String,
1240
+ _ name: String,
1241
+ _ details: String?,
1242
+ _ precision: NSNumber,
1243
+ _ mediaFilePath: String?,
1244
+ _ attachmentsFilePaths: NSArray
1245
+ ) -> NSDictionary {
1246
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1247
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1248
+ }
1249
+
1250
+ do {
1251
+ var attachmentsList: [String] = []
1252
+ for attachment in attachmentsFilePaths {
1253
+ if let attachmentStr = attachment as? String {
1254
+ attachmentsList.append(attachmentStr)
1255
+ }
1256
+ }
1257
+
1258
+ let asset = try session.wallet.issueAssetUda(
1259
+ ticker: ticker,
1260
+ name: name,
1261
+ details: details,
1262
+ precision: precision.uint8Value,
1263
+ mediaFilePath: mediaFilePath,
1264
+ attachmentsFilePaths: attachmentsList
1265
+ )
1266
+
1267
+ return assetUdaToDict(asset)
1268
+ } catch {
1269
+ let errorData = [
1270
+ "error": parseErrorMessage(error),
1271
+ "errorCode": getErrorClassName(error)
1272
+ ] as NSDictionary
1273
+ return errorData
1274
+ }
1275
+ }
1276
+
1277
+ @objc(_listAssets:filterAssetSchemas:)
1278
+ public static func _listAssets(_ walletId: NSNumber, _ filterAssetSchemas: NSArray) -> NSDictionary {
1279
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1280
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1281
+ }
1282
+
1283
+ do {
1284
+ var schemaList: [AssetSchema] = []
1285
+ for schemaStr in filterAssetSchemas {
1286
+ if let schemaString = schemaStr as? String {
1287
+ schemaList.append(getAssetSchema(schemaString))
1288
+ }
1289
+ }
1290
+
1291
+ let assets = try session.wallet.listAssets(filterAssetSchemas: schemaList)
1292
+
1293
+ var niaArray: [[String: Any]] = []
1294
+ for asset in assets.nia ?? [] {
1295
+ niaArray.append(assetNiaToDict(asset) as! [String: Any])
1296
+ }
1297
+
1298
+ var udaArray: [[String: Any]] = []
1299
+ for asset in assets.uda ?? [] {
1300
+ udaArray.append(assetUdaToDict(asset) as! [String: Any])
1301
+ }
1302
+
1303
+ var cfaArray: [[String: Any]] = []
1304
+ for asset in assets.cfa ?? [] {
1305
+ cfaArray.append(assetCfaToDict(asset) as! [String: Any])
1306
+ }
1307
+
1308
+ var ifaArray: [[String: Any]] = []
1309
+ for asset in assets.ifa ?? [] {
1310
+ ifaArray.append(assetIfaToDict(asset) as! [String: Any])
1311
+ }
1312
+
1313
+ return [
1314
+ "nia": niaArray,
1315
+ "uda": udaArray,
1316
+ "cfa": cfaArray,
1317
+ "ifa": ifaArray
1318
+ ] as NSDictionary
1319
+ } catch {
1320
+ let errorData = [
1321
+ "error": parseErrorMessage(error),
1322
+ "errorCode": getErrorClassName(error)
1323
+ ] as NSDictionary
1324
+ return errorData
1325
+ }
1326
+ }
1327
+
1328
+ @objc(_listTransactions:skipSync:)
1329
+ public static func _listTransactions(_ walletId: NSNumber, _ skipSync: NSNumber) -> NSDictionary {
1330
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1331
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1332
+ }
1333
+
1334
+ do {
1335
+ let transactions = try session.wallet.listTransactions(online: session.online, skipSync: skipSync.boolValue)
1336
+
1337
+ var transactionsArray: [[String: Any]] = []
1338
+ for tx in transactions {
1339
+ let txTypeString: String
1340
+ switch tx.transactionType {
1341
+ case .rgbSend: txTypeString = "RGB_SEND"
1342
+ case .drain: txTypeString = "DRAIN"
1343
+ case .createUtxos: txTypeString = "CREATE_UTXOS"
1344
+ case .user: txTypeString = "USER"
1345
+ }
1346
+
1347
+ var txDict: [String: Any] = [
1348
+ "transactionType": txTypeString,
1349
+ "txid": tx.txid,
1350
+ "received": NSNumber(value: tx.received),
1351
+ "sent": NSNumber(value: tx.sent),
1352
+ "fee": NSNumber(value: tx.fee)
1353
+ ]
1354
+
1355
+ if let confirmationTime = tx.confirmationTime {
1356
+ txDict["confirmationTime"] = NSNumber(value: confirmationTime.timestamp)
1357
+ }
1358
+
1359
+ transactionsArray.append(txDict)
1360
+ }
1361
+
1362
+ return ["transactions": transactionsArray] as NSDictionary
1363
+ } catch {
1364
+ let errorData = [
1365
+ "error": parseErrorMessage(error),
1366
+ "errorCode": getErrorClassName(error)
1367
+ ] as NSDictionary
1368
+ return errorData
1369
+ }
1370
+ }
1371
+
1372
+ @objc(_listTransfers:assetId:)
1373
+ public static func _listTransfers(_ walletId: NSNumber, _ assetId: String?) -> NSDictionary {
1374
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1375
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1376
+ }
1377
+
1378
+ do {
1379
+ let transfers = try session.wallet.listTransfers(assetId: assetId)
1380
+
1381
+ var transfersArray: [[String: Any]] = []
1382
+ for transfer in transfers {
1383
+ let kindString: String
1384
+ switch transfer.kind {
1385
+ case .issuance: kindString = "ISSUANCE"
1386
+ case .receiveBlind: kindString = "RECEIVE_BLIND"
1387
+ case .receiveWitness: kindString = "RECEIVE_WITNESS"
1388
+ case .send: kindString = "SEND"
1389
+ case .inflation: kindString = "INFLATION"
1390
+ }
1391
+
1392
+ let statusString: String
1393
+ switch transfer.status {
1394
+ case .waitingCounterparty: statusString = "WAITING_COUNTERPARTY"
1395
+ case .waitingConfirmations: statusString = "WAITING_CONFIRMATIONS"
1396
+ case .settled: statusString = "SETTLED"
1397
+ case .failed: statusString = "FAILED"
1398
+ }
1399
+
1400
+ var transportEndpointsStrings: [String] = []
1401
+ for endpoint in transfer.transportEndpoints {
1402
+ transportEndpointsStrings.append(endpoint.endpoint)
1403
+ }
1404
+
1405
+ var transferDict: [String: Any] = [
1406
+ "transferIdx": NSNumber(value: transfer.idx),
1407
+ "batchTransferIdx": NSNumber(value: transfer.batchTransferIdx),
1408
+ "createdAt": NSNumber(value: transfer.createdAt),
1409
+ "updatedAt": NSNumber(value: transfer.updatedAt),
1410
+ "kind": kindString,
1411
+ "status": statusString,
1412
+ "transportEndpoints": transportEndpointsStrings.joined(separator: ","),
1413
+ "assignments": transfer.assignments.count
1414
+ ]
1415
+
1416
+ if let txid = transfer.txid {
1417
+ transferDict["txid"] = txid
1418
+ }
1419
+ if let recipientId = transfer.recipientId {
1420
+ transferDict["recipientId"] = recipientId
1421
+ }
1422
+ if let receiveUtxo = transfer.receiveUtxo {
1423
+ transferDict["receiveUtxo"] = NSNumber(value: receiveUtxo.vout)
1424
+ }
1425
+ if let changeUtxo = transfer.changeUtxo {
1426
+ transferDict["changeUtxo"] = NSNumber(value: changeUtxo.vout)
1427
+ }
1428
+ if let expiration = transfer.expiration {
1429
+ transferDict["expiration"] = NSNumber(value: expiration)
1430
+ }
1431
+ if let invoiceString = transfer.invoiceString {
1432
+ transferDict["invoiceString"] = invoiceString
1433
+ }
1434
+ if let consignmentPath = transfer.consignmentPath {
1435
+ transferDict["consignmentPath"] = consignmentPath
1436
+ }
1437
+
1438
+ transfersArray.append(transferDict)
1439
+ }
1440
+
1441
+ return ["transfers": transfersArray] as NSDictionary
1442
+ } catch {
1443
+ let errorData = [
1444
+ "error": parseErrorMessage(error),
1445
+ "errorCode": getErrorClassName(error)
1446
+ ] as NSDictionary
1447
+ return errorData
1448
+ }
1449
+ }
1450
+
1451
+ @objc(_listUnspents:settledOnly:skipSync:)
1452
+ public static func _listUnspents(
1453
+ _ walletId: NSNumber,
1454
+ _ settledOnly: NSNumber,
1455
+ _ skipSync: NSNumber
1456
+ ) -> NSDictionary {
1457
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1458
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1459
+ }
1460
+
1461
+ do {
1462
+ let unspents = try session.wallet.listUnspents(online: session.online, settledOnly: settledOnly.boolValue, skipSync: skipSync.boolValue)
1463
+
1464
+ var unspentsArray: [[String: Any]] = []
1465
+ for unspent in unspents {
1466
+ var unspentDict: [String: Any] = [
1467
+ // "utxo": unspent.utxo.txid,
1468
+ // "vout": NSNumber(value: unspent.utxo.vout),
1469
+ // "amount": NSNumber(value: unspent.amount),
1470
+ // "colorable": String(unspent.utxo.colorable),
1471
+ "rgbAllocations": NSNumber(value: unspent.rgbAllocations.count)
1472
+ ]
1473
+
1474
+ unspentsArray.append(unspentDict)
1475
+ }
1476
+
1477
+ return ["unspents": unspentsArray] as NSDictionary
1478
+ } catch {
1479
+ let errorData = [
1480
+ "error": parseErrorMessage(error),
1481
+ "errorCode": getErrorClassName(error)
1482
+ ] as NSDictionary
1483
+ return errorData
1484
+ }
1485
+ }
1486
+
1487
+ @objc(_refresh:assetId:filter:skipSync:)
1488
+ public static func _refresh(
1489
+ _ walletId: NSNumber,
1490
+ _ assetId: String?,
1491
+ _ filter: NSArray,
1492
+ _ skipSync: NSNumber
1493
+ ) -> NSDictionary {
1494
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1495
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1496
+ }
1497
+
1498
+ guard let online = session.online else {
1499
+ return ["error": "Wallet is not online"] as NSDictionary
1500
+ }
1501
+
1502
+ do {
1503
+ var filterList: [RefreshFilter] = []
1504
+ for filterItem in filter {
1505
+ if let filterDict = filterItem as? NSDictionary {
1506
+ filterList.append(getRefreshFilter(filterDict))
1507
+ }
1508
+ }
1509
+
1510
+ let refreshed = try session.wallet.refresh(online: online, assetId: assetId, filter: filterList, skipSync: skipSync.boolValue)
1511
+
1512
+ var result: [String: Any] = [:]
1513
+ for (idx, refreshedTransfer) in refreshed {
1514
+ var refreshedDict: [String: Any] = [:]
1515
+ if let updatedStatus = refreshedTransfer.updatedStatus {
1516
+ let statusString: String
1517
+ switch updatedStatus {
1518
+ case .waitingCounterparty: statusString = "WAITING_COUNTERPARTY"
1519
+ case .waitingConfirmations: statusString = "WAITING_CONFIRMATIONS"
1520
+ case .settled: statusString = "SETTLED"
1521
+ case .failed: statusString = "FAILED"
1522
+ }
1523
+ refreshedDict["updatedStatus"] = statusString
1524
+ }
1525
+ if let failure = refreshedTransfer.failure {
1526
+ refreshedDict["failure"] = failure.localizedDescription
1527
+ }
1528
+ result[String(idx)] = refreshedDict
1529
+ }
1530
+
1531
+ return result as NSDictionary
1532
+ } catch {
1533
+ let errorData = [
1534
+ "error": parseErrorMessage(error),
1535
+ "errorCode": getErrorClassName(error)
1536
+ ] as NSDictionary
1537
+ return errorData
1538
+ }
1539
+ }
1540
+
1541
+ @objc(_send:recipientMap:donation:feeRate:minConfirmations:skipSync:)
1542
+ public static func _send(
1543
+ _ walletId: NSNumber,
1544
+ _ recipientMap: NSDictionary,
1545
+ _ donation: NSNumber,
1546
+ _ feeRate: NSNumber,
1547
+ _ minConfirmations: NSNumber,
1548
+ _ skipSync: NSNumber
1549
+ ) -> NSDictionary {
1550
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1551
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1552
+ }
1553
+
1554
+ guard let online = session.online else {
1555
+ return ["error": "Wallet is not online"] as NSDictionary
1556
+ }
1557
+
1558
+ do {
1559
+ var recipientMapNative: [String: [Recipient]] = [:]
1560
+ for (key, value) in recipientMap {
1561
+ if let keyStr = key as? String, let recipientsArray = value as? NSArray {
1562
+ var recipientsList: [Recipient] = []
1563
+ for recipientItem in recipientsArray {
1564
+ if let recipientDict = recipientItem as? NSDictionary {
1565
+ recipientsList.append(getRecipient(recipientDict))
1566
+ }
1567
+ }
1568
+ recipientMapNative[keyStr] = recipientsList
1569
+ }
1570
+ }
1571
+
1572
+ let result = try session.wallet.send(
1573
+ online: online,
1574
+ recipientMap: recipientMapNative,
1575
+ donation: donation.boolValue,
1576
+ feeRate: feeRate.uint64Value,
1577
+ minConfirmations: minConfirmations.uint8Value,
1578
+ skipSync: skipSync.boolValue
1579
+ )
1580
+
1581
+ return operationResultToDict(result)
1582
+ } catch {
1583
+ let errorData = [
1584
+ "error": parseErrorMessage(error),
1585
+ "errorCode": getErrorClassName(error)
1586
+ ] as NSDictionary
1587
+ return errorData
1588
+ }
1589
+ }
1590
+
1591
+ @objc(_sendBegin:recipientMap:donation:feeRate:minConfirmations:)
1592
+ public static func _sendBegin(
1593
+ _ walletId: NSNumber,
1594
+ _ recipientMap: NSDictionary,
1595
+ _ donation: NSNumber,
1596
+ _ feeRate: NSNumber,
1597
+ _ minConfirmations: NSNumber
1598
+ ) -> NSDictionary {
1599
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1600
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1601
+ }
1602
+
1603
+ guard let online = session.online else {
1604
+ return ["error": "Wallet is not online"] as NSDictionary
1605
+ }
1606
+
1607
+ do {
1608
+ var recipientMapNative: [String: [Recipient]] = [:]
1609
+ for (key, value) in recipientMap {
1610
+ if let keyStr = key as? String, let recipientsArray = value as? NSArray {
1611
+ var recipientsList: [Recipient] = []
1612
+ for recipientItem in recipientsArray {
1613
+ if let recipientDict = recipientItem as? NSDictionary {
1614
+ recipientsList.append(getRecipient(recipientDict))
1615
+ }
1616
+ }
1617
+ recipientMapNative[keyStr] = recipientsList
1618
+ }
1619
+ }
1620
+
1621
+ let psbt = try session.wallet.sendBegin(
1622
+ online: online,
1623
+ recipientMap: recipientMapNative,
1624
+ donation: donation.boolValue,
1625
+ feeRate: feeRate.uint64Value,
1626
+ minConfirmations: minConfirmations.uint8Value
1627
+ )
1628
+
1629
+ return ["psbt": psbt] as NSDictionary
1630
+ } catch {
1631
+ let errorData = [
1632
+ "error": parseErrorMessage(error),
1633
+ "errorCode": getErrorClassName(error)
1634
+ ] as NSDictionary
1635
+ return errorData
1636
+ }
1637
+ }
1638
+
1639
+ @objc(_sendBtc:address:amount:feeRate:skipSync:)
1640
+ public static func _sendBtc(
1641
+ _ walletId: NSNumber,
1642
+ _ address: String,
1643
+ _ amount: NSNumber,
1644
+ _ feeRate: NSNumber,
1645
+ _ skipSync: NSNumber
1646
+ ) -> NSDictionary {
1647
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1648
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1649
+ }
1650
+
1651
+ guard let online = session.online else {
1652
+ return ["error": "Wallet is not online"] as NSDictionary
1653
+ }
1654
+
1655
+ do {
1656
+ let txid = try session.wallet.sendBtc(
1657
+ online: online,
1658
+ address: address,
1659
+ amount: amount.uint64Value,
1660
+ feeRate: feeRate.uint64Value,
1661
+ skipSync: skipSync.boolValue
1662
+ )
1663
+ return ["txid": txid] as NSDictionary
1664
+ } catch {
1665
+ let errorData = [
1666
+ "error": parseErrorMessage(error),
1667
+ "errorCode": getErrorClassName(error)
1668
+ ] as NSDictionary
1669
+ return errorData
1670
+ }
1671
+ }
1672
+
1673
+ @objc(_sendBtcBegin:address:amount:feeRate:skipSync:)
1674
+ public static func _sendBtcBegin(
1675
+ _ walletId: NSNumber,
1676
+ _ address: String,
1677
+ _ amount: NSNumber,
1678
+ _ feeRate: NSNumber,
1679
+ _ skipSync: NSNumber
1680
+ ) -> NSDictionary {
1681
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1682
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1683
+ }
1684
+
1685
+ guard let online = session.online else {
1686
+ return ["error": "Wallet is not online"] as NSDictionary
1687
+ }
1688
+
1689
+ do {
1690
+ let psbt = try session.wallet.sendBtcBegin(
1691
+ online: online,
1692
+ address: address,
1693
+ amount: amount.uint64Value,
1694
+ feeRate: feeRate.uint64Value,
1695
+ skipSync: skipSync.boolValue
1696
+ )
1697
+ return ["psbt": psbt] as NSDictionary
1698
+ } catch {
1699
+ let errorData = [
1700
+ "error": parseErrorMessage(error),
1701
+ "errorCode": getErrorClassName(error)
1702
+ ] as NSDictionary
1703
+ return errorData
1704
+ }
1705
+ }
1706
+
1707
+ @objc(_sendBtcEnd:signedPsbt:skipSync:)
1708
+ public static func _sendBtcEnd(
1709
+ _ walletId: NSNumber,
1710
+ _ signedPsbt: String,
1711
+ _ skipSync: NSNumber
1712
+ ) -> NSDictionary {
1713
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1714
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1715
+ }
1716
+
1717
+ guard let online = session.online else {
1718
+ return ["error": "Wallet is not online"] as NSDictionary
1719
+ }
1720
+
1721
+ do {
1722
+ let txid = try session.wallet.sendBtcEnd(online: online, signedPsbt: signedPsbt, skipSync: skipSync.boolValue)
1723
+ return ["txid": txid] as NSDictionary
1724
+ } catch {
1725
+ let errorData = [
1726
+ "error": parseErrorMessage(error),
1727
+ "errorCode": getErrorClassName(error)
1728
+ ] as NSDictionary
1729
+ return errorData
1730
+ }
1731
+ }
1732
+
1733
+ @objc(_sendEnd:signedPsbt:skipSync:)
1734
+ public static func _sendEnd(
1735
+ _ walletId: NSNumber,
1736
+ _ signedPsbt: String,
1737
+ _ skipSync: NSNumber
1738
+ ) -> NSDictionary {
1739
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1740
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1741
+ }
1742
+
1743
+ guard let online = session.online else {
1744
+ return ["error": "Wallet is not online"] as NSDictionary
1745
+ }
1746
+
1747
+ do {
1748
+ let result = try session.wallet.sendEnd(online: online, signedPsbt: signedPsbt, skipSync: skipSync.boolValue)
1749
+ return operationResultToDict(result)
1750
+ } catch {
1751
+ let errorData = [
1752
+ "error": parseErrorMessage(error),
1753
+ "errorCode": getErrorClassName(error)
1754
+ ] as NSDictionary
1755
+ return errorData
1756
+ }
1757
+ }
1758
+
1759
+ @objc(_signPsbt:unsignedPsbt:)
1760
+ public static func _signPsbt(_ walletId: NSNumber, _ unsignedPsbt: String) -> NSDictionary {
1761
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1762
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1763
+ }
1764
+
1765
+ do {
1766
+ let signedPsbt = try session.wallet.signPsbt(unsignedPsbt: unsignedPsbt)
1767
+ return ["psbt": signedPsbt] as NSDictionary
1768
+ } catch {
1769
+ let errorData = [
1770
+ "error": parseErrorMessage(error),
1771
+ "errorCode": getErrorClassName(error)
1772
+ ] as NSDictionary
1773
+ return errorData
1774
+ }
1775
+ }
1776
+
1777
+ @objc(_sync:)
1778
+ public static func _sync(_ walletId: NSNumber) -> NSDictionary {
1779
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1780
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1781
+ }
1782
+
1783
+ guard let online = session.online else {
1784
+ return ["error": "Wallet is not online"] as NSDictionary
1785
+ }
1786
+
1787
+ do {
1788
+ try session.wallet.sync(online: online)
1789
+ return [:] as NSDictionary
1790
+ } catch {
1791
+ let errorData = [
1792
+ "error": parseErrorMessage(error),
1793
+ "errorCode": getErrorClassName(error)
1794
+ ] as NSDictionary
1795
+ return errorData
1796
+ }
1797
+ }
1798
+
1799
+ @objc(_witnessReceive:assetId:assignment:durationSeconds:transportEndpoints:minConfirmations:)
1800
+ public static func _witnessReceive(
1801
+ _ walletId: NSNumber,
1802
+ _ assetId: String?,
1803
+ _ assignment: NSDictionary,
1804
+ _ durationSeconds: NSNumber?,
1805
+ _ transportEndpoints: NSArray,
1806
+ _ minConfirmations: NSNumber
1807
+ ) -> NSDictionary {
1808
+ guard let session = WalletStore.shared.get(id: walletId.intValue) else {
1809
+ return ["error": "Wallet with id \(walletId) not found"] as NSDictionary
1810
+ }
1811
+
1812
+ do {
1813
+ let assignmentObj = getAssignment(assignment)
1814
+ var endpoints: [String] = []
1815
+ for endpoint in transportEndpoints {
1816
+ if let endpointStr = endpoint as? String {
1817
+ endpoints.append(endpointStr)
1818
+ }
1819
+ }
1820
+
1821
+ let receiveData = try session.wallet.witnessReceive(
1822
+ assetId: assetId,
1823
+ assignment: assignmentObj,
1824
+ durationSeconds: durationSeconds?.uint32Value,
1825
+ transportEndpoints: endpoints,
1826
+ minConfirmations: minConfirmations.uint8Value
1827
+ )
1828
+
1829
+ return receiveDataToDict(receiveData)
1830
+ } catch {
1831
+ let errorData = [
1832
+ "error": parseErrorMessage(error),
1833
+ "errorCode": getErrorClassName(error)
1834
+ ] as NSDictionary
1835
+ return errorData
1836
+ }
1837
+ }
1838
+
1839
+ private static func assignmentToDict(_ assignment: Assignment) -> NSDictionary {
1840
+ var assignmentDict: [String: Any] = [:]
1841
+ switch assignment {
1842
+ case .fungible(let amount):
1843
+ assignmentDict["type"] = "FUNGIBLE"
1844
+ assignmentDict["amount"] = NSNumber(value: amount)
1845
+ case .nonFungible:
1846
+ assignmentDict["type"] = "NON_FUNGIBLE"
1847
+ case .inflationRight(let amount):
1848
+ assignmentDict["type"] = "INFLATION_RIGHT"
1849
+ assignmentDict["amount"] = NSNumber(value: amount)
1850
+ case .replaceRight:
1851
+ assignmentDict["type"] = "REPLACE_RIGHT"
1852
+ case .any:
1853
+ assignmentDict["type"] = "ANY"
1854
+ }
1855
+ return assignmentDict as NSDictionary
1856
+ }
1857
+
1858
+ private static func assetSchemaToString(_ schema: AssetSchema?) -> String? {
1859
+ guard let schema = schema else { return nil }
1860
+ switch schema {
1861
+ case .nia: return "NIA"
1862
+ case .uda: return "UDA"
1863
+ case .cfa: return "CFA"
1864
+ case .ifa: return "IFA"
1865
+ }
1866
+ }
1867
+
1868
+ private static func networkToString(_ network: BitcoinNetwork) -> String {
1869
+ switch network {
1870
+ case .mainnet: return "MAINNET"
1871
+ case .testnet: return "TESTNET"
1872
+ case .testnet4: return "TESTNET4"
1873
+ case .regtest: return "REGTEST"
1874
+ case .signet: return "SIGNET"
1875
+ }
1876
+ }
1877
+
1878
+ @objc(_decodeInvoice:)
1879
+ public static func _decodeInvoice(_ invoice: String) -> NSDictionary {
1880
+ do {
1881
+ let invoiceData = try Invoice(invoiceString: invoice).invoiceData()
1882
+
1883
+ var dict: [String: Any] = [
1884
+ "invoice": invoice,
1885
+ "recipientId": invoiceData.recipientId,
1886
+ "assignment": assignmentToDict(invoiceData.assignment),
1887
+ "network": networkToString(invoiceData.network),
1888
+ "transportEndpoints": invoiceData.transportEndpoints
1889
+ ]
1890
+
1891
+ if let assetSchema = assetSchemaToString(invoiceData.assetSchema) {
1892
+ dict["assetSchema"] = assetSchema
1893
+ }
1894
+
1895
+ if let assetId = invoiceData.assetId {
1896
+ dict["assetId"] = assetId
1897
+ }
1898
+
1899
+ if let assignmentName = invoiceData.assignmentName {
1900
+ dict["assignmentName"] = assignmentName
1901
+ }
1902
+
1903
+ if let expirationTimestamp = invoiceData.expirationTimestamp {
1904
+ dict["expirationTimestamp"] = NSNumber(value: expirationTimestamp)
1905
+ }
1906
+
1907
+ return dict as NSDictionary
1908
+ } catch {
1909
+ let errorData = [
1910
+ "error": parseErrorMessage(error),
1911
+ "errorCode": getErrorClassName(error)
1912
+ ] as NSDictionary
1913
+ return errorData
1914
+ }
1915
+ }
1916
+ }