Skip to content

Blockchain building blocks that run on the browser and the edge

Notifications You must be signed in to change notification settings

niconiahi/ethernauta

Repository files navigation

logo

Philosophy

The monorepo is arquitectured as per described in Valibot's thesis so that it takes full use of tree-shaking thus making the bundle size of the library much smaller than similar libraries. It comes with the burden of getting used to composing functions (of small bundle size) but this is helped with a clear API

It's ESM-first, it should run anywhere in the web. Only Web APIs are used. This repository won't use Node APIs as part of its design

Characteristics

  • It has no dependencies
  • It heavily uses validation schemas to validate every transaction parameters and results
  • Seamless API for interacting with multiple blockchain ecosystems (currently: Ethereum and Solana)

Modules

Features

  • Chain manipulation methods (CAIP)
  • Ethereum base methods (specification)
  • Solana base methods (specification)
  • JSON RPC methods (specification)
  • Methods for interacting with ERC20 contracts (EIP-20)
  • Methods for interacting with Metamask (EIP-1102)
  • A function that allows to read the blockchain
  • Support multiple transports for reader
  • A function that allows to write the blockchain
  • Support multiple transports for writer
  • WalletConnect's connector using Fetch

API

reader

in Ethernauta

import { eip155_11155111, eth_getBlockByHash } from "@ethernauta/eth"
import { getBalance } from "@ethernauta/sol"
import { createReader, encodeChainId, http } from "@ethernauta/transport"

// unique reader
const reader = createReader([
  {
    chainId: "eip155:11155111",
    transports: [
      http(
        "https://snowy-fragrant-haze.ethereum-sepolia.quiknode.pro/71bd09c56eb85b1c709871faa17483fa65ba8177/"
      ),
    ],
  },
  {
    chainId: "solana:devnet",
    transports: [
      http(
        "https://withered-wider-pool.solana-devnet.quiknode.pro/742e63a8f44b2b9ea78af3feb44e4be930a830a6"
      ),
    ],
  },
])

// ethereum
const ethereumReadable = eth_getBlockByHash([
  "0x31386e6cfba70bb4d8a95404bdb740572b758a15c62e51ee912071a7b5be9e26",
  false,
])
const ethereumSepolia = encodeChainId({
  namespace: "eip155",
  reference: eip155_11155111.chainId,
})
const block = await readable(reader(ethereumSepolia))
// const block: {
//     number: `0x${string}`;
//     hash: `0x${string}`;
//     parentHash: `0x${string}`;
//     sha3Uncles: `0x${string}`;
//     miner: `0x${string}`;
//     stateRoot: `0x${string}`;
//     transactionsRoot: `0x${string}`;
//     receiptsRoot: `0x${string}`;
//     logsBloom: `0x${string}`;
//     ... 16 more ...;
//     withdrawals?: {
//         ...;
//     }[] | undefined;
// } | null

// solana
const solanaReadable = getBalance([
  "5U3bH5b6XtG99aVWLqwVzYPVpQiFHytBD68Rz2eFPZd7",
])
const solanaDevnet = encodeChainId({
  namespace: "solana",
  reference: "devnet",
})
const balance = await readable(reader(solanaDevnet))
// const balance: {
//    context: {
//        apiVersion: string;
//        slot: number;
//    };
//    value: number;
// }

in Viem

import { createPublicClient, fallback, http } from "viem"
import { mainnet, rinkeby } from "viem/chains"

const client = createPublicClient({
  chain: env.environment === "production" ? mainnet : rinkeby,
  transport: fallback([
    http("https://eth-mainnet.g.alchemy.com/v2"),
    http("https://eth-mainnet.g.alchemy.com/v2"),
  ]),
})
const blockNumber = await client.getBlockNumber()
const chain = await client.chain()

writer

in Ethernauta

import { mainnet, rinkeby } from "@ethernauta/chain"
import { createWalletConnect } from "@ethernauta/connectors"
import { eth_sendTransaction } from "@ethernauta/eth"
import { createWriter, http } from "@ethernauta/transport"

const walletConnect = createWalletConnect(env.WALLET_CONNECT_PROJECT_ID)
const writer = createWriter(
  http(walletConnect(env.ENVIRONMENT === "production" ? mainnet : rinkeby))
)
const writable = eth_sendTransaction([
  {
    from: "0xF344B01DA08b142D2466dae9e47E333f22e64588",
    data: "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675",
  },
])
const hash = await writable(writer)

in Viem

import { createWalletClient, custom } from "viem"
import { mainnet } from "viem/chains"

const client = createWalletClient({
  chain: mainnet,
  transport: custom(window.ethereum),
})
const [address] = await client.getAddresses()
const hash = await client.sendTransaction({
  account: address,
  to: "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC",
})