Non-custodial limit orders, DCA & portfolio P&L for tokenized stocks on Robinhood Chain, executed through Uniswap V2.
Aim. Set. Hit.
Longbow fills the gap Uniswap V2 leaves open for stock-token traders: there is no native limit order or DCA. Longbow adds both β as a ~200-line permissionless executor contract plus a keeper β while your funds never leave your wallet.
apps/web Next.js 14 β landing (3D hero), app (/app/*), docs (/docs/*), API routes
apps/keeper Node worker β polls orders every ~15s and executes them
packages/contracts Foundry β LongbowExecutor.sol + mocks + tests + deploy scripts
packages/shared TS β chains, token registry, ABIs, V2 math, mock market engine
pnpm install
# terminal 1 β web (landing + app + docs) β http://localhost:3000
pnpm dev
# terminal 2 β keeper (fills your limit/DCA orders)
pnpm keeperMock mode is the default (USE_MOCKS=true): prices, reserves, holdings and
keeper fills are simulated deterministically. Place a limit or DCA order at
/app/orders and watch the keeper fill it.
cd packages/contracts
forge test # 11 tests β triggers, DCA multi-run, slippage, expiry,
# oraclePaused, stale price, sequencer down, cancel authDeploy:
# testnet demo environment (mock router+tokens+feeds+pools+executor)
forge script script/SeedDemo.s.sol --rpc-url robinhood_testnet --broadcast --private-key $KEY
# mainnet executor against the real Uniswap V2 Router02
ROUTER=0x89e5db8b5aa49aa85ac63f691524311aeb649eba \
forge script script/Deploy.s.sol --rpc-url robinhood_mainnet --broadcast --private-key $KEYThen copy the printed addresses into packages/shared/src/addresses.ts and
.env (EXECUTOR_ADDRESS), set USE_MOCKS=false, restart.
cp .env.example .env β everything is optional in mock mode.
| Var | Purpose |
|---|---|
NEXT_PUBLIC_CHAIN_ID |
46630 testnet (default) / 4663 mainnet |
NEXT_PUBLIC_USE_MOCKS / USE_MOCKS |
true (default) = offline demo |
FINNHUB_API_KEY |
real stock quotes (primary) |
ALPHAVANTAGE_API_KEY |
quote fallback |
EXECUTOR_ADDRESS |
deployed LongbowExecutor |
KEEPER_PRIVATE_KEY |
funded keeper wallet (live mode) |
- USDG is 6 decimals; every stock token is 18.
- Chainlink stock feeds are total-return (dividends via ERC-8056
uiMultiplier). Apply the multiplier to balances, never to feed prices. - Never hardcode the V2 pair init code hash on Robinhood Chain β resolve
pairs via
factory.getPair(). - Execution guards: feed staleness (1h),
oraclePaused(), sequencer uptime feed + 1h grace,minAmountOut, reentrancy, path validation.
Orders are mirrored in a JSON file (apps/web/.data/orders.json) so the demo
has zero native dependencies. The production schema mirror lives in
apps/web/prisma/schema.prisma (Postgres) β swap lib/orderStore.ts for a
Prisma client when deploying.
Experimental software, provided as-is, MIT licensed. Not financial advice. Robinhood Chain stock tokens are not available to US persons; Longbow is non-custodial tooling and does not facilitate restricted access.