dash-shielded-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 +5 -0
- package/LICENSE +27 -0
- package/README.md +36 -0
- package/android/build.gradle +56 -0
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/java/app/edge/rndashshielded/RNDashShieldedModule.kt +215 -0
- package/android/src/main/java/app/edge/rndashshielded/RNDashShieldedPackage.kt +16 -0
- package/android/src/main/java/uniffi/dash/dash.kt +1665 -0
- package/android/src/main/jniLibs/arm64-v8a/libdashshielded.so +0 -0
- package/dash-shielded-native.podspec +32 -0
- package/ios/.uniffi-generated +1 -0
- package/ios/EdgeDashClient.swift +88 -0
- package/ios/RNDashShielded.m +83 -0
- package/ios/RNDashShielded.swift +214 -0
- package/ios/dash-shielded-native-Bridging-Header.h +2 -0
- package/ios/dash.swift +1124 -0
- package/ios/libdashshielded.xcframework/Info.plist +47 -0
- package/ios/libdashshielded.xcframework/ios-arm64/Headers/dashFFI.h +696 -0
- package/ios/libdashshielded.xcframework/ios-arm64/Headers/module.modulemap +7 -0
- package/ios/libdashshielded.xcframework/ios-arm64/libdashshielded.a +0 -0
- package/ios/libdashshielded.xcframework/ios-arm64-simulator/Headers/dashFFI.h +696 -0
- package/ios/libdashshielded.xcframework/ios-arm64-simulator/Headers/module.modulemap +7 -0
- package/ios/libdashshielded.xcframework/ios-arm64-simulator/libdashshielded.a +0 -0
- package/lib/load-addon.d.ts +34 -0
- package/lib/node.d.ts +50 -0
- package/lib/react-native.d.ts +31 -0
- package/lib/rndash.rn.js +267 -0
- package/lib/rndash.rn.js.map +1 -0
- package/lib/src/node.js +328 -0
- package/lib/src/node.js.map +1 -0
- package/lib/types.d.ts +73 -0
- package/node.d.ts +1 -0
- package/node.js +2 -0
- package/package.json +105 -0
- package/prebuilds/darwin-arm64/dashshielded.node +0 -0
- package/rust/Cargo.lock +6795 -0
- package/rust/Cargo.toml +63 -0
- package/rust/build.rs +7 -0
- package/rust/rust-toolchain.toml +3 -0
- package/rust/src/dash.udl +90 -0
- package/rust/src/lib.rs +16 -0
- package/rust/src/napi_api.rs +164 -0
- package/rust/src/uniffi_api.rs +116 -0
- package/rust/src/wallet.rs +888 -0
- package/rust/uniffi-bindgen.rs +3 -0
- package/src/load-addon.ts +99 -0
- package/src/node.ts +248 -0
- package/src/react-native.ts +212 -0
- package/src/types.ts +88 -0
package/CHANGELOG.md
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Airbitz, Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
This package wraps the Dash Platform wallet crates, which are MIT, and ships
|
|
26
|
+
binaries compiled from them. The Rust dependencies they pull in remain under
|
|
27
|
+
their own licenses.
|
package/README.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# dash-shielded-native
|
|
2
|
+
|
|
3
|
+
Native Dash Platform shielded-pool wallet library for React Native and Node.js.
|
|
4
|
+
|
|
5
|
+
One package serves both hosts, matching `monero-native` / `zcash-native` / `zano-native`:
|
|
6
|
+
|
|
7
|
+
| Export | Backend |
|
|
8
|
+
|--------|---------|
|
|
9
|
+
| `dash-shielded-native` / `./rn` | UniFFI iOS + Android |
|
|
10
|
+
| `dash-shielded-native/node` | N-API (`makeNodeDashShieldedModule`) |
|
|
11
|
+
|
|
12
|
+
v1 covers keys, `dash1z` / `tdash1z` addresses, sync stubs, and `ShieldedTransfer` proposal/create. Create currently requires `rs-platform-wallet` DAPI bindings before a live testnet send.
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
import { makeNodeDashShieldedModule } from 'dash-shielded-native/node'
|
|
16
|
+
|
|
17
|
+
const io = makeNodeDashShieldedModule({ documentDirectory })
|
|
18
|
+
const keys = await io.Tools.deriveViewingKey(mnemonic, 'testnet')
|
|
19
|
+
const synchronizer = await io.makeSynchronizer({
|
|
20
|
+
mnemonicSeed: mnemonic,
|
|
21
|
+
account: 0,
|
|
22
|
+
alias: 'wallet',
|
|
23
|
+
network: 'testnet',
|
|
24
|
+
dataDir: documentDirectory,
|
|
25
|
+
defaultHost: 'seed-1.testnet.networks.dash.org',
|
|
26
|
+
defaultPort: 1443
|
|
27
|
+
})
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Host build:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
socket npm install
|
|
34
|
+
socket npm run build-native-host
|
|
35
|
+
socket npm run smoke-node
|
|
36
|
+
```
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
def kotlinVersion = rootProject.ext.has('kotlinVersion')
|
|
3
|
+
? rootProject.ext.get('kotlinVersion')
|
|
4
|
+
: '2.1.10'
|
|
5
|
+
|
|
6
|
+
repositories {
|
|
7
|
+
mavenCentral()
|
|
8
|
+
google()
|
|
9
|
+
}
|
|
10
|
+
dependencies {
|
|
11
|
+
classpath 'com.android.tools.build:gradle:8.5.0'
|
|
12
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
apply plugin: 'com.android.library'
|
|
17
|
+
apply plugin: 'kotlin-android'
|
|
18
|
+
|
|
19
|
+
def safeExtGet(prop, fallback) {
|
|
20
|
+
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
android {
|
|
24
|
+
compileSdkVersion safeExtGet('compileSdkVersion', 35)
|
|
25
|
+
defaultConfig {
|
|
26
|
+
minSdkVersion safeExtGet('minSdkVersion', 27)
|
|
27
|
+
targetSdkVersion safeExtGet('targetSdkVersion', 35)
|
|
28
|
+
ndk {
|
|
29
|
+
abiFilters 'arm64-v8a'
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
sourceSets {
|
|
33
|
+
main {
|
|
34
|
+
jniLibs.srcDirs = ['src/main/jniLibs']
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
lintOptions {
|
|
38
|
+
abortOnError false
|
|
39
|
+
}
|
|
40
|
+
namespace 'app.edge.rndashshielded'
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
repositories {
|
|
44
|
+
maven {
|
|
45
|
+
url('../node_modules/react-native/android')
|
|
46
|
+
}
|
|
47
|
+
google()
|
|
48
|
+
mavenCentral()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
dependencies {
|
|
52
|
+
implementation 'com.facebook.react:react-native:+'
|
|
53
|
+
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
|
|
54
|
+
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3"
|
|
55
|
+
implementation 'net.java.dev.jna:jna:5.17.0@aar'
|
|
56
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android" />
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
package app.edge.rndashshielded
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
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 com.facebook.react.bridge.WritableMap
|
|
9
|
+
import kotlinx.coroutines.CoroutineScope
|
|
10
|
+
import kotlinx.coroutines.Dispatchers
|
|
11
|
+
import kotlinx.coroutines.launch
|
|
12
|
+
import uniffi.dash.Poll
|
|
13
|
+
import java.io.File
|
|
14
|
+
|
|
15
|
+
class RNDashShieldedModule(
|
|
16
|
+
private val reactContext: ReactApplicationContext,
|
|
17
|
+
) : ReactContextBaseJavaModule(reactContext) {
|
|
18
|
+
private val moduleScope: CoroutineScope = CoroutineScope(Dispatchers.IO)
|
|
19
|
+
|
|
20
|
+
override fun getName() = "RNDashShielded"
|
|
21
|
+
|
|
22
|
+
@Volatile private var documentDirReady = false
|
|
23
|
+
|
|
24
|
+
init {
|
|
25
|
+
System.setProperty("uniffi.component.dash.libraryOverride", "dashshielded")
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
private fun ensureDocumentDirectory() {
|
|
29
|
+
if (documentDirReady) return
|
|
30
|
+
synchronized(this) {
|
|
31
|
+
if (documentDirReady) return
|
|
32
|
+
val dir = File(reactContext.filesDir, "native/dashshielded")
|
|
33
|
+
dir.mkdirs()
|
|
34
|
+
uniffi.dash.setDocumentDirectory(dir.absolutePath)
|
|
35
|
+
documentDirReady = true
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private inline fun Promise.wrap(block: () -> Any?) {
|
|
40
|
+
try {
|
|
41
|
+
ensureDocumentDirectory()
|
|
42
|
+
resolve(block())
|
|
43
|
+
} catch (t: Throwable) {
|
|
44
|
+
reject("Err", t)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private fun pollMap(snap: Poll): WritableMap {
|
|
49
|
+
val transactions = Arguments.createArray()
|
|
50
|
+
snap.transactions.forEach { tx ->
|
|
51
|
+
val map = Arguments.createMap()
|
|
52
|
+
map.putString("txid", tx.txid)
|
|
53
|
+
map.putInt("blockTimeInSeconds", tx.blockTimeInSeconds.toInt())
|
|
54
|
+
map.putInt("minedHeight", tx.minedHeight.toInt())
|
|
55
|
+
map.putString("value", tx.value)
|
|
56
|
+
tx.fee?.let { map.putString("fee", it) }
|
|
57
|
+
tx.toAddress?.let { map.putString("toAddress", it) }
|
|
58
|
+
map.putArray("memos", Arguments.fromList(tx.memos))
|
|
59
|
+
transactions.pushMap(map)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
val out = Arguments.createMap()
|
|
63
|
+
out.putString("alias", snap.alias)
|
|
64
|
+
out.putString("status", snap.status)
|
|
65
|
+
out.putDouble("scanProgress", snap.scanProgress)
|
|
66
|
+
out.putInt("networkBlockHeight", snap.networkBlockHeight.toInt())
|
|
67
|
+
out.putString("availableCredits", snap.availableCredits)
|
|
68
|
+
out.putString("totalCredits", snap.totalCredits)
|
|
69
|
+
out.putArray("transactions", transactions)
|
|
70
|
+
return out
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@ReactMethod
|
|
74
|
+
fun initialize(
|
|
75
|
+
seed: String,
|
|
76
|
+
account: Int,
|
|
77
|
+
alias: String,
|
|
78
|
+
networkName: String,
|
|
79
|
+
defaultHost: String,
|
|
80
|
+
defaultPort: Int,
|
|
81
|
+
promise: Promise,
|
|
82
|
+
) {
|
|
83
|
+
moduleScope.launch {
|
|
84
|
+
promise.wrap {
|
|
85
|
+
uniffi.dash.initialize(
|
|
86
|
+
seed,
|
|
87
|
+
account.toUInt(),
|
|
88
|
+
alias,
|
|
89
|
+
networkName,
|
|
90
|
+
defaultHost,
|
|
91
|
+
defaultPort.toUInt(),
|
|
92
|
+
)
|
|
93
|
+
null
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@ReactMethod
|
|
99
|
+
fun stop(alias: String, promise: Promise) {
|
|
100
|
+
moduleScope.launch {
|
|
101
|
+
promise.wrap { uniffi.dash.stop(alias) }
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@ReactMethod
|
|
106
|
+
fun startSync(alias: String, promise: Promise) {
|
|
107
|
+
moduleScope.launch {
|
|
108
|
+
promise.wrap {
|
|
109
|
+
uniffi.dash.startSync(alias)
|
|
110
|
+
null
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
@ReactMethod
|
|
116
|
+
fun stopSync(alias: String, promise: Promise) {
|
|
117
|
+
moduleScope.launch {
|
|
118
|
+
promise.wrap {
|
|
119
|
+
uniffi.dash.stopSync(alias)
|
|
120
|
+
null
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
@ReactMethod
|
|
126
|
+
fun deriveShieldedAddress(alias: String, promise: Promise) {
|
|
127
|
+
moduleScope.launch {
|
|
128
|
+
promise.wrap {
|
|
129
|
+
val addresses = uniffi.dash.deriveShieldedAddress(alias)
|
|
130
|
+
val map = Arguments.createMap()
|
|
131
|
+
map.putString("shieldedAddress", addresses.shieldedAddress)
|
|
132
|
+
map
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@ReactMethod
|
|
138
|
+
fun deriveShieldedAddressFromSeed(
|
|
139
|
+
seed: String,
|
|
140
|
+
network: String,
|
|
141
|
+
account: Int,
|
|
142
|
+
promise: Promise,
|
|
143
|
+
) {
|
|
144
|
+
moduleScope.launch {
|
|
145
|
+
promise.wrap {
|
|
146
|
+
uniffi.dash.deriveShieldedAddressFromSeed(seed, network, account.toUInt())
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
@ReactMethod
|
|
152
|
+
fun isValidAddress(address: String, network: String, promise: Promise) {
|
|
153
|
+
moduleScope.launch {
|
|
154
|
+
promise.wrap { uniffi.dash.isValidAddress(address, network) }
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
@ReactMethod
|
|
159
|
+
fun deriveViewingKey(seed: String, network: String, promise: Promise) {
|
|
160
|
+
moduleScope.launch {
|
|
161
|
+
promise.wrap { uniffi.dash.deriveViewingKey(seed, network) }
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
@ReactMethod
|
|
166
|
+
fun warmUpProver(promise: Promise) {
|
|
167
|
+
moduleScope.launch {
|
|
168
|
+
promise.wrap {
|
|
169
|
+
uniffi.dash.warmUpProver()
|
|
170
|
+
null
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@ReactMethod
|
|
176
|
+
fun isProverReady(promise: Promise) {
|
|
177
|
+
moduleScope.launch {
|
|
178
|
+
promise.wrap { uniffi.dash.isProverReady() }
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@ReactMethod
|
|
183
|
+
fun poll(alias: String, promise: Promise) {
|
|
184
|
+
moduleScope.launch {
|
|
185
|
+
promise.wrap { pollMap(uniffi.dash.poll(alias)) }
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
@ReactMethod
|
|
190
|
+
fun proposeTransfer(
|
|
191
|
+
alias: String,
|
|
192
|
+
amountCredits: String,
|
|
193
|
+
toAddress: String,
|
|
194
|
+
memo: String?,
|
|
195
|
+
promise: Promise,
|
|
196
|
+
) {
|
|
197
|
+
moduleScope.launch {
|
|
198
|
+
promise.wrap {
|
|
199
|
+
uniffi.dash.proposeTransfer(alias, amountCredits, toAddress, memo)
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
@ReactMethod
|
|
205
|
+
fun createTransfer(
|
|
206
|
+
alias: String,
|
|
207
|
+
proposalId: String,
|
|
208
|
+
seed: String,
|
|
209
|
+
promise: Promise,
|
|
210
|
+
) {
|
|
211
|
+
moduleScope.launch {
|
|
212
|
+
promise.wrap { uniffi.dash.createTransfer(alias, proposalId, seed) }
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
package app.edge.rndashshielded
|
|
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.Collections.emptyList
|
|
8
|
+
|
|
9
|
+
class RNDashShieldedPackage : ReactPackage {
|
|
10
|
+
override fun createNativeModules(reactContext: ReactApplicationContext) =
|
|
11
|
+
listOf<NativeModule>(
|
|
12
|
+
RNDashShieldedModule(reactContext),
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> = emptyList()
|
|
16
|
+
}
|