Skip to content

Commit 0796157

Browse files
committed
chore: update app
1 parent 47e3659 commit 0796157

File tree

6 files changed

+155
-7
lines changed

6 files changed

+155
-7
lines changed

App.js

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,73 @@
11
import './globals.js'
2+
import './globals-crypto.js'
23
import { StatusBar } from 'expo-status-bar'
34
import { StyleSheet, Text, View } from 'react-native'
45
import { useState, useEffect } from 'react'
56
import { createLibp2p } from 'libp2p'
7+
import { webSockets } from '@libp2p/websockets'
8+
import { bootstrap } from '@libp2p/bootstrap'
9+
import { noise } from '@chainsafe/libp2p-noise'
10+
import { yamux } from '@chainsafe/libp2p-yamux'
11+
import { identify } from '@libp2p/identify'
12+
import { circuitRelayTransport } from '@libp2p/circuit-relay-v2'
13+
import { kadDHT } from '@libp2p/kad-dht'
14+
import debug from 'debug'
15+
16+
debug.enable('libp2p:circuit-relay:*')
617

718
export default function App () {
819
const [libp2p, setLibp2p] = useState(null)
20+
const [peers, setPeers] = useState(null)
21+
const [multiaddrs, setMultiaddrs] = useState(null)
22+
923
useEffect(() => {
1024
async function getLibp2p() {
11-
const node = await createLibp2p()
25+
const node = await createLibp2p({
26+
transports: [
27+
webSockets(),
28+
circuitRelayTransport({
29+
discoverRelays: 1
30+
})
31+
],
32+
connectionEncryption: [
33+
noise()
34+
],
35+
streamMuxers: [
36+
yamux()
37+
],
38+
peerDiscovery: [
39+
bootstrap({
40+
list: [
41+
'/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN',
42+
'/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa',
43+
'/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb',
44+
'/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt',
45+
'/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ'
46+
]
47+
})
48+
],
49+
services: {
50+
identify: identify(),
51+
kadDHT: kadDHT()
52+
}
53+
})
54+
55+
setInterval(() => {
56+
setPeers(node.getPeers())
57+
setMultiaddrs(node.getMultiaddrs())
58+
}, 1000)
59+
1260
setLibp2p(node)
1361
}
1462
getLibp2p()
1563
}, [])
1664

1765
return (
1866
<View style={styles.container}>
19-
<Text>Open up App.js to start working on your app!</Text>
67+
<Text>js-libp2p running on React Native</Text>
2068
<Text>Our PeerId is {libp2p?.peerId.toString()}</Text>
69+
<Text>Peers {peers?.join(', ')}</Text>
70+
<Text>Multiaddrs {multiaddrs?.join(', ')}</Text>
2171
<StatusBar style="auto" />
2272
</View>
2373
)

README.md

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Running js-libp2p under React Native
22

3-
Very basic support so far, just js-libp2p itself, no extra modules yet.
3+
There is some setup that needs to be done to modernise the react-native runtime.
44

55
1. Turn on [exports map support](https://reactnative.dev/blog/2023/06/21/package-exports-support)
66

@@ -19,16 +19,53 @@ Some standard JS APIs aren't available in React Native, these need to be polyfil
1919

2020
```js
2121
// globals.js - this should be imported at the top of your App.js file
22+
import '@azure/core-asynciterator-polyfill'
23+
import 'react-native-url-polyfill/auto'
2224
import 'react-native-get-random-values'
25+
import 'weakmap-polyfill'
2326
import { TextEncoder, TextDecoder } from 'text-encoding'
2427
import { EventTarget, Event } from 'event-target-shim'
28+
import { Buffer } from '@craftzdog/react-native-buffer'
2529

2630
global.TextEncoder = TextEncoder
2731
global.TextDecoder = TextDecoder
2832
global.EventTarget = EventTarget
2933
global.Event = Event
34+
35+
global.AbortSignal.timeout = (ms) => {
36+
const controller = new AbortController()
37+
setTimeout(() => {
38+
controller.abort(new Error('Aborted'))
39+
}, ms)
40+
}
41+
global.Buffer = Buffer
42+
```
43+
44+
3. WebCrypto
45+
46+
It's necessary to shim support for [SubtleCrypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto)
47+
until it's added to react-native by default.
48+
49+
First install the necessary dependencies:
50+
51+
```console
52+
$ npm i @peculiar/webcrypto
53+
```
54+
55+
..and create a shim file:
56+
57+
```js
58+
// globals-crypto.js - this should be imported at the top of your App.js file
59+
// but AFTER globals.js
60+
import { Crypto } from '@peculiar/webcrypto'
61+
62+
global.crypto.subtle = new Crypto().subtle
3063
```
3164

65+
IMPORTANT: until [PeculiarVentures/webcrypto#67](https://github.com/PeculiarVentures/webcrypto/pull/67) is
66+
merged, SubtleCrypto has to be shimmed *after* the node Buffer polyfill has
67+
been added to the global context.
68+
3269
## Running
3370

3471
### iOS
@@ -50,3 +87,18 @@ $ npm start
5087
```
5188

5289
Follow the instructions - press `i` to start iOS or `a` for Android.
90+
91+
## Notes
92+
93+
- By default this demo uses pure-js crypto - it's not efficient enough to run on an actual device, `crypto-browserify` should be replaced with `react-native-quick-crypto` in `bable.config.js` for native builds
94+
- `@libp2p/webrtc` can also only run on a device since it needs native code
95+
96+
### Debugging
97+
98+
Put this at the top of your app file:
99+
100+
```js
101+
import debug from 'debug'
102+
103+
debug.enable('libp2p:*')
104+
```

babel.config.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@ module.exports = function (api) {
44
return {
55
presets: [
66
'babel-preset-expo'
7+
],
8+
plugins: [
9+
['module-resolver', {
10+
alias: {
11+
//'crypto': 'react-native-quick-crypto',
12+
'crypto': 'crypto-browserify',
13+
'node:crypto': 'crypto-browserify',
14+
'stream': 'stream-browserify',
15+
'node:stream': 'stream-browserify'
16+
}
17+
}]
718
]
819
}
920
}

globals-crypto.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Ship SubtleCrypto - this has do be done after the Buffer polyfill has been
2+
// added to the global object. Can be folded into `./globals.js` if
3+
// https://github.com/PeculiarVentures/webcrypto/pull/67 is merged
4+
5+
import { Crypto } from '@peculiar/webcrypto'
6+
7+
global.crypto.subtle = new Crypto().subtle

globals.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
11
// Shim global JS objects, hopefully this won't be necessary forever
22
// https://github.com/facebook/hermes/discussions/1072
33

4+
import '@azure/core-asynciterator-polyfill'
5+
import 'react-native-url-polyfill/auto'
46
import 'react-native-get-random-values'
7+
import 'weakmap-polyfill'
58
import { TextEncoder, TextDecoder } from 'text-encoding'
69
import { EventTarget, Event } from 'event-target-shim'
10+
import { Buffer } from '@craftzdog/react-native-buffer'
711

812
global.TextEncoder = TextEncoder
913
global.TextDecoder = TextDecoder
1014
global.EventTarget = EventTarget
1115
global.Event = Event
16+
17+
global.AbortSignal.timeout = (ms) => {
18+
const controller = new AbortController()
19+
setTimeout(() => {
20+
controller.abort(new Error('Aborted'))
21+
}, ms)
22+
}
23+
global.Buffer = Buffer

package.json

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,39 @@
33
"version": "1.0.0",
44
"main": "node_modules/expo/AppEntry.js",
55
"scripts": {
6-
"start": "expo start",
6+
"start": "expo start -c",
77
"android": "expo start --android",
88
"ios": "expo start --ios",
99
"web": "expo start --web"
1010
},
1111
"dependencies": {
12+
"@azure/core-asynciterator-polyfill": "^1.0.2",
1213
"@chainsafe/libp2p-noise": "^14.0.0",
1314
"@chainsafe/libp2p-yamux": "^6.0.1",
15+
"@craftzdog/react-native-buffer": "^6.0.5",
16+
"@libp2p/bootstrap": "^10.0.6",
17+
"@libp2p/circuit-relay-v2": "^1.0.6",
18+
"@libp2p/identify": "^1.0.5",
19+
"@libp2p/kad-dht": "^11.0.6",
1420
"@libp2p/websockets": "^8.0.6",
21+
"@peculiar/webcrypto": "^1.4.3",
22+
"crypto-browserify": "^3.12.0",
1523
"event-target-shim": "^6.0.2",
1624
"expo": "~49.0.15",
17-
"expo-status-bar": "~1.6.0",
25+
"expo-status-bar": "^1.7.1",
1826
"libp2p": "^1.0.9",
27+
"os-browserify": "^0.3.0",
28+
"path-browserify": "^1.0.1",
29+
"process": "^0.11.10",
1930
"react": "18.2.0",
20-
"react-native": "0.72.6",
31+
"react-native": "^0.73.0",
2132
"react-native-get-random-values": "^1.10.0",
22-
"text-encoding": "^0.7.0"
33+
"react-native-quick-crypto": "^0.6.1",
34+
"react-native-url-polyfill": "^2.0.0",
35+
"react-native-webrtc": "^118.0.0",
36+
"stream-browserify": "^3.0.0",
37+
"text-encoding": "^0.7.0",
38+
"weakmap-polyfill": "^2.0.4"
2339
},
2440
"devDependencies": {
2541
"@babel/core": "^7.20.0"

0 commit comments

Comments
 (0)