# Agent-js metadata request path

**URL:** <https://forum.dfinity.org/t/agent-js-metadata-request-path/27111>\
**Category:** Developers\
**Created:** [January 29, 2024, 8:46pm UTC](https://forum.dfinity.org/t/agent-js-metadata-request-path/27111 "2024-01-29T20:46:11Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![peterparker](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@peterparker](https://forum.dfinity.org/u/peterparker)\
**Post date:** [January 29, 2024, 8:46pm UTC](https://forum.dfinity.org/t/agent-js-metadata-request-path/27111/1 "2024-01-29T20:46:11Z")

</div>

Follow-up of [Read+write canister wasm module metadata - #3 by peterparker](https://forum.dfinity.org/t/read-write-canister-wasm-module-metadata/27066/3)

I try to query wasm metadata using agent-js and I do not understand what value of `CustomPath` or `Metadata` should be provided to agent-js because it seems that any combination just works out.

e.g given such metadata:

```auto
await spawn({
    command: 'ic-wasm',
    args: [
      OUTPUT,
      '-o',
      OUTPUT,
      'metadata',
      'hello:world', // <-------- here hello:world === metadata key
      '-d',
      '"yolo"', // <-------- here value === yolo
      '-v',
      'public'
    ]
  });

```

I try to request the medata as following:

```auto
const agent = new HttpAgent({
    host: import.meta.env.VITE_HOST,
  });

  await agent.fetchRootKey();

  const request = await CanisterStatus.request({
    canisterId: Principal.from(import.meta.env.VITE_CANISTER_ID),
    agent,
    paths: [
      {
        kind: "metadata",
        key: "",
        path: "hello:world",
        decodeStrategy: "utf-8",
      },
    ],
  });

  console.log(request);

```

Above works out but also

```auto
{
        key: "",
        path: "hello:world",
        decodeStrategy: "utf-8",
      },

```

or even

```auto
{
        kind: "metadata",
        key: "whatever-this-does-not-matter",
        path: "hello:world",
        decodeStrategy: "utf-8",
      },

```

So I’m curious what’s correct, what’s the key and what’s the path because unless I missed something it isn’t that obvious from the ts doc:

```auto
**
 * Interface to define a custom path. Nested paths will be represented as individual buffers, and can be created from text using {@link TextEncoder}
 */
export interface CustomPath {
    key: string;
    path: ArrayBuffer[] | string;
    decodeStrategy: 'cbor' | 'hex' | 'leb128' | 'utf-8' | 'raw';
}
/**
 * Interface to request metadata from the icp:public or icp:private sections.
 * Similar to {@link CustomPath}, but accepts a simple string argument.
 * Private metadata will require the ${@link Identity} used by the ${@link HttpAgent} will need to be requested using an identity that controlls the canister.
 */
export interface MetaData {
    kind: 'metadata';
    key: string;
    path: string | ArrayBuffer;
    decodeStrategy: 'cbor' | 'hex' | 'leb128' | 'utf-8' | 'raw';
}

```

---

<div class="post-metadata">

**Author:** ![peterparker](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@peterparker](https://forum.dfinity.org/u/peterparker)\
**Post date:** [January 30, 2024, 2:35pm UTC](https://forum.dfinity.org/t/agent-js-metadata-request-path/27111/2 "2024-01-30T14:35:34Z")

</div>

Maybe I’m dumb but, I cannot understand the TypeScript definition I shared above and the relation with the effective implementation ([source](https://github.com/dfinity/agent-js/blob/20639481aa7693c70f8d8123bb268f0ff3241df3/packages/agent/src/canisterStatus/index.ts#L318)) in agent-js.

```auto
// Check for CustomPath signature
      if ('key' in path && 'path' in path) {
        // For simplified metadata queries
        if (typeof path['path'] === 'string' || path['path'] instanceof ArrayBuffer) {
          const metaPath = path.path;
          const encoded = typeof metaPath === 'string' ? encode(metaPath) : metaPath;

          return [encode('canister'), canisterBuffer, encode('metadata'), encoded];

          // For non-metadata, return the provided custompath
        } else {
          return path['path'];
        }
      }

```

Looks like the `key` can indeed be anything and `kind: 'metadata'` just doesn’t matter but, I’m probably missing something.

Anyone has use this? Can anyone provide an example or explain what at the correct parameters to query a custom metadata on a wasm module?

---

<div class="post-metadata">

**Author:** ![anon74414410](https://avatars.discourse-cdn.com/v4/letter/a/85f322/32.png) [@anon74414410](https://forum.dfinity.org/u/anon74414410)\
**Post date:** [January 30, 2024, 5:07pm UTC](https://forum.dfinity.org/t/agent-js-metadata-request-path/27111/3 "2024-01-30T17:07:40Z")

</div>

An example of metadata is the predefined `candid`, path, which is an alias for:

```auto
case 'candid':
    return [encode('canister'), canisterBuffer, encode('metadata'), encode('candid:service')];

```

It’s not the friendliest API - I’m happy to add any known metadata fields as known paths to query, since custom paths are difficult to intuit.

There are multiple ways to query paths, though. `CustomPath` is the most broad utility, because it can request paths outside of metadata. `metadata` is simply a shorthand, skipping part of the definition. Whatever suits you is the “right” way to query, from my POV

What metadata field were you originally trying to query?

---

<div class="post-metadata">

**Author:** ![peterparker](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@peterparker](https://forum.dfinity.org/u/peterparker)\
**Post date:** [January 30, 2024, 5:11pm UTC](https://forum.dfinity.org/t/agent-js-metadata-request-path/27111/4 "2024-01-30T17:11:52Z")

</div>

> [@anon74414410](#):
>
> What metadata field were you trying to query?

That’s the thing, a custom metadata as in the example I shared above.

```auto
ic-wasm test.wasm -o test.wasm metadata hello:world -d "yolo" -v public

```

---

<div class="post-metadata">

**Author:** ![peterparker](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@peterparker](https://forum.dfinity.org/u/peterparker)\
**Post date:** [January 30, 2024, 5:13pm UTC](https://forum.dfinity.org/t/agent-js-metadata-request-path/27111/5 "2024-01-30T17:13:14Z")

</div>

Also all the example above using agent-js are able to read this custom metadata: [Agent-js metadata request path](https://forum.dfinity.org/t/agent-js-metadata-request-path/27111)

But because they can all read the data, I’m really confused about what is the actually proper way.

---

<div class="post-metadata">

**Author:** ![anon74414410](https://avatars.discourse-cdn.com/v4/letter/a/85f322/32.png) [@anon74414410](https://forum.dfinity.org/u/anon74414410)\
**Post date:** [January 30, 2024, 5:17pm UTC](https://forum.dfinity.org/t/agent-js-metadata-request-path/27111/6 "2024-01-30T17:17:22Z")

</div>

I wasn’t aware that the `metadata` type was superfluous - maybe I’ll deprecate that in favor of the

```auto
{
    key: "",
    path: "hello:world",
    decodeStrategy: "utf-8",
},

```

pattern just because it’s shorter.

As for the `key`, the `request` can send multiple paths, and will return a map of all the paths you requested. The `key`, is just what you’ll use to look up the value in the returned map

---

<div class="post-metadata">

**Author:** ![peterparker](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@peterparker](https://forum.dfinity.org/u/peterparker)\
**Post date:** [January 30, 2024, 5:21pm UTC](https://forum.dfinity.org/t/agent-js-metadata-request-path/27111/7 "2024-01-30T17:21:09Z")

</div>

I was really confused by the `key`, make sense now that you explains it. Thanks a lot!

---

<div class="post-metadata">

**Author:** ![anon74414410](https://avatars.discourse-cdn.com/v4/letter/a/85f322/32.png) [@anon74414410](https://forum.dfinity.org/u/anon74414410)\
**Post date:** [January 30, 2024, 5:36pm UTC](https://forum.dfinity.org/t/agent-js-metadata-request-path/27111/8 "2024-01-30T17:36:58Z")

</div>

I’ll be modifying this feature today, so this was great timing! I’ll add some more documentation
