{"id":20975233,"url":"https://github.com/functionland/react-native-fula","last_synced_at":"2026-02-22T01:36:05.132Z","repository":{"id":37236491,"uuid":"491016599","full_name":"functionland/react-native-fula","owner":"functionland","description":"React (JS/Native) wrapper for go-fula/mobile which creates a bridge between Fula for React Native to enable connection between blox and mobile apps","archived":false,"fork":false,"pushed_at":"2026-02-12T06:13:44.000Z","size":4446,"stargazers_count":3,"open_issues_count":11,"forks_count":5,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-12T16:21:23.871Z","etag":null,"topics":["filesystem","fula","java","javascript","mobile-app","mobile-development","react-native","reactjs","webnative","wnfs","wrapper-library"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@functionland/react-native-fula","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/functionland.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-05-11T08:12:25.000Z","updated_at":"2026-02-12T06:13:22.000Z","dependencies_parsed_at":"2023-02-12T11:15:18.397Z","dependency_job_id":"ad2f76ab-44e1-49e8-8db3-424b56a25800","html_url":"https://github.com/functionland/react-native-fula","commit_stats":{"total_commits":154,"total_committers":5,"mean_commits":30.8,"dds":0.3701298701298701,"last_synced_commit":"76c78fae063ac91b1e2d0372058ea073e62341c7"},"previous_names":[],"tags_count":96,"template":false,"template_full_name":null,"purl":"pkg:github/functionland/react-native-fula","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functionland%2Freact-native-fula","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functionland%2Freact-native-fula/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functionland%2Freact-native-fula/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functionland%2Freact-native-fula/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/functionland","download_url":"https://codeload.github.com/functionland/react-native-fula/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functionland%2Freact-native-fula/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29703227,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-21T23:35:04.139Z","status":"ssl_error","status_checked_at":"2026-02-21T23:35:03.832Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["filesystem","fula","java","javascript","mobile-app","mobile-development","react-native","reactjs","webnative","wnfs","wrapper-library"],"created_at":"2024-11-19T04:41:15.137Z","updated_at":"2026-02-22T01:36:05.127Z","avatar_url":"https://github.com/functionland.png","language":"TypeScript","readme":"# react-native-fula\n\nReact Native bridge for the [Fula protocols](https://github.com/functionland/go-fula), providing blockchain operations, blox device management, plugin management, and AI interactions via go-fula/mobile.\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────┐\n│              React Native App                    │\n├─────────────────────────────────────────────────┤\n│   TypeScript API (fula, blockchain, fxblox, fxAi)│\n├───────────────────┬─────────────────────────────┤\n│  Android (Java)   │       iOS (Swift)           │\n│  FulaModule.java  │       FulaModule.swift       │\n├───────────────────┼─────────────────────────────┤\n│  go-fula/mobile   │       go-fula/mobile        │\n│  (JNI via .aar)   │       (Fula framework)      │\n└───────────────────┴─────────────────────────────┘\n```\n\nThe library uses React Native's NativeModules bridge. All heavy operations run on background threads (single-threaded executor on Android, `DispatchQueue.global` on iOS) to avoid blocking the JS thread. Responses are returned as JSON strings from the native layer and parsed into typed objects in TypeScript.\n\n## Installation\n\n```sh\nnpm install @functionland/react-native-fula\n```\n\n### iOS\n\n```sh\ncd ios \u0026\u0026 pod install\n```\n\nRequires iOS 15.0+.\n\n### Android\n\nThe Android AAR is fetched automatically from [JitPack](https://jitpack.io/#functionland/fula-build-aar). Make sure your project-level `build.gradle` (or the library's own repositories block) includes:\n\n```gradle\nmaven { url 'https://jitpack.io' }\n```\n\nRequires `minSdkVersion` 26+, Java 17.\n\n## Usage\n\nThe library exports four namespaced modules:\n\n```js\nimport { fula, blockchain, fxblox, fxAi } from '@functionland/react-native-fula';\n```\n\n### fula -- Client Lifecycle\n\nManages the Fula client: initialization, connectivity, and shutdown.\n\n```js\n// Register lifecycle listeners for proper cleanup on app background/termination\nawait fula.registerLifecycleListener();\n\n// Create a new client and connect to the blox node\nconst peerId = await fula.newClient(\n  identity,    // string -- base64 private key of DID identity\n  storePath,   // string -- local store path (empty string for default)\n  bloxAddr,    // string -- blox multiaddr (empty string for testing without backend)\n  exchange,    // string -- 'noop' for testing, '' for production\n  autoFlush,   // boolean (default: false) -- flush writes to disk after each operation\n  useRelay,    // boolean (default: true) -- force connection through relay\n  refresh      // boolean (default: false) -- force recreate the fula object\n);\n\n// init() is a backward-compatible alias for newClient.\n// Returns { peerId, rootCid } where rootCid is always \"\".\nconst { peerId, rootCid } = await fula.init(\n  identity, storePath, bloxAddr, exchange,\n  autoFlush, rootCid, useRelay, refresh\n);\n```\n\n```js\n// Check if fula is initialized (optionally check filesystem too)\nconst ready = await fula.isReady(filesystemCheck); // default: true\n\n// Check if client can reach the blox\nconst connected = await fula.checkConnection(timeout); // timeout in seconds, default 20\n\n// Ping blox peer (tries direct -\u003e relay -\u003e DHT fallback)\nconst result = await fula.ping(timeout); // default 60s\n// result: { success: boolean, successes: number, avg_rtt_ms: number, errors: string[] }\n\n// Shut down libp2p and datastore (client must be discarded after this)\nawait fula.shutdown();\n\n// Shut down and clear all local data\nconst success = await fula.logout(identity, storePath);\n```\n\n### blockchain -- On-Chain Operations\n\nAll blockchain operations are relayed through the connected blox node. The client must be initialized first via `fula.newClient()` or `fula.init()`.\n\n#### Account Management\n\n```js\n// Check if account exists on-chain\nconst { account, exists } = await blockchain.checkAccountExists(account);\n\n// Fund an account\nconst { from, to, amount } = await blockchain.accountFund(account);\n\n// Get current account info\nconst { account } = await blockchain.getAccount();\n\n// Query asset balance\nconst { amount } = await blockchain.assetsBalance(account, assetId, classId);\n\n// Transfer tokens to Fula network\nconst { msg, description } = await blockchain.transferToFula(amount, wallet, chain);\n```\n\n#### Pool Management\n\n```js\n// List all pools\nconst { pools } = await blockchain.listPools();\n// pools: [{ poolID, creator, poolName, parent, participants, region }]\n\n// Join / leave a pool\nconst joined = await blockchain.joinPool(poolID);\nconst left = await blockchain.leavePool(poolID);\n\n// Join / leave with a specific blockchain\nconst joined = await blockchain.joinPoolWithChain(poolID, chainName);\nconst left = await blockchain.leavePoolWithChain(poolID, chainName);\n\n// Cancel a pending join request\nconst cancelled = await blockchain.cancelPoolJoin(poolID);\n\n// List pending join requests for a pool\nconst { poolRequests } = await blockchain.listPoolJoinRequests(poolID);\n// poolRequests: [{ poolID, account, voted, positiveVotes, peerID }]\n```\n\n#### Storage and Replication\n\n```js\n// Upload manifest for multiple CIDs\nconst { storer, cid, pool_id } = await blockchain.batchUploadManifest(\n  cids, poolId, replicationFactor\n);\n\n// Replicate content in pool\nconst replicatedCids = await blockchain.replicateInPool(cids, account, poolId);\n\n// List available replication requests\nconst available = await blockchain.listAvailableReplicationRequests(poolID);\n```\n\n#### Blox Info\n\n```js\n// Get free space on blox device\nconst { size, avail, used, used_percentage } = await blockchain.bloxFreeSpace();\n```\n\n### fxblox -- Device and Plugin Management\n\nHardware commands, diagnostics, and plugin management for blox devices. Commands are sent over libp2p to the connected blox.\n\n#### Hardware Commands\n\n```js\nconst { status, msg } = await fxblox.wifiRemoveall();  // Remove all saved WiFi connections\nconst { status, msg } = await fxblox.reboot();          // Reboot device\nconst { status, msg } = await fxblox.partition();        // Partition device storage\nconst { status, msg } = await fxblox.eraseBlData();      // Erase all blox local data\n```\n\n#### Diagnostics\n\n```js\n// Fetch Docker container logs\nconst { status, msg } = await fxblox.fetchContainerLogs(containerName, tailCount);\n\n// Analyze logs for best/target peers\nconst { best, target, err } = await fxblox.findBestAndTargetInLogs(containerName, tailCount);\n\n// Storage information\nconst { folder_path, size } = await fxblox.getFolderSize(folderPath);\nconst { size, storage_max, count, folder_path, version } = await fxblox.getDatastoreSize();\n\n// Docker image info\nconst { images } = await fxblox.getDockerImageBuildDates();\n// images: [{ container_name, image_name, image_created, image_digest }]\n\n// IPFS cluster info\nconst { cluster_peer_id, cluster_peer_name } = await fxblox.getClusterInfo();\n```\n\n#### Plugin Management\n\n```js\n// List all available plugins\nconst { plugins } = await fxblox.listPlugins();\n// plugins: [{ name, description, version, usage, rewards, socials, requiredInputs, approved, installed }]\n\n// List currently active plugins\nconst { msg, status } = await fxblox.listActivePlugins();\n\n// Install / uninstall / update a plugin\nconst installed = await fxblox.installPlugin(pluginName, params);\nconst uninstalled = await fxblox.uninstallPlugin(pluginName);\nconst updated = await fxblox.updatePlugin(pluginName);\n\n// Check plugin status\nconst { status } = await fxblox.showPluginStatus(pluginName, lines);\nconst { status, msg } = await fxblox.getInstallStatus(pluginName);\nconst { status, msg } = await fxblox.getInstallOutput(pluginName, params);\n```\n\n### fxAi -- AI Chat\n\nInteract with AI models running on the blox device. Responses are streamed over libp2p.\n\n```js\n// Start a chat session -- returns a stream ID\nconst streamID = await fxAi.chatWithAI(aiModel, userMessage);\n\n// Option 1: Collect all chunks into a single response\nconst fullResponse = await fxAi.fetchChunksUsingIterator(streamID);\n\n// Option 2: Stream chunks with callbacks\nconst cancel = fxAi.streamChunks(streamID, {\n  onChunk: (chunk) =\u003e console.log(chunk),\n  onComplete: () =\u003e console.log('done'),\n  onError: (err) =\u003e console.error(err),\n});\n// Call cancel() to stop listening\n\n// Option 3: Get chunks manually one at a time\nconst chunk = await fxAi.getChatChunk(streamID);\n```\n\n## Deprecated / Dead Code\n\nThe following methods still exist in the TypeScript layer (`src/protocols/blockchain.ts` and `src/interfaces/fulaNativeModule.ts`) but have **no native implementation** on either Android or iOS. They were removed from native modules when direct chain/polkadot APIs were dropped. Calling them will result in a runtime error:\n\n- `blockchain.createAccount(seed)` -- use blox-side account creation instead\n- `blockchain.createPool(seed, poolName)` -- use blox-side pool creation instead\n- `blockchain.votePoolJoinRequest(seed, poolID, account, accept)`\n- `blockchain.newStoreRequest(seed, poolID, uploader, cid)`\n- `blockchain.removeReplicationRequest(seed, poolID, cid)`\n- `blockchain.removeStorer(seed, storer, poolID, cid)`\n- `blockchain.removeStoredReplication(seed, uploader, poolID, cid)`\n\n\u003e **TODO:** Clean up the TypeScript layer to remove these dead methods and their associated types (`SeededResponse`, `PoolCreateResponse`, `PoolVoteResponse`).\n\n## Native Dependency Versions\n\n| Platform | Dependency | Version | Source |\n| --- | --- | --- | --- |\n| Android | `com.github.functionland:fula-build-aar` | v1.57.7 | [JitPack](https://jitpack.io/#functionland/fula-build-aar) |\n| iOS | `Fula` (go-fula/mobile) | ~\u003e 1.57.7 | [CocoaPods](https://cocoapods.org/) |\n\n## Development\n\n### Prerequisites\n\n- Node \u003e= 16\n- Yarn 1.22+\n- For Android: JDK 17, Android SDK with NDK 27.1.12297006\n- For iOS: Xcode with iOS 15.0+ SDK\n\n### Setup\n\n```sh\n# Enable corepack (run as admin/sudo)\ncorepack enable\n\n# Install dependencies\nyarn install\n\n# Install iOS pods (macOS only)\nyarn example pods\n```\n\n### Running the Example App\n\n```sh\n# Android\nyarn example android\n\n# iOS\nyarn example ios\n```\n\n### Scripts\n\n| Command | Description |\n| --- | --- |\n| `yarn install` | Install dependencies |\n| `yarn example android` | Run example app on Android |\n| `yarn example ios` | Run example app on iOS |\n| `yarn test` | Run Jest tests |\n| `yarn typecheck` | TypeScript type checking |\n| `yarn lint` | ESLint + Prettier |\n| `yarn build:android` | Build Android debug APK |\n| `yarn build:ios` | Build iOS for simulator |\n\n## Project Structure\n\n```\nsrc/\n  index.tsx                     # Entry point -- re-exports all modules\n  interfaces/\n    fulaNativeModule.ts         # NativeModules bridge interface\n  protocols/\n    fula.ts                     # Client lifecycle (init, connect, shutdown)\n    blockchain.ts               # On-chain operations (accounts, pools, storage)\n    fxblox.ts                   # Device and plugin management\n    fx-ai.ts                    # AI chat streaming\n  types/\n    blockchain.ts               # Blockchain response types\n    fxblox.ts                   # Fxblox response types\nandroid/\n  src/main/java/land/fx/fula/\n    FulaModule.java             # Android native module\n    FulaPackage.java            # React Native package registration\n    ThreadUtils.java            # Single-threaded executor for background work\nios/\n  Fula.swift                    # iOS native module (Swift)\n  Fula.mm                       # Objective-C++ bridge declarations\n  Extensions.swift              # String/Data/UInt8 utility extensions\nexample/                        # Example React Native app\n```\n\n## Related Libraries\n\n| Name | Description |\n| --- | --- |\n| [go-fula](https://github.com/functionland/go-fula) | Core Fula protocol implementation in Go |\n| [fula-build-aar](https://github.com/functionland/fula-build-aar) | Android .aar build of go-fula/mobile |\n| [Fx Fotos](https://github.com/functionland/fx-fotos) | Photo dApp built with react-native-fula |\n\n## Contributing\n\nSee the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.\n\n## License\n\nMIT\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunctionland%2Freact-native-fula","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffunctionland%2Freact-native-fula","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunctionland%2Freact-native-fula/lists"}