web3-storage / web3.storage

DEPRECATED ⁂ The simple file storage service for IPFS & Filecoin
https://web3.storage
Other
501 stars 122 forks source link

New web3.storage JS client: w3up-client #2337

Closed atinkapoor closed 8 months ago

atinkapoor commented 8 months ago

Hi, This might not be a bug but want to clarify regarding new JS client: w3up-client Previously we were using API option, using API Key/Token to upload files, now it seems we will have these steps:

const client = await create() const myAccount = await client.login('zaphod@beeblebrox.galaxy') const space = await client.createSpace('my-awesome-space') await client.setCurrentSpace(space.did())

and then we can upload files.

Our use case is we will allow users to upload files on our website, and we can't have user authenticate/login to their email address before they can upload files. We would want a master/admin account, where we have created a space (which we have already done), and then allow users to upload files in there, which worked using API. Can you suggest a way to do that with current JS client?

travis commented 8 months ago

Hi @atinkapoor! Based on what you've described, we have a couple options for using w3up the way you want to - please take a look at https://web3.storage/docs/concepts/architecture-options/ - it sounds like the "Client-Server" or "Delegated" options would work for your use-case.

I'm going to close this for now, but please feel free to re-open and @ me if this doesn't solve your issue.

atinkapoor commented 8 months ago

Hi @travis thanks for the details, could you let me know how can i generate 'private key' and 'proof' for the Space that i have already created in my account?

travis commented 8 months ago

Ah - you'll want to create a new private key and delegate access to your existing space using the instructions here:

https://github.com/web3-storage/w3up/tree/main/packages/w3up-client#bringing-your-own-agent-and-delegation

This is the important part:

// KEY: `npx ucan-key ed --json` in command line, which returns private key and DID for Agent (the private key is stored in KEY)
// PROOF: w3cli used to run `w3 delegation create <did_from_ucan-key_command_above> --can 'store/add' --can 'upload/add' | base64`, which returns the delegation from Space to the Agent we're using (stored in PROOF)
atinkapoor commented 8 months ago

H @travis I did that, here are the steps i performed:

async function backend(did) { const web3Key = "Mxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx="; const web3Proof = process.env.PROOF; const did= "did:key:zyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" //This is DID of the space i have created

// Load client with specific private key const principal = Signer.parse(web3Key) const client = await Client.create({ principal })

// Add proof that this agent has been delegated capabilities on the space const proof = await parseProof(web3Proof) const space = await client.addSpace(proof) await client.setCurrentSpace(space.did())

// Create a delegation for a specific DID const audience = DID.parse(did) const abilities = ['store/add', 'upload/add'] const expiration = Math.floor(Date.now() / 1000) + 60 60 24 // 24 hours from now const delegation = await client.createDelegation(audience, abilities, { expiration })

// Serialize the delegation and send it to the client const archive = await delegation.archive()

return archive.ok }

But i am getting error as:

store cannot be used with did:key:zyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy, stored principal and passed principal must match at Module.create (index.js:48:13)

Any pointer what i am doing wrong?

travis commented 8 months ago

Ah - that generally means that the store underlying Client has already been initialized with a different principal.

If you're using this in a stateless environment like an AWS Lambda or something you're probably better off using the in-memory store StoreMemory - you can see an example of calling Client.create with an in-memory store here:

https://github.com/web3-storage/w3up/blob/main/packages/w3up-client/test/test.js#L41

Even if you aren't using this in a stateless environment, it sounds like this is probably the way to go, just be aware that any delegations you've created or claimed will disappear once the process is terminated.

atinkapoor commented 8 months ago

It is still not working, now a different error. Just to make sure i am doing correct steps, i will mention here all the steps i performed.

  1. While creating account with web3.storage, i created a Space, which has a Key as: did:key:z6xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Lets name it as {did-space1}

  2. Then i performed the 2 commands you mentioned:

npx ucan-key ed --json The result of this command was: { "did": "did:key:z6yyyyyyyyyyyyyyyyyyyyyyy", "key": "Mgyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy=" } Lets name it as {did-space2} and {key-space2}

w3 delegation create {did-space2} --can 'store/add' --can 'upload/add' | base64 The result of this command is Proof, lets call it as {proof-space2}

Now here is my code:

============= Option 1 =============

const web3Key = {key-space2}
const web3Proof = {proof-space2}
const web3Space = {did-space2}

const principal = Signer.parse(web3Key)
const client = await Client.create({principal})

// now give Agent the delegation from the Space
const proof = await parseProof(web3Proof)
const space = await client.addSpace(proof)
await client.setCurrentSpace(space.did())

// Create a delegation for a specific DID
const audience = DID.parse(web3Space)
const abilities = ['store/add', 'upload/add']
const expiration = Math.floor(Date.now() / 1000) + 60 * 60 * 24 // 24 hours from now
const delegation = await client.createDelegation(audience, abilities, { expiration })

const files = [data];
const directoryCid = await client.uploadDirectory(files);

This gives error as: web3storage.js:593 Error: store cannot be used with {did-space2}, stored principal and passed principal must match

Then i updated the code as per your last comment

============= Option 2 ============= 

const web3Key = {key-space2}
const web3Proof = {proof-space2}
const web3Space = {did-space2}

const principal = Signer.parse(web3Key)
const client = await Client.create({store: new StoreMemory()})

// now give Agent the delegation from the Space
const proof = await parseProof(web3Proof)
const space = await client.addSpace(proof)
await client.setCurrentSpace(space.did())

// Create a delegation for a specific DID
const audience = DID.parse(web3Space)
const abilities = ['store/add', 'upload/add']
const expiration = Math.floor(Date.now() / 1000) + 60 * 60 * 24 // 24 hours from now
const delegation = await client.createDelegation(audience, abilities, { expiration })

const files = [data];
const directoryCid = await client.uploadDirectory(files);

Then it gives eror as: Error: cannot delegate capability store/add with {did-space1}

Could you let me know what step i am missing?