Este documento está en progreso y se seguirá refinando.
Conceptos clave
Estos son los conceptos clave que debes conocer antes de usar el SDK de IQLabs.
Almacenamiento de datos (Code In)
Así es como almacenas cualquier dato (archivos, texto, JSON) en cadena.
¿Cómo se almacena?
Según el tamaño de los datos, el SDK elige el método óptimo:
- Datos pequeños (< 900 bytes): se almacenan de inmediato, más rápido
- Datos medianos (< 8.5 KB): se dividen en múltiples transacciones
- Datos grandes (>= 8.5 KB): se suben en paralelo para mayor velocidad
Funciones clave relacionadas
codeIn(): subir datos y obtener un ID de transacción
readCodeIn(): leer datos desde un ID de transacción
PDA de estado de usuario
Una cuenta de perfil en cadena para un usuario.
¿Qué se almacena?
- Información del perfil (nombre, foto de perfil, biografía, etc.)
- Número de archivos subidos
- Registros de solicitudes de amistad
Las solicitudes de amistad no se almacenan como valores en el PDA; se envían como transacciones.
¿Cuándo se crea?
Se crea automáticamente la primera vez que llamas a codeIn(). No se requiere configuración adicional, pero el primer usuario puede necesitar firmar dos veces.
PDA de conexión
Una cuenta en cadena que gestiona las relaciones entre dos usuarios (amigos, mensajes, etc.).
¿Qué estados puede tener?
- pending: se envió una solicitud de amistad pero aún no fue aceptada
- approved: la solicitud fue aceptada y los usuarios están conectados
- blocked: una de las partes bloqueó a la otra
Una conexión bloqueada solo puede ser desbloqueada por quien bloqueó.
Funciones clave relacionadas
Tablas de base de datos
Almacena datos JSON en tablas como una base de datos.
¿Cómo se crean las tablas?
No existe una función dedicada para “crear tabla”. La primera escritura con writeRow() crea la tabla automáticamente.
Una tabla se identifica de forma única por la combinación de dbRootId y tableSeed (nombre de la tabla).
Funciones clave relacionadas
Detalles de funciones
Almacenamiento y recuperación de datos
codeIn()
| Parámetros | connection: conexión RPC de Solana
signer: billetera firmante
data: datos a subir (cadena o arreglo)
mode: modo de contrato (predeterminado: ‘anchor’) |
|---|
| Devuelve | Firma de transacción (string) |
import { codeIn } from 'iqlabs-sdk';
// Subir un solo archivo
const signature = await codeIn(connection, signer, 'Hello, blockchain!');
// Subir varios archivos
const multiSig = await codeIn(connection, signer, ['file1.txt', 'file2.txt', 'file3.txt']);
readCodeIn()
| Parámetros | txSignature: firma de transacción
connection: (opcional) conexión RPC de Solana |
|---|
| Devuelve | Datos almacenados (string) |
import { readCodeIn } from 'iqlabs-sdk';
const data = await readCodeIn('5Xg7...', connection);
console.log(data); // 'Hello, blockchain!'
Gestión de conexiones
requestConnection()
| Parámetros | connection: conexión RPC de Solana
signer: billetera firmante
dbRootId: ID de base de datos
partyA, partyB: los dos usuarios a conectar
tableName: nombre de la tabla de conexión
columns: lista de columnas
idCol: columna ID
extKeys: claves de extensión |
|---|
| Devuelve | Firma de transacción (string) |
import { requestConnection } from 'iqlabs-sdk';
// Enviar una solicitud de amistad
await requestConnection(
connection, signer, 'my-db',
myWalletAddress, friendWalletAddress,
'dm_table', ['message', 'timestamp'], 'message_id', []
);
manageConnection()
| Parámetros | builder: InstructionBuilder
accounts: { db_root, connection_table, signer }
args: { db_root_id, connection_seed, new_status } |
|---|
| Devuelve | TransactionInstruction |
import { contract } from 'iqlabs-sdk';
// Aprobar una solicitud de amistad
const approveIx = contract.manageConnectionInstruction(
builder,
{ db_root, connection_table, signer: myPubkey },
{ db_root_id, connection_seed, new_status: contract.CONNECTION_STATUS_APPROVED }
);
// Bloquear a un usuario
const blockIx = contract.manageConnectionInstruction(
builder,
{ db_root, connection_table, signer: myPubkey },
{ db_root_id, connection_seed, new_status: contract.CONNECTION_STATUS_BLOCKED }
);
readConnection()
| Parámetros | dbRootId: ID de base de datos
walletA, walletB: las dos billeteras a comprobar |
|---|
| Devuelve | { status: 'pending' | 'approved' | 'blocked', requester, blocker } |
import { readConnection } from 'iqlabs-sdk';
const { status, requester, blocker } = await readConnection('my-db', walletA, walletB);
console.log(status); // 'pending' | 'approved' | 'blocked'
writeConnectionRow()
| Parámetros | connection: conexión RPC de Solana
signer: billetera firmante
dbRootId: ID de base de datos
connectionSeed: semilla de conexión
rowJson: datos JSON |
|---|
| Devuelve | Firma de transacción (string) |
import { writeConnectionRow } from 'iqlabs-sdk';
await writeConnectionRow(
connection, signer, 'my-db', connectionSeed,
JSON.stringify({ message_id: '123', message: 'Hello friend!', timestamp: Date.now() })
);
fetchUserConnections()
Obtiene todas las conexiones (solicitudes de amistad) de un usuario analizando el historial de transacciones del PDA UserState. Cada conexión incluye su dbRootId, que identifica a qué app pertenece la conexión.
| Parámetros | userPubkey: clave pública del usuario (string o PublicKey)
options: ajustes opcionales |
|---|
| Opciones | limit: número máximo de transacciones a obtener
before: firma desde la que paginar
speed: perfil de límite de tasa (‘light’, ‘medium’, ‘heavy’, ‘extreme’)
mode: modo de contrato (opcional) |
| Devuelve | Arreglo de objetos de conexión con dbRootId, partyA, partyB, status, requester, blocker, timestamp |
import { fetchUserConnections } from 'iqlabs-sdk/reader';
// Obtener todas las conexiones (¡en todas las apps!)
const connections = await fetchUserConnections(myPubkey, {
speed: 'light', // 6 RPS (predeterminado)
limit: 100
});
// Filtrar por app
const solchatConnections = connections.filter(c => c.dbRootId === 'solchat');
const zoConnections = connections.filter(c => c.dbRootId === 'zo-trading');
// Filtrar por estado
const pendingRequests = connections.filter(c => c.status === 'pending');
const friends = connections.filter(c => c.status === 'approved');
const blocked = connections.filter(c => c.status === 'blocked');
// Revisar detalles de conexión
connections.forEach(conn => {
console.log(`App: ${conn.dbRootId}, ${conn.partyA} <-> ${conn.partyB}, status: ${conn.status}`);
});
Gestión de tablas
writeRow()
| Parámetros | connection: conexión RPC de Solana
signer: billetera firmante
dbRootId: ID de base de datos
tableSeed: nombre de la tabla
rowJson: datos JSON de la fila |
|---|
| Devuelve | Firma de transacción (string) |
import { writeRow } from 'iqlabs-sdk';
// Escribir la primera fila para crear la tabla
await writeRow(connection, signer, 'my-db', 'users', JSON.stringify({
id: 1, name: 'Alice', email: 'alice@example.com'
}));
// Agregar otra fila a la misma tabla
await writeRow(connection, signer, 'my-db', 'users', JSON.stringify({
id: 2, name: 'Bob', email: 'bob@example.com'
}));
readTableRows()
| Parámetros | accountInfo: información de la cuenta de la tabla |
|---|
| Devuelve | Arreglo de filas (Row[]) |
import { readTableRows, contract } from 'iqlabs-sdk';
const dbRootPda = contract.pda.getDbRootPda('my-db');
const tablePda = contract.pda.getTablePda(dbRootPda, 'users');
const accountInfo = await connection.getAccountInfo(tablePda);
const rows = readTableRows(accountInfo);
console.log(`Total rows: ${rows.length}`);
getTablelistFromRoot()
| Parámetros | dbRootId: ID de base de datos |
|---|
| Devuelve | Arreglo de nombres de tabla (string[]) |
import { getTablelistFromRoot } from 'iqlabs-sdk';
const tables = await getTablelistFromRoot('my-db');
console.log('Table list:', tables);
fetchInventoryTransactions()
| Parámetros | userPubkey: clave pública del usuario
limit: máximo (opcional) |
|---|
| Devuelve | Arreglo de transacciones |
import { fetchInventoryTransactions } from 'iqlabs-sdk';
const myFiles = await fetchInventoryTransactions(myPubkey, 20);
myFiles.forEach(tx => {
let metadata: { data?: unknown } | null = null;
try {
metadata = JSON.parse(tx.metadata);
} catch {
metadata = null;
}
if (metadata && metadata.data !== undefined) {
const inlineData = typeof metadata.data === 'string'
? metadata.data
: JSON.stringify(metadata.data);
console.log(`Inline data: ${inlineData}`);
} else {
console.log(`Signature: ${tx.signature}`);
}
});
Configuración del entorno
setRpcUrl()
| Parámetros | url: URL de RPC de Solana |
|---|
| Devuelve | Ninguno (void) |
import { setRpcUrl } from 'iqlabs-sdk';
setRpcUrl('https://your-rpc.example.com');
Funciones avanzadas
Estas son funciones de bajo nivel del SDK. No son necesarias para el uso típico, pero son útiles al crear funciones personalizadas o depurar.
Funciones de escritura
manageRowData()
Función de bajo nivel para gestionar datos de filas en tablas.
| Módulo | writer |
|---|
| Caso de uso | Gestión de filas personalizada, operaciones por lotes |
import { manageRowData } from 'iqlabs-sdk/writer';
await manageRowData(connection, signer, {
dbRootId: 'my-db',
tableSeed: 'users',
operation: 'update',
rowData: JSON.stringify({ id: 1, name: 'Updated Name' })
});
Funciones de lectura
readUserState()
Lee el PDA UserState de un usuario.
| Módulo | reader |
|---|
| Caso de uso | Obtener datos de perfil, comprobar conteos de subida |
import { readUserState } from 'iqlabs-sdk/reader';
const userState = await readUserState(userPubkey);
console.log('Profile:', userState.profile);
console.log('Upload count:', userState.fileCount);
Lee los metadatos asociados al inventario del usuario (archivos subidos).
| Módulo | reader |
|---|
| Caso de uso | Listar archivos del usuario con metadatos, gestión de archivos |
import { readInventoryMetadata } from 'iqlabs-sdk/reader';
const metadata = await readInventoryMetadata(userPubkey);
metadata.forEach(item => {
console.log(`File: ${item.name}, Size: ${item.size}, Signature: ${item.signature}`);
});
fetchAccountTransactions()
Obtiene todas las transacciones de una cuenta específica.
| Módulo | reader |
|---|
| Caso de uso | Historial de transacciones, análisis de cuentas, depuración |
import { fetchAccountTransactions } from 'iqlabs-sdk/reader';
const transactions = await fetchAccountTransactions(accountPubkey, {
limit: 50,
before: lastSignature
});
transactions.forEach(tx => {
console.log(`Signature: ${tx.signature}, Block: ${tx.slot}`);
});
getSessionPdaList()
Recupera una lista de PDAs de sesión.
| Módulo | reader |
|---|
| Caso de uso | Gestión de sesiones, seguimiento de sesiones activas |
import { getSessionPdaList } from 'iqlabs-sdk/reader';
const sessions = await getSessionPdaList(userPubkey);
sessions.forEach(session => {
console.log(`Session PDA: ${session.pda}, Active: ${session.isActive}`);
});
Funciones de utilidad
deriveDmSeed()
Deriva una semilla determinista para mensajería directa (DM) entre dos usuarios.
| Módulo | utils / reader |
|---|
| Caso de uso | Crear identificadores de conexión consistentes, configuración de canal DM |
import { deriveDmSeed } from 'iqlabs-sdk/utils';
const seed1 = deriveDmSeed(walletA, walletB);
const seed2 = deriveDmSeed(walletB, walletA);
console.log(seed1 === seed2); // true
toSeedBytes()
Convierte una semilla de cadena al formato de bytes requerido para derivación de PDA.
| Módulo | utils |
|---|
| Caso de uso | Derivación de PDA personalizada, manipulación de semillas de bajo nivel |
import { toSeedBytes } from 'iqlabs-sdk/utils';
const seedString = 'my-custom-seed';
const seedBytes = toSeedBytes(seedString);
const [pda, bump] = PublicKey.findProgramAddressSync(
[seedBytes, otherSeed],
programId
);