FeatherScript

FeatherScript

chain::4663

Docs

08 / 09

Integrations

Build on top of FeatherScript

Cómo usar el protocolo FeatherScript desde aplicaciones externas, indexadores o scripts.


Integración directa con viem

import { createPublicClient, createWalletClient, http, stringToHex } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { robinhoodChain } from './chains';
import { INSCRIPTION_REGISTRY_ABI, INSCRIPTION_REGISTRY_ADDRESS } from './contract';

const publicClient = createPublicClient({
  chain: robinhoodChain,
  transport: http(),
});

const walletClient = createWalletClient({
  chain: robinhoodChain,
  transport: http(),
  account: privateKeyToAccount('0x...'),
});

// Inscribir
const hash = await walletClient.writeContract({
  address: INSCRIPTION_REGISTRY_ADDRESS!,
  abi: INSCRIPTION_REGISTRY_ABI,
  functionName: 'inscribe',
  args: [stringToHex('Hello, permanent world!')],
});

const receipt = await publicClient.waitForTransactionReceipt({ hash });

// Leer
const [creator, timestamp, blockNumber, data] = await publicClient.readContract({
  address: INSCRIPTION_REGISTRY_ADDRESS!,
  abi: INSCRIPTION_REGISTRY_ABI,
  functionName: 'getInscription',
  args: [1n],
});

Integración con ethers.js v6

import { ethers } from 'ethers';

const provider = new ethers.JsonRpcProvider('https://rpc.mainnet.chain.robinhood.com');
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);

const abi = [
  'function inscribe(bytes calldata data)',
  'function getInscription(uint256) view returns (address, uint256, uint256, bytes)',
  'function inscriptionCount() view returns (uint256)',
  'event Inscribed(uint256 indexed inscriptionId, address indexed creator, bytes data, uint256 timestamp, uint256 blockNumber)',
];

const registry = new ethers.Contract(CONTRACT_ADDRESS, abi, wallet);

// Inscribir
const tx = await registry.inscribe(ethers.toUtf8Bytes('My inscription'));
const receipt = await tx.wait();

// Leer
const count = await registry.inscriptionCount();
const [creator, timestamp, blockNumber, data] = await registry.getInscription(count);

Indexador de eventos

Para historial completo con txHash, implementa un indexador que escuche Inscribed:

import { createPublicClient, http, parseAbiItem } from 'viem';
import { robinhoodChain } from './chains';

const client = createPublicClient({
  chain: robinhoodChain,
  transport: http(),
});

const logs = await client.getLogs({
  address: REGISTRY_ADDRESS,
  event: parseAbiItem(
    'event Inscribed(uint256 indexed inscriptionId, address indexed creator, bytes data, uint256 timestamp, uint256 blockNumber)'
  ),
  fromBlock: DEPLOY_BLOCK,
  toBlock: 'latest',
});

for (const log of logs) {
  const { inscriptionId, creator, data, timestamp, blockNumber } = log.args;
  const txHash = log.transactionHash;
  const blockHash = log.blockHash;

  // Guardar en DB: { inscriptionId, creator, data, timestamp, blockNumber, txHash }
}

Esquema sugerido para base de datos

CREATE TABLE inscriptions (
    inscription_id    BIGINT PRIMARY KEY,
    creator           VARCHAR(42) NOT NULL,
    data              BYTEA NOT NULL,
    timestamp         BIGINT NOT NULL,
    block_number      BIGINT NOT NULL,
    tx_hash           VARCHAR(66) NOT NULL UNIQUE,
    block_hash        VARCHAR(66),
    created_at        TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_inscriptions_creator ON inscriptions(creator);
CREATE INDEX idx_inscriptions_timestamp ON inscriptions(timestamp DESC);

API REST (ejemplo conceptual)

Si construyes un backend sobre el indexador:

GET /api/inscriptions → Lista paginada GET /api/inscriptions/:id → Detalle por ID GET /api/inscriptions/creator/:address → Por creador GET /api/stats → Total, últimas 24h, etc.

Integración desde otra dApp

Solo lectura (sin wallet)

Cualquier app puede leer inscripciones con un RPC público:

const count = await publicClient.readContract({
  address: REGISTRY_ADDRESS,
  abi: INSCRIPTION_REGISTRY_ABI,
  functionName: 'inscriptionCount',
});

No necesitas wallet ni permisos.

Escritura (con wallet del usuario)

Usa wagmi hooks o wallet connect estándar:

import { useWriteContract } from 'wagmi';

const { writeContract } = useWriteContract();

writeContract({
  address: REGISTRY_ADDRESS,
  abi: INSCRIPTION_REGISTRY_ABI,
  functionName: 'inscribe',
  args: [data],
});

Formatos de datos recomendados (off-chain)

El contrato no impone formato. Convenciones sugeridas para interoperabilidad:

TipoFormato sugeridoEjemplo
Texto planoUTF-8 bytes"Hello world"
JSONUTF-8 JSON string{"type":"message","body":"..."}
Hash de archivoUTF-8 hex string"sha256:abc123..."
Imagen pequeñaRaw bytesPNG/JPG < 24KB

Puedes definir un prefijo opcional para tipado:

fs:v1:text:Hello world fs:v1:json:{"key":"value"}

Esto es convención off-chain — el contrato lo almacena tal cual.


SDK futuro (roadmap)

Posibles extensiones del protocolo:

  • @featherscript/sdk — npm package con tipos y helpers
  • Subgraph The Graph para queries GraphQL
  • CLI featherscript inscribe "message"
  • Widget embebible <FeatherScriptInscribe />

El contrato actual ya es suficiente como base estable para todas estas extensiones.


Siguiente lectura

← Back to AppInscribe On-Chain