@bennyblader/ddk-rn 0.3.43 → 1.0.0-rc1

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.
Files changed (46) hide show
  1. package/DdkRn.podspec +1 -1
  2. package/README.md +198 -49
  3. package/android/CMakeLists.txt +6 -3
  4. package/android/build.gradle +0 -1
  5. package/android/cpp-adapter.cpp +6 -26
  6. package/android/src/main/jniLibs/arm64-v8a/libddk_ffi.so +0 -0
  7. package/android/src/main/jniLibs/armeabi-v7a/libddk_ffi.so +0 -0
  8. package/android/src/main/jniLibs/x86/libddk_ffi.so +0 -0
  9. package/android/src/main/jniLibs/x86_64/libddk_ffi.so +0 -0
  10. package/cpp/bennyblader-ddk-rn.cpp +1 -1
  11. package/cpp/ddk_ffi.cpp +3446 -2669
  12. package/cpp/ddk_ffi.hpp +139 -255
  13. package/ios/DdkRn.xcframework/Info.plist +43 -0
  14. package/ios/DdkRn.xcframework/ios-arm64/libddk_ffi.a +0 -0
  15. package/ios/DdkRn.xcframework/ios-arm64-simulator/libddk_ffi.a +0 -0
  16. package/lib/commonjs/ddk_ffi-ffi.js +6 -29
  17. package/lib/commonjs/ddk_ffi-ffi.js.map +1 -1
  18. package/lib/commonjs/ddk_ffi.js +2828 -942
  19. package/lib/commonjs/ddk_ffi.js.map +1 -1
  20. package/lib/module/ddk_ffi-ffi.js +6 -29
  21. package/lib/module/ddk_ffi-ffi.js.map +1 -1
  22. package/lib/module/ddk_ffi.js +2750 -874
  23. package/lib/module/ddk_ffi.js.map +1 -1
  24. package/lib/typescript/commonjs/src/ddk_ffi-ffi.d.ts +124 -96
  25. package/lib/typescript/commonjs/src/ddk_ffi-ffi.d.ts.map +1 -1
  26. package/lib/typescript/commonjs/src/ddk_ffi.d.ts +2545 -466
  27. package/lib/typescript/commonjs/src/ddk_ffi.d.ts.map +1 -1
  28. package/lib/typescript/module/src/ddk_ffi-ffi.d.ts +124 -96
  29. package/lib/typescript/module/src/ddk_ffi-ffi.d.ts.map +1 -1
  30. package/lib/typescript/module/src/ddk_ffi.d.ts +2545 -466
  31. package/lib/typescript/module/src/ddk_ffi.d.ts.map +1 -1
  32. package/package.json +24 -45
  33. package/src/ddk_ffi-ffi.ts +609 -170
  34. package/src/ddk_ffi.ts +5643 -1910
  35. package/ubrn.config.yaml +18 -1
  36. package/ddk-ffi/Cargo.lock +0 -1013
  37. package/ddk-ffi/Cargo.toml +0 -36
  38. package/ddk-ffi/build.rs +0 -3
  39. package/ddk-ffi/rust-toolchain.toml +0 -10
  40. package/ddk-ffi/src/ddk_ffi.udl +0 -376
  41. package/ddk-ffi/src/lib.rs +0 -2509
  42. package/ddk-ffi/src/uniffi-bindgen.rs +0 -3
  43. package/ddk-ffi/uniffi.toml +0 -18
  44. package/scripts/apply-hotfix.js +0 -96
  45. package/scripts/postinstall.js +0 -298
  46. package/scripts/prepare-rust-src.js +0 -51
package/DdkRn.podspec CHANGED
@@ -17,7 +17,7 @@ Pod::Spec.new do |s|
17
17
 
18
18
  s.source_files = "ios/**/*.{h,m,mm,swift}", "ios/generated/**/*.{h,m,mm}", "cpp/**/*.{hpp,cpp,c,h}", "cpp/**/*.{hpp,cpp,c,h}"
19
19
  s.vendored_frameworks = "ios/DdkRn.xcframework"
20
- s.dependency "uniffi-bindgen-react-native", "0.29.3-1"
20
+ s.dependency "uniffi-bindgen-react-native", "0.31.0-3"
21
21
 
22
22
  # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
23
23
  # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
package/README.md CHANGED
@@ -10,6 +10,22 @@ npm install @bennyblader/ddk-rn
10
10
  pnpm add @bennyblader/ddk-rn
11
11
  ```
12
12
 
13
+ That's the whole install. The package ships prebuilt native binaries — the iOS
14
+ XCFramework and the Android JNI libraries — so nothing is compiled on your
15
+ machine and no Rust toolchain, Android NDK, or extra download is required.
16
+ `pod install` and Gradle pick the binaries up from `node_modules` directly.
17
+
18
+ Prebuilt platform coverage:
19
+
20
+ | Platform | Architectures |
21
+ |----------|---------------|
22
+ | iOS | `arm64` device, `arm64` simulator |
23
+ | Android | `arm64-v8a`, `armeabi-v7a`, `x86`, `x86_64` |
24
+
25
+ The Intel Mac simulator (`x86_64`) is not included.
26
+
27
+ Prereleases publish to the `next` dist-tag: `npm install @bennyblader/ddk-rn@next`.
28
+
13
29
  ## Quick Start
14
30
 
15
31
  ```typescript
@@ -18,18 +34,70 @@ import { version, createFundTxLockingScript } from '@bennyblader/ddk-rn';
18
34
  console.log(`DDK Version: ${version()}`);
19
35
  ```
20
36
 
21
- For complete API documentation, see the [main README](../README.md#api-reference).
37
+ ### The contract API
38
+
39
+ The whole DLC lifecycle runs on device, with no contract store — every
40
+ transaction is rebuilt from the offer/accept/sign wire messages when it is
41
+ needed, and funding secret keys stay inside Rust behind a `ContractKeyProvider`.
42
+
43
+ ```typescript
44
+ import {
45
+ ContractKeyProvider,
46
+ chainHashFromNetwork,
47
+ createOffer,
48
+ acceptOffer,
49
+ signAccept,
50
+ finalizeSign,
51
+ signContractCet,
52
+ } from '@bennyblader/ddk-rn';
53
+
54
+ const keys = ContractKeyProvider.fromMnemonic(MNEMONIC, undefined, 'regtest');
55
+ const temporaryContractId = new Uint8Array(32).fill(1).buffer;
56
+
57
+ const offer = createOffer({
58
+ chainHash: chainHashFromNetwork('regtest'),
59
+ temporaryContractId,
60
+ contractInfo: CONTRACT_INFO,
61
+ offerCollateralSats: 50_000n,
62
+ party: {
63
+ fundingPubkey: keys.fundingPubkey(temporaryContractId),
64
+ fundingInputs: [FUNDING_INPUT],
65
+ payoutSpk: SPK,
66
+ changeSpk: SPK,
67
+ },
68
+ feeRatePerVb: 2n,
69
+ cetLocktime: 0,
70
+ refundLocktime: 1_700_000_000,
71
+ contractFlags: 0,
72
+ });
73
+ // …acceptOffer → sign the funding PSBT → signAccept → finalizeSign →
74
+ // signContractCet / signContractRefund
75
+ ```
76
+
77
+ Bytes cross the JSI boundary as `ArrayBuffer` (`ddk-ts` uses `Buffer`).
78
+
79
+ `example/src/App.tsx` runs the complete flow on device — offline, deterministic,
80
+ and asserted by the Maestro E2E.
81
+
82
+ For complete API documentation, see the [main README](../README.md#-the-contract-api).
22
83
 
23
84
  ## Development
24
85
 
25
86
  ### Prerequisites
26
87
 
27
- - Node.js >= 14
88
+ - Node.js >= 20
28
89
  - Rust >= 1.70
29
90
  - pnpm
30
- - UniFFI React Native: `npm install -g uniffi-bindgen-react-native`
91
+ - UniFFI React Native, installed globally at the version pinned in
92
+ `package.json`: `pnpm add -g uniffi-bindgen-react-native@<version>`
31
93
  - iOS: Xcode 14+, CocoaPods
32
- - Android: Android Studio, NDK
94
+ - Android: Android Studio, NDK 27.1.12297006
95
+
96
+ > The `uniffi` crate, this package's `uniffi-bindgen-react-native` dependency,
97
+ > and the globally installed binary must all be the same release — the `just`
98
+ > recipes call the binary on `$PATH`, not the one in `node_modules`. A skew shows
99
+ > up as TypeScript errors like "Expected 2 arguments, but got 1" on every
100
+ > generated `.lower()` call.
33
101
 
34
102
  ### Building from Source
35
103
 
@@ -37,30 +105,26 @@ For complete API documentation, see the [main README](../README.md#api-reference
37
105
  # Install dependencies
38
106
  pnpm install
39
107
 
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"
108
+ # Generate all bindings and build the native libraries
109
+ just build
46
110
  ```
47
111
 
48
112
  ### Just Commands
49
113
 
50
114
  ```bash
51
- # Complete build (generates bindings + builds iOS/Android)
52
- just uniffi
115
+ # JSI + TurboModule bindings, the iOS XCFramework, and ddk-ts
116
+ just build
53
117
 
54
- # Generate JSI bindings only
118
+ # Generate JSI bindings only (TypeScript + C++)
55
119
  just uniffi-jsi
56
120
 
57
121
  # Generate TurboModule specifications
58
122
  just uniffi-turbo
59
123
 
60
- # Build iOS libraries
124
+ # Build the iOS XCFramework (release, stripped)
61
125
  just build-ios
62
126
 
63
- # Build Android libraries
127
+ # Build the Android JNI libraries (needs the NDK)
64
128
  just build-android
65
129
 
66
130
  # Setup example app
@@ -72,51 +136,101 @@ just example-ios
72
136
  # Android example build
73
137
  just example-android
74
138
 
139
+ # Report the size of every binary destined for the npm package
140
+ just binary-sizes
141
+
75
142
  # Clean all generated files
76
143
  just clean
77
-
78
- # Release new version
79
- just release
80
-
81
- # Create release archives
82
- just release-archives
83
144
  ```
84
145
 
146
+ > Adding a new `#[uniffi::export]` needs `just build-ios`, not just
147
+ > `just uniffi-jsi`. `uniffi-jsi` regenerates the TypeScript and C++, but the C++
148
+ > calls into the XCFramework, which only `build-ios` rebuilds — skip it and the
149
+ > app fails at link with `Undefined symbols … _uniffi_ddk_ffi_fn_func_<name>`.
150
+ > Nothing earlier in the chain catches this.
151
+
85
152
  ### Project Structure
86
153
 
87
154
  ```
88
155
  ddk-rn/
89
156
  ├── src/ # Generated TypeScript bindings
90
157
  │ ├── index.tsx # Main entry point (generated)
91
- │ └── ddk_ffi*.ts # Type definitions (generated)
158
+ │ ├── ddk_ffi.ts # The API consumers import (generated)
159
+ │ ├── ddk_ffi-ffi.ts # Native JSI symbol declarations (generated)
160
+ │ └── __tests__/ # Hand-written — the only non-generated code in src/
92
161
  ├── cpp/ # Generated C++ JSI bindings
93
162
  │ ├── ddk_ffi.hpp # C++ header (generated)
94
163
  │ ├── ddk_ffi.cpp # C++ implementation (generated)
95
164
  │ └── *.cpp/.h # TurboModule files (generated)
96
165
  ├── ios/ # iOS native module
97
- │ ├── DdkRn.xcframework/ # iOS framework (generated)
98
- │ └── *.swift/.m # iOS bridge code
166
+ │ ├── DdkRn.xcframework/ # Prebuilt iOS framework (generated, shipped)
167
+ │ └── *.h/.mm # iOS bridge code
99
168
  ├── android/ # Android native module
100
169
  │ └── src/main/
101
170
  │ ├── java/ # Kotlin/Java bridge code
102
- │ └── jniLibs/ # Native libraries (generated)
103
- ├── example/ # Example React Native app
104
- ├── scripts/ # Build and release scripts
171
+ │ └── jniLibs/ # Prebuilt native libraries (generated, shipped)
172
+ ├── example/ # Example React Native app + Maestro flows
173
+ ├── patches/ # pnpm patch for an unreleased ubrn fix
174
+ ├── scripts/ # Package verification
105
175
  └── ubrn.config.yaml # UniFFI React Native configuration
106
176
  ```
107
177
 
178
+ Everything in `src/` except `src/__tests__/` is generated — don't hand-edit it,
179
+ and don't "fix" lint errors inside it (those files are in `eslintIgnore` for
180
+ exactly that reason).
181
+
182
+ ### Testing
183
+
184
+ ```bash
185
+ pnpm test # jest
186
+ pnpm typecheck # tsc
187
+ pnpm lint # eslint
188
+ ```
189
+
190
+ `src/__tests__/contractBindings.test.js` is a binding-surface test: the JSI
191
+ bindings can't execute under Node, so it asserts instead that generation was
192
+ complete — every function, record, and constructor present in both the
193
+ TypeScript surface and the native symbol layer. It catches the classic
194
+ regression where `ddk-ffi` changed but `ddk-rn` wasn't regenerated. Runtime
195
+ behavior is covered by the shared Rust (`ddk-ffi` unit tests and the `ddk-ts`
196
+ suite exercise the same functions).
197
+
198
+ ### End-to-end, on a device
199
+
200
+ CI installs the example app on an iOS simulator and an Android emulator and
201
+ drives the full contract flow with Maestro. It is the only layer that exercises
202
+ the real JSI bindings, and the only one that catches an app that never finishes
203
+ launching.
204
+
205
+ | command | needs | time |
206
+ |---|---|---|
207
+ | `just e2e-flows` | nothing — no device, no app | ~15s |
208
+ | `just e2e-ios-test` | the app already installed | ~10s |
209
+ | `just e2e-ios` | full: build + install + run | ~5-10m |
210
+
211
+ Android needs a one-time `just e2e-android-setup` (~1.5GB) to create the
212
+ emulator and AVD, then `just e2e-android`.
213
+
214
+ While editing a flow, stay in `e2e-ios-test`; only rebuild when the app itself
215
+ changes (JS, Rust, or the generated bindings).
216
+
108
217
  ### Platform Support
109
218
 
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 |
219
+ | Platform | Architecture | Status |
220
+ | ------------- | ---------------- | --------------- |
221
+ | iOS | ARM64 | ✅ Supported |
222
+ | iOS Simulator | ARM64 | ✅ Supported |
223
+ | iOS Simulator | x64 (Intel Mac) | ❌ Not included |
224
+ | Android | ARM64-v8a | ✅ Supported |
225
+ | Android | ARMv7 | ✅ Supported |
226
+ | Android | x86 / x86_64 | ✅ Supported |
117
227
 
118
228
  ### Building the Example App
119
229
 
230
+ The example is pinned to React Native 0.80 / React 19.1 — the release these
231
+ bindings are supported against, so the E2E exercises the toolchain consuming
232
+ apps actually build with.
233
+
120
234
  #### iOS
121
235
 
122
236
  ```bash
@@ -141,35 +255,60 @@ npx react-native run-android
141
255
 
142
256
  ### Release Process
143
257
 
144
- To release a new version:
258
+ `ddk-ts` and `ddk-rn` are versioned and released together, from the repo root:
145
259
 
146
260
  ```bash
147
- just release
261
+ just release 0.5.0
148
262
  ```
149
263
 
150
264
  This will:
151
265
 
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
266
+ 1. Check the working directory is clean
267
+ 2. Set the version in `ddk-ts/package.json`, `ddk-rn/package.json` and `ddk-ffi/Cargo.toml`
268
+ 3. Commit, tag as `v0.5.0` and push
269
+
270
+ Publishing happens in CI — pushing the tag is what publishes. The iOS
271
+ XCFramework is built on `macos-latest`, the Android JNI libraries on
272
+ `ubuntu-latest` with the NDK, and a final job assembles both and verifies the
273
+ binaries are in the tarball before publishing. Nothing is published from a
274
+ developer machine; `prepublishOnly` refuses a hand-run `npm publish` that would
275
+ ship without binaries.
276
+
277
+ Update the `[Unreleased]` section of [CHANGELOG.md](./CHANGELOG.md) **before**
278
+ releasing — the release script refuses a dirty tree, so it can't be part of the
279
+ release commit.
158
280
 
159
281
  ### API Compatibility
160
282
 
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.
283
+ All bindings are generated from the compiled `ddk-ffi` library, whose Rust
284
+ source — annotated with UniFFI proc-macros, with no `.udl` file — is the single
285
+ source of truth for the interface.
162
286
 
163
- ### Known Issues
287
+ `@bennyblader/ddk-ts` is hand-written NAPI over the same crates and is kept in
288
+ parity by CI. Two differences to know: bytes are `ArrayBuffer` here and `Buffer`
289
+ there, and a dozen transaction operations are methods on a record here
290
+ (`TxOutput.isDust`, `Transaction.signCet`, …) but free functions there. See the
291
+ [comparison table](../README.md#where-the-two-packages-differ).
164
292
 
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"`
293
+ ### Known Issues
168
294
 
169
- 2. **New Architecture**: The library requires React Native's new architecture to be enabled:
295
+ 1. **New Architecture**: The library requires React Native's new architecture to be enabled:
170
296
  - iOS: Set `RCT_NEW_ARCH_ENABLED=1`
171
297
  - Android: Set `newArchEnabled=true` in `gradle.properties`
172
298
 
299
+ 2. **Android C++ builds need an unreleased ubrn fix.** The generated
300
+ `android/CMakeLists.txt` resolves the ubrn package with
301
+ `require.resolve('uniffi-bindgen-react-native/package.json')`, which throws
302
+ `ERR_PACKAGE_PATH_NOT_EXPORTED` because ubrn's `exports` map doesn't expose
303
+ that subpath. The include dir silently becomes `/cpp/includes` and the build
304
+ dies with `'UniffiCallInvoker.h' file not found`. This repo patches it
305
+ (`patches/uniffi-bindgen-react-native@0.31.0-3.patch`, applied by
306
+ `pnpm install`), but a pnpm patch only applies to this repo — building an
307
+ Android app against the published package hits the original error until ubrn
308
+ ships the fix ([#404](https://github.com/jhugman/uniffi-bindgen-react-native/issues/404),
309
+ fixed on `main`, release tracked in
310
+ [#421](https://github.com/jhugman/uniffi-bindgen-react-native/issues/421)).
311
+
173
312
  ## Troubleshooting
174
313
 
175
314
  ### iOS Build Issues
@@ -198,7 +337,17 @@ If bindings are missing, regenerate them:
198
337
 
199
338
  ```bash
200
339
  just clean
201
- just uniffi
340
+ just build
341
+ ```
342
+
343
+ ### A modified `android/build.gradle` after building
344
+
345
+ `just build-android <abi>` narrows `abiFilters` to the ABIs you passed and wipes
346
+ `jniLibs/` for the rest. Never commit that — a single-ABI `build.gradle` ships an
347
+ app that only runs on one architecture:
348
+
349
+ ```bash
350
+ git checkout android/build.gradle
202
351
  ```
203
352
 
204
353
  ## License
@@ -37,13 +37,16 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-all")
37
37
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
38
38
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
39
39
 
40
+ # Set linker flags for 16KB page size alignment (required for Android 15+)
41
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,max-page-size=16384")
42
+
40
43
  cmake_path(
41
44
  SET MY_RUST_LIB
42
- ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libddk_ffi.a
45
+ ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libddk_ffi.so
43
46
  NORMALIZE
44
47
  )
45
- add_library(my_rust_lib STATIC IMPORTED)
46
- set_target_properties(my_rust_lib PROPERTIES IMPORTED_LOCATION ${MY_RUST_LIB})
48
+ add_library(my_rust_lib SHARED IMPORTED)
49
+ set_target_properties(my_rust_lib PROPERTIES IMPORTED_LOCATION ${MY_RUST_LIB} IMPORTED_NO_SONAME ON)
47
50
 
48
51
  # Add ReactAndroid libraries, being careful to account for different versions.
49
52
  find_package(ReactAndroid REQUIRED CONFIG)
@@ -133,7 +133,6 @@ dependencies {
133
133
  //noinspection GradleDynamicVersion
134
134
  implementation "com.facebook.react:react-native:+"
135
135
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
136
- implementation "net.java.dev.jna:jna:5.17.0@aar"
137
136
  }
138
137
 
139
138
  if (isNewArchitectureEnabled()) {
@@ -24,34 +24,14 @@ Java_com_ddkrn_DdkRnModule_nativeInstallRustCrate(
24
24
  jlong rtPtr,
25
25
  jobject callInvokerHolderJavaObj
26
26
  ) {
27
- // https://github.com/realm/realm-js/blob/main/packages/realm/binding/android/src/main/cpp/io_realm_react_RealmReactModule.cpp#L122-L145
28
- // React Native uses the fbjni library for handling JNI, which has the concept of "hybrid objects",
29
- // which are Java objects containing a pointer to a C++ object. The CallInvokerHolder, which has the
30
- // invokeAsync method we want access to, is one such hybrid object.
31
- // Rather than reworking our code to use fbjni throughout, this code unpacks the C++ object from the Java
32
- // object `callInvokerHolderJavaObj` manually, based on reverse engineering the fbjni code.
33
-
34
- // 1. Get the Java object referred to by the mHybridData field of the Java holder object
35
- auto callInvokerHolderClass = env->GetObjectClass(callInvokerHolderJavaObj);
36
- auto hybridDataField = env->GetFieldID(callInvokerHolderClass, "mHybridData", "Lcom/facebook/jni/HybridData;");
37
- auto hybridDataObj = env->GetObjectField(callInvokerHolderJavaObj, hybridDataField);
38
-
39
- // 2. Get the destructor Java object referred to by the mDestructor field from the myHybridData Java object
40
- auto hybridDataClass = env->FindClass("com/facebook/jni/HybridData");
41
- auto destructorField =
42
- env->GetFieldID(hybridDataClass, "mDestructor", "Lcom/facebook/jni/HybridData$Destructor;");
43
- auto destructorObj = env->GetObjectField(hybridDataObj, destructorField);
44
-
45
- // 3. Get the mNativePointer field from the mDestructor Java object
46
- auto destructorClass = env->FindClass("com/facebook/jni/HybridData$Destructor");
47
- auto nativePointerField = env->GetFieldID(destructorClass, "mNativePointer", "J");
48
- auto nativePointerValue = env->GetLongField(destructorObj, nativePointerField);
49
-
50
- // 4. Cast the mNativePointer back to its C++ type
51
- auto nativePointer = reinterpret_cast<facebook::react::CallInvokerHolder*>(nativePointerValue);
52
- auto jsCallInvoker = nativePointer->getCallInvoker();
27
+ using JCallInvokerHolder = facebook::react::CallInvokerHolder;
53
28
 
29
+ auto holderLocal = facebook::jni::make_local(callInvokerHolderJavaObj);
30
+ auto holderRef = facebook::jni::static_ref_cast<JCallInvokerHolder::javaobject>(holderLocal);
31
+ auto* holderCxx = holderRef->cthis();
32
+ auto jsCallInvoker = holderCxx->getCallInvoker();
54
33
  auto runtime = reinterpret_cast<jsi::Runtime *>(rtPtr);
34
+
55
35
  return bennyblader_ddkrn::installRustCrate(*runtime, jsCallInvoker);
56
36
  }
57
37
 
@@ -1,6 +1,6 @@
1
1
  // Generated by uniffi-bindgen-react-native
2
2
  #include "bennyblader-ddk-rn.h"
3
- #include "/ddk_ffi.hpp"
3
+ #include "ddk_ffi.hpp"
4
4
 
5
5
  namespace bennyblader_ddkrn {
6
6
  using namespace facebook;