> ## Documentation Index
> Fetch the complete documentation index at: https://sequence-0fb8d9e6-shop-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Gestión de metadatos de colecciones

> Cómo almacenar archivos multimedia usando la API de Sequence Collections con Cloudflare Workers, así como leer desde la Metadata API para mostrar imágenes.

Tiempo estimado: 20 minutos

En esta guía le mostraremos cómo almacenar archivos multimedia usando la API de Sequence Collections con [Cloudflare Workers](https://www.cloudflare.com/), así como leer desde la Metadata API para mostrar imágenes.

Esto se puede lograr en 8 pasos

1. [Obtenga una clave API secreta](/guides/metadata-guide#1-obtain-a-secret-api-key) desde el [Sequence Builder Console](https://sequence.build)
2. [Cree una colección](/guides/metadata-guide#2-create-collection-from-a-curl-request) mediante una solicitud cURL una sola vez
3. [Cree un token](/guides/metadata-guide#3-create-token-using-tokenid) usando un tokenID
4. [Cree un asset](/guides/metadata-guide#4-create-asset-using-tokenid) usando un assetID
5. [Almacene una imagen](/guides/metadata-guide#5-store-image-asset) procese y almacene una imagen
6. [Actualice a no privado](/guides/metadata-guide#6-update-non-private-token) cambie un asset a no privado
7. [Publique la colección](/guides/metadata-guide#7-publish-collection-from-a-curl-request) mediante una solicitud cURL una sola vez
8. [Renderice el asset desde la API](/guides/metadata-guide#8-render-asset-from-api-publicly) mediante una solicitud cURL una sola vez

Primero siga [esta sección de la Guía de Servicio de Minteo de Coleccionables](/guides/mint-collectibles-serverless#1-setup-cloudflare-environment-with-wrangler-cli-and-deploy-a-test) para crear un Cloudflare Worker

## 1. Obtenga una clave secreta de API (JWT\_ACCESS\_KEY)

Para utilizar el servicio backend, debe obtener una `Secret API` Key para autenticar las solicitudes a su proyecto.

Primero, acceda a la configuración y seleccione las claves API desde el [Sequence Builder Console](https://sequence.build/)

<Frame>
  ![builder settings access keys](https://mintlify.s3.us-west-1.amazonaws.com/sequence-0fb8d9e6-shop-docs/images/builder/builder_settings_access_keys.png)
</Frame>

Desplácese hacia abajo y seleccione `+ Add Admin API Secret Key`

<Frame>
  ![builder settings add service account](https://mintlify.s3.us-west-1.amazonaws.com/sequence-0fb8d9e6-shop-docs/images/builder/builder_settings_add_service_account.png)
</Frame>

Luego cambie el acceso a `write` y confirme presionando `+ Add API Secret Key`

<Frame>
  ![builder settings add service account](https://mintlify.s3.us-west-1.amazonaws.com/sequence-0fb8d9e6-shop-docs/images/builder/builder_settings_add_service_account_confirm.png)
</Frame>

Finalmente, `copie` la clave y guárdela en su `wrangler.toml` como `JWT_ACCESS_KEY`, ya que no podrá acceder a ella en el futuro desde el Sequence Builder Console.

## 2. Crear una colección desde una solicitud cURL

Como requisito previo para subir medios al servicio, primero debe crear una colección. Utilice la `Secret API Key` y el `projectID` obtenidos desde el [Builder Console](https://sequence.build/)

Llamamos al servicio para obtener un `collectionID`

```shell
curl --location 'https://metadata.sequence.app/rpc/Collections/CreateCollection' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <jwt_access_key>' \
--data '{
    "projectId": <project_id>,
    "collection": {
        "metadata": {
            "name": "<collection_name>",
            "description": "<description>",
            "external_link" : "<https://link>"
        },
        "image": "",
        "decimals": <decimals_typically_as_0>,
        "properties": null,
        "attributes": null
    }
}'
```

Luego, establecemos el `collectionID` de la respuesta recibida en el `wrangler.toml` como `COLLECTION_ID`

## 3. Crear un token usando TokenID

<Note>
  Si usa un worker de Cloudflare, asegúrese de agregar `node_compat = true` a su `wrangler.toml` para que el objeto window esté disponible para el paquete `@0xsequence/metadata`
</Note>

Instale el paquete de metadata para usar `SequenceCollections` con `pnpm install @0xsequence/metadata`

```typescript
import { SequenceCollections } from '@0xsequence/metadata'
import { ethers } from 'ethers'
...
const METADATA_URL = 'https://metadata.sequence.app'
const collectionsService = new SequenceCollections(METADATA_URL, JWT_ACCESS_KEY)

const randomTokenIDSpace = ethers.BigNumber.from(ethers.hexlify(ethers.randomBytes(20)))

const res1 = await collectionsService.createToken({
	projectId: projectID,
	collectionId: collectionID,
	token: {
		tokenId: String(randomTokenIDSpace),
		name: name,
		description: description,
		decimals: 0,
		attributes: attributes // can leave blank
	}
})

```

## 4. Crear un asset usando TokenID

En la solicitud, establezca el `metadadaField` (assetType) en `image`, completando los otros campos necesarios para obtener una respuesta de asset que se usará en el siguiente paso

```typescript
const jsonCreateAsset = await collectionsService.createAsset({
	projectId: projectID,
	asset: {
		id: Number(String(randomTokenIDSpace).slice(0,10)),
		collectionId: collectionID,
		tokenId: String(randomTokenIDSpace),
		metadataField: "image"
	}
})

```

## 5. Almacenar el asset de imagen

Con el `asset.id` proporcionado del objeto `jsonCreateAsset` anterior

```typescript
	...
	const uploadAsset = async (env: Env, projectID: any, collectionID: any, assetID: any, tokenID: any, url: any) => {
		const response = await fetch(url);
		if (!response.ok) throw new Error(`Failed to fetch file from ${url}: ${response.statusText}`);
		const arrayBuffer = await response.arrayBuffer();
		const blob = new Blob([arrayBuffer]);

		const formData = new FormData();
		
		formData.append('file', blob);
		
		let METADATA_URL = 'https://metadata.sequence.app'

		// Construct the endpoint URL
		const endpointURL = `${METADATA_URL}/projects/${projectID}/collections/${collectionID}/tokens/${tokenID}/upload/${assetID}`;

		try {
			// Use fetch to make the request
			const fetchResponse = await fetch(endpointURL, {
				method: 'PUT',
				body: formData,
				headers: {
					Authorization: `Bearer ${env.JWT_ACCESS_KEY}`, // Put your token here
				},
			});
		
			// Assuming the response is JSON
			const data = await fetchResponse.json();

			return data;
		}catch(err){
			console.log(err)
		}
	}
	...
	const uploadAssetRes = await uploadAsset(env, projectID, collectionID, jsonCreateAsset.asset.id, String(randomTokenIDSpace), imageUrl)
	...
```

Donde el `uploadAssetRes.url` devuelto es la URL del archivo multimedia alojado en los servidores de Sequence

## 6. Actualizar token no privado

Ahora, hacemos que el token sea no privado estableciendo el booleano `private` en `false`

```typescript
const res3 = await collectionsService.updateToken({
	projectId: projectID,
	collectionId: collectionID,
	private: false,
	tokenId: String(randomTokenIDSpace),
	token: {
		name: name,
		attributes: attributes,
		tokenId: String(randomTokenIDSpace),
	}
})
```

***

## 7. Publicar colección desde una solicitud cURL

Finalmente, también como una solicitud única, publicamos la colección usando el `projectID` y el `collectionID` ejecutando el siguiente comando

```shell
curl --location 'https://metadata.sequence.app/rpc/Collections/PublishCollection' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <jwt_access_key> \
--data '{
    "projectId": <project_id>,
    "collectionId": <collection_id>
}'
```

Esto hará que la colección y todos los tokens con la propiedad `private` establecida en `false` sean accesibles públicamente, mientras que los demás permanecerán ocultos hasta que se cambie su estado

## 8. Renderizar asset desde la API públicamente

Puede probar su trabajo anterior llamando a esta solicitud cURL con las variables actualizadas, lo que descargará el archivo en su terminal local.

O puede copiar y pegar la URL en un navegador y ver la imagen

Si usó el mismo código, el `<file_name>` será `image.png`

```shell [cURL]
curl --location 'https://metadata.sequence.app/projects/<project_id>/collections/<collection_id>/tokens/<token_id>/<file_name>' --output stored_file.png
```

Y si estaba usando la colección para el `baseURI` de un `ERC721` o `ERC1155`, escribiría en un smart contract `setBaseMetadataURI` la siguiente `URI`

```
https://metadata.sequence.app/projects/<project_id>/collections/<collection_id>/tokens/
```

Y el smart contract agregará automáticamente el `tokenID` al final

Pruébelo usted mismo

```shell [cURL]
curl https://metadata.sequence.app/projects/1229/collections/40/tokens/457657099779485875855215293997335918990635014431
```

O en un [navegador](https://metadata.sequence.app/projects/1229/collections/40/tokens/457657099779485875855215293997335918990635014431)

### Renderizar asset desde la API de forma privada

Si decide mantener sus activos privados (en el parámetro token, private: true), aún puede ver la imagen del token si proporciona el jwt\_access\_key en el encabezado.

Para esta guía, el `metadata_field` está configurado como `image`

```shell [cURL]
curl --location 'https://metadata.sequence.app/projects/<project_id>/collections/<collection_id>/tokens/<token_id>/asset/<metadada_field>' \
--header 'Authorization: Bearer <jwt_access_key>' \
--output stored_file.png
```

<Note>
  El código completo para esta guía se encuentra [aquí](https://github.com/0xsequence-demos/template-cloudflare-worker-collections-api/tree/master)
</Note>
