Construye en Flow: Aprende FCL - 5. Obtener una lista de NFTs viviendo una direccion conocida
Tags: javascript, web3, flow, fcl
Published: 2022-06-12 23:18:59

**Resumen**

En esta guía, expandirás tu conocimiento interactuando con contratos inteligentes a través de scripts en Cadence. Aprenderás como:

- sacar una lista de NFTs almacenados en la cuenta de una dirección (usaremos un Flovatar para este ejemplo)
- preparar y retornarlas como un Array de `Struct` personalizados.

**Previamente en “Aprende FCL”**

[En el post pasado](https://dev.to/onflow/construye-en-flow-aprende-fcl-4-como-resolver-identidades-en-find-a-direcciones-en-flow-26nm), aprendimos como interactuar con contratos desplegados y como retornar un valor `Struct` personalizado de un script. Aprenderemos como construir sobre ese conocimiento y ejecutar un procedimiento más complejo - traer una lista de NFTs almacenados en una cuenta, mapearlos a nuestro formato favorito y retornarlos de vuelta. 

Empecemos! 💪

**¿Qué es Flovatar?**

Flovatar es una de los muchos asombrosos proyectos sobre NFTs construido encima de Flow. En vez de dejarte comprar uno de esos miles de NFTs únicos, provee herramientas para que tu puedas agregar tu toque personal a un Flovatar que vaya con tu estilo

**Preparación**

Las primeras cosas primero, deberías encontrar la dirección donde el contrato está desplegado. El [GitHub de Flovatar](https://github.com/crash13override/flovatar) tiene las direcciones para los contratos desplegados en la página principal.

- Mainnet - **0x921ea449dffec68a**
- Testnet - **0x0cf264811b95d465**

Y en el archivo `get_flovatars.cdc`, El contrato Flovatar tiene un método util que podemos usar llamado `getFlovatars` que acepta una dirección como argumento:

```jsx
import Flovatar from **0x921ea449dffec68a**
pub fun main(address:Address) : [Flovatar.FlovatarData] {
	return Flovatar.getFlovatars(address: address)
}
```

### Paso 1- Instalación

Agrega `"onflow/fcl": "1.0.0"` como tu dependencia.

### Paso 2 - Setup

Como la última vez importaremos los métodos necesarios para configurar FCL:

```jsx
//Importamos métodos de FCL
import { query, config } from "@onflow/fcl";

// Especifica el endpoint de la API - esta vez usaremos Mainnet
const api = "https://rest-mainnet.onflow.org";

// Configurar FCL para usar Testnet como el nodo de acceso
config().put("accessNode.api", api);

```

### Paso 3 - Implementar el método `getFlovatar`

```jsx
// Obtén una lista de Flovatars a través de direcciones.
const getFlovatars = async (adddress) => {
	const cadence = `
		import Flovatar from **0x921ea449dffec68a**
	
		pub fun main(address:Address) : [Flovatar.FlovatarData] {
			return Flovatar.getFlovatars(address: address)
		}
	`
	// Necesitamos pasar un sólo argumento de tipo Address
	const args = (arg, t) => [arg(address, t.Address)];

	const flovatars = await query({ cadence, args });
	console.log({ flovatars })
}
```

### Paso 4 - Démosle un intento

Hagamos un llamado a nuestro método. Nuestro objetivo sera [Luca (creador de Flovatar)](https://find.xyz/luca) - su dirección es `0x2a0eccae942667be` 

```jsx
(async()=>{
	const user = "0x2a0eccae942667be"
	await getFlovatars(user)
})()
```

Si das una mirada a la consola veras una lista de objetos representando Flovatars.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0j19ryzlfv7dl0wu5mc3.png)
 

No tan mal, verdad? Bueno… tratemos de desenvolver ese campo `metadata` :

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cb0d0mv0y8j88g17t2z3.png)
 

Ahora eso es SVG para ti. Mientras que puedes traer esta data cada vez que el usuario refresque la página, idealmente querrías cachearla de alguna manera y solo consultarla cuando la necesites.

Adicionalmente si consultas cuentas con cientos/miles de NFTs podrias sobrepasar el límite de valor retornable, el cual es alrededor de ~10Mbs.

Si vas al [Showroom de Flovatar](https://flovatar.com/showroom) y usas las dev tools en tu navegador puedes encontrar que todas las imágenes estan cacheadas en `https://flovatar.com/api/image/{id}`. Traigamos solo los subcampos `id` y `creatorAddress` del campo `metadata` de los NFTs. De esta manera podemos identificar si el dueño es un creador original de dicho NFT.

## Paso 5- Mejorando el script en Cadence

Como recordarás del último post- podemos crear Struct personales que almacenarán toda la data que queremos retornar. Definiremos un Struct llamado `Avatar` con dos campos: `id` y `isCreator`

```jsx
// Trae una lista de FLovatars de una dirección
const getFlovatarsImproved = async (adddress) => {
	const cadence = `
		import Flovatar from **0x921ea449dffec68a
	
		pub struct Avatar{
      pub let id: UInt64
      pub let isCreator: Bool

      // guión abajo en frente de los argumentos nos permite pasarlos sin nombrarlos
			init(_ id: UInt64, _ isCreator: Bool){
        self.id = id
        self.isCreator = isCreator
      }
		}**

		pub fun main(address:Address) : [Avatar] {
			// Como la última vez llamaremos el método "getFlovatars"
			let flovatars = Flovatar.getFlovatars(address: address)

			// Colectaremos la data procesada del Flovatar aquí
      let data: [Avatar] = []
      
			// Un loop simple para iterar sobre Flovatars
      for flovatar in flovatars {
        let isCreator = flovatar.metadata.creatorAddress == address
        let avatar = Avatar(flovatar.id, isCreator)

				// agregar nueva instancia del Avatar en la lista resultante
        data.append(avatar)
      }
      return data  
    }
	`

	// Pasaremos la dirección como un argumento solitario de tipo Address
	const args = (arg, t) => [arg(address, t.Address)];

	const flovatars = await query({ cadence, args });
	console.log({ flovatars })
}
```

### **Finalmente**

Actualicemos nuestro IFEE e intentemos nuevamente:

```jsx
(async ()=> {
	const user = "0x2a0eccae942667be"
	await getFlovatarsImproved(user)
})()
```

Esta invocación resulta en una huella más reducida en la consola.

![flovatars-small.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/d51371ac-885c-4c30-afd7-c1060e4aaa2a/flovatars-small.png)

Contained information would be enough to construct a link 

La información contenida sería suficiente para construir un link (`https://flovatar.com/flovatars/{id}`) o imagen (`https://flovatar.com/api/image/{id}`) en tu interfaz. 

## ⭐Challenge Extra

Usando tu conocimiento de [el post sobre resolver identidades en .find](https://dev.to/onflow/construye-en-flow-aprende-fcl-4-como-resolver-identidades-en-find-a-direcciones-en-flow-26nm) modifica el codigo para permitir pasar identidades de .find al método `getFlovatars`

## Recursos

- **Código del ejemplo**:  [https://codesandbox.io/s/dev-to-fcl-05-list-flovatars-at-address-0bibcd](https://codesandbox.io/s/dev-to-fcl-05-list-flovatars-at-address-0bibcd?file=/src/index.js)
- **Cadence Structs** - [https://docs.onflow.org/cadence/language/composite-types/#composite-type-declaration-and-creation](https://docs.onflow.org/cadence/language/composite-types/#composite-type-declaration-and-creation)
- **Repositorio de Flovatar en GitHub** - [https://github.com/crash13override/flovatar](https://github.com/crash13override/flovatar)
- **Contrato de Flovatar en Flow View Source** - [https://flow-view-source.com/mainnet/account/0x921ea449dffec68a/contract/Flovatar](https://flow-view-source.com/mainnet/account/0x921ea449dffec68a/contract/Flovatar)

 Otros recursos que podrías encontrar útil:

- **Documentación de Flow** - [https://docs.onflow.org/](https://docs.onflow.org/) - Más información detallada acerca de la blockchain de Flow y como interactuar con ella.
- **Flow Portal** - [https://flow.com/](https://flow.com/) - Tu portal de entrada a Flow.
- **FCL JS** - [https://github.com/onflow/fcl-js](https://github.com/onflow/fcl-js) - Código fuente y la habilidad de contribuir a la libreria de FCL JS.
- **Cadence** - [https://docs.onflow.org/cadence/](https://docs.onflow.org/cadence/) - Introduccion a Cadence.
- **Codesandbox** - [https://codesandbox.io](https://codesandbox.io/) - Un editor de texto genial para prototipar en el navegador.

Esta es una traducción al español del quinto artículo de la serie Build on Flow | Learn FCL escrito por [Maksimus Starka](https://twitter.com/MaxStalker).