react-native-monero 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 +0 -0
- package/README.md +45 -0
- package/android/build.gradle +40 -0
- package/android/src/main/java/app/edge/rnmonero/RnMoneroModule.java +51 -0
- package/android/src/main/java/app/edge/rnmonero/RnMoneroPackage.java +21 -0
- package/ios/MoneroModule.h +4 -0
- package/ios/MoneroModule.mm +86 -0
- package/lib/src/index.d.ts +0 -0
- package/lib/src/index.js +1 -0
- package/package.json +48 -0
package/CHANGELOG.md
ADDED
|
File without changes
|
package/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# react-native-monero-lwsf
|
|
2
|
+
|
|
3
|
+
This library packages Monero C++ client for use on React Native.
|
|
4
|
+
|
|
5
|
+
Supported platforms:
|
|
6
|
+
|
|
7
|
+
- Android
|
|
8
|
+
- iOS
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
First, add this library to your React Native app using NPM or Yarn, and run `pod install` as necessary to integrate it with your app's native code.
|
|
13
|
+
|
|
14
|
+
Here is a simple usage example:
|
|
15
|
+
|
|
16
|
+
```js
|
|
17
|
+
import { what } from 'react-native-monero-lwsf'
|
|
18
|
+
|
|
19
|
+
// ???
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Developing
|
|
23
|
+
|
|
24
|
+
This library relies on a large amount of native C++ code from other repos. To integrate this code, you must run the following script before publishing this library to NPM:
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
npm run build-native
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
This script does the following tasks:
|
|
31
|
+
|
|
32
|
+
- Download third-party source code.
|
|
33
|
+
- Compile shared libraries for Android.
|
|
34
|
+
- Compile an iOS universal static library and put it into an XCFramework.
|
|
35
|
+
|
|
36
|
+
The `build-native` script is also the place to make edits when upgrading any of the third-party dependencies. The react-native-monero-lwsf repo doesn't include these third-party C++ sources, since they are enormous.
|
|
37
|
+
|
|
38
|
+
For this to work, you need:
|
|
39
|
+
|
|
40
|
+
- A recent Android SDK, installed at `$ANDROID_HOME`
|
|
41
|
+
- Xcode command-line tools
|
|
42
|
+
- `autoreconf`, provided by `brew install autoconf`
|
|
43
|
+
- `automake`, provided by `brew install automake`
|
|
44
|
+
- `cmake`, provided by `brew install cmake`
|
|
45
|
+
- `llvm-objcopy`, provided by `brew install llvm`
|
|
@@ -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,51 @@
|
|
|
1
|
+
package app.edge.rnmonero;
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReadableArray;
|
|
4
|
+
import com.facebook.react.bridge.Promise;
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
6
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
7
|
+
import com.facebook.react.bridge.ReactMethod;
|
|
8
|
+
import java.util.HashMap;
|
|
9
|
+
import java.util.Map;
|
|
10
|
+
|
|
11
|
+
public class RnMoneroModule extends ReactContextBaseJavaModule {
|
|
12
|
+
private native String callMoneroJNI(String method, String[] arguments);
|
|
13
|
+
|
|
14
|
+
private native String[] getMethodNames();
|
|
15
|
+
|
|
16
|
+
static {
|
|
17
|
+
System.loadLibrary("rnmonero");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public RnMoneroModule(ReactApplicationContext reactContext) {
|
|
21
|
+
super(reactContext);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@Override
|
|
25
|
+
public Map<String, Object> getConstants() {
|
|
26
|
+
final Map<String, Object> constants = new HashMap<>();
|
|
27
|
+
constants.put("methodNames", getMethodNames());
|
|
28
|
+
constants.put("documentDirectory", getReactApplicationContext().getFilesDir().getAbsolutePath());
|
|
29
|
+
return constants;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@Override
|
|
33
|
+
public String getName() {
|
|
34
|
+
return "MoneroLwsfModule";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@ReactMethod
|
|
38
|
+
public void callMonero(String method, ReadableArray arguments, Promise promise) {
|
|
39
|
+
// Re-package the arguments:
|
|
40
|
+
String[] strings = new String[arguments.size()];
|
|
41
|
+
for (int i = 0; i < arguments.size(); ++i) {
|
|
42
|
+
strings[i] = arguments.getString(i);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
promise.resolve(callMoneroJNI(method, strings));
|
|
47
|
+
} catch (Exception e) {
|
|
48
|
+
promise.reject("MoneroError", e);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -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,86 @@
|
|
|
1
|
+
#import "MoneroModule.h"
|
|
2
|
+
#include "monero-methods.hpp"
|
|
3
|
+
|
|
4
|
+
@implementation MoneroModule
|
|
5
|
+
|
|
6
|
+
RCT_EXPORT_MODULE();
|
|
7
|
+
|
|
8
|
+
+ (BOOL)requiresMainQueueSetup { return NO; }
|
|
9
|
+
|
|
10
|
+
RCT_REMAP_METHOD(
|
|
11
|
+
callMonero,
|
|
12
|
+
callMoneroMethod:(NSString *)method
|
|
13
|
+
arguments:(NSArray *)arguments
|
|
14
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
15
|
+
rejecter:(RCTPromiseRejectBlock)reject
|
|
16
|
+
) {
|
|
17
|
+
const std::string methodString = [method UTF8String];
|
|
18
|
+
|
|
19
|
+
// Re-package the arguments:
|
|
20
|
+
NSUInteger length = [arguments count];
|
|
21
|
+
std::vector<const std::string> strings;
|
|
22
|
+
strings.reserve(length);
|
|
23
|
+
for (NSUInteger i = 0; i < length; ++i) {
|
|
24
|
+
NSString *string = [arguments objectAtIndex:i];
|
|
25
|
+
strings.push_back([string UTF8String]);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Find the named method:
|
|
29
|
+
for (int i = 0; i < moneroMethodCount; ++i) {
|
|
30
|
+
if (moneroMethods[i].name != methodString) continue;
|
|
31
|
+
|
|
32
|
+
// Validate the argument count:
|
|
33
|
+
if (moneroMethods[i].argc != strings.size()) {
|
|
34
|
+
reject(@"Error", @"monero incorrect C++ argument count", nil);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Call the method, with error handling:
|
|
39
|
+
try {
|
|
40
|
+
const std::string out = moneroMethods[i].method(strings);
|
|
41
|
+
resolve(
|
|
42
|
+
[NSString stringWithCString:out.c_str() encoding:NSUTF8StringEncoding]
|
|
43
|
+
);
|
|
44
|
+
} catch (std::exception &e) {
|
|
45
|
+
reject(
|
|
46
|
+
@"Error",
|
|
47
|
+
[NSString stringWithCString:e.what() encoding:NSUTF8StringEncoding],
|
|
48
|
+
nil
|
|
49
|
+
);
|
|
50
|
+
} catch (...) {
|
|
51
|
+
reject(@"Error", @"monero threw a C++ exception", nil);
|
|
52
|
+
}
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
reject(
|
|
57
|
+
@"TypeError",
|
|
58
|
+
[NSString stringWithFormat:@"No monero C++ method %@", method],
|
|
59
|
+
nil
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
- (NSDictionary *)constantsToExport
|
|
64
|
+
{
|
|
65
|
+
NSMutableArray *out = [NSMutableArray arrayWithCapacity:moneroMethodCount];
|
|
66
|
+
for (int i = 0; i < moneroMethodCount; ++i) {
|
|
67
|
+
NSString *name = [NSString stringWithCString:moneroMethods[i].name
|
|
68
|
+
encoding:NSUTF8StringEncoding];
|
|
69
|
+
out[i] = name;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
73
|
+
NSURL *docsDir = [fileManager URLForDirectory:NSDocumentDirectory
|
|
74
|
+
inDomain:NSUserDomainMask
|
|
75
|
+
appropriateForURL:nil
|
|
76
|
+
create:YES
|
|
77
|
+
error:nil];
|
|
78
|
+
NSString *docsPath = [docsDir path];
|
|
79
|
+
|
|
80
|
+
return @{
|
|
81
|
+
@"methodNames": out,
|
|
82
|
+
@"documentDirectory": docsPath
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
@end
|
|
File without changes
|
package/lib/src/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-native-monero",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "React Native bindings for the Monero blockchain",
|
|
5
|
+
"homepage": "https://github.com/EdgeApp/react-native-monero",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git@github.com:EdgeApp/react-native-monero.git"
|
|
9
|
+
},
|
|
10
|
+
"license": "BSD-3-Clause",
|
|
11
|
+
"author": "Airbitz, Inc.",
|
|
12
|
+
"main": "lib/src/index.js",
|
|
13
|
+
"types": "lib/src/index.d.ts",
|
|
14
|
+
"files": [
|
|
15
|
+
"/android/build.gradle",
|
|
16
|
+
"/android/src/",
|
|
17
|
+
"/CHANGELOG.md",
|
|
18
|
+
"/ios/",
|
|
19
|
+
"/lib/src/",
|
|
20
|
+
"/package.json",
|
|
21
|
+
"/README.md"
|
|
22
|
+
],
|
|
23
|
+
"lint-staged": {
|
|
24
|
+
"*.{js,ts}": "eslint"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"fix": "npm run lint -- --fix",
|
|
28
|
+
"lint": "eslint .",
|
|
29
|
+
"-prepack": "npm run build-native",
|
|
30
|
+
"prepare": "husky && lint-staged && rimraf lib && tsc",
|
|
31
|
+
"precommit": "npm run lint",
|
|
32
|
+
"build-native": "ZERO_AR_DATE=1 node -r sucrase/register ./scripts/build-native.ts"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^24.10.0",
|
|
36
|
+
"eslint": "^9.39.1",
|
|
37
|
+
"eslint-config-standard-kit": "^1.0.0",
|
|
38
|
+
"husky": "^9.1.7",
|
|
39
|
+
"lint-staged": "^16.2.6",
|
|
40
|
+
"prettier": "^3.6.2",
|
|
41
|
+
"rimraf": "^6.1.0",
|
|
42
|
+
"sucrase": "^3.35.0",
|
|
43
|
+
"typescript": "^5.9.3"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"cleaners": "^0.3.17"
|
|
47
|
+
}
|
|
48
|
+
}
|