Skip to content

Commit f48a389

Browse files
author
André Costa Lima
committed
initial commit
0 parents  commit f48a389

File tree

74 files changed

+16262
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+16262
-0
lines changed

.eslintrc.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
root: true,
3+
extends: '@react-native-community',
4+
};

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.pbxproj -text

.gitignore

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# OSX
2+
#
3+
.DS_Store
4+
5+
# Xcode
6+
#
7+
build/
8+
*.pbxuser
9+
!default.pbxuser
10+
*.mode1v3
11+
!default.mode1v3
12+
*.mode2v3
13+
!default.mode2v3
14+
*.perspectivev3
15+
!default.perspectivev3
16+
xcuserdata
17+
*.xccheckout
18+
*.moved-aside
19+
DerivedData
20+
*.hmap
21+
*.ipa
22+
*.xcuserstate
23+
24+
# Android/IntelliJ
25+
#
26+
build/
27+
.idea
28+
.gradle
29+
local.properties
30+
*.iml
31+
32+
# node.js
33+
#
34+
node_modules/
35+
npm-debug.log
36+
yarn-error.log
37+
38+
# BUCK
39+
buck-out/
40+
\.buckd/
41+
*.keystore
42+
!debug.keystore
43+
44+
# fastlane
45+
#
46+
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
47+
# screenshots whenever they are needed.
48+
# For more information about the recommended setup visit:
49+
# https://docs.fastlane.tools/best-practices/source-control/
50+
51+
*/fastlane/report.xml
52+
*/fastlane/Preview.html
53+
*/fastlane/screenshots
54+
55+
# Bundle artifact
56+
*.jsbundle
57+
58+
# CocoaPods
59+
/ios/Pods/

.prettierrc.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
bracketSpacing: false,
3+
jsxBracketSameLine: true,
4+
singleQuote: true,
5+
trailingComma: 'all',
6+
};

.watchmanconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2020 Protocol Labs 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
13+
all 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
21+
THE SOFTWARE.

README.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# IPFS React Native app
2+
3+
This repository:
4+
- explores how IPFS' HTTP client can be used in a React Native app targeting Android and iOS platforms.
5+
- documents what issues we have been running into while using the API.
6+
- documents the on-going efforts and results of our debugging sessions.
7+
- documents what issues have been fixed so far.
8+
- documents possible strategies to address open issues.
9+
10+
## Usage
11+
12+
Spawn a local IPFS node with the `daemon` command. The app assumes the node is avaiable at http://localhost:5002.
13+
14+
### Run the app on Android
15+
16+
TODO add instructions on how to setup `adb forward` to allow an Android device to connect to localhost.
17+
18+
```sh
19+
npm run start:android:debug
20+
```
21+
```sh
22+
npm run start:android:release
23+
```
24+
25+
### Run the app on iOS
26+
27+
TODO add instructions on how to setup app signing for iOS
28+
29+
```sh
30+
npm run start:ios:debug
31+
```
32+
```sh
33+
npm run start:ios:release
34+
```
35+
36+
## HTTP client
37+
38+
### Factory
39+
40+
The `URL` API needs to be polyfilled otherwise an error is thrown as [many methods](https://github.com/facebook/react-native/blob/cd347a7e0ed29ae1049e041fcb34588e1aac76f9/Libraries/Blob/URL.js#L115) are not implemented in React Native and thus not conformant with the [spec](https://url.spec.whatwg.org). The exact same goes for `URLSearchParams` API as only a [few methods](https://github.com/facebook/react-native/blob/cd347a7e0ed29ae1049e041fcb34588e1aac76f9/Libraries/Blob/URL.js#L56) are implemented as well.
41+
42+
To work around these issues, we used the implementations provided by [`whatwg-url`](https://github.com/jsdom/whatwg-url) polyfill. `whatwg-url` depends on two core Node.js modules, `punycode` and `util`, which are not available in React Native environment. We have shimed them with alternative implementations:
43+
44+
- `util`: https://github.com/browserify/node-util. `whatwg-url` attempts to require `TextEncoder` and `TextDecoder` APIs from `node-util` and if such objects are not found, it fallbacks to `global.TextEncoder` and `global.TextDecoder`. Since `node-util` does not provide encoding APIs as in Node.js, we have to polyfill them with [`text-encoding`](https://github.com/inexorabletash/text-encoding) instead.
45+
- `punycode`: https://github.com/bestiejs/punycode.js
46+
47+
`whatwg-url` also depends on standard built-in objects such as `BigInt` and `SharedArrayBuffer` via [webidl-conversions](https://github.com/jsdom/webidl-conversions) which are not available in React Native as well. While we can [polyfill](https://github.com/peterolson/BigInteger.js) `BigInt`, `SharedArrayBuffer` is little more tricker. If IPFS does not need `SharedArrayBuffer`, we can probably come up with a way to cheat the type checks out by, e.g., using `ArrayBuffer` in its place. Right now we're using [`react-native-url-polyfill`](https://github.com/charpeni/react-native-url-polyfill), which is an optimized URL standard-compliant implementation for React Native based on [`whatwg-url-without-unicode`](https://github.com/charpeni/whatwg-url). However, it comes without Unicode support thus it's more light in size.
48+
49+
Our experience reveals both `whatwg-url` and `react-native-url-polyfill` appear to not be so comformant with the spec as they claim to be. When the `base` argument of the `URL` constructor is an empty string and the `url` argument is an absolute URL, the constructor is throwing an [error](https://github.com/charpeni/whatwg-url/blob/f934c822a2598ecef25ca7b224e96c29f7e52c65/lib/URL-impl.js#L15) indicating `base` is invalid. As per spec, when `url` is absolute the provided `base` should be ignored. However, it is not implemented this way.
50+
51+
Another issue we detected concerns the [normalization logic](https://github.com/ipfs/js-ipfs/blob/3ff833db6444a3e931db9b76bf74c3420e57ee02/packages/ipfs-http-client/src/lib/core.js#L21) for the input options of the IPFS HTTP client factory. It seems there is a case where `options` is a boxed string and an error is thrown by the `URL` [constructor](https://github.com/ipfs/js-ipfs/blob/3ff833db6444a3e931db9b76bf74c3420e57ee02/packages/ipfs-http-client/src/lib/core.js#L28) because `options.url` is undefined.
52+
53+
### [ipfs.id](https://github.com/ipfs/js-ipfs/blob/master/docs/core-api/MISCELLANEOUS.md#ipfsidoptions)
54+
55+
Runs just fine after setting up the client successfully.
56+
57+
### [ipfs.add](https://github.com/ipfs/js-ipfs/blob/master/docs/core-api/FILES.md#ipfsadddata-options)
58+
59+
- Async generators have to be transformed as they are not available in JSC. The Babel plugin [@babel/plugin-proposal-async-generator-functions](https://babeljs.io/docs/en/babel-plugin-proposal-async-generator-functions) takes care of that.
60+
61+
- The `FormData` API [implementation](https://github.com/facebook/react-native/blob/cd347a7e0ed29ae1049e041fcb34588e1aac76f9/Libraries/Network/FormData.js#L51) provided by React Native only has `append` and `getParts` methods implemented. However, IPFS uses the `set` method and thus an error is being thrown.

android/app/_BUCK

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# To learn about Buck see [Docs](https://buckbuild.com/).
2+
# To run your application with Buck:
3+
# - install Buck
4+
# - `npm start` - to start the packager
5+
# - `cd android`
6+
# - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
7+
# - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
8+
# - `buck install -r android/app` - compile, install and run application
9+
#
10+
11+
load(":build_defs.bzl", "create_aar_targets", "create_jar_targets")
12+
13+
lib_deps = []
14+
15+
create_aar_targets(glob(["libs/*.aar"]))
16+
17+
create_jar_targets(glob(["libs/*.jar"]))
18+
19+
android_library(
20+
name = "all-libs",
21+
exported_deps = lib_deps,
22+
)
23+
24+
android_library(
25+
name = "app-code",
26+
srcs = glob([
27+
"src/main/java/**/*.java",
28+
]),
29+
deps = [
30+
":all-libs",
31+
":build_config",
32+
":res",
33+
],
34+
)
35+
36+
android_build_config(
37+
name = "build_config",
38+
package = "com.ipfsdemo",
39+
)
40+
41+
android_resource(
42+
name = "res",
43+
package = "com.ipfsdemo",
44+
res = "src/main/res",
45+
)
46+
47+
android_binary(
48+
name = "app",
49+
keystore = "//android/keystores:debug",
50+
manifest = "src/main/AndroidManifest.xml",
51+
package_type = "debug",
52+
deps = [
53+
":app-code",
54+
],
55+
)

0 commit comments

Comments
 (0)