Closed atinkapoor closed 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.
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?
Ah - you'll want to create a new private key and delegate access to your existing space using the instructions here:
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)
H @travis I did that, here are the steps i performed:
npx ucan-key ed --json
This provided me with DID and Key: { "did": "did:key:zxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "key": "Mxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=" }
Then i used the DID in this command: w3 delegation create did:key:zxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx --can 'store/add' --can 'upload/add' | base64
This gave me the Proof
Now i am using the code as :
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?
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.
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.
While creating account with web3.storage, i created a Space, which has a Key as: did:key:z6xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Lets name it as {did-space1}
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?
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?