Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use delegation on the client side? #1514

Closed
adamazad opened this issue Jun 22, 2024 · 2 comments
Closed

How to use delegation on the client side? #1514

adamazad opened this issue Jun 22, 2024 · 2 comments

Comments

@adamazad
Copy link

Hi, I'm following the example about using delegation to upload directly to the network. I have a next.js route located at /api/w3up/delegation:

// app/api/w3up/delegation/route.ts

import * as DID from '@ipld/dag-ucan/did';
import { getWeb3StorageClient } from './getWeb3StorageClient';
import { NextResponse } from 'next/server';

export async function GET() {
  const web3StorageClient = await getWeb3StorageClient();
  const did = web3StorageClient.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 web3StorageClient.createDelegation(audience, abilities, {
    expiration,
  });

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

  return NextResponse.json({
    delegation: u4?.toString(),
  });
}

on the frontend, I have a hook to create a client:

// api/hooks/useWeb3StorageClient.ts

import * as Delegation from '@ucanto/core/delegation';
import * as Client from '@web3-storage/w3up-client';

import { useEffect, useState } from 'react';

export async function getWeb3StorageClient(): Promise<{
  error: Error | null;
  client: Client.Client | null;
}> {
  try {
    // Fetch the delegation from the backend
    const response = await fetch(`/api/w3up/delegation`);
    const data = await response.arrayBuffer();

    console.log('getDelegationResponse', data);

    const delegationUint8Array = new Uint8Array(data);

    console.log('delegationUint8Array', delegationUint8Array);

    const client = await Client.create();
    // Deserialize the delegation
    const delegation = await Delegation.extract(delegationUint8Array);

    if (!delegation.ok) {
      throw delegation.error as Error;
    }

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

    return {
      error: null,
      client,
    };
  } catch (error) {
    return {
      error: error as Error,
      client: null,
    };
  }
}

export function useWeb3StorageClient() {
  const [ready, setReady] = useState(false);
  const [client, setClient] = useState<Client.Client | null>(null);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    if (ready) {
      return;
    }

    getWeb3StorageClient().then(({ error, client }) => {
      if (error) {
        console.error(error);
        setReady(false);
        setClient(null);
        setError(error);
        return;
      }

      setClient(client);
      setReady(true);
      setError(null);
    });
  }, []);

  return { ready, client, error };
}

I get the following error:

image
@travis
Copy link
Contributor

travis commented Jun 28, 2024

hm, unless I'm reading wrong, I think that in your server code you are returning the delegation inside a json blob but then in the client you are trying to read the json as CBOR - this is, of course, failing.

@adamazad
Copy link
Author

Closing this in favor of #1515

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants