monero-native 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,36 @@
1
+ # monero-native
2
+
3
+ ## Unreleased
4
+
5
+ ## 0.5.0 (2026-08-14)
6
+
7
+ - changed: (Breaking) `broadcastTransaction` returns a `BroadcastResult` with the transaction secret key (`txKey`) instead of the string `"success"`. The key is the sender's only proof of payment and the broadcast is the send path's only chance to hand it to the caller, since it cannot be derived from the seed. A key the wallet cannot report never fails an already-broadcast payment: the result simply carries no `txKey`.
8
+
9
+ ## 0.4.2 (2026-07-17)
10
+
11
+ - changed: Bump vtnerd/lwsf to da8e2617958312f10fe4406808c2a951c5cf0a09
12
+
13
+ ## 0.4.1 (2026-07-14)
14
+
15
+ - fixed: iOS no longer crashes with EXC_BAD_INSTRUCTION (SIGILL) in `CRYPTO_atomic_load` on A11 and older devices (iPhone X, 8, 7, 6s) the moment a wallet opens. OpenSSL's `ios64-xcrun` build target stopped passing a deployment-target flag, so clang targeted the SDK version and raised the CPU baseline to apple-a12, emitting ARMv8.3 `ldapr` (and ARMv8.1 LSE) instructions those chips lack; the first SSL client construction (`getWalletManager` → `boost::asio::ssl::context` → `ERR_clear_error`) executed one and crash-looped the app on login. The OpenSSL build now pins `-miphoneos-version-min`/`-mios-simulator-version-min` to the platform minimum, restoring the ARMv8.0 baseline (`ldar`).
16
+
17
+ ## 0.4.0 (2026-07-06)
18
+
19
+ - added: `getWalletStatus` reports a `refreshed` flag, true once the wallet has completed its first server refresh (and so knows its real balance and spendable outputs). LWS wallets report seed heights that look synced before then, so treat a wallet as synced only when `refreshed` is true.
20
+ - fixed: LWS wallets can spend and receive over the Nym mixnet. The lwsf RPC timeout of 5 seconds was too short for a mixnet round-trip, so single-shot spend and receive calls failed; the Nym path now uses a 120-second budget.
21
+
22
+ ## 0.3.0 (2026-07-03)
23
+
24
+ - added: `getPendingTransactions`, a paged view of the not-yet-mined transactions. `getAllTransactions` sorts pending entries behind all confirmed ones, so a cursor-based scan of confirmed history never reaches them; this exposes the pending set directly.
25
+ - fixed: LWS wallets sync again. The 0.2.0 https change passed `use_ssl=true` to `wallet->init` for https daemons; wallet2 (monerod) ignores that flag, but lwsf honors it and switches from tolerant `ssl_support_autodetect` to `ssl_support_enabled`, whose certificate verification always fails on iOS/Android (no OpenSSL system CA store in the app sandbox). Every LWS connection was silently dropped at the TLS handshake, so LWS wallets polled forever at height 0 with no transactions or balance. Revert to `use_ssl=false` (TLS still autodetected from the `https://` scheme); the Nym scheme fix is unaffected since it derives https from the port inside NymHttpClient.
26
+ - fixed: Monero Full Node (monerod) sends no longer fail with "Failed to load transaction from file". `createTransaction` now retains the signed transaction natively and `broadcastTransaction` commits it directly, instead of saving it to a file and reloading it: on the full-node (wallet2) backend `save_tx` writes an unsigned tx set while `submitTransaction`'s `load_tx` requires a signed one, so the file round-trip always failed. Retained transactions are capped at 50 per wallet (oldest disposed first) and cleared when the wallet closes. Method signatures are unchanged, but the semantics narrow: `signedTxHex` is now an opaque token (the txid) identifying the retained transaction rather than serialized bytes, a signed transaction can no longer be broadcast after its wallet closes or the app restarts (`broadcastTransaction` reports that it must be recreated), and payments the wallet would split into multiple on-chain transactions are rejected at creation so a broadcast is atomic.
27
+
28
+ ## 0.2.0 (2026-06-29)
29
+
30
+ - changed: Switch the package manager from yarn to npm (package-lock.json + `.npmrc` legacy-peer-deps), matching the other Edge currency repos.
31
+ - fixed: Monero Full Node (monerod) wallets now sync, calculate max, and send when the Nym mixnet is enabled. The Nym HTTP client rebuilt request URLs from an unreliable SSL flag and emitted `http://` on port 443, so every monerod RPC failed under Nym while the same wallet worked with Nym off. Derive the scheme from the daemon address (and treat port 443 as https).
32
+ - fixed: `getWalletStatus` now reads the live wallet balance on every call instead of only recomputing it when the synced block height changes, so a pending incoming transaction (or pending change after a send) is reflected immediately rather than after the next block.
33
+
34
+ ## 0.1.0 (2026-06-15)
35
+
36
+ - Initial release
package/LICENSE ADDED
@@ -0,0 +1,38 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, Airbitz, Inc.
4
+ Copyright (c) 2014-2024, The Monero Project
5
+
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions are met:
10
+
11
+ 1. Redistributions of source code must retain the above copyright notice, this
12
+ list of conditions and the following disclaimer.
13
+
14
+ 2. Redistributions in binary form must reproduce the above copyright notice,
15
+ this list of conditions and the following disclaimer in the documentation
16
+ and/or other materials provided with the distribution.
17
+
18
+ 3. Neither the name of the copyright holder nor the names of its contributors
19
+ may be used to endorse or promote products derived from this software
20
+ without specific prior written permission.
21
+
22
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+
33
+ ---
34
+
35
+ This package wraps the Monero Project, which is BSD-3-Clause, and ships
36
+ binaries compiled from it. The wrapper carries the same license so the package
37
+ and what it distributes agree. Boost, OpenSSL, libsodium, libunbound, libexpat
38
+ and libzmq are also compiled in and remain under their own licenses.
package/README.md ADDED
@@ -0,0 +1,26 @@
1
+ # monero-native
2
+
3
+ Native Monero wallet library (LWSF) for React Native and Node.js.
4
+
5
+ The compiled C++ lives in this package. React Native and Node are hosts.
6
+
7
+ - GitHub: [EdgeApp/monero-native](https://github.com/EdgeApp/monero-native)
8
+ - npm: `monero-native`
9
+
10
+ ## React Native
11
+
12
+ Add the package and run `pod install` as needed.
13
+
14
+ ```js
15
+ import { makeMonero } from 'monero-native'
16
+ ```
17
+
18
+ Mobile binaries: `npm run build-native` (Android + iOS). That script fetches third-party C++ and is not run on `npm install`.
19
+
20
+ ## Node (CLI)
21
+
22
+ ```js
23
+ import { makeNodeMoneroModule } from 'monero-native/node'
24
+ ```
25
+
26
+ Host addon: `npm run build-native-host` (explicit; `prepare` / `prepack` compile JavaScript only).
@@ -0,0 +1,40 @@
1
+ buildscript {
2
+ repositories {
3
+ mavenCentral()
4
+ google()
5
+ }
6
+
7
+ dependencies {
8
+ classpath 'com.android.tools.build:gradle:7.3.1'
9
+ }
10
+ }
11
+
12
+ apply plugin: 'com.android.library'
13
+
14
+ def safeExtGet(prop, fallback) {
15
+ rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
16
+ }
17
+
18
+ android {
19
+ compileSdkVersion safeExtGet('compileSdkVersion', 32)
20
+ defaultConfig {
21
+ minSdkVersion safeExtGet('minSdkVersion', 23)
22
+ targetSdkVersion safeExtGet('targetSdkVersion', 32)
23
+ }
24
+ lintOptions {
25
+ abortOnError false
26
+ }
27
+ namespace 'app.edge.rnmonero'
28
+ }
29
+
30
+ repositories {
31
+ maven {
32
+ url('../node_modules/react-native/android')
33
+ }
34
+ google()
35
+ mavenCentral()
36
+ }
37
+
38
+ dependencies {
39
+ implementation 'com.facebook.react:react-native:+'
40
+ }
@@ -0,0 +1,93 @@
1
+ package app.edge.rnmonero;
2
+
3
+ import com.facebook.react.bridge.Arguments;
4
+ import com.facebook.react.bridge.ReadableArray;
5
+ import com.facebook.react.bridge.Promise;
6
+ import com.facebook.react.bridge.ReactApplicationContext;
7
+ import com.facebook.react.bridge.ReactContextBaseJavaModule;
8
+ import com.facebook.react.bridge.ReactMethod;
9
+ import com.facebook.react.bridge.WritableMap;
10
+ import com.facebook.react.modules.core.DeviceEventManagerModule;
11
+ import java.util.HashMap;
12
+ import java.util.Map;
13
+ import java.util.concurrent.ExecutorService;
14
+ import java.util.concurrent.Executors;
15
+
16
+ public class RnMoneroModule extends ReactContextBaseJavaModule {
17
+ private native String callMoneroJNI(String method, String[] arguments);
18
+
19
+ private native String[] getMethodNames();
20
+
21
+ // Sets the C++ callback so WalletListener events route through onWalletEvent
22
+ private native void initEventCallback();
23
+
24
+ private final ExecutorService moneroExecutor = Executors.newSingleThreadExecutor();
25
+ private final ExecutorService nymCompletionExecutor = Executors.newSingleThreadExecutor();
26
+
27
+ static {
28
+ System.loadLibrary("rnmonero");
29
+ }
30
+
31
+ public RnMoneroModule(ReactApplicationContext reactContext) {
32
+ super(reactContext);
33
+ initEventCallback();
34
+ }
35
+
36
+ @Override
37
+ public Map<String, Object> getConstants() {
38
+ final Map<String, Object> constants = new HashMap<>();
39
+ constants.put("methodNames", getMethodNames());
40
+ constants.put("documentDirectory", getReactApplicationContext().getFilesDir().getAbsolutePath());
41
+ return constants;
42
+ }
43
+
44
+ @Override
45
+ public String getName() {
46
+ return "MoneroLwsfModule";
47
+ }
48
+
49
+ @ReactMethod
50
+ public void callMonero(String method, ReadableArray arguments, Promise promise) {
51
+ // Re-package the arguments:
52
+ String[] strings = new String[arguments.size()];
53
+ for (int i = 0; i < arguments.size(); ++i) {
54
+ strings[i] = arguments.getString(i);
55
+ }
56
+
57
+ ExecutorService executor =
58
+ isNymCompletionMethod(method) ? nymCompletionExecutor : moneroExecutor;
59
+ executor.execute(() -> {
60
+ try {
61
+ promise.resolve(callMoneroJNI(method, strings));
62
+ } catch (Exception e) {
63
+ promise.reject("MoneroError", e);
64
+ }
65
+ });
66
+ }
67
+
68
+ private static boolean isNymCompletionMethod(String method) {
69
+ return "resolveFetch".equals(method) || "rejectFetch".equals(method);
70
+ }
71
+
72
+ // Required by React Native NativeEventEmitter on Android
73
+ @ReactMethod
74
+ public void addListener(String eventName) {}
75
+
76
+ @ReactMethod
77
+ public void removeListeners(int count) {}
78
+
79
+ // Called from C++ WalletListener via JNI on the SDK refresh thread.
80
+ // Forwards the event to JS through RCTDeviceEventEmitter.
81
+ public void onWalletEvent(String walletId, String eventName, String jsonPayload) {
82
+ ReactApplicationContext ctx = getReactApplicationContext();
83
+ if (ctx == null || !ctx.hasActiveReactInstance()) return;
84
+
85
+ WritableMap params = Arguments.createMap();
86
+ params.putString("walletId", walletId);
87
+ params.putString("eventName", eventName);
88
+ params.putString("data", jsonPayload);
89
+
90
+ ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
91
+ .emit("MoneroWalletEvent", params);
92
+ }
93
+ }
@@ -0,0 +1,21 @@
1
+ package app.edge.rnmonero;
2
+
3
+ import com.facebook.react.ReactPackage;
4
+ import com.facebook.react.bridge.NativeModule;
5
+ import com.facebook.react.bridge.ReactApplicationContext;
6
+ import com.facebook.react.uimanager.ViewManager;
7
+ import java.util.Arrays;
8
+ import java.util.Collections;
9
+ import java.util.List;
10
+
11
+ public class RnMoneroPackage implements ReactPackage {
12
+ @Override
13
+ public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
14
+ return Arrays.<NativeModule>asList(new RnMoneroModule(reactContext));
15
+ }
16
+
17
+ @Override
18
+ public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
19
+ return Collections.emptyList();
20
+ }
21
+ }
@@ -0,0 +1,5 @@
1
+ #import <React/RCTBridgeModule.h>
2
+ #import <React/RCTEventEmitter.h>
3
+
4
+ @interface MoneroModule : RCTEventEmitter <RCTBridgeModule>
5
+ @end
@@ -0,0 +1,143 @@
1
+ #import "MoneroModule.h"
2
+ #include "monero-methods.hpp"
3
+
4
+ @interface MoneroModule () {
5
+ dispatch_queue_t _moneroQueue;
6
+ dispatch_queue_t _nymCompletionQueue;
7
+ }
8
+ @end
9
+
10
+ static bool isNymCompletionMethod(const std::string& method) {
11
+ return method == "resolveFetch" || method == "rejectFetch";
12
+ }
13
+
14
+ // Global pointer so the C++ callback can reach the ObjC module instance
15
+ static __weak MoneroModule* g_module = nil;
16
+
17
+ @implementation MoneroModule
18
+
19
+ RCT_EXPORT_MODULE(MoneroLwsfModule);
20
+
21
+ + (BOOL)requiresMainQueueSetup { return NO; }
22
+
23
+ - (instancetype)init {
24
+ self = [super init];
25
+ if (self) {
26
+ g_module = self;
27
+ _moneroQueue = dispatch_queue_create(
28
+ "app.edge.rnmonero.monero", DISPATCH_QUEUE_SERIAL);
29
+ _nymCompletionQueue = dispatch_queue_create(
30
+ "app.edge.rnmonero.nymCompletion", DISPATCH_QUEUE_SERIAL);
31
+
32
+ // Wire the C++ wallet-event callback to this module's event emitter
33
+ moneroSetEventCallback([](const std::string& walletId,
34
+ const std::string& eventName,
35
+ const std::string& jsonPayload) {
36
+ MoneroModule* module = g_module;
37
+ if (module == nil) return;
38
+
39
+ NSString *nsWalletId = [NSString stringWithUTF8String:walletId.c_str()];
40
+ NSString *nsEventName = [NSString stringWithUTF8String:eventName.c_str()];
41
+ NSString *nsPayload = [NSString stringWithUTF8String:jsonPayload.c_str()];
42
+
43
+ dispatch_async(dispatch_get_main_queue(), ^{
44
+ [module sendEventWithName:@"MoneroWalletEvent" body:@{
45
+ @"walletId": nsWalletId,
46
+ @"eventName": nsEventName,
47
+ @"data": nsPayload
48
+ }];
49
+ });
50
+ });
51
+ }
52
+ return self;
53
+ }
54
+
55
+ - (NSArray<NSString *> *)supportedEvents {
56
+ return @[@"MoneroWalletEvent"];
57
+ }
58
+
59
+ - (void)startObserving {}
60
+ - (void)stopObserving {}
61
+
62
+ RCT_REMAP_METHOD(
63
+ callMonero,
64
+ callMoneroMethod:(NSString *)method
65
+ arguments:(NSArray *)arguments
66
+ resolver:(RCTPromiseResolveBlock)resolve
67
+ rejecter:(RCTPromiseRejectBlock)reject
68
+ ) {
69
+ const std::string methodString = [method UTF8String];
70
+
71
+ // Re-package the arguments:
72
+ NSUInteger length = [arguments count];
73
+ std::vector<std::string> strings;
74
+ strings.reserve(length);
75
+ for (NSUInteger i = 0; i < length; ++i) {
76
+ NSString *string = [arguments objectAtIndex:i];
77
+ strings.push_back([string UTF8String]);
78
+ }
79
+
80
+ // Find the named method:
81
+ for (int i = 0; i < moneroMethodCount; ++i) {
82
+ if (moneroMethods[i].name != methodString) continue;
83
+
84
+ // Validate the argument count:
85
+ if (moneroMethods[i].argc != strings.size()) {
86
+ reject(@"Error", @"monero incorrect C++ argument count", nil);
87
+ return;
88
+ }
89
+
90
+ const MoneroMethod methodInfo = moneroMethods[i];
91
+ dispatch_queue_t queue =
92
+ isNymCompletionMethod(methodString) ? _nymCompletionQueue : _moneroQueue;
93
+ dispatch_async(queue, ^{
94
+ // Call the method, with error handling:
95
+ try {
96
+ const std::string out = methodInfo.method(strings);
97
+ resolve(
98
+ [NSString stringWithCString:out.c_str() encoding:NSUTF8StringEncoding]
99
+ );
100
+ } catch (std::exception &e) {
101
+ reject(
102
+ @"Error",
103
+ [NSString stringWithCString:e.what() encoding:NSUTF8StringEncoding],
104
+ nil
105
+ );
106
+ } catch (...) {
107
+ reject(@"Error", @"monero threw a C++ exception", nil);
108
+ }
109
+ });
110
+ return;
111
+ }
112
+
113
+ reject(
114
+ @"TypeError",
115
+ [NSString stringWithFormat:@"No monero C++ method %@", method],
116
+ nil
117
+ );
118
+ }
119
+
120
+ - (NSDictionary *)constantsToExport
121
+ {
122
+ NSMutableArray *out = [NSMutableArray arrayWithCapacity:moneroMethodCount];
123
+ for (int i = 0; i < moneroMethodCount; ++i) {
124
+ NSString *name = [NSString stringWithCString:moneroMethods[i].name
125
+ encoding:NSUTF8StringEncoding];
126
+ out[i] = name;
127
+ }
128
+
129
+ NSFileManager *fileManager = [NSFileManager defaultManager];
130
+ NSURL *docsDir = [fileManager URLForDirectory:NSDocumentDirectory
131
+ inDomain:NSUserDomainMask
132
+ appropriateForURL:nil
133
+ create:YES
134
+ error:nil];
135
+ NSString *docsPath = [docsDir path];
136
+
137
+ return @{
138
+ @"methodNames": out,
139
+ @"documentDirectory": docsPath
140
+ };
141
+ }
142
+
143
+ @end
@@ -0,0 +1,43 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>AvailableLibraries</key>
6
+ <array>
7
+ <dict>
8
+ <key>BinaryPath</key>
9
+ <string>libmonero-module.a</string>
10
+ <key>LibraryIdentifier</key>
11
+ <string>ios-arm64</string>
12
+ <key>LibraryPath</key>
13
+ <string>libmonero-module.a</string>
14
+ <key>SupportedArchitectures</key>
15
+ <array>
16
+ <string>arm64</string>
17
+ </array>
18
+ <key>SupportedPlatform</key>
19
+ <string>ios</string>
20
+ </dict>
21
+ <dict>
22
+ <key>BinaryPath</key>
23
+ <string>libmonero-module.a</string>
24
+ <key>LibraryIdentifier</key>
25
+ <string>ios-arm64-simulator</string>
26
+ <key>LibraryPath</key>
27
+ <string>libmonero-module.a</string>
28
+ <key>SupportedArchitectures</key>
29
+ <array>
30
+ <string>arm64</string>
31
+ </array>
32
+ <key>SupportedPlatform</key>
33
+ <string>ios</string>
34
+ <key>SupportedPlatformVariant</key>
35
+ <string>simulator</string>
36
+ </dict>
37
+ </array>
38
+ <key>CFBundlePackageType</key>
39
+ <string>XFWK</string>
40
+ <key>XCFrameworkFormatVersion</key>
41
+ <string>1.0</string>
42
+ </dict>
43
+ </plist>
@@ -0,0 +1,181 @@
1
+ import type { BroadcastResult, DerivedKeys, EncodeUriParams, GeneratedWallet, NetworkType, ParsedUri, Recipient, SignedTransaction, TransactionPriority, TransactionsPage, WalletBackend, WalletStatus } from './types';
2
+ /**
3
+ * The shape of the native C++ module exposed to React Native.
4
+ *
5
+ * You do not normally need this, but it is accessible as
6
+ * `require('react-native').NativeModules.MoneroLwsfModule`.
7
+ *
8
+ * Pass this object to the `CppBridge` constructor to re-assemble the API.
9
+ */
10
+ export interface NativeMoneroLwsfModule {
11
+ readonly callMonero: (name: string, jsonArguments: string[]) => Promise<string>;
12
+ readonly methodNames: string[];
13
+ readonly documentDirectory: string;
14
+ }
15
+ export declare class CppBridge {
16
+ private readonly module;
17
+ constructor(moneroLwsfModule: NativeMoneroLwsfModule);
18
+ /**
19
+ * Generate a new wallet's keys in memory (no disk I/O).
20
+ * @param nettype - Network type (0=mainnet, 1=testnet, 2=stagenet)
21
+ * @param language - Mnemonic language (e.g., "English")
22
+ * @returns Generated wallet with mnemonic and spend keys
23
+ */
24
+ generateWallet(nettype: NetworkType, language?: string): Promise<GeneratedWallet>;
25
+ /**
26
+ * Derive all keys from a mnemonic (no disk I/O).
27
+ * @param mnemonic - The 25-word mnemonic seed
28
+ * @param nettype - Network type (0=mainnet, 1=testnet, 2=stagenet)
29
+ * @returns All four keys (view and spend, public and secret)
30
+ */
31
+ seedAndKeysFromMnemonic(mnemonic: string, nettype: NetworkType): Promise<DerivedKeys>;
32
+ /**
33
+ * Get the current network blockchain height from a daemon.
34
+ * @param backend - Backend type ('lws' or 'monerod')
35
+ * @param nettype - Network type (0=mainnet, 1=testnet, 2=stagenet)
36
+ * @param daemonAddress - Daemon address to query
37
+ * @returns Current blockchain height
38
+ */
39
+ getNetworkBlockHeight(backend: WalletBackend, nettype: NetworkType, daemonAddress: string): Promise<number>;
40
+ /**
41
+ * Validate a Monero address.
42
+ * @param address - The address to validate
43
+ * @param nettype - Network type (0=mainnet, 1=testnet, 2=stagenet)
44
+ * @returns true if valid, false otherwise
45
+ */
46
+ isValidAddress(address: string, nettype: NetworkType): Promise<boolean>;
47
+ /**
48
+ * Open or create a wallet. If already open, returns current status.
49
+ * If wallet exists on disk, opens it. Otherwise creates from mnemonic.
50
+ * @param walletId - Unique identifier for the wallet
51
+ * @param backend - Backend type ("lws" or "monerod")
52
+ * @param mnemonic - The 25-word mnemonic seed
53
+ * @param nettype - Network type (0=mainnet, 1=testnet, 2=stagenet)
54
+ * @param restoreHeight - Block height to restore from
55
+ * @param daemonAddress - Daemon address to connect to
56
+ * @returns Current wallet status (heights and balances)
57
+ */
58
+ openWallet(walletId: string, backend: WalletBackend, mnemonic: string, password: string, nettype: NetworkType, restoreHeight: number, daemonAddress: string): Promise<WalletStatus>;
59
+ /**
60
+ * Get the current status of an open wallet.
61
+ * @param walletId - Unique identifier for the wallet
62
+ * @returns Current wallet status (heights and balances)
63
+ */
64
+ getWalletStatus(walletId: string): Promise<WalletStatus>;
65
+ /**
66
+ * Close an open wallet.
67
+ * @param walletId - Unique identifier for the wallet to close
68
+ */
69
+ closeWallet(walletId: string): Promise<void>;
70
+ /**
71
+ * Delete a wallet's files from disk. Closes the wallet first if it's open.
72
+ * @param walletId - Unique identifier for the wallet
73
+ * @param backend - Backend type ('lws' or 'monerod')
74
+ */
75
+ deleteWallet(walletId: string, backend: WalletBackend): Promise<void>;
76
+ /**
77
+ * Get all transactions with pagination.
78
+ * @param walletId - Unique identifier for the wallet
79
+ * @param page - Page number (0-indexed)
80
+ * @param pageSize - Number of transactions per page
81
+ * @param sort - Sort order: 'asc' (oldest first) or 'desc' (newest first), pending always at end
82
+ * @returns Paginated transactions with metadata
83
+ */
84
+ getAllTransactions(walletId: string, page: number, pageSize: number, sort?: 'asc' | 'desc'): Promise<TransactionsPage>;
85
+ /**
86
+ * Get not-yet-mined transactions with pagination. Same shape as
87
+ * getAllTransactions, filtered to pending entries. Pending transactions sort
88
+ * behind all confirmed ones in getAllTransactions, so a cursor-based scan of
89
+ * confirmed history never reaches them; use this to read the pending set
90
+ * directly. The set can include entries the backend reports as permanently
91
+ * failed (isFailed: true); callers decide how to label those.
92
+ * @param walletId - Unique identifier for the wallet
93
+ * @param page - Page number (0-indexed)
94
+ * @param pageSize - Number of transactions per page
95
+ * @returns Paginated pending transactions with metadata
96
+ */
97
+ getPendingTransactions(walletId: string, page: number, pageSize: number): Promise<TransactionsPage>;
98
+ /**
99
+ * Create a transaction (supports multiple recipients).
100
+ * The transaction is created and signed but not broadcast yet: it is retained
101
+ * natively for a later broadcastTransaction call. At most 50 transactions are
102
+ * retained per wallet (oldest disposed first; broadcasting an evicted one
103
+ * reports that it must be recreated), and all are released when the wallet
104
+ * closes. Payments the wallet would split into multiple on-chain
105
+ * transactions are rejected, so a later broadcast is atomic.
106
+ * @param walletId - Unique identifier for the wallet
107
+ * @param recipients - Array of recipients with addresses and amounts (atomic units)
108
+ * @param priority - Transaction priority (0=Default, 1=Low, 2=Medium, 3=High)
109
+ * @returns SignedTransaction with txid, signedTxHex, and fee (atomic units)
110
+ */
111
+ createTransaction(walletId: string, recipients: Recipient[], priority: TransactionPriority): Promise<SignedTransaction>;
112
+ /**
113
+ * Broadcast a previously created transaction. `signedTx` identifies the
114
+ * natively retained transaction to broadcast.
115
+ * @param walletId - Unique identifier for the wallet
116
+ * @param signedTx - The signedTxHex returned by createTransaction
117
+ * @returns BroadcastResult with the transaction secret key, when the wallet
118
+ * can report it. This is the only chance to read the key on the send path:
119
+ * it is not derivable from the seed, so a caller that drops it here can
120
+ * only recover it from this wallet's local cache later.
121
+ * @throws Error if the transaction is no longer retained (evicted, or the
122
+ * wallet was closed since creation) or the broadcast fails
123
+ */
124
+ broadcastTransaction(walletId: string, signedTx: string): Promise<BroadcastResult>;
125
+ /**
126
+ * Parse a monero: URI into its components.
127
+ * @param uri - The monero: URI to parse
128
+ * @param nettype - Network type (0=mainnet, 1=testnet, 2=stagenet)
129
+ * @returns Parsed URI components
130
+ * @throws Error if URI is invalid
131
+ */
132
+ parseUri(uri: string, nettype: NetworkType): Promise<ParsedUri>;
133
+ /**
134
+ * Encode a monero: URI from components.
135
+ * @param params - URI components (address, amount, etc.)
136
+ * @param nettype - Network type (0=mainnet, 1=testnet, 2=stagenet)
137
+ * @returns The encoded monero: URI
138
+ * @throws Error if parameters are invalid
139
+ */
140
+ encodeUri(params: EncodeUriParams, nettype: NetworkType): Promise<string>;
141
+ /**
142
+ * Set the API key for LWS (Light Wallet Server) requests.
143
+ * Once set, the key will be included in all subsequent LWS HTTP POST requests
144
+ * as an "api_key" field in the JSON body.
145
+ * @param apiKey - The API key to include in LWS requests
146
+ */
147
+ setLwsApiKey(apiKey: string): Promise<void>;
148
+ /**
149
+ * Enable or disable the Nym fetch interceptor.
150
+ *
151
+ * When enabled, all LWSF HTTP POST requests that the C++ wallet code
152
+ * would have issued are redirected through the native event bridge. The
153
+ * consumer must register a handler via `NativeEventEmitter` on the
154
+ * "MoneroWalletEvent" event with `eventName === 'nymFetchRequest'` and
155
+ * call `resolveFetch` / `rejectFetch` to complete the request.
156
+ *
157
+ * @param enabled - Whether to route HTTP through the JS fetch bridge
158
+ * @param baseUrl - scheme://host[:port] of the LWSF server (must match
159
+ * the daemon address used at openWallet time). Empty
160
+ * when disabling.
161
+ */
162
+ setNymEnabled(enabled: boolean, baseUrl: string): Promise<void>;
163
+ /**
164
+ * Resolve a pending nym fetch request that was emitted as a
165
+ * `nymFetchRequest` wallet event. Must be called with the same
166
+ * `requestId` carried on the incoming event.
167
+ *
168
+ * @param requestId - id forwarded via the native event
169
+ * @param status - HTTP status code returned from fetch
170
+ * @param bodyBase64 - response body encoded as base64
171
+ */
172
+ resolveFetch(requestId: string, status: number, bodyBase64: string): Promise<void>;
173
+ /**
174
+ * Reject a pending nym fetch request. The blocked C++ caller will
175
+ * receive a runtime_error bubbled as an RPC failure.
176
+ *
177
+ * @param requestId - id forwarded via the native event
178
+ * @param errorMessage - human-readable error description
179
+ */
180
+ rejectFetch(requestId: string, errorMessage: string): Promise<void>;
181
+ }