Tiempo estimado: 5 minutos de lectura

La conexión de la wallet de usuario es fundamental para interactuar con las DApps de la blockchain. Se ilustra el uso de algunas librerías de apoyo que facilitan la tarea así como la integración de una wallet con login social.

¿En qué consiste la conexión de la wallet de usuario?

Cualquier operación desencadenada desde una aplicación descentralizada que cambie el estado de la blockchain, operación de escritura o transacción, requiere la conexión previa de la wallet de usuario.

La wallet de usuario almacena las claves criptográficas necesarias para poder transaccionar con la blockchain y acceder a los activos digitales registrados.

Los dos elementos principales de una wallet de usuario son la clave pública, de la que deriva la dirección que identifica al propietario de la wallet, y la clave privada que permite firmar transacciones y demostrar la propiedad de los activos almacenados bajo la dirección pública.

En los siguientes apartados se esquematizarán los componentes principales para conectar la wallet de usuario en una DApp programada en React.

Modal de conexión

Posiblemente la forma más extendida de permitir al usuario que escoja su wallet preferida para interactuar con la DApp sea la integración de algún framework que provea de una modal de conexión sobre la que poder parametrizar distintos aspectos tales como la lista de wallets compatibles, las redes soportadas y la forma de presentar visualmente la modal en la interfaz gráfica.

Algunas de las librerías más populares en este ámbito son el AppKit de Reown (antes conocida como Web3Modal), Rainbowkit o Web3 Onboard de Blocknative.

En este caso se ha escogido AppKit por la facilidad de integración con la librería Wagmi y por su completa compatibilidad con la opción de conexión a través de WalletConnect, de la que se hablará más adelante.

Wagmi es una librería de tipo reactivo que facilita las interacciones entre las DApps y la blockchain en múltiples aspectos por ejemplo para conectar wallets, permitir cambiar de red, firmar mensajes y enviar transacciones.

Los siguientes fragmentos de código esquematizarían la integración de todos estos componentes.

En primer lugar se configuran las redes compatibles y los endpoints RPC de acceso al proveedor de nodo elegido para interactuar con la blockchain. Se observa que se definen mediante constantes declaradas en otro fichero:

import { sepolia, baseSepolia } from '@wagmi/core/chains'

const chains = [baseSepolia, sepolia];
const transports = {};


chains.forEach(chain => {
	
	if (chain.id === SEPOLIA.chainId) {		
		transports[chain.id] = http(SEPOLIA.rpcUrl, { timeout: 5_000, });
	}
	else if (chain.id === BASE_SEPOLIA.chainId) {		
		transports[chain.id] = http(BASE_SEPOLIA.rpcUrl, { timeout: 5_000, });
	}
	else return;
})

El siguiente paso es definir los conectores de la librería Wagmi para dar soporte a las wallets de usuario. Por el momento tan sólo se configuran las wallet de tipo «inyectado», aquellas que usualmente se instalan como una extensión del navegador mediante el protocolo definido en la EIP-1193. El ejemplo más común de este tipo de wallets es Metamask.

// Connectors for Wagmi config
const connectors = [
	injected({
		shimDisconnect: true, 
	}),		
]

Con el siguiente fragmento se configura la librería Wagmi con todos los elementos anteriores. Lo habitual es utilizar la función «createConfig» de Wagmi; sin embargo en este ejemplo se utiliza el «wrapper» WagmiAdapter sumimistrado por la librería AppKit para directamente integrar Wagmi con la modal de conexión. Se observa que es preciso contar con un «proyectId» creado a través del panel de control de Reown.

export const wagmiAdapter = new WagmiAdapter({
	projectId: WALLET_CONNECT_PROJECT_ID,
	networks: chains,
	transports,
	connectors,
});

A continuación se crea la modal de conexión. Las opciones de configuración están documentadas en la página del componente:

const web3Modal = createAppKit({
	themeMode: 'light',
	adapters: [wagmiAdapter],
	defaultNetwork: baseSepolia,
	networks: chains,
	projectId: WALLET_CONNECT_PROJECT_ID,
	enableWalletConnect: true,
	debug: true,	
	features: {
		email: false,
		socials: false,
		analytics: false,
		swaps: false,
		onramp: false,
		legalCheckbox: false
	},
	allWallets: 'SHOW',		
});

Se observa la integración directa con WalletConnect. Se trata de un protocolo abierto que posibilita conectar una wallet con una aplicación descentralizada estableciendo una conexión segura cifrada punto a punto entre ambos. De esta forma se permite por ejemplo firmar las transacciones con la blockchain en una DApp de escritorio a través del wallet instalado en un móvil. El único requisito es que la wallet sea compatible con el protocolo de WalletConnect.

También se observa la configuración del elemento «allWallets» que muestra toda la lista de wallets compatibles con la modal de conexión. De ese modo se logra una gran compatibilidad sin tener que integrar de forma explícita conectores particulares en la librería Wagmi.

Por último habría que definir los componentes en la aplicación React:

// Main react app wrapper component
export function WalletConnectors() {		

	return (						 
		<WagmiProvider config={wagmiAdapter.wagmiConfig}>				
			<QueryClientProvider client={queryClient}>
				<App />
			</QueryClientProvider>				
		</WagmiProvider>	
	);
}

Para invocar la modal de conexión desde nuestra DApp se puede utilizar directamente el elemento <appkit-button /> suministrado por AppKit. Se trata de un elemento HTML global que no requiere importación para su uso.

Su inclusión hará aparecer el clásico botón de «Conectar Wallet». Después de establecer la conexión será sustituido de forma automática por el botón que muestra la dirección pública y permite abrir el wallet.

A continuación varias imágenes ilustrando el procedimiento, con la modal de conexión en el centro:

Conexión del wallet de usuario

Login social

Una de las principales barreras de entrada que frenan la adopción de las aplicaciones web3 es la complejidad inherente para gestionar una wallet de usuario autocustodiada, aquella cuya seguridad es responsabilidad exclusiva de su propietario. 

La ventaja de estas wallets frente a las custodiadas es que el control de los activos digitales es también exclusivo del propietario.

El mecanismo más extendido desde el comienzo de implantación de las primeras aplicaciones web3 ha sido crear las wallets de usuario autocustodiadas a partir de una frase semilla, una serie de 12, 18 o 24 palabras que permiten generar y recuperar las claves criptográficas asociadas a las wallets de tipo determinista, de acuerdo al estandar BIP-39.

El proceso de creación de este tipo de wallets difiere bastante de los mecanismos habituales de creación de cuentas en el mundo web2, generando mucha fricción para los nuevos usuarios. Además la llave que permite recuperar la billetera y poderla migrar de dispositivo es la frase semilla. Extraviarla o exponerla a robos puede suponer perder la propiedad de todos los activos digitales asociados a la wallet.

Para paliar estos inconvenientes han surgido en los últimos tiempos iniciativas que permiten crear wallets autocustodiadas mediante procedimientos más comunes como una dirección de email o una passkey almacenada en un medio seguro.

En este artículo se explora la wallet de usuario de Particle, un servicio de Wallet-as-a-Service que posibilita la creación de las claves criptógraficas de la wallet mediante un email o una cuenta de una red social. Las claves privadas son almacenadas de forma segura repartidas entre el dispositivo del usuario y la red del proveedor, permitiendo la recuperación de la cuenta usando el mismo procedimiento inicial que durante la creación (por ejemplo el email).

Para incorporar la wallet de Particle con la modal de conexión, se puede seguir esta guía de integración, junto con la página que describe la opciones de configuración.

El resultado se puede ver en estos framentos de código:

const particleConfig = {
	projectId: PARTICLE_PROJECT_ID,
	clientKey: PARTICLE_CLIENT_KEY,
	appId: PARTICLE_APP_ID,
	web3Modal,	
	authTypes: [AuthType.email],
	fiatCoin: "EUR",
	themeType: "light",	
	promptSettingConfig: {
        promptPaymentPasswordSettingWhenSign: 0,
        promptMasterPasswordSettingWhenLogin: 0,
    },
	wallet: {
		visible: false,		
		customStyle: {
			supportAddToken: true,
			supportChains: [BaseSepolia, EthereumSepolia],
		}
	},
}

// Main react app wrapper component
export function WalletConnectors() {

	return (		
		<AuthCoreContextProvider options={particleConfig}>			 
			<WagmiProvider config={wagmiAdapter.wagmiConfig}>				
				<QueryClientProvider client={queryClient}>
					<App />
				</QueryClientProvider>				
			</WagmiProvider>
		</AuthCoreContextProvider>	
	);
}

El login con la wallet de Particle quedaría de esta forma:

Login con el wallet de Particle

Conclusión: facilitando la adopción de la web3 a los nuevos usuarios

El primer paso para interactuar con cualquier aplicación descentralizada requiere la conexión de una wallet de usuario que identifique al firmante de las transacciones sobre la blockchain.

En el artículo se han presentado algunas librerías y servicios que permiten integrar en las aplicaciones los componentes que facilitan la conexión de la wallet de usuario:

  • Wallet de Particle para crear una dirección blockchain a partir de un email.
  • Modal de conexión de AppKit para conseguir la mayor compatibilidad posible de wallets.
  • Librería Wagmi para gestionar la conexión e interacción con la blockchain en una aplicación React.

El siguiente paso a explorar será la gestión de las transacciones con la blockchain, otro de los aspectos más importantes y que más fricción generan a los usuarios de las aplicaciones web3.


¿Qué librerías usas para conectar la wallet de usuario en tus DApps? ¿Te han resultado de interés las propuestas planteadas en el artículo?

Si quieres facilitar la adopción de tus aplicaciones y servicios web3 a tus usuarios, puedo ayudarte a escoger las mejores alternativas. Contáctame y hablamos.