1
-#include <stdint.h>
2
-#include "cstdlib"
3
-#include <chrono>
4
-#include <functional>
5
-#include <iostream>
6
-#include <fstream>
7
-#include <unistd.h>
8
-#include <mutex>
9
-#include <list>
10
-#include "thread"
11
-#include "CwWalletListener.h"
12
-#if __APPLE__
13
-// Fix for randomx on ios
14
-void __clear_cache(void* start, void* end) { }
15
-#include "../External/ios/include/wallet2_api.h"
16
-#else
17
-#include "../External/android/include/wallet2_api.h"
18
-#endif
19
-
20
-using namespace std::chrono_literals;
21
-#ifdef __cplusplus
22
-extern "C"
23
-{
24
-#endif
25
- const uint64_t MONERO_BLOCK_SIZE = 1000;
26
-
27
- struct Utf8Box
28
- {
29
- char *value;
30
-
31
- Utf8Box(char *_value)
32
- {
33
- value = _value;
34
- }
35
- };
36
-
37
- struct SubaddressRow
38
- {
39
- uint64_t id;
40
- char *address;
41
- char *label;
42
-
43
- SubaddressRow(std::size_t _id, char *_address, char *_label)
44
- {
45
- id = static_cast<uint64_t>(_id);
46
- address = _address;
47
- label = _label;
48
- }
49
- };
50
-
51
- struct AccountRow
52
- {
53
- uint64_t id;
54
- char *label;
55
-
56
- AccountRow(std::size_t _id, char *_label)
57
- {
58
- id = static_cast<uint64_t>(_id);
59
- label = _label;
60
- }
61
- };
62
-
63
- struct MoneroWalletListener : Monero::WalletListener
64
- {
65
- uint64_t m_height;
66
- bool m_need_to_refresh;
67
- bool m_new_transaction;
68
-
69
- MoneroWalletListener()
70
- {
71
- m_height = 0;
72
- m_need_to_refresh = false;
73
- m_new_transaction = false;
74
- }
75
-
76
- void moneySpent(const std::string &txId, uint64_t amount)
77
- {
78
- m_new_transaction = true;
79
- }
80
-
81
- void moneyReceived(const std::string &txId, uint64_t amount)
82
- {
83
- m_new_transaction = true;
84
- }
85
-
86
- void unconfirmedMoneyReceived(const std::string &txId, uint64_t amount)
87
- {
88
- m_new_transaction = true;
89
- }
90
-
91
- void newBlock(uint64_t height)
92
- {
93
- m_height = height;
94
- }
95
-
96
- void updated()
97
- {
98
- m_new_transaction = true;
99
- }
100
-
101
- void refreshed()
102
- {
103
- m_need_to_refresh = true;
104
- }
105
-
106
- void resetNeedToRefresh()
107
- {
108
- m_need_to_refresh = false;
109
- }
110
-
111
- bool isNeedToRefresh()
112
- {
113
- return m_need_to_refresh;
114
- }
115
-
116
- bool isNewTransactionExist()
117
- {
118
- return m_new_transaction;
119
- }
120
-
121
- void resetIsNewTransactionExist()
122
- {
123
- m_new_transaction = false;
124
- }
125
-
126
- uint64_t height()
127
- {
128
- return m_height;
129
- }
130
- };
131
-
132
- struct TransactionInfoRow
133
- {
134
- uint64_t amount;
135
- uint64_t fee;
136
- uint64_t blockHeight;
137
- uint64_t confirmations;
138
- uint32_t subaddrAccount;
139
- int8_t direction;
140
- int8_t isPending;
141
- uint32_t subaddrIndex;
142
-
143
- char *hash;
144
- char *paymentId;
145
-
146
- int64_t datetime;
147
-
148
- TransactionInfoRow(Monero::TransactionInfo *transaction)
149
- {
150
- amount = transaction->amount();
151
- fee = transaction->fee();
152
- blockHeight = transaction->blockHeight();
153
- subaddrAccount = transaction->subaddrAccount();
154
- std::set<uint32_t>::iterator it = transaction->subaddrIndex().begin();
155
- subaddrIndex = *it;
156
- confirmations = transaction->confirmations();
157
- datetime = static_cast<int64_t>(transaction->timestamp());
158
- direction = transaction->direction();
159
- isPending = static_cast<int8_t>(transaction->isPending());
160
- std::string *hash_str = new std::string(transaction->hash());
161
- hash = strdup(hash_str->c_str());
162
- paymentId = strdup(transaction->paymentId().c_str());
163
- }
164
- };
165
-
166
- struct PendingTransactionRaw
167
- {
168
- uint64_t amount;
169
- uint64_t fee;
170
- char *hash;
171
- char *hex;
172
- char *txKey;
173
- Monero::PendingTransaction *transaction;
174
-
175
- PendingTransactionRaw(Monero::PendingTransaction *_transaction)
176
- {
177
- transaction = _transaction;
178
- amount = _transaction->amount();
179
- fee = _transaction->fee();
180
- hash = strdup(_transaction->txid()[0].c_str());
181
- hex = strdup(_transaction->hex()[0].c_str());
182
- txKey = strdup(_transaction->txKey()[0].c_str());
183
- }
184
- };
185
-
186
- struct CoinsInfoRow
187
- {
188
- uint64_t blockHeight;
189
- char *hash;
190
- uint64_t internalOutputIndex;
191
- uint64_t globalOutputIndex;
192
- bool spent;
193
- bool frozen;
194
- uint64_t spentHeight;
195
- uint64_t amount;
196
- bool rct;
197
- bool keyImageKnown;
198
- uint64_t pkIndex;
199
- uint32_t subaddrIndex;
200
- uint32_t subaddrAccount;
201
- char *address;
202
- char *addressLabel;
203
- char *keyImage;
204
- uint64_t unlockTime;
205
- bool unlocked;
206
- char *pubKey;
207
- bool coinbase;
208
- char *description;
209
-
210
- CoinsInfoRow(Monero::CoinsInfo *coinsInfo)
211
- {
212
- blockHeight = coinsInfo->blockHeight();
213
- std::string *hash_str = new std::string(coinsInfo->hash());
214
- hash = strdup(hash_str->c_str());
215
- internalOutputIndex = coinsInfo->internalOutputIndex();
216
- globalOutputIndex = coinsInfo->globalOutputIndex();
217
- spent = coinsInfo->spent();
218
- frozen = coinsInfo->frozen();
219
- spentHeight = coinsInfo->spentHeight();
220
- amount = coinsInfo->amount();
221
- rct = coinsInfo->rct();
222
- keyImageKnown = coinsInfo->keyImageKnown();
223
- pkIndex = coinsInfo->pkIndex();
224
- subaddrIndex = coinsInfo->subaddrIndex();
225
- subaddrAccount = coinsInfo->subaddrAccount();
226
- address = strdup(coinsInfo->address().c_str()) ;
227
- addressLabel = strdup(coinsInfo->addressLabel().c_str());
228
- keyImage = strdup(coinsInfo->keyImage().c_str());
229
- unlockTime = coinsInfo->unlockTime();
230
- unlocked = coinsInfo->unlocked();
231
- pubKey = strdup(coinsInfo->pubKey().c_str());
232
- coinbase = coinsInfo->coinbase();
233
- description = strdup(coinsInfo->description().c_str());
234
- }
235
-
236
- void setUnlocked(bool unlocked);
237
- };
238
-
239
- Monero::Coins *m_coins;
240
-
241
- Monero::Wallet *m_wallet;
242
- Monero::TransactionHistory *m_transaction_history;
243
- MoneroWalletListener *m_listener;
244
- Monero::Subaddress *m_subaddress;
245
- Monero::SubaddressAccount *m_account;
246
- uint64_t m_last_known_wallet_height;
247
- uint64_t m_cached_syncing_blockchain_height = 0;
248
- std::list<Monero::CoinsInfo*> m_coins_info;
249
- std::mutex store_lock;
250
- bool is_storing = false;
251
-
252
- void change_current_wallet(Monero::Wallet *wallet)
253
- {
254
- m_wallet = wallet;
255
- m_listener = nullptr;
256
-
257
-
258
- if (wallet != nullptr)
259
- {
260
- m_transaction_history = wallet->history();
261
- }
262
- else
263
- {
264
- m_transaction_history = nullptr;
265
- }
266
-
267
- if (wallet != nullptr)
268
- {
269
- m_account = wallet->subaddressAccount();
270
- }
271
- else
272
- {
273
- m_account = nullptr;
274
- }
275
-
276
- if (wallet != nullptr)
277
- {
278
- m_subaddress = wallet->subaddress();
279
- }
280
- else
281
- {
282
- m_subaddress = nullptr;
283
- }
284
-
285
- m_coins_info = std::list<Monero::CoinsInfo*>();
286
-
287
- if (wallet != nullptr)
288
- {
289
- m_coins = wallet->coins();
290
- }
291
- else
292
- {
293
- m_coins = nullptr;
294
- }
295
- }
296
-
297
- Monero::Wallet *get_current_wallet()
298
- {
299
- return m_wallet;
300
- }
301
-
302
- bool create_wallet(char *path, char *password, char *language, int32_t networkType, char *error)
303
- {
304
- Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
305
- Monero::WalletManager *walletManager = Monero::WalletManagerFactory::getWalletManager();
306
- Monero::Wallet *wallet = walletManager->createWallet(path, password, language, _networkType);
307
-
308
- int status;
309
- std::string errorString;
310
-
311
- wallet->statusWithErrorString(status, errorString);
312
-
313
- if (wallet->status() != Monero::Wallet::Status_Ok)
314
- {
315
- error = strdup(wallet->errorString().c_str());
316
- return false;
317
- }
318
-
319
- change_current_wallet(wallet);
320
-
321
- return true;
322
- }
323
-
324
- bool restore_wallet_from_seed(char *path, char *password, char *seed, int32_t networkType, uint64_t restoreHeight, char *error)
325
- {
326
- Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
327
- Monero::Wallet *wallet = Monero::WalletManagerFactory::getWalletManager()->recoveryWallet(
328
- std::string(path),
329
- std::string(password),
330
- std::string(seed),
331
- _networkType,
332
- (uint64_t)restoreHeight);
333
-
334
- int status;
335
- std::string errorString;
336
-
337
- wallet->statusWithErrorString(status, errorString);
338
-
339
- if (status != Monero::Wallet::Status_Ok || !errorString.empty())
340
- {
341
- error = strdup(errorString.c_str());
342
- return false;
343
- }
344
-
345
- change_current_wallet(wallet);
346
- return true;
347
- }
348
-
349
- bool restore_wallet_from_keys(char *path, char *password, char *language, char *address, char *viewKey, char *spendKey, int32_t networkType, uint64_t restoreHeight, char *error)
350
- {
351
- Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
352
- Monero::Wallet *wallet = Monero::WalletManagerFactory::getWalletManager()->createWalletFromKeys(
353
- std::string(path),
354
- std::string(password),
355
- std::string(language),
356
- _networkType,
357
- (uint64_t)restoreHeight,
358
- std::string(address),
359
- std::string(viewKey),
360
- std::string(spendKey));
361
-
362
- int status;
363
- std::string errorString;
364
-
365
- wallet->statusWithErrorString(status, errorString);
366
-
367
- if (status != Monero::Wallet::Status_Ok || !errorString.empty())
368
- {
369
- error = strdup(errorString.c_str());
370
- return false;
371
- }
372
-
373
- change_current_wallet(wallet);
374
- return true;
375
- }
376
-
377
- bool restore_wallet_from_spend_key(char *path, char *password, char *seed, char *language, char *spendKey, int32_t networkType, uint64_t restoreHeight, char *error)
378
- {
379
- Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
380
- Monero::Wallet *wallet = Monero::WalletManagerFactory::getWalletManager()->createDeterministicWalletFromSpendKey(
381
- std::string(path),
382
- std::string(password),
383
- std::string(language),
384
- _networkType,
385
- (uint64_t)restoreHeight,
386
- std::string(spendKey));
387
-
388
- // Cache Raw to support Polyseed
389
- wallet->setCacheAttribute("cakewallet.seed", std::string(seed));
390
-
391
- int status;
392
- std::string errorString;
393
-
394
- wallet->statusWithErrorString(status, errorString);
395
-
396
- if (status != Monero::Wallet::Status_Ok || !errorString.empty())
397
- {
398
- error = strdup(errorString.c_str());
399
- return false;
400
- }
401
-
402
- change_current_wallet(wallet);
403
- return true;
404
- }
405
-
406
- bool load_wallet(char *path, char *password, int32_t nettype)
407
- {
408
- nice(19);
409
- Monero::NetworkType networkType = static_cast<Monero::NetworkType>(nettype);
410
- Monero::WalletManager *walletManager = Monero::WalletManagerFactory::getWalletManager();
411
- Monero::Wallet *wallet = walletManager->openWallet(std::string(path), std::string(password), networkType);
412
- int status;
413
- std::string errorString;
414
-
415
- wallet->statusWithErrorString(status, errorString);
416
- change_current_wallet(wallet);
417
-
418
- return !(status != Monero::Wallet::Status_Ok || !errorString.empty());
419
- }
420
-
421
- char *error_string() {
422
- return strdup(get_current_wallet()->errorString().c_str());
423
- }
424
-
425
-
426
- bool is_wallet_exist(char *path)
427
- {
428
- return Monero::WalletManagerFactory::getWalletManager()->walletExists(std::string(path));
429
- }
430
-
431
- void close_current_wallet()
432
- {
433
- Monero::WalletManagerFactory::getWalletManager()->closeWallet(get_current_wallet());
434
- change_current_wallet(nullptr);
435
- }
436
-
437
- char *get_filename()
438
- {
439
- return strdup(get_current_wallet()->filename().c_str());
440
- }
441
-
442
- char *secret_view_key()
443
- {
444
- return strdup(get_current_wallet()->secretViewKey().c_str());
445
- }
446
-
447
- char *public_view_key()
448
- {
449
- return strdup(get_current_wallet()->publicViewKey().c_str());
450
- }
451
-
452
- char *secret_spend_key()
453
- {
454
- return strdup(get_current_wallet()->secretSpendKey().c_str());
455
- }
456
-
457
- char *public_spend_key()
458
- {
459
- return strdup(get_current_wallet()->publicSpendKey().c_str());
460
- }
461
-
462
- char *get_address(uint32_t account_index, uint32_t address_index)
463
- {
464
- return strdup(get_current_wallet()->address(account_index, address_index).c_str());
465
- }
466
-
467
- char *get_cache_attribute(char *name)
468
- {
469
- return strdup(get_current_wallet()->getCacheAttribute(std::string(name)).c_str());
470
- }
471
-
472
- bool set_cache_attribute(char *name, char *value)
473
- {
474
- get_current_wallet()->setCacheAttribute(std::string(name), std::string(value));
475
- return true;
476
- }
477
-
478
- const char *seed()
479
- {
480
- std::string _rawSeed = get_current_wallet()->getCacheAttribute("cakewallet.seed");
481
- if (!_rawSeed.empty())
482
- {
483
- return strdup(_rawSeed.c_str());
484
- }
485
- return strdup(get_current_wallet()->seed().c_str());
486
- }
487
-
488
- uint64_t get_full_balance(uint32_t account_index)
489
- {
490
- return get_current_wallet()->balance(account_index);
491
- }
492
-
493
- uint64_t get_unlocked_balance(uint32_t account_index)
494
- {
495
- return get_current_wallet()->unlockedBalance(account_index);
496
- }
497
-
498
- uint64_t get_current_height()
499
- {
500
- return get_current_wallet()->blockChainHeight();
501
- }
502
-
503
- uint64_t get_node_height()
504
- {
505
- return get_current_wallet()->daemonBlockChainHeight();
506
- }
507
-
508
- bool connect_to_node(char *error)
509
- {
510
- nice(19);
511
- bool is_connected = get_current_wallet()->connectToDaemon();
512
-
513
- if (!is_connected)
514
- {
515
- error = strdup(get_current_wallet()->errorString().c_str());
516
- }
517
-
518
- return is_connected;
519
- }
520
-
521
- bool setup_node(char *address, char *login, char *password, bool use_ssl, bool is_light_wallet, char *socksProxyAddress, char *error)
522
- {
523
- nice(19);
524
- Monero::Wallet *wallet = get_current_wallet();
525
-
526
- std::string _login = "";
527
- std::string _password = "";
528
- std::string _socksProxyAddress = "";
529
-
530
- if (login != nullptr)
531
- {
532
- _login = std::string(login);
533
- }
534
-
535
- if (password != nullptr)
536
- {
537
- _password = std::string(password);
538
- }
539
-
540
- if (socksProxyAddress != nullptr)
541
- {
542
- _socksProxyAddress = std::string(socksProxyAddress);
543
- }
544
-
545
- bool inited = wallet->init(std::string(address), 0, _login, _password, use_ssl, is_light_wallet, _socksProxyAddress);
546
-
547
- if (!inited)
548
- {
549
- error = strdup(wallet->errorString().c_str());
550
- } else if (!wallet->connectToDaemon()) {
551
- error = strdup(wallet->errorString().c_str());
552
- }
553
-
554
- return inited;
555
- }
556
-
557
- bool is_connected()
558
- {
559
- return get_current_wallet()->connected();
560
- }
561
-
562
- void start_refresh()
563
- {
564
- get_current_wallet()->refreshAsync();
565
- get_current_wallet()->startRefresh();
566
- }
567
-
568
- void set_refresh_from_block_height(uint64_t height)
569
- {
570
- get_current_wallet()->setRefreshFromBlockHeight(height);
571
- }
572
-
573
- void set_recovering_from_seed(bool is_recovery)
574
- {
575
- get_current_wallet()->setRecoveringFromSeed(is_recovery);
576
- }
577
-
578
- void store(char *path)
579
- {
580
- store_lock.lock();
581
- if (is_storing) {
582
- return;
583
- }
584
-
585
- is_storing = true;
586
- get_current_wallet()->store(std::string(path));
587
- is_storing = false;
588
- store_lock.unlock();
589
- }
590
-
591
- bool set_password(char *password, Utf8Box &error) {
592
- bool is_changed = get_current_wallet()->setPassword(std::string(password));
593
-
594
- if (!is_changed) {
595
- error = Utf8Box(strdup(get_current_wallet()->errorString().c_str()));
596
- }
597
-
598
- return is_changed;
599
- }
600
-
601
- bool transaction_create(char *address, char *payment_id, char *amount,
602
- uint8_t priority_raw, uint32_t subaddr_account,
603
- char **preferred_inputs, uint32_t preferred_inputs_size,
604
- Utf8Box &error, PendingTransactionRaw &pendingTransaction)
605
- {
606
- nice(19);
607
-
608
- std::set<std::string> _preferred_inputs;
609
-
610
- for (int i = 0; i < preferred_inputs_size; i++) {
611
- _preferred_inputs.insert(std::string(*preferred_inputs));
612
- preferred_inputs++;
613
- }
614
-
615
- auto priority = static_cast<Monero::PendingTransaction::Priority>(priority_raw);
616
- std::string _payment_id;
617
- Monero::PendingTransaction *transaction;
618
-
619
- if (payment_id != nullptr)
620
- {
621
- _payment_id = std::string(payment_id);
622
- }
623
-
624
- if (amount != nullptr)
625
- {
626
- uint64_t _amount = Monero::Wallet::amountFromString(std::string(amount));
627
- transaction = m_wallet->createTransaction(std::string(address), _payment_id, _amount, m_wallet->defaultMixin(), priority, subaddr_account, {}, _preferred_inputs);
628
- }
629
- else
630
- {
631
- transaction = m_wallet->createTransaction(std::string(address), _payment_id, Monero::optional<uint64_t>(), m_wallet->defaultMixin(), priority, subaddr_account, {}, _preferred_inputs);
632
- }
633
-
634
- int status = transaction->status();
635
-
636
- if (status == Monero::PendingTransaction::Status::Status_Error || status == Monero::PendingTransaction::Status::Status_Critical)
637
- {
638
- error = Utf8Box(strdup(transaction->errorString().c_str()));
639
- return false;
640
- }
641
-
642
- if (m_listener != nullptr) {
643
- m_listener->m_new_transaction = true;
644
- }
645
-
646
- pendingTransaction = PendingTransactionRaw(transaction);
647
- return true;
648
- }
649
-
650
- bool transaction_create_mult_dest(char **addresses, char *payment_id, char **amounts, uint32_t size,
651
- uint8_t priority_raw, uint32_t subaddr_account,
652
- char **preferred_inputs, uint32_t preferred_inputs_size,
653
- Utf8Box &error, PendingTransactionRaw &pendingTransaction)
654
- {
655
- nice(19);
656
-
657
- std::vector<std::string> _addresses;
658
- std::vector<uint64_t> _amounts;
659
-
660
- for (int i = 0; i < size; i++) {
661
- _addresses.push_back(std::string(*addresses));
662
- _amounts.push_back(Monero::Wallet::amountFromString(std::string(*amounts)));
663
- addresses++;
664
- amounts++;
665
- }
666
-
667
- std::set<std::string> _preferred_inputs;
668
-
669
- for (int i = 0; i < preferred_inputs_size; i++) {
670
- _preferred_inputs.insert(std::string(*preferred_inputs));
671
- preferred_inputs++;
672
- }
673
-
674
- auto priority = static_cast<Monero::PendingTransaction::Priority>(priority_raw);
675
- std::string _payment_id;
676
- Monero::PendingTransaction *transaction;
677
-
678
- if (payment_id != nullptr)
679
- {
680
- _payment_id = std::string(payment_id);
681
- }
682
-
683
- transaction = m_wallet->createTransactionMultDest(_addresses, _payment_id, _amounts, m_wallet->defaultMixin(), priority, subaddr_account);
684
-
685
- int status = transaction->status();
686
-
687
- if (status == Monero::PendingTransaction::Status::Status_Error || status == Monero::PendingTransaction::Status::Status_Critical)
688
- {
689
- error = Utf8Box(strdup(transaction->errorString().c_str()));
690
- return false;
691
- }
692
-
693
- if (m_listener != nullptr) {
694
- m_listener->m_new_transaction = true;
695
- }
696
-
697
- pendingTransaction = PendingTransactionRaw(transaction);
698
- return true;
699
- }
700
-
701
- bool transaction_commit(PendingTransactionRaw *transaction, Utf8Box &error)
702
- {
703
- bool committed = transaction->transaction->commit();
704
-
705
- if (!committed)
706
- {
707
- error = Utf8Box(strdup(transaction->transaction->errorString().c_str()));
708
- } else if (m_listener != nullptr) {
709
- m_listener->m_new_transaction = true;
710
- }
711
-
712
- return committed;
713
- }
714
-
715
- uint64_t get_node_height_or_update(uint64_t base_eight)
716
- {
717
- if (m_cached_syncing_blockchain_height < base_eight) {
718
- m_cached_syncing_blockchain_height = base_eight;
719
- }
720
-
721
- return m_cached_syncing_blockchain_height;
722
- }
723
-
724
- uint64_t get_syncing_height()
725
- {
726
- if (m_listener == nullptr) {
727
- return 0;
728
- }
729
-
730
- uint64_t height = m_listener->height();
731
-
732
- if (height <= 1) {
733
- return 0;
734
- }
735
-
736
- if (height != m_last_known_wallet_height)
737
- {
738
- m_last_known_wallet_height = height;
739
- }
740
-
741
- return height;
742
- }
743
-
744
- uint64_t is_needed_to_refresh()
745
- {
746
- if (m_listener == nullptr) {
747
- return false;
748
- }
749
-
750
- bool should_refresh = m_listener->isNeedToRefresh();
751
-
752
- if (should_refresh) {
753
- m_listener->resetNeedToRefresh();
754
- }
755
-
756
- return should_refresh;
757
- }
758
-
759
- uint8_t is_new_transaction_exist()
760
- {
761
- if (m_listener == nullptr) {
762
- return false;
763
- }
764
-
765
- bool is_new_transaction_exist = m_listener->isNewTransactionExist();
766
-
767
- if (is_new_transaction_exist)
768
- {
769
- m_listener->resetIsNewTransactionExist();
770
- }
771
-
772
- return is_new_transaction_exist;
773
- }
774
-
775
- void set_listener()
776
- {
777
- m_last_known_wallet_height = 0;
778
-
779
- if (m_listener != nullptr)
780
- {
781
- free(m_listener);
782
- }
783
-
784
- m_listener = new MoneroWalletListener();
785
- get_current_wallet()->setListener(m_listener);
786
- }
787
-
788
- int64_t *subaddrress_get_all()
789
- {
790
- std::vector<Monero::SubaddressRow *> _subaddresses = m_subaddress->getAll();
791
- size_t size = _subaddresses.size();
792
- int64_t *subaddresses = (int64_t *)malloc(size * sizeof(int64_t));
793
-
794
- for (int i = 0; i < size; i++)
795
- {
796
- Monero::SubaddressRow *row = _subaddresses[i];
797
- SubaddressRow *_row = new SubaddressRow(row->getRowId(), strdup(row->getAddress().c_str()), strdup(row->getLabel().c_str()));
798
- subaddresses[i] = reinterpret_cast<int64_t>(_row);
799
- }
800
-
801
- return subaddresses;
802
- }
803
-
804
- int32_t subaddrress_size()
805
- {
806
- std::vector<Monero::SubaddressRow *> _subaddresses = m_subaddress->getAll();
807
- return _subaddresses.size();
808
- }
809
-
810
- void subaddress_add_row(uint32_t accountIndex, char *label)
811
- {
812
- m_subaddress->addRow(accountIndex, std::string(label));
813
- }
814
-
815
- void subaddress_set_label(uint32_t accountIndex, uint32_t addressIndex, char *label)
816
- {
817
- m_subaddress->setLabel(accountIndex, addressIndex, std::string(label));
818
- }
819
-
820
- void subaddress_refresh(uint32_t accountIndex)
821
- {
822
- m_subaddress->refresh(accountIndex);
823
- }
824
-
825
- int32_t account_size()
826
- {
827
- std::vector<Monero::SubaddressAccountRow *> _accocunts = m_account->getAll();
828
- return _accocunts.size();
829
- }
830
-
831
- int64_t *account_get_all()
832
- {
833
- std::vector<Monero::SubaddressAccountRow *> _accocunts = m_account->getAll();
834
- size_t size = _accocunts.size();
835
- int64_t *accocunts = (int64_t *)malloc(size * sizeof(int64_t));
836
-
837
- for (int i = 0; i < size; i++)
838
- {
839
- Monero::SubaddressAccountRow *row = _accocunts[i];
840
- AccountRow *_row = new AccountRow(row->getRowId(), strdup(row->getLabel().c_str()));
841
- accocunts[i] = reinterpret_cast<int64_t>(_row);
842
- }
843
-
844
- return accocunts;
845
- }
846
-
847
- void account_add_row(char *label)
848
- {
849
- m_account->addRow(std::string(label));
850
- }
851
-
852
- void account_set_label_row(uint32_t account_index, char *label)
853
- {
854
- m_account->setLabel(account_index, label);
855
- }
856
-
857
- void account_refresh()
858
- {
859
- m_account->refresh();
860
- }
861
-
862
- int64_t *transactions_get_all()
863
- {
864
- std::vector<Monero::TransactionInfo *> transactions = m_transaction_history->getAll();
865
- size_t size = transactions.size();
866
- int64_t *transactionAddresses = (int64_t *)malloc(size * sizeof(int64_t));
867
-
868
- for (int i = 0; i < size; i++)
869
- {
870
- Monero::TransactionInfo *row = transactions[i];
871
- TransactionInfoRow *tx = new TransactionInfoRow(row);
872
- transactionAddresses[i] = reinterpret_cast<int64_t>(tx);
873
- }
874
-
875
- return transactionAddresses;
876
- }
877
-
878
- void transactions_refresh()
879
- {
880
- m_transaction_history->refresh();
881
- }
882
-
883
- int64_t transactions_count()
884
- {
885
- return m_transaction_history->count();
886
- }
887
-
888
- TransactionInfoRow* get_transaction(char * txId)
889
- {
890
- Monero::TransactionInfo *row = m_transaction_history->transaction(std::string(txId));
891
- return new TransactionInfoRow(row);
892
- }
893
-
894
- int LedgerExchange(
895
- unsigned char *command,
896
- unsigned int cmd_len,
897
- unsigned char *response,
898
- unsigned int max_resp_len)
899
- {
900
- return -1;
901
- }
902
-
903
- int LedgerFind(char *buffer, size_t len)
904
- {
905
- return -1;
906
- }
907
-
908
- void on_startup()
909
- {
910
- Monero::Utils::onStartup();
911
- Monero::WalletManagerFactory::setLogLevel(0);
912
- }
913
-
914
- void rescan_blockchain()
915
- {
916
- m_wallet->rescanBlockchainAsync();
917
- }
918
-
919
- char * get_tx_key(char * txId)
920
- {
921
- return strdup(m_wallet->getTxKey(std::string(txId)).c_str());
922
- }
923
-
924
- char *get_subaddress_label(uint32_t accountIndex, uint32_t addressIndex)
925
- {
926
- return strdup(get_current_wallet()->getSubaddressLabel(accountIndex, addressIndex).c_str());
927
- }
928
-
929
- void set_trusted_daemon(bool arg)
930
- {
931
- m_wallet->setTrustedDaemon(arg);
932
- }
933
-
934
- bool trusted_daemon()
935
- {
936
- return m_wallet->trustedDaemon();
937
- }
938
-
939
- // Coin Control //
940
-
941
- CoinsInfoRow* coin(int index)
942
- {
943
- if (index >= 0 && index < m_coins_info.size()) {
944
- std::list<Monero::CoinsInfo*>::iterator it = m_coins_info.begin();
945
- std::advance(it, index);
946
- Monero::CoinsInfo* element = *it;
947
- std::cout << "Element at index " << index << ": " << element << std::endl;
948
- return new CoinsInfoRow(element);
949
- } else {
950
- std::cout << "Invalid index." << std::endl;
951
- return nullptr; // Return a default value (nullptr) for invalid index
952
- }
953
- }
954
-
955
- void refresh_coins(uint32_t accountIndex)
956
- {
957
- m_coins_info.clear();
958
-
959
- m_coins->refresh();
960
- for (const auto i : m_coins->getAll()) {
961
- if (i->subaddrAccount() == accountIndex && !(i->spent())) {
962
- m_coins_info.push_back(i);
963
- }
964
- }
965
- }
966
-
967
- uint64_t coins_count()
968
- {
969
- return m_coins_info.size();
970
- }
971
-
972
- CoinsInfoRow** coins_from_account(uint32_t accountIndex)
973
- {
974
- std::vector<CoinsInfoRow*> matchingCoins;
975
-
976
- for (int i = 0; i < coins_count(); i++) {
977
- CoinsInfoRow* coinInfo = coin(i);
978
- if (coinInfo->subaddrAccount == accountIndex) {
979
- matchingCoins.push_back(coinInfo);
980
- }
981
- }
982
-
983
- CoinsInfoRow** result = new CoinsInfoRow*[matchingCoins.size()];
984
- std::copy(matchingCoins.begin(), matchingCoins.end(), result);
985
- return result;
986
- }
987
-
988
- CoinsInfoRow** coins_from_txid(const char* txid, size_t* count)
989
- {
990
- std::vector<CoinsInfoRow*> matchingCoins;
991
-
992
- for (int i = 0; i < coins_count(); i++) {
993
- CoinsInfoRow* coinInfo = coin(i);
994
- if (std::string(coinInfo->hash) == txid) {
995
- matchingCoins.push_back(coinInfo);
996
- }
997
- }
998
-
999
- *count = matchingCoins.size();
1000
- CoinsInfoRow** result = new CoinsInfoRow*[*count];
1001
- std::copy(matchingCoins.begin(), matchingCoins.end(), result);
1002
- return result;
1003
- }
1004
-
1005
- CoinsInfoRow** coins_from_key_image(const char** keyimages, size_t keyimageCount, size_t* count)
1006
- {
1007
- std::vector<CoinsInfoRow*> matchingCoins;
1008
-
1009
- for (int i = 0; i < coins_count(); i++) {
1010
- CoinsInfoRow* coinsInfoRow = coin(i);
1011
- for (size_t j = 0; j < keyimageCount; j++) {
1012
- if (coinsInfoRow->keyImageKnown && std::string(coinsInfoRow->keyImage) == keyimages[j]) {
1013
- matchingCoins.push_back(coinsInfoRow);
1014
- break;
1015
- }
1016
- }
1017
- }
1018
-
1019
- *count = matchingCoins.size();
1020
- CoinsInfoRow** result = new CoinsInfoRow*[*count];
1021
- std::copy(matchingCoins.begin(), matchingCoins.end(), result);
1022
- return result;
1023
- }
1024
-
1025
- void freeze_coin(int index)
1026
- {
1027
- m_coins->setFrozen(index);
1028
- }
1029
-
1030
- void thaw_coin(int index)
1031
- {
1032
- m_coins->thaw(index);
1033
- }
1034
-
1035
- // Sign Messages //
1036
-
1037
- char *sign_message(char *message, char *address = "")
1038
- {
1039
- return strdup(get_current_wallet()->signMessage(std::string(message), std::string(address)).c_str());
1040
- }
1041
-
1042
-#ifdef __cplusplus
1043
-}
1044
-#endif