I am writing a front-end up, without no server. Just a front-end react application.
Now, users should be able to upload files to IPFS. Since it’s a front-end only without server, I really don’t have much idea how to let them upload files to IPFS.
I saw this code…
const IPFS = require('ipfs-core')
const ipfs = await IPFS.create()
const { cid } = await ipfs.add(file)
console.info(cid)
The above works.
Question 1. I want to confirm something. does IPFS.create
create a node in the browser and that’s how it starts to work ? Is this stable and performant ? since node(i don’t mean node.js
) is running in browser, maybe it’s not performant. What do you think ?
Question 2. if IPFS.create
creates a node in the browser, I guess, when I refresh the page and that code again gets executed, old node dies and new one gets created. is this performant ?
I’d appreciate your insights on this, folks…
1 Like
@Discordian
Thanks a lot for the follow up and answers.
I might ask though: what’s repo
exactly ? if I initialize 2 nodes with different repos, what would be the actual difference between those nodes ? and if I initialize 2 nodes with the same repos then what would be the difference ?
Thanks in advance.
Two nodes with different repos would be 2 nodes operating independently. Their own blockstore, pins, MFS, PeerID, etc. 2 nodes using the same repo is invalid, a lockfile will trigger an error. This would cause many conflicts as the nodes would attempt writes in the same locations, among other issues.
Happy to help
1 Like
Hey @Discordian
Thanks for all your help. I realized that i have a couple of questions related to this package.
-
When I add file to ipfs, which node does it get stored on ? If it’s a node in browser, then if browser dies as in closing the browser, node would get destroyed and no one would be able to get it . I understand that If I ask for the file one time from other node, for sure, that other node will store it too and this way, closing and killing the browser wouldn’t cause any issue. File would still be found. Any idea ?
-
it seems like that the safest way is to pin it after uploading. So this is what i do
const { cid } = await ipfs.add(file);
const res = await ipfs.pin.add(cid);
would this be enough ? but I really don’t understand how to check if it’s pinned and which node stores it so that it never gets erased or anything like that ever.
I’d appreciate the guidance.
1 Like
Thanks so much… @Discordian
I really don’t know what to do then… We have a website where it’s so important that data never goes missing that users upload through our front-end form…
Question 1. When do you think your demo will be ready ? as an approximation ?
Question 2. let’s say on my server, I also build my own node. How is it possible that I give the uploaded file from my local node in browser to my server’s node directly ? Is this possible and is it a good way and how can this be done ?
Question 3. What alternatives do I have ? one i can think of is that I build node.js
server and that’s where I upload my file and when the file reaches my node.js
server, I put it in the ipfs node that is on the same server as my node.js server. but I guess, this is wasted work, because Question:2
above should also be possible. right ?
It sounds like what you’re looking for is a pinning service. You want someone to store and serve the files when your frontend is closed. Setting up your own node.js server is like setting up your own pinning service. Using a pinning service should be greatly simplified by the new pinning service api introduced in go-ipfs 0.8 (I’m assuming js-ipfs was updated to support it) IPFS Pinning Service API
@zacharywhitley
js-ipfs
contains pinning functionality.
const { cid } = await ipfs.add(file);
const res = await ipfs.pin.add(cid);
This works, but as @Discordian said, this would still pin to the local node in browser which doesn’t look like a pinning to me at all
@Discordian
so basically, in my code, it would look like this…
const { cid } = await ipfs.add(file);
await ipfs.pin.remote.sevice.add('pinata', {
endpoint: new URL('https://api.pinata.cloud'),
key: 'your-pinata-key'
})
const res = await ipfs.pin.add(cid) // IMPORTANT: will this now add to pinata and to my local node automatically ?
1 Like
Close! Ensure you’re reading through the other pin.remote
API related commands . You’ll want to create pins now using ipfs.pin.remote.add
1 Like
@Discordian
haha, just saw this when you commented.
Thanks a lot.
One problem i can think of…
The process looks like this.
- browser uploads file to local node and gets cid.
- cid is then sent to pinata.
- pinata now asks for this
cid
and finds that my local node has it. pinata gets the file and stores it and also on all its nodes for safety.
What if as soon as cid
is successfully brought to pinata
, immediatelly my local node shut down(user turned browser or anything like this), this means that when pinata asks for the cid
, it won’t find it anywhere(my node is closed). This could happen quite a lot. What’s the workaround in this case ?
1 Like
Actually the purpose of having Pinata pin it, is the data itself is also sent to their nodes, where they’ll re-host it for you. So when the local node goes offline, the CID will still be accessible .
1 Like
@Discordian true, haha ,but I explained a different scenario.
Let’s follow together.
- we upload file to local node in browser with
ipfs.add
and this returns cid.
- we then do
await ipfs.pin.add(cid)
. After this is resolved, It means that cid
was received by pinata nodes. So what they will do is ask for the cid
to the ipfs nodes. and pinata node will find it in our local node, but the problem is that what if as soon as pinata receives cid
from my local node and starts to retrieve file by cid
, at that very moment, local node goes offline, meaning that it no longer serves the file and pinata will not be able to find it at all for the first time.
makes sense ?
1 Like
@Discordian
Hey , hope you had a wonderful weekend. Just as a reminder, what do you think about my last scenario ?
1 Like
Okay I understand. So you’d want to ensure you’re not just doing await ipfs.pin.add
but also doing await ipfs.remote.pin.add
afterwards, so Pinata pins it. I believe ipfs.remote.pin.add
will also block until Pinata completes the pin, so you could display a message when it completes, so the user doesn’t close the page too early.
Thank you! Sorry about that, I totally missed the reply!
1 Like
@Discordian
That’s awesome if it’s how it’s going to work, but:
Q1: I guess, if user uploads a really big file, for sure, it’s gonna take a good amount of time. which seems acceptable.
Q2: If you remember that we agreed on using pinata, and I don’t use the back-end service at all. I realized one problem. Where should i store pinata private key
? I mean, storing in front-end can be exploitable by other people. you might say that i can store it on CI/CD , but again, this just makes it harder for malicious users to get their hands on it, but it’s still possible, because the key is still built in the front-end. any ideas ?
Thanks a lot and no worries.
Q1. Yup
Q2. Oh jeeze I hadn’t thought that through I suppose . You could setup your own bootstrap node, and have other nodes communicate with it over PubSub, and have that node do the ipfs.remote.pin.add
. I’m hoping to have a demo more-or-less demonstrating a way to do this up hopefully today (at least a draft) (edit: draft likely won’t be ready until tomorrow).
tl;dr for how I’m doing it, I do the add, like you’re doing right now, then I broadcast some JSON over a PubSub topic, from that a python script running on a bootstrap node (but you can use nodejs) gets the JSON and then adds the embedded CID to the node. I use JSON for some metadata, and that’s it really.
1 Like
@Discordian
Yes, I think using pinata
is still a good choice and as you said, this can be done from the back-end node that is mine…
Can’t wait to see the DEMO <3
What do you mean by bootstrap
node ? is there anything my browser local node can do to connect with bootstrap
node better ? but I guess, this will be shown in the demo
itself.
1 Like