# Improved Architecture for Proof Generation in Mobile: Turbo Module Update
### **Goal**
To establish a single shared C++ folder for both iOS and Android platforms with bindings, improving maintainability and readability while optimizing proof generation.
---
## **Existing Solution for Rapidsnark Integration**
### **Current Steps:**
1. **Binary Generation:**
We generate `rapidsnark` and witness calculation binaries for different Android and iOS architectures.
2. **Native Code Bridging:**
Native code bridges are required to connect C++ code with the JS engine:
- For **Android**: Using Java/Kotlin.
- For **iOS**: Using Objective-C.
These bridge APIs are invoked whenever a C++ function needs to be accessed.
3. **React Native Limitations:**
Current React Native architecture does not natively support invoking C++ functions without these bridges. This limits readability and adds complexity.
---
## **Proposed Solution**
### **Shared C++ Folder**
We plan to create a shared folder containing C++ code that works seamlessly across both iOS and Android.
### **Why:**
- Enhanced readability and maintainability.
- No need for writing native code.
### **Challenges:**
- Android and iOS use different shared libraries.
- These libraries need to be bundled correctly or specified during runtime for each platform.
- How do we handle binding C++ code for various architectures into a unified system?
---
---
## **Steps to Implement**
### 1. Define a Spec File
The spec file is converted using the **codegen tool**, generating files in the `/generated` folder for Android and iOS.
```typescript
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
export interface Spec extends TurboModule {
reverseString: (str: string) => string;
getNumbers: () => Array<number>;
getObject: () => { [key: string]: string };
promiseNumber: (value: number) => Promise<number>;
callMeLater: (successCB: () => void, failureCB: () => void) => void;
}
export default TurboModuleRegistry.getEnforcing<Spec>('CppTurbo');
```
### 2. Shared Cpp Lib
1. Header File: For declarations.
2. Main C++ Methods File: For implementations.
```cpp
#include "NativeCppTurboModule.h"
namespace facebook::react {
NativeCppTurboModule::NativeCppTurboModule(std::shared_ptr<CallInvoker> jsInvoker)
: NativeCppTurboCxxSpec(std::move(jsInvoker)) {}
std::string NativeCppTurboModule::reverseString(jsi::Runtime &rt, std::string str) {
std::reverse(str.begin(), str.end());
return str;
}
std::vector<int> NativeCppTurboModule::getNumbers(jsi::Runtime &rt) {
std::vector<int> array;
for (std::size_t i = 0; i < 10; ++i) {
array.push_back(static_cast<int>(i));
}
return array;
}
std::map<std::string, std::string> NativeCppTurboModule::getObject(jsi::Runtime &rt) {
std::map<std::string, std::string> map;
map.insert(std::make_pair("result", "success"));
return map;
}
jsi::Value NativeCppTurboModule::promiseNumber(jsi::Runtime &rt, double number) {
jsi::Function promiseConstructor = rt.global().getPropertyAsFunction(rt, "Promise");
return promiseConstructor.callAsConstructor(
rt,
jsi::Function::createFromHostFunction(
rt,
jsi::PropNameID::forAscii(rt, "promiseArg"),
2,
[number](jsi::Runtime &runtime, const jsi::Value &thisValue, const jsi::Value *arguments, std::size_t count) -> jsi::Value {
jsi::Function resolve = arguments[0].asObject(runtime).asFunction(runtime);
resolve.call(runtime, number);
return jsi::Value::undefined();
}
)
);
}
void NativeCppTurboModule::callMeLater(jsi::Runtime &rt, jsi::Function successCB, jsi::Function failureCB) {
bool callSuccess = std::rand() % 2;
if (callSuccess) {
successCB.call(rt);
} else {
failureCB.call(rt);
}
}
} // namespace facebook::react
```
### 3. Android Integration
Use CMakeLists.txt to load the shared folder containing C++ code.
### 4. iOS Integration
Write a oneLoad() function that will be invoked by default during runtime.