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 +36 -0
- package/LICENSE +38 -0
- package/README.md +26 -0
- package/android/build.gradle +40 -0
- package/android/src/main/java/app/edge/rnmonero/RnMoneroModule.java +93 -0
- package/android/src/main/java/app/edge/rnmonero/RnMoneroPackage.java +21 -0
- package/android/src/main/jniLibs/arm64-v8a/librnmonero.so +0 -0
- package/ios/MoneroModule.h +5 -0
- package/ios/MoneroModule.mm +143 -0
- package/ios/MoneroModule.xcframework/Info.plist +43 -0
- package/ios/MoneroModule.xcframework/ios-arm64/libmonero-module.a +0 -0
- package/ios/MoneroModule.xcframework/ios-arm64-simulator/libmonero-module.a +0 -0
- package/lib/src/CppBridge.d.ts +181 -0
- package/lib/src/CppBridge.js +296 -0
- package/lib/src/index.d.ts +4 -0
- package/lib/src/index.js +27 -0
- package/lib/src/load-addon.d.ts +6 -0
- package/lib/src/load-addon.js +49 -0
- package/lib/src/node.d.ts +12 -0
- package/lib/src/node.js +23 -0
- package/lib/src/types.d.ts +120 -0
- package/lib/src/types.js +11 -0
- package/monero-native.podspec +28 -0
- package/node.d.ts +5 -0
- package/node.js +2 -0
- package/package.json +94 -0
- package/prebuilds/darwin-arm64/monero.node +0 -0
- package/src/monero-wrapper/monero-methods.hpp +25 -0
- package/src/node/monero-napi.cpp +248 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CppBridge = void 0;
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
class CppBridge {
|
|
6
|
+
constructor(moneroLwsfModule) {
|
|
7
|
+
this.module = moneroLwsfModule;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Generate a new wallet's keys in memory (no disk I/O).
|
|
11
|
+
* @param nettype - Network type (0=mainnet, 1=testnet, 2=stagenet)
|
|
12
|
+
* @param language - Mnemonic language (e.g., "English")
|
|
13
|
+
* @returns Generated wallet with mnemonic and spend keys
|
|
14
|
+
*/
|
|
15
|
+
async generateWallet(nettype, language = 'English') {
|
|
16
|
+
const response = await this.module.callMonero('generateWallet', [
|
|
17
|
+
(0, types_1.networkTypeToIntString)(nettype),
|
|
18
|
+
language
|
|
19
|
+
]);
|
|
20
|
+
return JSON.parse(response);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Derive all keys from a mnemonic (no disk I/O).
|
|
24
|
+
* @param mnemonic - The 25-word mnemonic seed
|
|
25
|
+
* @param nettype - Network type (0=mainnet, 1=testnet, 2=stagenet)
|
|
26
|
+
* @returns All four keys (view and spend, public and secret)
|
|
27
|
+
*/
|
|
28
|
+
async seedAndKeysFromMnemonic(mnemonic, nettype) {
|
|
29
|
+
const response = await this.module.callMonero('seedAndKeysFromMnemonic', [
|
|
30
|
+
mnemonic,
|
|
31
|
+
(0, types_1.networkTypeToIntString)(nettype)
|
|
32
|
+
]);
|
|
33
|
+
return JSON.parse(response);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get the current network blockchain height from a daemon.
|
|
37
|
+
* @param backend - Backend type ('lws' or 'monerod')
|
|
38
|
+
* @param nettype - Network type (0=mainnet, 1=testnet, 2=stagenet)
|
|
39
|
+
* @param daemonAddress - Daemon address to query
|
|
40
|
+
* @returns Current blockchain height
|
|
41
|
+
*/
|
|
42
|
+
async getNetworkBlockHeight(backend, nettype, daemonAddress) {
|
|
43
|
+
const response = await this.module.callMonero('getNetworkBlockHeight', [
|
|
44
|
+
backend,
|
|
45
|
+
(0, types_1.networkTypeToIntString)(nettype),
|
|
46
|
+
daemonAddress
|
|
47
|
+
]);
|
|
48
|
+
return parseInt(response, 10);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Validate a Monero address.
|
|
52
|
+
* @param address - The address to validate
|
|
53
|
+
* @param nettype - Network type (0=mainnet, 1=testnet, 2=stagenet)
|
|
54
|
+
* @returns true if valid, false otherwise
|
|
55
|
+
*/
|
|
56
|
+
async isValidAddress(address, nettype) {
|
|
57
|
+
const response = await this.module.callMonero('isValidAddress', [
|
|
58
|
+
address,
|
|
59
|
+
(0, types_1.networkTypeToIntString)(nettype)
|
|
60
|
+
]);
|
|
61
|
+
return response === 'true';
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Open or create a wallet. If already open, returns current status.
|
|
65
|
+
* If wallet exists on disk, opens it. Otherwise creates from mnemonic.
|
|
66
|
+
* @param walletId - Unique identifier for the wallet
|
|
67
|
+
* @param backend - Backend type ("lws" or "monerod")
|
|
68
|
+
* @param mnemonic - The 25-word mnemonic seed
|
|
69
|
+
* @param nettype - Network type (0=mainnet, 1=testnet, 2=stagenet)
|
|
70
|
+
* @param restoreHeight - Block height to restore from
|
|
71
|
+
* @param daemonAddress - Daemon address to connect to
|
|
72
|
+
* @returns Current wallet status (heights and balances)
|
|
73
|
+
*/
|
|
74
|
+
async openWallet(walletId, backend, mnemonic, password, nettype, restoreHeight, daemonAddress) {
|
|
75
|
+
const response = await this.module.callMonero('openWallet', [
|
|
76
|
+
this.module.documentDirectory,
|
|
77
|
+
walletId,
|
|
78
|
+
backend,
|
|
79
|
+
mnemonic,
|
|
80
|
+
password,
|
|
81
|
+
(0, types_1.networkTypeToIntString)(nettype),
|
|
82
|
+
restoreHeight.toString(),
|
|
83
|
+
daemonAddress
|
|
84
|
+
]);
|
|
85
|
+
return JSON.parse(response);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get the current status of an open wallet.
|
|
89
|
+
* @param walletId - Unique identifier for the wallet
|
|
90
|
+
* @returns Current wallet status (heights and balances)
|
|
91
|
+
*/
|
|
92
|
+
async getWalletStatus(walletId) {
|
|
93
|
+
const response = await this.module.callMonero('getWalletStatus', [walletId]);
|
|
94
|
+
return JSON.parse(response);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Close an open wallet.
|
|
98
|
+
* @param walletId - Unique identifier for the wallet to close
|
|
99
|
+
*/
|
|
100
|
+
async closeWallet(walletId) {
|
|
101
|
+
await this.module.callMonero('closeWallet', [walletId]);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Delete a wallet's files from disk. Closes the wallet first if it's open.
|
|
105
|
+
* @param walletId - Unique identifier for the wallet
|
|
106
|
+
* @param backend - Backend type ('lws' or 'monerod')
|
|
107
|
+
*/
|
|
108
|
+
async deleteWallet(walletId, backend) {
|
|
109
|
+
await this.module.callMonero('deleteWallet', [
|
|
110
|
+
this.module.documentDirectory,
|
|
111
|
+
walletId,
|
|
112
|
+
backend
|
|
113
|
+
]);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Get all transactions with pagination.
|
|
117
|
+
* @param walletId - Unique identifier for the wallet
|
|
118
|
+
* @param page - Page number (0-indexed)
|
|
119
|
+
* @param pageSize - Number of transactions per page
|
|
120
|
+
* @param sort - Sort order: 'asc' (oldest first) or 'desc' (newest first), pending always at end
|
|
121
|
+
* @returns Paginated transactions with metadata
|
|
122
|
+
*/
|
|
123
|
+
async getAllTransactions(walletId, page, pageSize, sort = 'asc') {
|
|
124
|
+
const response = await this.module.callMonero('getAllTransactions', [
|
|
125
|
+
walletId,
|
|
126
|
+
page.toString(),
|
|
127
|
+
pageSize.toString(),
|
|
128
|
+
sort
|
|
129
|
+
]);
|
|
130
|
+
return JSON.parse(response);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Get not-yet-mined transactions with pagination. Same shape as
|
|
134
|
+
* getAllTransactions, filtered to pending entries. Pending transactions sort
|
|
135
|
+
* behind all confirmed ones in getAllTransactions, so a cursor-based scan of
|
|
136
|
+
* confirmed history never reaches them; use this to read the pending set
|
|
137
|
+
* directly. The set can include entries the backend reports as permanently
|
|
138
|
+
* failed (isFailed: true); callers decide how to label those.
|
|
139
|
+
* @param walletId - Unique identifier for the wallet
|
|
140
|
+
* @param page - Page number (0-indexed)
|
|
141
|
+
* @param pageSize - Number of transactions per page
|
|
142
|
+
* @returns Paginated pending transactions with metadata
|
|
143
|
+
*/
|
|
144
|
+
async getPendingTransactions(walletId, page, pageSize) {
|
|
145
|
+
const response = await this.module.callMonero('getPendingTransactions', [
|
|
146
|
+
walletId,
|
|
147
|
+
page.toString(),
|
|
148
|
+
pageSize.toString()
|
|
149
|
+
]);
|
|
150
|
+
return JSON.parse(response);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Create a transaction (supports multiple recipients).
|
|
154
|
+
* The transaction is created and signed but not broadcast yet: it is retained
|
|
155
|
+
* natively for a later broadcastTransaction call. At most 50 transactions are
|
|
156
|
+
* retained per wallet (oldest disposed first; broadcasting an evicted one
|
|
157
|
+
* reports that it must be recreated), and all are released when the wallet
|
|
158
|
+
* closes. Payments the wallet would split into multiple on-chain
|
|
159
|
+
* transactions are rejected, so a later broadcast is atomic.
|
|
160
|
+
* @param walletId - Unique identifier for the wallet
|
|
161
|
+
* @param recipients - Array of recipients with addresses and amounts (atomic units)
|
|
162
|
+
* @param priority - Transaction priority (0=Default, 1=Low, 2=Medium, 3=High)
|
|
163
|
+
* @returns SignedTransaction with txid, signedTxHex, and fee (atomic units)
|
|
164
|
+
*/
|
|
165
|
+
async createTransaction(walletId, recipients, priority) {
|
|
166
|
+
const addresses = recipients.map(r => r.address).join(',');
|
|
167
|
+
const amounts = recipients.map(r => r.amount).join(',');
|
|
168
|
+
const response = await this.module.callMonero('createTransaction', [
|
|
169
|
+
walletId,
|
|
170
|
+
addresses,
|
|
171
|
+
amounts,
|
|
172
|
+
priority.toString(),
|
|
173
|
+
this.module.documentDirectory
|
|
174
|
+
]);
|
|
175
|
+
return JSON.parse(response);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Broadcast a previously created transaction. `signedTx` identifies the
|
|
179
|
+
* natively retained transaction to broadcast.
|
|
180
|
+
* @param walletId - Unique identifier for the wallet
|
|
181
|
+
* @param signedTx - The signedTxHex returned by createTransaction
|
|
182
|
+
* @returns BroadcastResult with the transaction secret key, when the wallet
|
|
183
|
+
* can report it. This is the only chance to read the key on the send path:
|
|
184
|
+
* it is not derivable from the seed, so a caller that drops it here can
|
|
185
|
+
* only recover it from this wallet's local cache later.
|
|
186
|
+
* @throws Error if the transaction is no longer retained (evicted, or the
|
|
187
|
+
* wallet was closed since creation) or the broadcast fails
|
|
188
|
+
*/
|
|
189
|
+
async broadcastTransaction(walletId, signedTx) {
|
|
190
|
+
const response = await this.module.callMonero('broadcastTransaction', [
|
|
191
|
+
walletId,
|
|
192
|
+
signedTx,
|
|
193
|
+
this.module.documentDirectory
|
|
194
|
+
]);
|
|
195
|
+
return JSON.parse(response);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Parse a monero: URI into its components.
|
|
199
|
+
* @param uri - The monero: URI to parse
|
|
200
|
+
* @param nettype - Network type (0=mainnet, 1=testnet, 2=stagenet)
|
|
201
|
+
* @returns Parsed URI components
|
|
202
|
+
* @throws Error if URI is invalid
|
|
203
|
+
*/
|
|
204
|
+
async parseUri(uri, nettype) {
|
|
205
|
+
const response = await this.module.callMonero('parseUri', [
|
|
206
|
+
uri,
|
|
207
|
+
(0, types_1.networkTypeToIntString)(nettype)
|
|
208
|
+
]);
|
|
209
|
+
const parsed = JSON.parse(response);
|
|
210
|
+
if (typeof parsed === 'object' && 'error' in parsed) {
|
|
211
|
+
throw new Error(parsed.error);
|
|
212
|
+
}
|
|
213
|
+
return parsed;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Encode a monero: URI from components.
|
|
217
|
+
* @param params - URI components (address, amount, etc.)
|
|
218
|
+
* @param nettype - Network type (0=mainnet, 1=testnet, 2=stagenet)
|
|
219
|
+
* @returns The encoded monero: URI
|
|
220
|
+
* @throws Error if parameters are invalid
|
|
221
|
+
*/
|
|
222
|
+
async encodeUri(params, nettype) {
|
|
223
|
+
const response = await this.module.callMonero('encodeUri', [
|
|
224
|
+
params.address,
|
|
225
|
+
params.paymentId ?? '',
|
|
226
|
+
params.amount,
|
|
227
|
+
params.txDescription ?? '',
|
|
228
|
+
params.recipientName ?? '',
|
|
229
|
+
(0, types_1.networkTypeToIntString)(nettype)
|
|
230
|
+
]);
|
|
231
|
+
// Check for error response (JSON object with error field)
|
|
232
|
+
if (response.startsWith('{')) {
|
|
233
|
+
const parsed = JSON.parse(response);
|
|
234
|
+
if (typeof parsed === 'object' && 'error' in parsed) {
|
|
235
|
+
throw new Error(parsed.error);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return response;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Set the API key for LWS (Light Wallet Server) requests.
|
|
242
|
+
* Once set, the key will be included in all subsequent LWS HTTP POST requests
|
|
243
|
+
* as an "api_key" field in the JSON body.
|
|
244
|
+
* @param apiKey - The API key to include in LWS requests
|
|
245
|
+
*/
|
|
246
|
+
async setLwsApiKey(apiKey) {
|
|
247
|
+
await this.module.callMonero('setLwsApiKey', [apiKey]);
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Enable or disable the Nym fetch interceptor.
|
|
251
|
+
*
|
|
252
|
+
* When enabled, all LWSF HTTP POST requests that the C++ wallet code
|
|
253
|
+
* would have issued are redirected through the native event bridge. The
|
|
254
|
+
* consumer must register a handler via `NativeEventEmitter` on the
|
|
255
|
+
* "MoneroWalletEvent" event with `eventName === 'nymFetchRequest'` and
|
|
256
|
+
* call `resolveFetch` / `rejectFetch` to complete the request.
|
|
257
|
+
*
|
|
258
|
+
* @param enabled - Whether to route HTTP through the JS fetch bridge
|
|
259
|
+
* @param baseUrl - scheme://host[:port] of the LWSF server (must match
|
|
260
|
+
* the daemon address used at openWallet time). Empty
|
|
261
|
+
* when disabling.
|
|
262
|
+
*/
|
|
263
|
+
async setNymEnabled(enabled, baseUrl) {
|
|
264
|
+
await this.module.callMonero('setNymEnabled', [
|
|
265
|
+
enabled ? 'true' : 'false',
|
|
266
|
+
baseUrl
|
|
267
|
+
]);
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Resolve a pending nym fetch request that was emitted as a
|
|
271
|
+
* `nymFetchRequest` wallet event. Must be called with the same
|
|
272
|
+
* `requestId` carried on the incoming event.
|
|
273
|
+
*
|
|
274
|
+
* @param requestId - id forwarded via the native event
|
|
275
|
+
* @param status - HTTP status code returned from fetch
|
|
276
|
+
* @param bodyBase64 - response body encoded as base64
|
|
277
|
+
*/
|
|
278
|
+
async resolveFetch(requestId, status, bodyBase64) {
|
|
279
|
+
await this.module.callMonero('resolveFetch', [
|
|
280
|
+
requestId,
|
|
281
|
+
status.toString(),
|
|
282
|
+
bodyBase64
|
|
283
|
+
]);
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Reject a pending nym fetch request. The blocked C++ caller will
|
|
287
|
+
* receive a runtime_error bubbled as an RPC failure.
|
|
288
|
+
*
|
|
289
|
+
* @param requestId - id forwarded via the native event
|
|
290
|
+
* @param errorMessage - human-readable error description
|
|
291
|
+
*/
|
|
292
|
+
async rejectFetch(requestId, errorMessage) {
|
|
293
|
+
await this.module.callMonero('rejectFetch', [requestId, errorMessage]);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
exports.CppBridge = CppBridge;
|
package/lib/src/index.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.makeMonero = makeMonero;
|
|
18
|
+
const react_native_1 = require("react-native");
|
|
19
|
+
const CppBridge_1 = require("./CppBridge");
|
|
20
|
+
function makeMonero() {
|
|
21
|
+
const { MoneroLwsfModule } = react_native_1.NativeModules;
|
|
22
|
+
if (MoneroLwsfModule == null) {
|
|
23
|
+
throw new Error('monero-native native module not linked');
|
|
24
|
+
}
|
|
25
|
+
return new CppBridge_1.CppBridge(MoneroLwsfModule);
|
|
26
|
+
}
|
|
27
|
+
__exportStar(require("./types"), exports);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export interface NativeMoneroAddon {
|
|
2
|
+
callMonero: (method: string, args: string[]) => Promise<string>;
|
|
3
|
+
methodNames: () => string[];
|
|
4
|
+
setEventListener: (cb: (walletId: string, eventName: string, data: string) => void) => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function loadNativeAddon(): NativeMoneroAddon;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadNativeAddon = loadNativeAddon;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
function candidatePaths() {
|
|
7
|
+
const here = __dirname;
|
|
8
|
+
const platform = `${process.platform}-${process.arch}`;
|
|
9
|
+
const out = [];
|
|
10
|
+
let dir = here;
|
|
11
|
+
for (let i = 0; i < 6; i++) {
|
|
12
|
+
out.push((0, path_1.join)(dir, 'prebuilds', platform, 'monero.node'));
|
|
13
|
+
out.push((0, path_1.join)(dir, 'build', 'Release', 'monero.node'));
|
|
14
|
+
const parent = (0, path_1.join)(dir, '..');
|
|
15
|
+
if (parent === dir)
|
|
16
|
+
break;
|
|
17
|
+
dir = parent;
|
|
18
|
+
}
|
|
19
|
+
return out;
|
|
20
|
+
}
|
|
21
|
+
let cached;
|
|
22
|
+
function loadNativeAddon() {
|
|
23
|
+
if (cached != null)
|
|
24
|
+
return cached;
|
|
25
|
+
const errors = [];
|
|
26
|
+
const missing = [];
|
|
27
|
+
for (const candidate of candidatePaths()) {
|
|
28
|
+
try {
|
|
29
|
+
if (!(0, fs_1.existsSync)(candidate)) {
|
|
30
|
+
missing.push(candidate);
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
// Native addon loaded at runtime when the .node binary exists.
|
|
34
|
+
const mod = require(candidate);
|
|
35
|
+
if (typeof mod.callMonero !== 'function')
|
|
36
|
+
continue;
|
|
37
|
+
cached = mod;
|
|
38
|
+
return cached;
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
42
|
+
errors.push(`${candidate}: ${message}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
throw new Error('monero-native addon not found. Run `npm run build-native-host`. ' +
|
|
46
|
+
(errors.length > 0
|
|
47
|
+
? errors.join('; ')
|
|
48
|
+
: `Looked in: ${missing.join(', ')}`));
|
|
49
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import type { NativeMoneroLwsfModule } from './CppBridge';
|
|
3
|
+
export type { WalletEventData } from './types';
|
|
4
|
+
export interface MakeNodeMoneroModuleOpts {
|
|
5
|
+
documentDirectory: string;
|
|
6
|
+
}
|
|
7
|
+
export type NodeMoneroModule = NativeMoneroLwsfModule & EventEmitter;
|
|
8
|
+
/**
|
|
9
|
+
* Node N-API implementation of the native Monero module.
|
|
10
|
+
* Same `callMonero` contract as `NativeModules.MoneroLwsfModule`.
|
|
11
|
+
*/
|
|
12
|
+
export declare function makeNodeMoneroModule(opts: MakeNodeMoneroModuleOpts): NodeMoneroModule;
|
package/lib/src/node.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeNodeMoneroModule = makeNodeMoneroModule;
|
|
4
|
+
const events_1 = require("events");
|
|
5
|
+
const load_addon_1 = require("./load-addon");
|
|
6
|
+
/**
|
|
7
|
+
* Node N-API implementation of the native Monero module.
|
|
8
|
+
* Same `callMonero` contract as `NativeModules.MoneroLwsfModule`.
|
|
9
|
+
*/
|
|
10
|
+
function makeNodeMoneroModule(opts) {
|
|
11
|
+
const addon = (0, load_addon_1.loadNativeAddon)();
|
|
12
|
+
const emitter = new events_1.EventEmitter();
|
|
13
|
+
addon.setEventListener((walletId, eventName, data) => {
|
|
14
|
+
emitter.emit('MoneroWalletEvent', { walletId, eventName, data });
|
|
15
|
+
});
|
|
16
|
+
const methodNames = addon.methodNames();
|
|
17
|
+
const module = Object.assign(emitter, {
|
|
18
|
+
callMonero: async (name, jsonArguments) => await addon.callMonero(name, jsonArguments),
|
|
19
|
+
methodNames,
|
|
20
|
+
documentDirectory: opts.documentDirectory
|
|
21
|
+
});
|
|
22
|
+
return module;
|
|
23
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
export type NetworkType = 'MAINNET' | 'TESTNET' | 'STAGENET';
|
|
2
|
+
export declare function networkTypeToIntString(type: NetworkType): string;
|
|
3
|
+
export type WalletBackend = 'lws' | 'monerod';
|
|
4
|
+
export interface GeneratedWallet {
|
|
5
|
+
mnemonic: string;
|
|
6
|
+
secretSpendKey: string;
|
|
7
|
+
publicSpendKey: string;
|
|
8
|
+
}
|
|
9
|
+
/** Return type for seedAndKeysFromMnemonic. */
|
|
10
|
+
export interface DerivedKeys {
|
|
11
|
+
address: string;
|
|
12
|
+
secretViewKey: string;
|
|
13
|
+
publicViewKey: string;
|
|
14
|
+
secretSpendKey: string;
|
|
15
|
+
publicSpendKey: string;
|
|
16
|
+
}
|
|
17
|
+
/** Return type for openWallet and getWalletStatus. */
|
|
18
|
+
export interface WalletStatus {
|
|
19
|
+
syncedHeight: number;
|
|
20
|
+
networkHeight: number;
|
|
21
|
+
balance: string;
|
|
22
|
+
unlockedBalance: string;
|
|
23
|
+
/**
|
|
24
|
+
* True once at least one server refresh has completed for this wallet. LWS
|
|
25
|
+
* wallets seed syncedHeight == networkHeight from the stored scan height
|
|
26
|
+
* until their first refresh, so heights alone cannot tell "caught up" from
|
|
27
|
+
* "has not looked yet"; treat the wallet as synced/spendable only when this
|
|
28
|
+
* is true.
|
|
29
|
+
*/
|
|
30
|
+
refreshed: boolean;
|
|
31
|
+
}
|
|
32
|
+
/** Transaction direction. */
|
|
33
|
+
export type TransactionDirection = 0 | 1;
|
|
34
|
+
/** Single transaction info. */
|
|
35
|
+
export interface TransactionInfo {
|
|
36
|
+
hash: string;
|
|
37
|
+
direction: TransactionDirection;
|
|
38
|
+
isPending: boolean;
|
|
39
|
+
isFailed: boolean;
|
|
40
|
+
isCoinbase: boolean;
|
|
41
|
+
amount: string;
|
|
42
|
+
fee: string;
|
|
43
|
+
blockHeight: number;
|
|
44
|
+
confirmations: number;
|
|
45
|
+
timestamp: number;
|
|
46
|
+
paymentId: string;
|
|
47
|
+
description: string;
|
|
48
|
+
label: string;
|
|
49
|
+
unlockTime: number;
|
|
50
|
+
subaddrAccount: number;
|
|
51
|
+
txKey?: string;
|
|
52
|
+
}
|
|
53
|
+
/** Return type for getAllTransactions. */
|
|
54
|
+
export interface TransactionsPage {
|
|
55
|
+
transactions: TransactionInfo[];
|
|
56
|
+
totalCount: number;
|
|
57
|
+
page: number;
|
|
58
|
+
pageSize: number;
|
|
59
|
+
}
|
|
60
|
+
/** Transaction priority levels. */
|
|
61
|
+
export type TransactionPriority = 0 | 1 | 2 | 3;
|
|
62
|
+
/** Recipient for createTransaction. */
|
|
63
|
+
export interface Recipient {
|
|
64
|
+
address: string;
|
|
65
|
+
amount: string;
|
|
66
|
+
}
|
|
67
|
+
/** Return type for createTransaction. */
|
|
68
|
+
export interface SignedTransaction {
|
|
69
|
+
txid: string;
|
|
70
|
+
signedTxHex: string;
|
|
71
|
+
fee: string;
|
|
72
|
+
}
|
|
73
|
+
/** Return type for broadcastTransaction. */
|
|
74
|
+
export interface BroadcastResult {
|
|
75
|
+
/**
|
|
76
|
+
* The transaction secret key, when the wallet can report it. The sender's
|
|
77
|
+
* only proof of payment: chosen at random while building the transaction,
|
|
78
|
+
* held only by the wallet that built it, and never recoverable later.
|
|
79
|
+
*/
|
|
80
|
+
txKey?: string;
|
|
81
|
+
}
|
|
82
|
+
/** Parsed Monero URI (parseUri result). */
|
|
83
|
+
export interface ParsedUri {
|
|
84
|
+
address: string;
|
|
85
|
+
paymentId: string;
|
|
86
|
+
amount: string;
|
|
87
|
+
txDescription: string;
|
|
88
|
+
recipientName: string;
|
|
89
|
+
unknownParameters: string[];
|
|
90
|
+
}
|
|
91
|
+
/** Params for encodeUri (make monero: URI). */
|
|
92
|
+
export interface EncodeUriParams {
|
|
93
|
+
address: string;
|
|
94
|
+
paymentId?: string;
|
|
95
|
+
amount: string;
|
|
96
|
+
txDescription?: string;
|
|
97
|
+
recipientName?: string;
|
|
98
|
+
}
|
|
99
|
+
/** Wallet event names emitted by the native WalletListener. */
|
|
100
|
+
export type WalletEventName = 'pendingTransactionReceived' | 'nymFetchRequest';
|
|
101
|
+
/** Payload delivered by "MoneroWalletEvent" NativeEventEmitter events. */
|
|
102
|
+
export interface WalletEventData {
|
|
103
|
+
walletId: string;
|
|
104
|
+
eventName: WalletEventName;
|
|
105
|
+
/**
|
|
106
|
+
* JSON string whose shape depends on `eventName`:
|
|
107
|
+
* - pendingTransactionReceived: { txId: string, amount: number }
|
|
108
|
+
* - nymFetchRequest: { url, method, headers, bodyBase64 } — in this
|
|
109
|
+
* case `walletId` holds the nym requestId that must be passed to
|
|
110
|
+
* `resolveFetch` / `rejectFetch`.
|
|
111
|
+
*/
|
|
112
|
+
data: string;
|
|
113
|
+
}
|
|
114
|
+
/** Parsed payload for the `nymFetchRequest` wallet event. */
|
|
115
|
+
export interface NymFetchRequestPayload {
|
|
116
|
+
url: string;
|
|
117
|
+
method: string;
|
|
118
|
+
headers: Record<string, string>;
|
|
119
|
+
bodyBase64: string;
|
|
120
|
+
}
|
package/lib/src/types.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.networkTypeToIntString = networkTypeToIntString;
|
|
4
|
+
const networkTypeMap = {
|
|
5
|
+
MAINNET: 0,
|
|
6
|
+
TESTNET: 1,
|
|
7
|
+
STAGENET: 2
|
|
8
|
+
};
|
|
9
|
+
function networkTypeToIntString(type) {
|
|
10
|
+
return networkTypeMap[type]?.toString() ?? '0';
|
|
11
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = package['name']
|
|
7
|
+
s.version = package['version']
|
|
8
|
+
s.summary = package['description']
|
|
9
|
+
s.homepage = package['homepage']
|
|
10
|
+
s.license = package['license']
|
|
11
|
+
s.authors = package['author']
|
|
12
|
+
|
|
13
|
+
s.platform = :ios, "13.0"
|
|
14
|
+
s.requires_arc = true
|
|
15
|
+
s.source = {
|
|
16
|
+
:git => "https://github.com/EdgeApp/monero-native.git",
|
|
17
|
+
:tag => "v#{s.version}"
|
|
18
|
+
}
|
|
19
|
+
s.source_files =
|
|
20
|
+
"ios/MoneroModule.h",
|
|
21
|
+
"ios/MoneroModule.mm",
|
|
22
|
+
"src/monero-wrapper/monero-methods.hpp"
|
|
23
|
+
s.vendored_frameworks = "ios/MoneroModule.xcframework"
|
|
24
|
+
s.libraries = "c++"
|
|
25
|
+
|
|
26
|
+
s.dependency "React-Core"
|
|
27
|
+
s.frameworks = 'Security'
|
|
28
|
+
end
|
package/node.d.ts
ADDED
package/node.js
ADDED