<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Arbitrum</title>
    <description>The latest articles on DEV Community by Arbitrum (arbitrum).</description>
    <link>https://dev.to/arbitrum</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F12331%2Fa8de55ab-1772-47dc-97f8-942a548265c6.png</url>
      <title>DEV Community: Arbitrum</title>
      <link>https://dev.to/arbitrum</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arbitrum"/>
    <language>en</language>
    <item>
      <title>I built my first Robinhood Chain app as an index basket</title>
      <dc:creator>Ben Greenberg</dc:creator>
      <pubDate>Sun, 12 Jul 2026 15:51:24 +0000</pubDate>
      <link>https://dev.to/arbitrum/i-built-my-first-robinhood-chain-app-as-an-index-basket-20li</link>
      <guid>https://dev.to/arbitrum/i-built-my-first-robinhood-chain-app-as-an-index-basket-20li</guid>
      <description>&lt;p&gt;I built a small index basket app on Robinhood Chain because I wanted to understand the developer path from the first contract deploy all the way to a working frontend.&lt;/p&gt;

&lt;p&gt;The app is intentionally plain: a user deposits Stock Tokens, which are blockchain tokens that represent real equity exposure, and receives an ERC-20 basket share. ERC-20 is Ethereum's standard token interface, so a compatible token exposes familiar methods like &lt;code&gt;balanceOf&lt;/code&gt;, &lt;code&gt;transfer&lt;/code&gt;, and &lt;code&gt;approve&lt;/code&gt;. The basket share is priced from live price feeds, and the user can redeem it back into the underlying Stock Tokens.&lt;/p&gt;

&lt;p&gt;That's the part that made this interesting to me. The chain is custom, but the app path is not. I still wrote Solidity, deployed with Foundry, read contract state with viem, and wrote transactions from React with wagmi.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm1c8mbe3qvudjo15x4gi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm1c8mbe3qvudjo15x4gi.png" alt="A user connects a wallet to the React frontend, which uses wagmi and viem to call Robinhood Chain contracts that interact with Stock Tokens and Chainlink feeds." width="600" height="76"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you've built normal web apps, think of the chain's RPC endpoint as the API base URL. A wallet is login plus a signing key. A smart contract is backend code you deploy to the chain, except you should treat it like immutable infrastructure because you don't get to hot-patch it casually later.&lt;/p&gt;

&lt;p&gt;The demo and source are here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App: &lt;a href="https://robinhood-chain-dapp.vercel.app/" rel="noopener noreferrer"&gt;https://robinhood-chain-dapp.vercel.app/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Code: &lt;a href="https://github.com/hummusonrails/robinhood-chain-dapp-example" rel="noopener noreferrer"&gt;https://github.com/hummusonrails/robinhood-chain-dapp-example&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The custom chain still feels like the EVM
&lt;/h2&gt;

&lt;p&gt;Robinhood Chain is a custom Arbitrum Chain, which means it runs as a dedicated chain on the stack of Arbitrum, an Ethereum scaling system. It is also EVM-compatible. EVM means Ethereum Virtual Machine, the runtime that executes Solidity contracts, so the tooling surface looks like the Ethereum developer flow many tutorials already teach.&lt;/p&gt;

&lt;p&gt;An L2, or rollup, is a chain that executes transactions separately and then posts compressed proof or transaction data back to Ethereum. Robinhood Chain uses Ethereum blobs for data availability, which is a cheaper Ethereum data lane for rollups to publish the data needed to reconstruct chain state. Gas, the metered compute fee you pay to run transactions, is paid in ETH.&lt;/p&gt;

&lt;p&gt;The first deploy looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PRIVATE_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0x&amp;lt;your_private_key&amp;gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;RH_RPC_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://rpc.testnet.chain.robinhood.com

forge create src/MyContract.sol:MyContract &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--rpc-url&lt;/span&gt; &lt;span class="nv"&gt;$RH_RPC_URL&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--private-key&lt;/span&gt; &lt;span class="nv"&gt;$PRIVATE_KEY&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--broadcast&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Foundry is the contract build, test, and deploy CLI. &lt;code&gt;forge create&lt;/code&gt; compiles the contract, sends the deployment transaction, and broadcasts it to the RPC endpoint.&lt;/p&gt;

&lt;p&gt;This is the part I appreciate as a developer. Robinhood gets its own chain configuration, infrastructure, pricing, and product controls. I still get the contract model I know how to reason about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stock Tokens are ERC-20s with display accounting
&lt;/h2&gt;

&lt;p&gt;Stock Tokens are ERC-20s that represent real market assets. That means contracts can read balances, request approvals, and transfer them using the same functions they would use for any other ERC-20.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IERC20 nvda = IERC20(NVDA_TOKEN_ADDRESS);

uint256 balance = nvda.balanceOf(user);
nvda.approve(spender, amount);
nvda.transfer(recipient, amount);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The wrinkle is corporate actions. Stocks split. Dividends happen. The economic relationship between one token and one underlying share can change.&lt;/p&gt;

&lt;p&gt;Stock Tokens implement ERC-8056, the Scaled UI Amount extension. Raw token balances stay stable for contracts. A UI multiplier is how wallets and apps display the share-equivalent amount.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F97bik6ktzeo8cc3thtrs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F97bik6ktzeo8cc3thtrs.png" alt="Raw token balances stay stable for contract accounting while corporate actions update a UI multiplier used for displayed share-equivalent balances." width="600" height="112"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface IScaledUIAmount {
    function uiMultiplier() external view returns (uint256);
    function balanceOfUI(address account) external view returns (uint256);
    function totalSupplyUI() external view returns (uint256);
    function newUIMultiplier() external view returns (uint256);
    function effectiveAt() external view returns (uint256);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The display conversion is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;underlyingShares = rawBalance * uiMultiplier / 1e18;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why not just mutate balances after a split?&lt;/p&gt;

&lt;p&gt;Because contracts depend on stable accounting. If my basket contract holds a raw token balance, I don't want a display-level corporate action to unexpectedly rewrite the reserve math inside the contract. The UI can show share-equivalent amounts, and the protocol can keep using raw ERC-20 units.&lt;/p&gt;

&lt;h2&gt;
  
  
  The basket contract does only a few things
&lt;/h2&gt;

&lt;p&gt;The sample app has two contracts and no owner.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Contract&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Control surface&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BasketFactory&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Deploys and records baskets&lt;/td&gt;
&lt;td&gt;Permissionless&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BasketToken&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Holds components, mints, redeems, prices shares&lt;/td&gt;
&lt;td&gt;No owner or upgrade path&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The factory does not custody user funds. It deploys a basket and records the address.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function createBasket(
    string calldata name,
    string calldata symbol,
    BasketToken.Component[] calldata components,
    uint256 maxPriceAge
) external returns (address basket) {
    basket = address(new BasketToken(name, symbol, components, maxPriceAge));
    _baskets.push(basket);
    isBasket[basket] = true;
    emit BasketCreated(basket, msg.sender, name, symbol);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each basket stores a fixed list of components. A component is a token, a price feed, and the amount of that token backing one basket share.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct Component {
    address token;
    address feed;
    uint256 unitsPerShare;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A price feed is an external data source a contract or app can read. In this app, the feeds come from Chainlink, an oracle network that publishes market data onchain. An oracle is the bridge between offchain facts, like a stock price, and onchain code.&lt;/p&gt;

&lt;p&gt;On mainnet, the production chain where real assets move, the demo basket uses TSLA, NVDA, and AAPL Stock Tokens with their Chainlink feeds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function _mainnetComponents()
    internal
    pure
    returns (BasketToken.Component[] memory c)
{
    c = new BasketToken.Component[](3);
    c[0] = BasketToken.Component(MAINNET_TSLA, MAINNET_TSLA_FEED, 0.4e18);
    c[1] = BasketToken.Component(MAINNET_NVDA, MAINNET_NVDA_FEED, 0.3e18);
    c[2] = BasketToken.Component(MAINNET_AAPL, MAINNET_AAPL_FEED, 0.3e18);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One &lt;code&gt;TRIO&lt;/code&gt; share is backed by &lt;code&gt;0.4 TSLA&lt;/code&gt;, &lt;code&gt;0.3 NVDA&lt;/code&gt;, and &lt;code&gt;0.3 AAPL&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;On testnet, which is a staging chain with no real funds at risk, the demo uses faucet Stock Tokens for TSLA, AMZN, and NFLX with mock feeds. A faucet is a service that gives you test tokens so you can build without spending real money.&lt;/p&gt;

&lt;h2&gt;
  
  
  Minting follows the ERC-20 approval pattern
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff9pnghj64spuyu4lhuaf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff9pnghj64spuyu4lhuaf.png" alt="Raw token balances stay stable for contract accounting while corporate actions update a UI multiplier used for displayed share-equivalent balances." width="528" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the frontend, minting is two steps: approve each component token, then call the basket.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;writeContract&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;stockTokenAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;abi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;erc20Abi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;functionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;approve&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;basketAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;writeContract&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;basketAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;abi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;basketTokenAbi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;functionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mint&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;shares&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That &lt;code&gt;writeContract&lt;/code&gt; call is from wagmi, a React library for wallet connections and contract writes. viem is the TypeScript Ethereum client underneath it for typed reads, writes, and transaction handling.&lt;/p&gt;

&lt;p&gt;Onchain, the basket pulls the required component amounts and mints shares in the same transaction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function mint(uint256 shares, address to) external nonReentrant {
    if (shares == 0) revert ZeroShares();

    uint256 count = _components.length;
    for (uint256 i = 0; i &amp;lt; count; i++) {
        Component memory c = _components[i];
        uint256 amount = Math.mulDiv(
            c.unitsPerShare,
            shares,
            SHARE_UNIT,
            Math.Rounding.Ceil
        );

        IERC20(c.token).safeTransferFrom(msg.sender, address(this), amount);
    }

    _mint(to, shares);
    emit Minted(msg.sender, to, shares);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rounding direction matters. Mint rounds up so a user cannot underpay the basket reserves by tiny decimal leftovers.&lt;/p&gt;

&lt;p&gt;Redeem is the mirror image. Burn first, transfer components out, and round down so the reserves cannot be overdrawn.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function redeem(uint256 shares, address to) external nonReentrant {
    if (shares == 0) revert ZeroShares();
    if (to == address(0)) revert ZeroAddress();

    _burn(msg.sender, shares);

    uint256 count = _components.length;
    for (uint256 i = 0; i &amp;lt; count; i++) {
        Component memory c = _components[i];
        uint256 amount = Math.mulDiv(
            c.unitsPerShare,
            shares,
            SHARE_UNIT,
            Math.Rounding.Floor
        );

        IERC20(c.token).safeTransfer(to, amount);
    }

    emit Redeemed(msg.sender, to, shares);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Redeem skips the price feed and the factory. It burns shares and returns the component tokens the contract already holds.&lt;/p&gt;

&lt;p&gt;I keep pricing and redemption apart on purpose. You use the price for the UI. Redeem returns the collateral.&lt;/p&gt;

&lt;h2&gt;
  
  
  Local to mainnet is the path I want rehearsed
&lt;/h2&gt;

&lt;p&gt;The repo gives you the whole loop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone &lt;span class="nt"&gt;--recurse-submodules&lt;/span&gt; https://github.com/hummusonrails/robinhood-chain-dapp-example.git
&lt;span class="nb"&gt;cd &lt;/span&gt;robinhood-chain-dapp-example

pnpm &lt;span class="nb"&gt;install
&lt;/span&gt;anvil
pnpm run deploy:local
pnpm run smoke
pnpm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;anvil&lt;/code&gt; is Foundry's local development chain. Think of it as a throwaway local server for contracts. The local deploy creates mock Stock Tokens, mock Chainlink feeds, the factory, and a demo &lt;code&gt;Tech Trio&lt;/code&gt; basket. It also writes &lt;code&gt;apps/frontend/.env.local&lt;/code&gt;, so the frontend knows which addresses to call.&lt;/p&gt;

&lt;p&gt;For Robinhood Chain testnet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;PRIVATE_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$YOUR_TESTNET_KEY&lt;/span&gt; pnpm run deploy:testnet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One Foundry script handles local, testnet, and mainnet by checking the &lt;code&gt;chainid&lt;/code&gt;, which is the chain's network identifier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function run() external {
    vm.startBroadcast();

    BasketFactory factory = new BasketFactory();
    console2.log("FACTORY=%s", address(factory));

    BasketToken.Component[] memory components;
    if (block.chainid == 4663) {
        components = _mainnetComponents();
    } else if (block.chainid == 46630) {
        components = _testnetComponents();
    } else {
        components = _localComponents();
    }

    address basket =
        factory.createBasket("Tech Trio", "TRIO", components, MAX_PRICE_AGE);

    console2.log("DEMO_BASKET=%s", basket);
    console2.log("CHAIN_ID=%s", block.chainid);

    vm.stopBroadcast();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The testnet deployment behind the live walkthrough is:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Contract&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BasketFactory&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0xC1940D5fd58ce735A44a53f910852B12250F6a14&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;BasketToken&lt;/code&gt; (&lt;code&gt;TRIO&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0x7633e0920Ea46A8Ec54F61C95adECD391c01Edd4&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Before spending mainnet gas, I want fork tests. A fork test runs tests against a local copy of live chain state, so you can check integration assumptions without sending real transactions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm run &lt;span class="nb"&gt;test&lt;/span&gt;:contracts
pnpm run &lt;span class="nb"&gt;test&lt;/span&gt;:fork
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the shape of the fork test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function test_mintAndRedeem_withRealStockTokens() public {
    deal(TSLA, alice, 1e18);
    deal(NVDA, alice, 1e18);
    deal(AAPL, alice, 1e18);

    vm.startPrank(alice);
    IERC20Metadata(TSLA).approve(address(basket), type(uint256).max);
    IERC20Metadata(NVDA).approve(address(basket), type(uint256).max);
    IERC20Metadata(AAPL).approve(address(basket), type(uint256).max);

    basket.mint(2e18, alice);
    assertEq(basket.balanceOf(alice), 2e18);
    assertEq(IERC20Metadata(TSLA).balanceOf(address(basket)), 0.8e18);

    basket.redeem(2e18, alice);
    assertEq(basket.totalSupply(), 0);
    assertEq(IERC20Metadata(TSLA).balanceOf(alice), 1e18);
    vm.stopPrank();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the development loop I want for this kind of app: mocks for speed, testnet for wallet flow, fork tests for live integration assumptions, and mainnet only after the path is rehearsed.&lt;/p&gt;

&lt;p&gt;A block explorer, which is basically hosted request logs for a chain, then gives you a way to inspect deployed contracts and transactions. The testnet contracts are verified on Blockscout, so you can read the source and calls after deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stock Tokens change the app assumptions
&lt;/h2&gt;

&lt;p&gt;Stock Tokens still fit the ERC-20 interface, but the surrounding assumptions are different from a generic token.&lt;/p&gt;

&lt;p&gt;For user balances, don't blindly show &lt;code&gt;balanceOf&lt;/code&gt;. Use &lt;code&gt;balanceOfUI&lt;/code&gt; or apply &lt;code&gt;uiMultiplier&lt;/code&gt; so the user sees the share-equivalent amount.&lt;/p&gt;

&lt;p&gt;For prices, read the per-token Chainlink feed on mainnet. For corporate actions, track multiplier updates and pending effective times. For valuation, remember that the feed price already includes the multiplier.&lt;/p&gt;

&lt;p&gt;Stock market hours matter too. Crypto feeds may update around the clock. Stock feeds follow market sessions, so stale data checks need to reflect that.&lt;/p&gt;

&lt;p&gt;The exit path is the one I care about most. If a user wants to redeem their basket share, I don't want that flow blocked because an oracle read is stale. The contract already holds the component tokens. Redemption should return the collateral.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn the chain later; start with the app
&lt;/h2&gt;

&lt;p&gt;Robinhood Chain runs on Arbitrum Nitro, the same underlying technology as Arbitrum One, deployed as a dedicated chain. Arbitrum One is the public shared L2. A custom Arbitrum Chain gives a team its own execution environment while keeping the Ethereum-style contract model.&lt;/p&gt;

&lt;p&gt;The mechanics under the hood are also why the fees are small. Transactions hit a sequencer, which is the service that orders transactions for the rollup, land in fast blocks, get batched, and settle back to Ethereum using blob data. The fee combines L2 execution gas with the data cost on L1, which is Ethereum itself.&lt;/p&gt;

&lt;p&gt;That's useful context, but I wouldn't start by trying to absorb the whole chain architecture.&lt;/p&gt;

&lt;p&gt;Start with the working system. Read a Stock Token balance. Approve a token. Mint a share. Redeem it. Check the price feed. Run the fork test. Look at the transaction in a block explorer.&lt;/p&gt;

&lt;p&gt;Plenty of apps can live on Robinhood Chain. This basket is a good first build because it touches the surfaces most apps using market assets will need: token reads, approvals, ERC-8056 display logic, Chainlink feeds, local mocks, testnet deployment, verified contracts, fork tests, and a Next.js frontend using wagmi and viem.&lt;/p&gt;

&lt;p&gt;What I learned from building it is where the real work sits: deciding where accounting belongs, where pricing belongs, and which assumptions deserve a test before real users and real assets touch the contract. The app stack itself is familiar.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>solidity</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Your backend code is a black box. It doesn't have to be.</title>
      <dc:creator>Ben Greenberg</dc:creator>
      <pubDate>Wed, 01 Apr 2026 09:07:54 +0000</pubDate>
      <link>https://dev.to/arbitrum/your-backend-code-is-a-black-box-it-doesnt-have-to-be-59bd</link>
      <guid>https://dev.to/arbitrum/your-backend-code-is-a-black-box-it-doesnt-have-to-be-59bd</guid>
      <description>&lt;p&gt;Your API takes inputs and returns outputs. The logic in between? Nobody outside your team can verify it. Regulators read documentation you wrote about it. Partners call your endpoint and trust the response. Users don't even get that.&lt;/p&gt;

&lt;p&gt;This has worked for decades. But there's a growing category of backend logic where "trust us" isn't enough. Scoring algorithms, compliance checks, eligibility rules, validation pipelines. Anywhere someone needs to independently confirm that your code does what you say it does.&lt;/p&gt;

&lt;p&gt;You don't have a code problem. You have a verifiability problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The case for publicly auditable code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvblmmb49iy7jrpp5e8h5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvblmmb49iy7jrpp5e8h5.png" alt="Black box vs verifiable compute" width="800" height="541"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most backend engineers don't think about code auditability because most code doesn't need it. Your CRUD endpoints, your auth flows, your data transformations, those are internal concerns. Nobody outside your org needs to verify them.&lt;/p&gt;

&lt;p&gt;But some functions carry weight. A scoring algorithm that determines loan eligibility. A validation pipeline that checks regulatory compliance. A pricing engine that partners depend on. For these functions, the standard answer is documentation: you write a spec, maybe you share pseudocode, and everyone agrees to trust that the running code matches the paper.&lt;/p&gt;

&lt;p&gt;That's not verification. That's trust with extra steps.&lt;/p&gt;

&lt;p&gt;Publicly auditable code means anyone can call the same function with the same inputs and confirm they get the same outputs. The logic is visible. Execution is deterministic. And the code can't change silently after deployment.&lt;/p&gt;

&lt;p&gt;This isn't a new idea. Open source gives you code visibility. But open source doesn't prove that the code running in production is the same code in the repo. You need a runtime where the deployed code is the source of truth, and where every execution is independently reproducible.&lt;/p&gt;

&lt;p&gt;That runtime exists. And you don't need to learn a new language to use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rust in, verifiable execution out
&lt;/h2&gt;

&lt;p&gt;When most engineers hear "deploy code onchain," they picture learning Solidity, memorizing gas optimization tricks, and rewriting working logic in an unfamiliar language. That's a reasonable reason to stop listening.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.arbitrum.io/stylus/gentle-introduction" rel="noopener noreferrer"&gt;Arbitrum Stylus&lt;/a&gt; skips that detour. You write Rust, compile to WASM, and deploy it to a blockchain that's optimized for low-cost computation. Your existing toolchain, your existing crates, your existing mental model. The contract runs alongside Solidity smart contracts with shared state, but you never need to touch Solidity yourself.&lt;/p&gt;

&lt;p&gt;This isn't about converting you to crypto. It's about giving you a deployment target where execution is publicly verifiable by default.&lt;/p&gt;

&lt;p&gt;Three properties matter here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Every execution is independently auditable.&lt;/strong&gt; Anyone can call the contract with the same inputs and confirm they get the same outputs. No trust required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The logic is immutable.&lt;/strong&gt; Once deployed, the code can't change silently. If you push an update, that's a new deployment with its own address and its own history. No "we patched it last Tuesday but forgot to tell you."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Execution is deterministic.&lt;/strong&gt; Same inputs, same outputs, every time, on every node. No environment-specific drift, no floating point surprises across hardware.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the architecture looks like
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frk0oqvh90439evj9hyur.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frk0oqvh90439evj9hyur.png" alt="Scoring engine architecture" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I built a &lt;a href="https://github.com/hummusonrails/stylus-scoring-engine" rel="noopener noreferrer"&gt;scoring engine&lt;/a&gt; to test this pattern. The architecture splits cleanly between what stays in your infrastructure and what moves onchain:&lt;/p&gt;

&lt;p&gt;Your backend stays exactly where it is. An Axum API server handles business rules, authentication, request routing. Normal backend work. The only difference is that when the API needs a computation verified, it calls an onchain contract instead of a local function.&lt;/p&gt;

&lt;p&gt;The onchain piece is a Stylus contract. It takes parameters, runs the calculation, and returns results. No state storage, just pure computation. Think of it as a function you deploy instead of host.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1w298ib5f7tb8xt2djjc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1w298ib5f7tb8xt2djjc.png" alt="Shared crate compilation" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A shared Rust crate holds the type definitions and compiles for both environments. The contract uses &lt;code&gt;no_std&lt;/code&gt; for WASM. The API server uses &lt;code&gt;std&lt;/code&gt; for native. Same types, both sides. The compiler guarantees they match. No serialization mismatches, no type drift between your API and your contract.&lt;/p&gt;

&lt;p&gt;One language across the entire stack. The chain boundary becomes a function call, not a language barrier.&lt;/p&gt;

&lt;h2&gt;
  
  
  The performance question
&lt;/h2&gt;

&lt;p&gt;The first objection any backend engineer raises: what's the overhead?&lt;/p&gt;

&lt;p&gt;Fair. Onchain computation has historically been expensive. That's the whole reason Solidity exists. It was designed to minimize execution cost on the EVM.&lt;/p&gt;

&lt;p&gt;Stylus changes the math. WASM execution on Arbitrum is dramatically cheaper than EVM execution for compute-heavy workloads. The scoring engine used over 90% less gas than the equivalent Solidity contract doing identical work:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Environment&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;th&gt;Gas Usage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Offchain Rust&lt;/td&gt;
&lt;td&gt;953&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Onchain Stylus (WASM)&lt;/td&gt;
&lt;td&gt;953&lt;/td&gt;
&lt;td&gt;76,048&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Onchain Solidity (EVM)&lt;/td&gt;
&lt;td&gt;810&lt;/td&gt;
&lt;td&gt;1,027,635&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Storage operations cost the same either way, but iterative math, weighted calculations, and loop-heavy logic is where WASM pulls ahead.&lt;/p&gt;

&lt;p&gt;This isn't a contrived benchmark. &lt;a href="https://redstone.finance/" rel="noopener noreferrer"&gt;RedStone&lt;/a&gt;, an oracle provider, &lt;a href="https://blog.arbitrum.io/how-redstone-is-advancing-oracle-capabilities-with-stylus" rel="noopener noreferrer"&gt;published similar results&lt;/a&gt; after porting their verification logic to Stylus. Compute-intensive work is where this architecture pays for itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where auditable code matters
&lt;/h2&gt;

&lt;p&gt;Not every function belongs onchain. But some backend logic sits in a category where "trust me" isn't good enough:&lt;/p&gt;

&lt;p&gt;Scoring and risk calculations, where regulators want to audit the exact computation, not a description of it. Eligibility determinations, where partners want to verify outcomes independently instead of trusting your API response. Compliance validation, where auditors want proof that the logic running today is the same logic approved last quarter. Data pipelines, where counterparties want to confirm their data passed through agreed-upon rules.&lt;/p&gt;

&lt;p&gt;If you've ever written documentation explaining how your algorithm works so someone else could trust it, that's the function that belongs onchain. Let them verify the code instead of reading your summary of the code.&lt;/p&gt;

&lt;p&gt;The scoring engine I built is one example of this pattern. But the pattern is the point, not the example. Any pure function where independent verification adds value is a candidate.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you'd actually do on a Monday morning
&lt;/h2&gt;

&lt;p&gt;If you write Rust, the learning curve is smaller than you think.&lt;/p&gt;

&lt;p&gt;Install &lt;a href="https://github.com/OffchainLabs/cargo-stylus" rel="noopener noreferrer"&gt;&lt;code&gt;cargo-stylus&lt;/code&gt;&lt;/a&gt;, which handles compilation and deployment. Write your function with &lt;code&gt;#[entrypoint]&lt;/code&gt; and &lt;code&gt;#[public]&lt;/code&gt; macros. Compile to WASM. Deploy to a testnet. Call it from your existing API using an RPC endpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[entrypoint]&lt;/span&gt;
&lt;span class="nd"&gt;#[storage]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;ScoringEngine&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[public]&lt;/span&gt;
&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;ScoringEngine&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;factors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Factor&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Rule&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Your computation logic here&lt;/span&gt;
        &lt;span class="c1"&gt;// Publicly verifiable, deterministic, immutable&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Your database, your auth, your business logic, none of that moves. You add one function that runs somewhere verifiable instead of somewhere trusted. Everything else stays the same.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/hummusonrails/stylus-scoring-engine" rel="noopener noreferrer"&gt;scoring engine repo&lt;/a&gt; has working code, setup instructions, and benchmarks comparing three execution paths: onchain Stylus, onchain Solidity, and offchain Rust. It's a concrete starting point, but the approach applies anywhere you need auditable computation.&lt;/p&gt;
&lt;h2&gt;
  
  
  You're adding a deployment target, not adopting a lifestyle
&lt;/h2&gt;

&lt;p&gt;The shift is smaller than it sounds. The same way you might deploy a function to Lambda for serverless execution or to a TEE for confidential computing, you deploy to Arbitrum for verifiable execution.&lt;/p&gt;

&lt;p&gt;Your Rust skills transfer directly. Your toolchain stays the same. The only thing that changes is who can verify your logic: everyone.&lt;/p&gt;

&lt;p&gt;If you've been dismissing onchain as irrelevant to backend work, spend thirty minutes with the &lt;a href="https://github.com/hummusonrails/stylus-scoring-engine" rel="noopener noreferrer"&gt;repo&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/hummusonrails" rel="noopener noreferrer"&gt;
        hummusonrails
      &lt;/a&gt; / &lt;a href="https://github.com/hummusonrails/stylus-scoring-engine" rel="noopener noreferrer"&gt;
        stylus-scoring-engine
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Verifiable credit/risk scoring engine: Stylus (Rust/WASM) vs Solidity on Arbitrum with three-way gas benchmark
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/hummusonrails/stylus-scoring-engine/.github/banner.svg"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fhummusonrails%2Fstylus-scoring-engine%2FHEAD%2F.github%2Fbanner.svg" alt="stylus-scoring-engine" width="100%"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;a href="https://github.com/hummusonrails/stylus-scoring-engine/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/942e017bf0672002dd32a857c95d66f28c5900ab541838c6c664442516309c8a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e7376673f7374796c653d666c61742d737175617265" alt="License"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/c609e2b41de6e411f523c403fb94432207ee58321549a51ad8398529273854eb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f727573742d312e38382d6f72616e67652e7376673f7374796c653d666c61742d737175617265"&gt;&lt;img src="https://camo.githubusercontent.com/c609e2b41de6e411f523c403fb94432207ee58321549a51ad8398529273854eb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f727573742d312e38382d6f72616e67652e7376673f7374796c653d666c61742d737175617265" alt="Rust"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/47a6086701dfe590e01cab365b8e6a5ef4fb5fbef9696ace98b09ee0d2133304/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7374796c75732d2d73646b2d302e31302e302d3132414146462e7376673f7374796c653d666c61742d737175617265"&gt;&lt;img src="https://camo.githubusercontent.com/47a6086701dfe590e01cab365b8e6a5ef4fb5fbef9696ace98b09ee0d2133304/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7374796c75732d2d73646b2d302e31302e302d3132414146462e7376673f7374796c653d666c61742d737175617265" alt="Stylus SDK"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/d49b7b9955764e444eb46dfd7f8e2fd481ec8fba30e9b7578e8d7a6ebb1fb480/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6178756d2d302e382d707572706c652e7376673f7374796c653d666c61742d737175617265"&gt;&lt;img src="https://camo.githubusercontent.com/d49b7b9955764e444eb46dfd7f8e2fd481ec8fba30e9b7578e8d7a6ebb1fb480/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6178756d2d302e382d707572706c652e7376673f7374796c653d666c61742d737175617265" alt="Axum"&gt;&lt;/a&gt;
  &lt;a href="https://github.com/hummusonrails/stylus-scoring-engine/issues" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/25b3e6d0d42c98de74a98cbb4d149a1c09020cf6d1361993b72d7d5b8ffed363/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5052732d77656c636f6d652d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265" alt="PRs Welcome"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;strong&gt;Verifiable credit/risk scoring on Arbitrum with a three-way gas benchmark: offchain Rust vs onchain Stylus vs onchain Solidity.&lt;/strong&gt;
  &lt;br&gt;
  &lt;a href="https://github.com/hummusonrails/stylus-scoring-engine#quick-start" rel="noopener noreferrer"&gt;Quick Start&lt;/a&gt; · &lt;a href="https://github.com/hummusonrails/stylus-scoring-engine#architecture" rel="noopener noreferrer"&gt;Architecture&lt;/a&gt; · &lt;a href="https://github.com/hummusonrails/stylus-scoring-engine/issues" rel="noopener noreferrer"&gt;Report a Bug&lt;/a&gt;
&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What it does&lt;/h2&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Benchmarks&lt;/strong&gt; the same scoring algorithm across three execution environments with real gas numbers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scores&lt;/strong&gt; entities against configurable weighted rules with iterative convergence and cross-factor correlation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Demonstrates&lt;/strong&gt; Stylus gas savings on compute-heavy workloads (over 90% cheaper than Solidity)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shares&lt;/strong&gt; Rust types between the onchain contract and offchain API server from a single crate&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stores&lt;/strong&gt; scoring rules in SQLite with full CRUD via REST endpoints&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/hummusonrails/stylus-scoring-engine/.github/demo.gif"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fhummusonrails%2Fstylus-scoring-engine%2FHEAD%2F.github%2Fdemo.gif" alt="Deploy and benchmark demo" width="100%"&gt;&lt;/a&gt;
&lt;/p&gt;



&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick Start&lt;/h2&gt;
&lt;/div&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; clone and install&lt;/span&gt;
git clone https://github.com/hummusonrails/stylus-scoring-engine.git
&lt;span class="pl-c1"&gt;cd&lt;/span&gt; stylus-scoring-engine
pnpm install

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; start the local arbitrum devnode&lt;/span&gt;
pnpm devnode

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; in a new terminal, deploy both contracts&lt;/span&gt;
pnpm deploy:all

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; start the api server (reads .env written by deploy)&lt;/span&gt;
pnpm api

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; in a new terminal, run the three-way benchmark&lt;/span&gt;
pnpm benchmark&lt;/pre&gt;

&lt;/div&gt;

&lt;strong&gt;Prerequisites&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://rustup.rs/" rel="nofollow noopener noreferrer"&gt;Rust&lt;/a&gt; 1.88+ with…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/hummusonrails/stylus-scoring-engine" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;The gap between "interesting in theory" and "I could actually use this" is shorter than you expect.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>webassembly</category>
      <category>blockchain</category>
      <category>backend</category>
    </item>
    <item>
      <title>What winning Arbitrum Open House teams do differently</title>
      <dc:creator>Ben Greenberg</dc:creator>
      <pubDate>Tue, 17 Feb 2026 14:13:22 +0000</pubDate>
      <link>https://dev.to/arbitrum/what-winning-arbitrum-open-house-teams-do-differently-18f8</link>
      <guid>https://dev.to/arbitrum/what-winning-arbitrum-open-house-teams-do-differently-18f8</guid>
      <description>&lt;p&gt;&lt;strong&gt;tl;dr You can also watch a quick 60-second animated video covering all these details:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-2023756279282589847-807" src="https://platform.twitter.com/embed/Tweet.html?id=2023756279282589847"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2023756279282589847-807');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2023756279282589847&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Most hackathon judging is a black box. You submit, you wait, you get a number. Maybe feedback, maybe not. Open House does it differently, and if you're applying, knowing the framework gives you an edge.&lt;/p&gt;

&lt;p&gt;We evaluate every Open House submission on execution, problem-solution fit, and traction. No mystery categories, no subjective vibes. Here's what the judges are looking at and why it matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Execution is the first filter
&lt;/h2&gt;

&lt;p&gt;The first thing judges open is your repo and your demo. Not your pitch deck. Not your Twitter bio.&lt;/p&gt;

&lt;p&gt;A strong execution score means you shipped a functional MVP with decent code structure, some docs and tests, and a demo that actually works. That's the baseline for being taken seriously. Below that, you're showing an idea, not a product. Above that, you're showing a team that can build under pressure and keep building after the event ends.&lt;/p&gt;

&lt;p&gt;In India, the first Open House cohort, here's what the team that won the highest execution score did. They implemented a high-precision math layer in Stylus using Q96.48 fixed-point arithmetic, added trade segmentation for large orders, and had the whole thing running on Arbitrum. That's not a weekend sketch. That's a team demonstrating they can ship production-grade work on a deadline.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F45egi514n3xvg1y0mi8m.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F45egi514n3xvg1y0mi8m.jpeg" alt="Developers at the India Founder House" width="680" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What judges are actually checking: Does the repo match the demo? Is the code structured like someone plans to maintain it? Is there a deployed contract on an Arbitrum chain? Does the team's background (GitHub history, prior work) support the claim that they can keep going?&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem and solution is where most teams lose points
&lt;/h2&gt;

&lt;p&gt;This is the criterion where most submissions land in the middle of the pack. Most teams can identify a problem. Fewer can explain why their solution is the right one, and fewer still can articulate why it needs to exist on Arbitrum specifically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scoring well here requires strong differentiation or an ecosystem-first approach, plus a roadmap that supports continued execution.&lt;/strong&gt; Generic DeFi dashboards and "blockchain for X" pitches without clear user value sit near the bottom.&lt;/p&gt;

&lt;p&gt;Right now, the sectors where we see the strongest builder momentum and clearest Arbitrum fit are payments and stablecoins, DeFi, RWAs, privacy, consumer products, and Arbitrum-native tooling around Stylus and Timeboost. Judges know what good looks like in each of these areas, and the bar is specific.&lt;/p&gt;

&lt;p&gt;In DeFi, for instance, we care about user-facing financial products, not standalone protocols. In payments, we want products where stablecoins feel like local money, not products that expose crypto complexity to end users. In privacy, we're looking for privacy-enabled products people would actually adopt, not abstract primitives.&lt;/p&gt;

&lt;p&gt;The difference between a mid-range and a top score here? A top score is a first-of-its-kind idea for Arbitrum with a well-articulated case for why the problem, the solution, and the chain all fit together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Traction or potential is the tiebreaker
&lt;/h2&gt;

&lt;p&gt;Two teams with similar execution and problem-solution scores get separated here. This criterion looks at whether there's evidence the project will continue to exist after the event.&lt;/p&gt;

&lt;p&gt;Judges look at GitHub activity beyond the hackathon commits, social presence, community engagement, and whether there's a defined path forward. A roadmap alone isn't enough. Judges want to see signals that the team is building something they intend to ship to users, not just something that wins a prize.&lt;/p&gt;

&lt;p&gt;In India, the first Open House cohort, many of the winning teams advanced to the mentorship program after the Founder House. Several of those teams are continuing their progress toward mainnet launch. That's the kind of trajectory this criterion is trying to predict.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5cwc8vcpv3ji8gvg6zgf.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5cwc8vcpv3ji8gvg6zgf.jpeg" alt="Builders pitching their projects" width="680" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the bottom of the range: dormant repo, no socials, no roadmap. At the top: demonstrated adoption or strong momentum with an engaged community, partnerships, repeat builders, or a credible launch plan.&lt;/p&gt;

&lt;h2&gt;
  
  
  The eligibility rule nobody should miss
&lt;/h2&gt;

&lt;p&gt;Before any scoring happens, there's one binary check: your project must be deployed on an Arbitrum chain. Not "plans to deploy." Not "could work on Arbitrum." Deployed. This eliminates a surprising number of submissions.&lt;/p&gt;

&lt;p&gt;That chain can be Arbitrum One, Arbitrum Sepolia, or your own Arbitrum chain. If you haven't explored launching your own, the &lt;a href="https://docs.arbitrum.io/launch-arbitrum-chain/a-gentle-introduction" rel="noopener noreferrer"&gt;gentle introduction&lt;/a&gt; is a good starting point. And if you want to test on infrastructure purpose-built for builders, Robinhood recently launched a testnet on Arbitrum and backed Open House with a $1 million investment in supporting builders in the ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-2021600209524969824-818" src="https://platform.twitter.com/embed/Tweet.html?id=2021600209524969824"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2021600209524969824-818');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2021600209524969824&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means for your project
&lt;/h2&gt;

&lt;p&gt;The NYC buildathon is live right now. The NYC Founder House is coming up and registration is open. Dubai registration is open too, with the buildathon running April 23 to May 14 and the Founder House May 28 to 31. Wherever you are in the pipeline, the scoring framework tells you where to spend your time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1iosaj8bm57asq6dzv6.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1iosaj8bm57asq6dzv6.jpeg" alt="Join either the NYC or Dubai program" width="680" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ship working software. A polished pitch deck with a broken demo loses to a rough pitch deck with a working MVP every time. Get your contracts deployed on Arbitrum Sepolia at minimum, Arbitrum One if you can.&lt;/p&gt;

&lt;p&gt;Know what good looks like in your sector. If you're building in DeFi, that means a user-facing product with clear financial utility, not another protocol wrapper. If you're building in payments, that means an experience where stablecoins feel invisible to the end user. Judges evaluate submissions against specific expectations for each category, so make sure your project speaks directly to what matters in yours.&lt;/p&gt;

&lt;p&gt;Show evidence of continued building. Active GitHub commits, a defined roadmap, social engagement, and pilot users all contribute to the traction score. If your repo goes silent after submission, judges notice.&lt;/p&gt;

&lt;p&gt;Build on the Arbitrum stack with intention. Using Stylus, leveraging Timeboost, composing with existing Arbitrum DeFi protocols, or scoping an Arbitrum chain for your use case are all signals that you understand the ecosystem, not just the EVM.&lt;/p&gt;

&lt;p&gt;Open House is designed to find teams that will keep building. The scoring reflects that. If you're serious about shipping a product on Arbitrum, the evaluation criteria work in your favor.&lt;/p&gt;

&lt;p&gt;The NYC buildathon is live, the NYC Founder House kicks off soon, and Dubai registration is open. If you're building in payments, DeFi, RWAs, privacy, consumer, or Arbitrum-native tooling, there's an entry point for you right now at &lt;a href="https://openhouse.arbitrum.io" rel="noopener noreferrer"&gt;openhouse.arbitrum.io&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>hackathon</category>
      <category>productivity</category>
      <category>career</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>How I Built a Claude Code Skill That Scaffolds Complete Arbitrum dApps</title>
      <dc:creator>Ben Greenberg</dc:creator>
      <pubDate>Thu, 05 Feb 2026 10:11:48 +0000</pubDate>
      <link>https://dev.to/arbitrum/how-i-built-a-claude-code-skill-that-scaffolds-complete-arbitrum-dapps-2njl</link>
      <guid>https://dev.to/arbitrum/how-i-built-a-claude-code-skill-that-scaffolds-complete-arbitrum-dapps-2njl</guid>
      <description>&lt;p&gt;There is a gap in Web3 developer tooling that has always frustrated me. On one side, you have hello-world tutorials that deploy a counter contract and stop there. On the other, you have production codebases with thousands of lines of configuration that took months to evolve. The space in between -- where you need a working dApp with contracts, a frontend, a local chain, and a deployment pipeline -- is where most developers get stuck.&lt;/p&gt;

&lt;p&gt;I work in DevRel at Arbitrum, and I kept seeing the same pattern: developers would ask Claude Code to help them build on Arbitrum, and it would produce plausible-looking code that used outdated SDK versions, wrong RPC endpoints, or patterns that simply do not work on Stylus. The model has general Solidity knowledge, but it lacks the specific, opinionated context needed to scaffold a real Arbitrum project from scratch.&lt;/p&gt;

&lt;p&gt;So I built a Claude Code skill to fix that.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Claude Code Skills?
&lt;/h2&gt;

&lt;p&gt;Claude Code skills are structured markdown files that you drop into &lt;code&gt;~/.claude/skills/&lt;/code&gt;. When Claude Code starts a session, it reads these files and treats them as domain-specific knowledge. Think of a skill as a system prompt, but modular and version-controlled.&lt;/p&gt;

&lt;p&gt;A skill has two parts. First, a &lt;code&gt;SKILL.md&lt;/code&gt; file at the root that defines the core knowledge: what tools to use, what decisions to make, and what patterns to follow. Second, a &lt;code&gt;references/&lt;/code&gt; directory containing deeper documentation that Claude loads on demand. This two-tier approach keeps the context window lean -- Claude reads the decision tree up front and only pulls in detailed reference material when the conversation heads in that direction.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcv4e7jvl33864mz9t47v.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcv4e7jvl33864mz9t47v.webp" alt="Skill and Context Window from the Anthropic Blog" width="799" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The key insight is that skills are not code generators. They do not template out files. Instead, they give Claude the structured knowledge it needs to generate correct code itself, tailored to whatever the developer actually asks for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture of the Skill
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/hummusonrails/arbitrum-dapp-skill" rel="noopener noreferrer"&gt;arbitrum-dapp-skill&lt;/a&gt; is organized around a decision tree and six reference documents.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3f9omkcj84p75e9022mg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3f9omkcj84p75e9022mg.png" alt="Decision Tree" width="800" height="778"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The decision tree lives at the top of &lt;code&gt;SKILL.md&lt;/code&gt; and handles the first question any Arbitrum project faces: Stylus Rust, Solidity, or both?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Need maximum performance and lower gas costs? Route to Stylus Rust, load &lt;code&gt;references/stylus-rust-contracts.md&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Need broad tooling compatibility and rapid prototyping? Route to Solidity, load &lt;code&gt;references/solidity-contracts.md&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Hybrid project? Use both. Stylus and Solidity contracts are fully interoperable on Arbitrum -- they share the same address space, storage model, and ABI encoding.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below the decision tree, the skill defines an opinionated project structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-arbitrum-dapp/
├── apps/
│   ├── frontend/            # React / Next.js app
│   ├── contracts-stylus/    # Rust Stylus contracts
│   ├── contracts-solidity/  # Foundry Solidity contracts
│   └── nitro-devnode/       # Local dev chain (git submodule)
├── pnpm-workspace.yaml
└── package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a pnpm monorepo. The &lt;code&gt;apps/&lt;/code&gt; directory separates concerns cleanly. The &lt;code&gt;nitro-devnode&lt;/code&gt; directory is a git submodule pointing to the official Offchain Labs devnode, which gives you a local Arbitrum chain running in Docker on &lt;code&gt;localhost:8547&lt;/code&gt; with pre-funded accounts ready for deployment.&lt;/p&gt;

&lt;p&gt;The six reference documents cover the full development lifecycle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;stylus-rust-contracts.md&lt;/code&gt; -- Stylus SDK patterns, &lt;code&gt;sol_storage!&lt;/code&gt; macros, &lt;code&gt;#[public]&lt;/code&gt; methods, events, error handling&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;solidity-contracts.md&lt;/code&gt; -- Solidity 0.8.x on Arbitrum with Foundry workflows&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;frontend-integration.md&lt;/code&gt; -- viem + wagmi setup, hydration safety, contract reads and writes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;local-devnode.md&lt;/code&gt; -- Docker setup, pre-funded accounts, CORS proxy for browser access&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;deployment.md&lt;/code&gt; -- Testnet (Arbitrum Sepolia) and mainnet (Arbitrum One) deployment&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;testing.md&lt;/code&gt; -- Unit testing strategies for both Stylus and Solidity contracts&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why These Tech Choices
&lt;/h2&gt;

&lt;p&gt;Every choice in the stack is deliberate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stylus SDK v0.10+&lt;/strong&gt; because earlier versions had breaking API differences in storage macros and entrypoint attributes. Pinning to 0.10+ means Claude generates code that actually compiles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Foundry over Hardhat&lt;/strong&gt; for Solidity because Foundry's &lt;code&gt;forge&lt;/code&gt; is faster, its testing framework uses Solidity itself (no JavaScript test wrappers), and &lt;code&gt;cast&lt;/code&gt; provides a clean CLI for chain interaction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;viem over ethers.js&lt;/strong&gt; because viem provides strict TypeScript types for contract interaction. When Claude generates a &lt;code&gt;readContract&lt;/code&gt; call with the wrong function name, TypeScript catches it at compile time rather than failing silently at runtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;wagmi&lt;/strong&gt; because it wraps viem in React hooks with built-in state management for wallet connections, transaction confirmations, and contract reads. The skill includes hydration safety patterns for Next.js, which is a common stumbling block.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;pnpm&lt;/strong&gt; because workspaces let the frontend import ABIs directly from the contract directories, and pnpm's strict dependency resolution avoids the phantom dependency issues that plague npm in monorepos.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Concrete Walkthrough
&lt;/h2&gt;

&lt;p&gt;Here is what it looks like in practice. You install the skill, start Claude Code, and type:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Build me an NFT contract using Stylus Rust with a React frontend that lets users mint tokens.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Claude reads the skill, routes to the Stylus path, and starts scaffolding. It creates the monorepo structure, generates a Stylus contract using &lt;code&gt;sol_storage!&lt;/code&gt; for the token state, implements &lt;code&gt;mint&lt;/code&gt; and &lt;code&gt;balance_of&lt;/code&gt; as &lt;code&gt;#[public]&lt;/code&gt; methods, and emits a &lt;code&gt;Transfer&lt;/code&gt; event using &lt;code&gt;alloy_sol_types&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;sol_storage!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;#[entrypoint]&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;NftContract&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uint256&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;owners&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nf"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;balances&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;total_supply&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[public]&lt;/span&gt;
&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;NftContract&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;mint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;U256&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;token_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.total_supply&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nn"&gt;U256&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.total_supply&lt;/span&gt;&lt;span class="nf"&gt;.set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.owners&lt;/span&gt;&lt;span class="nf"&gt;.setter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.balances&lt;/span&gt;&lt;span class="nf"&gt;.setter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="nf"&gt;.set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.balances&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nn"&gt;U256&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nn"&gt;evm&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="k"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Transfer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ZERO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;token_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="n"&gt;token_id&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the frontend side, Claude sets up the wagmi provider, creates a mint button using &lt;code&gt;useWriteContract&lt;/code&gt;, and wires up a display component with &lt;code&gt;useReadContract&lt;/code&gt; -- all with proper hydration guards for Next.js. It exports the ABI from &lt;code&gt;cargo stylus export-abi&lt;/code&gt; and places it where the frontend can import it.&lt;/p&gt;

&lt;p&gt;The entire project is configured to run against &lt;code&gt;nitro-devnode&lt;/code&gt; out of the box. You start Docker, run the devnode script, deploy with &lt;code&gt;cargo stylus deploy&lt;/code&gt;, and the frontend connects through a CORS proxy route.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install It
&lt;/h2&gt;

&lt;p&gt;One command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bash &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://raw.githubusercontent.com/hummusonrails/arbitrum-dapp-skill/main/install.sh&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This clones the skill into &lt;code&gt;~/.claude/skills/arbitrum-dapp-skill&lt;/code&gt;. The next time you start Claude Code, it picks it up automatically. You can also install via &lt;a href="https://clawhub.ai/hummusonrails/arbitrum-dapp-skill" rel="noopener noreferrer"&gt;ClawHub&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx clawhub@latest &lt;span class="nb"&gt;install &lt;/span&gt;arbitrum-dapp-skill
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or if you prefer manual installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/hummusonrails/arbitrum-dapp-skill.git ~/.claude/skills/arbitrum-dapp-skill
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To see it in action before installing, there is a &lt;a href="https://youtu.be/vsejiaOTmJA" rel="noopener noreferrer"&gt;demo video on YouTube&lt;/a&gt; that walks through the full workflow. &lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/vsejiaOTmJA"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I also wrote a &lt;a href="https://x.com/hummusonrails/status/2019335992902095183" rel="noopener noreferrer"&gt;deeper technical thread on X&lt;/a&gt; covering the design decisions in more detail.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-2019337368033992833-676" src="https://platform.twitter.com/embed/Tweet.html?id=2019337368033992833"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2019337368033992833-676');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2019337368033992833&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The skill covers the core development lifecycle, but there is more to build. Token bridging patterns between L1 and Arbitrum, integration with Orbit chains, and more advanced Stylus patterns like precompile access are all on the roadmap.&lt;/p&gt;

&lt;p&gt;If you are building on Arbitrum and run into a pattern the skill does not cover well, open an issue or submit a PR on the &lt;a href="https://github.com/hummusonrails/arbitrum-dapp-skill" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;. The whole point of packaging this as a skill rather than a tutorial is that it evolves with the ecosystem. As the Stylus SDK ships new versions, as viem adds new features, the skill updates and every developer who installed it gets the improvements on their next &lt;code&gt;git pull&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Skills are a new primitive for developer tooling. Instead of writing documentation that developers read and then translate into code, you write structured knowledge that an AI agent consumes directly. The developer describes what they want, and the agent applies the knowledge to generate a working implementation. I think this pattern is going to reshape how we think about developer education in Web3 and beyond.&lt;/p&gt;

&lt;p&gt;You can find the full source, documentation, and installation instructions at &lt;a href="https://hummusonrails.github.io/arbitrum-dapp-skill/" rel="noopener noreferrer"&gt;hummusonrails.github.io/arbitrum-dapp-skill&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>claudeai</category>
      <category>web3</category>
      <category>rust</category>
      <category>ai</category>
    </item>
    <item>
      <title>Open House NYC</title>
      <dc:creator>benjamintan.eth (💙,🧡)</dc:creator>
      <pubDate>Mon, 26 Jan 2026 17:37:06 +0000</pubDate>
      <link>https://dev.to/arbitrum/open-house-nyc-4dck</link>
      <guid>https://dev.to/arbitrum/open-house-nyc-4dck</guid>
      <description>&lt;h3&gt;
  
  
  Open House first started out in India. Now in 2026, it’s back - with its first stop in NYC  👉🏻 &lt;a href="https://openhouse.arbitrum.io/?utm_source=devto&amp;amp;utm_medium=website&amp;amp;utm_campaign=oh-nyc-founder-house,oh-nyc-buildathon&amp;amp;utm_content=devto-ohw" rel="noopener noreferrer"&gt;Register Now&lt;/a&gt; 👈🏻
&lt;/h3&gt;

&lt;p&gt;

&lt;iframe class="tweet-embed" id="tweet-2010698393157574780-223" src="https://platform.twitter.com/embed/Tweet.html?id=2010698393157574780"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2010698393157574780-223');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2010698393157574780&amp;amp;theme=dark"
  }





&lt;/p&gt;

&lt;p&gt;Open House NYC consists of a &lt;strong&gt;3-week Online Buildathon (Feb 5 – Feb 26, 2026)&lt;/strong&gt; and an &lt;strong&gt;IRL Founder House (Mar 6 - Mar 8)&lt;/strong&gt;, designed to help experienced builders go from prototype to something that actually ships onchain.&lt;/p&gt;

&lt;p&gt;This isn’t about rushing demos; It’s about building with intent and follow-through.&lt;/p&gt;




&lt;h3&gt;
  
  
  What to expect
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Deep technical sessions on the Arbitrum stack
&lt;/li&gt;
&lt;li&gt;Live coding demos and hands-on workshops
&lt;/li&gt;
&lt;li&gt;Founder-focused sessions on GTM and shipping post-buildathon
&lt;/li&gt;
&lt;li&gt;Mentorship from builders in the Arbitrum ecosystem
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;$60,000 in prizes and grants&lt;/strong&gt; to keep teams building


&lt;iframe class="tweet-embed" id="tweet-2015007731724525872-286" src="https://platform.twitter.com/embed/Tweet.html?id=2015007731724525872"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2015007731724525872-286');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2015007731724525872&amp;amp;theme=dark"
  }





&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Join Open House NYC
&lt;/h2&gt;

&lt;p&gt;If you’re looking for a structured, builder-first way to take your project further, this might be for you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://openhouse.arbitrum.io/?utm_source=devto&amp;amp;utm_medium=website&amp;amp;utm_campaign=oh-nyc-founder-house,oh-nyc-buildathon&amp;amp;utm_content=devto-ohw" rel="noopener noreferrer"&gt;Apply here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See you at Open House 🗽&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
