@bennyblader/ddk-rn 0.1.4 → 0.2.0

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/README.md CHANGED
@@ -1,33 +1,206 @@
1
- # ddk-rn
1
+ # @bennyblader/ddk-rn
2
2
 
3
- rust-dlc bindings for react-native
3
+ React Native bindings for the DLC Dev Kit (DDK) - UniFFI-based native bindings for React Native applications.
4
4
 
5
5
  ## Installation
6
6
 
7
- ```sh
8
- npm install ddk-rn
7
+ ```bash
8
+ npm install @bennyblader/ddk-rn
9
+ # or
10
+ pnpm add @bennyblader/ddk-rn
9
11
  ```
10
12
 
11
- ## Usage
13
+ ## Quick Start
12
14
 
15
+ ```typescript
16
+ import { version, createFundTxLockingScript } from '@bennyblader/ddk-rn';
13
17
 
14
- ```js
15
- import { multiply } from 'ddk-rn';
18
+ console.log(`DDK Version: ${version()}`);
19
+ ```
20
+
21
+ For complete API documentation, see the [main README](../README.md#api-reference).
22
+
23
+ ## Development
24
+
25
+ ### Prerequisites
16
26
 
17
- // ...
27
+ - Node.js >= 14
28
+ - Rust >= 1.70
29
+ - pnpm
30
+ - UniFFI React Native: `npm install -g uniffi-bindgen-react-native`
31
+ - iOS: Xcode 14+, CocoaPods
32
+ - Android: Android Studio, NDK
18
33
 
19
- const result = multiply(3, 7);
34
+ ### Building from Source
35
+
36
+ ```bash
37
+ # Install dependencies
38
+ pnpm install
39
+
40
+ # Generate all bindings and build native libraries
41
+ just uniffi
42
+
43
+ # Note: After building, manually fix the include path in cpp/bennyblader-ddk-rn.cpp
44
+ # Change: #include "/ddk_ffi.hpp"
45
+ # To: #include "ddk_ffi.hpp"
20
46
  ```
21
47
 
48
+ ### Just Commands
22
49
 
23
- ## Contributing
50
+ ```bash
51
+ # Complete build (generates bindings + builds iOS/Android)
52
+ just uniffi
24
53
 
25
- See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
54
+ # Generate JSI bindings only
55
+ just uniffi-jsi
26
56
 
27
- ## License
57
+ # Generate TurboModule specifications
58
+ just uniffi-turbo
28
59
 
29
- MIT
60
+ # Build iOS libraries
61
+ just build-ios
62
+
63
+ # Build Android libraries
64
+ just build-android
65
+
66
+ # Setup example app
67
+ just example
68
+
69
+ # iOS example setup
70
+ just example-ios
71
+
72
+ # Android example build
73
+ just example-android
74
+
75
+ # Clean all generated files
76
+ just clean
77
+
78
+ # Release new version
79
+ just release
80
+
81
+ # Create release archives
82
+ just release-archives
83
+ ```
84
+
85
+ ### Project Structure
86
+
87
+ ```
88
+ ddk-rn/
89
+ ├── src/ # Generated TypeScript bindings
90
+ │ ├── index.tsx # Main entry point (generated)
91
+ │ └── ddk_ffi*.ts # Type definitions (generated)
92
+ ├── cpp/ # Generated C++ JSI bindings
93
+ │ ├── ddk_ffi.hpp # C++ header (generated)
94
+ │ ├── ddk_ffi.cpp # C++ implementation (generated)
95
+ │ └── *.cpp/.h # TurboModule files (generated)
96
+ ├── ios/ # iOS native module
97
+ │ ├── DdkRn.xcframework/ # iOS framework (generated)
98
+ │ └── *.swift/.m # iOS bridge code
99
+ ├── android/ # Android native module
100
+ │ └── src/main/
101
+ │ ├── java/ # Kotlin/Java bridge code
102
+ │ └── jniLibs/ # Native libraries (generated)
103
+ ├── example/ # Example React Native app
104
+ ├── scripts/ # Build and release scripts
105
+ └── ubrn.config.yaml # UniFFI React Native configuration
106
+ ```
107
+
108
+ ### Platform Support
109
+
110
+ | Platform | Architecture | Status |
111
+ | ------------- | ------------ | ------------ |
112
+ | iOS | ARM64 | ✅ Supported |
113
+ | iOS Simulator | x64/ARM64 | ✅ Supported |
114
+ | Android | ARM64-v8a | ✅ Supported |
115
+ | Android | ARMv7 | ✅ Supported |
116
+ | Android | x86_64 | ✅ Supported |
117
+
118
+ ### Building the Example App
119
+
120
+ #### iOS
121
+
122
+ ```bash
123
+ # Install iOS dependencies with new architecture
124
+ just example-ios
125
+
126
+ # Run the app
127
+ cd example
128
+ npx react-native run-ios
129
+ ```
130
+
131
+ #### Android
30
132
 
31
- ---
133
+ ```bash
134
+ # Build Android app
135
+ just example-android
32
136
 
33
- Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
137
+ # Run the app
138
+ cd example
139
+ npx react-native run-android
140
+ ```
141
+
142
+ ### Release Process
143
+
144
+ To release a new version:
145
+
146
+ ```bash
147
+ just release
148
+ ```
149
+
150
+ This will:
151
+
152
+ 1. Build all native bindings
153
+ 2. Run tests
154
+ 3. Update version
155
+ 4. Create release commit and tag
156
+ 5. Push to GitHub
157
+ 6. Publish to npm
158
+
159
+ ### API Compatibility
160
+
161
+ The React Native bindings maintain 100% API compatibility with the UniFFI definitions. All functions are generated directly from the UDL file ensuring consistency across platforms.
162
+
163
+ ### Known Issues
164
+
165
+ 1. **Manual Include Path Fix**: After running `just uniffi`, you must manually fix the include path in `cpp/bennyblader-ddk-rn.cpp`:
166
+ - Change: `#include "/ddk_ffi.hpp"`
167
+ - To: `#include "ddk_ffi.hpp"`
168
+
169
+ 2. **New Architecture**: The library requires React Native's new architecture to be enabled:
170
+ - iOS: Set `RCT_NEW_ARCH_ENABLED=1`
171
+ - Android: Set `newArchEnabled=true` in `gradle.properties`
172
+
173
+ ## Troubleshooting
174
+
175
+ ### iOS Build Issues
176
+
177
+ If you encounter build issues on iOS:
178
+
179
+ ```bash
180
+ cd example/ios
181
+ pod deintegrate
182
+ pod install
183
+ ```
184
+
185
+ ### Android Build Issues
186
+
187
+ Clean and rebuild Android:
188
+
189
+ ```bash
190
+ cd example/android
191
+ ./gradlew clean
192
+ ./gradlew build
193
+ ```
194
+
195
+ ### Missing Bindings
196
+
197
+ If bindings are missing, regenerate them:
198
+
199
+ ```bash
200
+ just clean
201
+ just uniffi
202
+ ```
203
+
204
+ ## License
205
+
206
+ MIT
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bennyblader/ddk-rn",
3
- "version": "0.1.4",
4
- "description": "rust-dlc bindings for react-native",
3
+ "version": "0.2.0",
4
+ "description": "dlcdevkit bindings for react-native",
5
5
  "source": "./src/index.tsx",
6
6
  "main": "./lib/commonjs/index.js",
7
7
  "module": "./lib/module/index.js",
@@ -21,20 +21,27 @@
21
21
  "files": [
22
22
  "src",
23
23
  "lib",
24
- "android",
25
- "ios",
26
24
  "cpp",
25
+ "android/build.gradle",
26
+ "android/CMakeLists.txt",
27
+ "android/cpp-adapter.cpp",
28
+ "android/gradle.properties",
29
+ "android/proguard-rules.pro",
30
+ "android/src/main/AndroidManifest.xml",
31
+ "android/src/main/AndroidManifestNew.xml",
32
+ "android/src/main/java",
33
+ "ios/DdkRn.h",
34
+ "ios/DdkRn.mm",
27
35
  "scripts/postinstall.js",
28
36
  "*.podspec",
29
37
  "react-native.config.json",
30
- "!ios/build",
31
- "!ios/*.xcframework",
32
- "!android/build",
33
- "!android/gradle",
34
- "!android/gradlew",
35
- "!android/gradlew.bat",
36
- "!android/local.properties",
37
- "!android/src/main/jniLibs",
38
+ "README.md",
39
+ "!**/*.a",
40
+ "!**/*.so",
41
+ "!**/*.dylib",
42
+ "!**/*.framework",
43
+ "!**/*.xcframework",
44
+ "!**/jniLibs",
38
45
  "!**/__tests__",
39
46
  "!**/__fixtures__",
40
47
  "!**/__mocks__",
@@ -77,7 +84,6 @@
77
84
  },
78
85
  "devDependencies": {
79
86
  "@commitlint/config-conventional": "^17.0.2",
80
- "@evilmartians/lefthook": "^1.5.0",
81
87
  "@react-native-community/cli": "15.0.0-alpha.2",
82
88
  "@react-native/eslint-config": "^0.73.1",
83
89
  "@release-it/conventional-changelog": "^9.0.2",
@@ -104,12 +110,15 @@
104
110
  "react": "*",
105
111
  "react-native": "*"
106
112
  },
107
- "packageManager": "yarn@3.6.1",
108
113
  "jest": {
109
- "preset": "react-native",
114
+ "testEnvironment": "node",
110
115
  "modulePathIgnorePatterns": [
111
116
  "<rootDir>/example/node_modules",
112
117
  "<rootDir>/lib/"
118
+ ],
119
+ "testMatch": [
120
+ "**/__tests__/**/*.js",
121
+ "**/?(*.)+(spec|test).js"
113
122
  ]
114
123
  },
115
124
  "commitlint": {
@@ -5,25 +5,47 @@ const path = require('path');
5
5
  const https = require('https');
6
6
  const { execSync } = require('child_process');
7
7
 
8
- // Get package version to determine which release to download
9
- // __dirname is ddk-rn/scripts/, so package.json is at ../package.json
10
- const packageJsonPath = path.join(__dirname, '..', 'package.json');
11
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
8
+ const packageRoot = path.join(__dirname, '..');
9
+ const packageJson = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8'));
12
10
  const version = packageJson.version;
13
11
 
14
12
  const GITHUB_REPO = 'bennyhodl/ddk-ffi';
15
13
  const RELEASE_TAG = `v${version}`;
16
14
 
17
- // Detect platform and architecture
18
- const platform = process.platform;
19
- const arch = process.arch;
15
+ console.log(`📦 DDK-RN Post-install: Setting up native binaries for v${version}...`);
20
16
 
21
- console.log(`📦 Installing native binaries for ${platform}-${arch}...`);
17
+ // Define all required files for verification
18
+ const requiredFiles = {
19
+ 'TypeScript bindings': [
20
+ 'src/ddk_ffi.ts',
21
+ 'src/ddk_ffi-ffi.ts',
22
+ 'src/NativeDdkRn.ts',
23
+ 'src/index.tsx'
24
+ ],
25
+ 'C++ bindings': [
26
+ 'cpp/ddk_ffi.hpp',
27
+ 'cpp/ddk_ffi.cpp',
28
+ 'cpp/bennyblader-ddk-rn.h',
29
+ 'cpp/bennyblader-ddk-rn.cpp'
30
+ ],
31
+ 'Android libraries': [
32
+ 'android/src/main/arm64-v8a/libddk_ffi.a',
33
+ 'android/src/main/armeabi-v7a/libddk_ffi.a',
34
+ 'android/src/main/x86/libddk_ffi.a',
35
+ 'android/src/main/x86_64/libddk_ffi.a'
36
+ ],
37
+ 'iOS framework': [
38
+ 'ios/DdkRn.xcframework/Info.plist',
39
+ 'ios/DdkRn.xcframework/ios-arm64/libddk_ffi.a',
40
+ 'ios/DdkRn.xcframework/ios-arm64-simulator/libddk_ffi.a'
41
+ ],
42
+ 'JavaScript modules': [
43
+ 'lib/commonjs/index.js',
44
+ 'lib/module/index.js'
45
+ ]
46
+ };
22
47
 
23
48
  // Create directories if they don't exist
24
- const androidLibsDir = path.join(__dirname, '..', 'android', 'src', 'main', 'jniLibs');
25
- const iosFrameworksDir = path.join(__dirname, '..', 'ios');
26
-
27
49
  function ensureDir(dir) {
28
50
  if (!fs.existsSync(dir)) {
29
51
  fs.mkdirSync(dir, { recursive: true });
@@ -32,7 +54,7 @@ function ensureDir(dir) {
32
54
 
33
55
  function downloadFile(url, dest) {
34
56
  return new Promise((resolve, reject) => {
35
- console.log(`⬇️ Downloading ${url}`);
57
+ console.log(`⬇️ Downloading from ${url}...`);
36
58
 
37
59
  const file = fs.createWriteStream(dest);
38
60
 
@@ -71,60 +93,141 @@ function extractTarGz(tarPath, extractDir) {
71
93
  }
72
94
  }
73
95
 
96
+ function verifyAllFiles() {
97
+ console.log('\n🔍 Verifying all required files...');
98
+
99
+ let allFilesPresent = true;
100
+ const platform = process.platform;
101
+
102
+ for (const [category, files] of Object.entries(requiredFiles)) {
103
+ // Skip iOS files on non-macOS platforms
104
+ if (category === 'iOS framework' && platform !== 'darwin') {
105
+ console.log(`\n⚠️ Skipping ${category} verification (not on macOS)`);
106
+ continue;
107
+ }
108
+
109
+ console.log(`\n📋 Checking ${category}...`);
110
+
111
+ for (const file of files) {
112
+ const filePath = path.join(packageRoot, file);
113
+ if (fs.existsSync(filePath)) {
114
+ console.log(` ✅ ${file}`);
115
+ } else {
116
+ console.error(` ❌ Missing: ${file}`);
117
+ allFilesPresent = false;
118
+ }
119
+ }
120
+ }
121
+
122
+ return allFilesPresent;
123
+ }
124
+
74
125
  async function downloadAndExtractBinaries() {
126
+ const platform = process.platform;
127
+
75
128
  try {
76
- // Download Android JNI libraries
129
+ // Download Android native libraries
130
+ const androidLibsDir = path.join(packageRoot, 'android', 'src', 'main');
131
+ ensureDir(androidLibsDir);
132
+
77
133
  const androidArchiveUrl = `https://github.com/${GITHUB_REPO}/releases/download/${RELEASE_TAG}/android-jni-libs.tar.gz`;
78
- const androidTarPath = path.join(__dirname, '..', 'android-jni-libs.tar.gz');
134
+ const androidTarPath = path.join(packageRoot, 'android-jni-libs.tar.gz');
79
135
 
80
- ensureDir(androidLibsDir);
136
+ console.log('\n📱 Setting up Android native libraries...');
81
137
  await downloadFile(androidArchiveUrl, androidTarPath);
82
- extractTarGz(androidTarPath, path.join(__dirname, '..', 'android', 'src', 'main'));
83
- fs.unlinkSync(androidTarPath); // Clean up
138
+ extractTarGz(androidTarPath, androidLibsDir);
139
+ fs.unlinkSync(androidTarPath); // Clean up tar file
84
140
 
85
- // Download iOS XCFramework (only on macOS for iOS development)
141
+ // Download iOS XCFramework (only on macOS)
86
142
  if (platform === 'darwin') {
143
+ const iosFrameworksDir = path.join(packageRoot, 'ios');
144
+ ensureDir(iosFrameworksDir);
145
+
87
146
  const iosArchiveUrl = `https://github.com/${GITHUB_REPO}/releases/download/${RELEASE_TAG}/ios-xcframeworks.tar.gz`;
88
- const iosTarPath = path.join(__dirname, '..', 'ios-xcframeworks.tar.gz');
147
+ const iosTarPath = path.join(packageRoot, 'ios-xcframeworks.tar.gz');
89
148
 
90
- ensureDir(iosFrameworksDir);
149
+ console.log('\n🍎 Setting up iOS framework...');
91
150
  await downloadFile(iosArchiveUrl, iosTarPath);
92
151
  extractTarGz(iosTarPath, iosFrameworksDir);
93
- fs.unlinkSync(iosTarPath); // Clean up
152
+ fs.unlinkSync(iosTarPath); // Clean up tar file
94
153
  } else {
95
- console.log('⚠️ Skipping iOS binaries (not on macOS)');
154
+ console.log('\n⚠️ Skipping iOS framework (not on macOS)');
96
155
  }
97
156
 
98
- console.log('🎉 All native binaries installed successfully!');
99
-
100
157
  } catch (error) {
101
- console.error('❌ Failed to install native binaries:', error.message);
158
+ console.error('\n❌ Failed to download native binaries:', error.message);
102
159
  console.error('');
103
- console.error('📋 Manual installation:');
160
+ console.error('📋 Manual installation instructions:');
104
161
  console.error(` 1. Download binaries from: https://github.com/${GITHUB_REPO}/releases/tag/${RELEASE_TAG}`);
105
162
  console.error(' 2. Extract android-jni-libs.tar.gz to android/src/main/');
106
163
  console.error(' 3. Extract ios-xcframeworks.tar.gz to ios/ (macOS only)');
107
164
  console.error('');
165
+ console.error('Or report this issue at: https://github.com/bennyhodl/ddk-ffi/issues');
108
166
 
109
- // Don't fail the installation - let users manually install if needed
167
+ // Don't fail the installation completely
110
168
  process.exit(0);
111
169
  }
112
170
  }
113
171
 
114
- // Check if binaries already exist (skip if they do)
115
- const androidLibExists = fs.existsSync(path.join(androidLibsDir, 'arm64-v8a'));
116
- const iosFrameworkExists = fs.existsSync(path.join(iosFrameworksDir, 'DdkFFI.xcframework'));
117
-
118
- if (androidLibExists && (platform !== 'darwin' || iosFrameworkExists)) {
119
- console.log('✅ Native binaries already installed, skipping download.');
120
- process.exit(0);
121
- }
122
-
123
- // Only download if we're not in a CI environment or explicit opt-in
124
- if (process.env.CI && !process.env.DOWNLOAD_BINARIES) {
125
- console.log('⚠️ Skipping binary download in CI environment.');
126
- console.log(' Set DOWNLOAD_BINARIES=1 to force download in CI.');
127
- process.exit(0);
172
+ async function main() {
173
+ const platform = process.platform;
174
+
175
+ // Skip in CI unless explicitly requested
176
+ if (process.env.CI && !process.env.DOWNLOAD_BINARIES) {
177
+ console.log('⚠️ Skipping binary download in CI environment.');
178
+ console.log(' Set DOWNLOAD_BINARIES=1 to force download in CI.');
179
+ process.exit(0);
180
+ }
181
+
182
+ // Check if binaries already exist
183
+ const androidLibExists = fs.existsSync(path.join(packageRoot, 'android', 'src', 'main', 'arm64-v8a', 'libddk_ffi.a'));
184
+ const iosFrameworkExists = fs.existsSync(path.join(packageRoot, 'ios', 'DdkRn.xcframework'));
185
+
186
+ let needsDownload = false;
187
+
188
+ if (!androidLibExists) {
189
+ console.log('📱 Android libraries not found, will download...');
190
+ needsDownload = true;
191
+ }
192
+
193
+ if (platform === 'darwin' && !iosFrameworkExists) {
194
+ console.log('🍎 iOS framework not found, will download...');
195
+ needsDownload = true;
196
+ }
197
+
198
+ if (needsDownload) {
199
+ await downloadAndExtractBinaries();
200
+ } else {
201
+ console.log('✅ Native binaries already present.');
202
+ }
203
+
204
+ // Fix the C++ include path issue if needed
205
+ const cppFile = path.join(packageRoot, 'cpp', 'bennyblader-ddk-rn.cpp');
206
+ if (fs.existsSync(cppFile)) {
207
+ let content = fs.readFileSync(cppFile, 'utf8');
208
+ if (content.includes('#include "/ddk_ffi.hpp"')) {
209
+ content = content.replace('#include "/ddk_ffi.hpp"', '#include "ddk_ffi.hpp"');
210
+ fs.writeFileSync(cppFile, content);
211
+ console.log('\n🔧 Fixed include path in C++ bindings');
212
+ }
213
+ }
214
+
215
+ // Verify all files are present
216
+ const allFilesPresent = verifyAllFiles();
217
+
218
+ if (!allFilesPresent) {
219
+ console.error('\n❌ Some required files are missing!');
220
+ console.error('The package installation may have failed.');
221
+ console.error('Please report this issue at: https://github.com/bennyhodl/ddk-ffi/issues');
222
+ process.exit(1);
223
+ }
224
+
225
+ console.log('\n✅ All required files verified!');
226
+ console.log('🎉 DDK-RN is ready to use!\n');
128
227
  }
129
228
 
130
- downloadAndExtractBinaries();
229
+ // Run the main function
230
+ main().catch(error => {
231
+ console.error('❌ Unexpected error:', error);
232
+ process.exit(1);
233
+ });
package/LICENSE DELETED
@@ -1,20 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 benny b
4
- Permission is hereby granted, free of charge, to any person obtaining a copy
5
- of this software and associated documentation files (the "Software"), to deal
6
- in the Software without restriction, including without limitation the rights
7
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- copies of the Software, and to permit persons to whom the Software is
9
- furnished to do so, subject to the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be included in all
12
- copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
- SOFTWARE.