|
1 | 1 | # Delegation, invocation and procrastination
|
2 | 2 |
|
3 |
| -Excellent cat gifs. Well done you. |
| 3 | +Excellent cat memes. Well done you. |
4 | 4 |
|
5 | 5 | Now, lets talk UCAN.
|
6 | 6 |
|
7 |
| -UCANs are like JWTs with super powers. They’re an essential component in decentralized authorization. They use public key cryptography - so whenever you create a UCAN you _sign it_ with your private key. |
| 7 | +**What are UCANs?** |
| 8 | +UCANs (User Controlled Authorization Networks) are like supercharged passwords. They’re used for secure, decentralized authorization. When you create a UCAN, you sign it with your private key, kind of like signing a document with your unique signature. |
8 | 9 |
|
9 |
| -The best thing about UCANs is that you can provably delegate "capabilities" that allow others to act on your behalf, without ever sharing your private key. |
| 10 | +**Why are UCANs cool?** |
| 11 | +The best thing about UCANs is that you can securely give permission to others to do things on your behalf without sharing your private key. This is called "delegation". |
10 | 12 |
|
11 |
| -In this exercise, you're going to delegate an `upload/list` capability to the workshop. Behind the scenes the workshop will create it's own private key, and pass it's public key (it's DID) to you on `stdin`. |
| 13 | +**Your Mission** |
| 14 | +In this exercise, you're going to delegate an `upload/list` capability to the workshop. The workshop will create its own private key and pass its public key (DID) to you via `stdin` (standard input). |
12 | 15 |
|
13 | 16 | Your program should read from `process.stdin`, create a delegation for the `upload/list` capability and write it to `process.stdout`. So, something like this:
|
14 | 17 |
|
15 | 18 | ```
|
16 | 19 | DID => your program => delegation
|
17 | 20 | ```
|
18 | 21 |
|
19 |
| -Then the workshop will be able to **invoke** the capability to list the items _you've_ uploaded to _your_ space. It'll verify it can find that cat gif you uploaded in the previous exercise. |
| 22 | +Then the workshop will be able to **invoke** the capability to list the items _you've_ uploaded to _your_ space. It'll verify it can find that cat meme you uploaded in the previous exercise. |
| 23 | + |
| 24 | +One last thing, make sure the delegation remains valid for **more than one hour**. |
20 | 25 |
|
21 |
| -You can read and parse the DID from `stdin` like so: |
22 | 26 |
|
| 27 | +**Steps to complete the task** |
| 28 | +**1. Create new file and read a DID from `stdin`** |
| 29 | +Create new file, like `ex4.mjs` and then you can read and parse the DID from `process.stdin`: |
23 | 30 | ```js
|
24 | 31 | import fs from 'node:fs'
|
25 | 32 | import * as DID from '@ipld/dag-ucan/did'
|
26 | 33 |
|
27 | 34 | const data = fs.readFileSync(process.stdin.fd, 'utf-8')
|
28 | 35 | const principal = DID.parse(data)
|
29 | 36 | ```
|
| 37 | +**2. Create the delegetion** |
| 38 | +Use the client to create a delegation for `upload/list` to the provided DID: |
| 39 | +```js |
| 40 | +import * as Client from '@web3-storage/w3up-client' |
| 41 | +``` |
| 42 | +Create the client and set the expiration time for the delegation: |
| 43 | +```js |
| 44 | +const client = await Client.create() |
| 45 | +const twoHours = 1000 * 60 * 60 * 2 // Two hours in milliseconds |
| 46 | +``` |
| 47 | +In the example above, it is set to two hours. |
| 48 | +**3. Generate the delegation** |
| 49 | +Create the delegation for the `upload/list` capability: |
| 50 | +```js |
| 51 | +const delegation = await client.createDelegation(principal, ['upload/list'], { |
| 52 | + // Expiration is in seconds from Unix epoch |
| 53 | + expiration: Math.round((Date.now() + twoHours) / 1000), |
| 54 | +}) |
| 55 | +``` |
30 | 56 |
|
31 |
| -Create a _new_ file for your solution e.g. `ex4.mjs` and use the client to create a delegation for `upload/list` to the provided DID. Create an archive of the delegation and write it to `process.stdout`. |
32 |
| - |
33 |
| -One last thing, make sure the delegation remains valid for **more than one hour**. |
| 57 | +**4. Archive the delegation** |
| 58 | +Archive the delegation and handle any errors: |
| 59 | +```js |
| 60 | +const { ok: archive, error } = await delegation.archive() |
| 61 | +if (!archive) { |
| 62 | + throw new Error('Failed to create delegation archive', { cause: error }) |
| 63 | +} |
| 64 | +``` |
34 | 65 |
|
| 66 | +**5. Output the delegation** |
| 67 | +Write the delegation to `process.stdout`: |
| 68 | + ```js |
| 69 | + process.stdout.write(archive) |
| 70 | + ``` |
35 | 71 | ─────────────────────────────────────────────────────────────────────────────
|
36 | 72 | * To print these instructions again, run: `$ADVENTURE_NAME print`
|
37 | 73 | * To verify your program, run: `$ADVENTURE_NAME verify ex4.mjs`
|
|
0 commit comments