From 6a888ab1e9b57905d2e8ec32a9b1f2cbc9606618 Mon Sep 17 00:00:00 2001 From: OfficialAbhinavSingh Date: Fri, 6 Nov 2026 12:32:00 +0530 Subject: [PATCH] docs(arkiv): real service wallet, a runnable query, live friction notes Fill the README and arkiv/schema.md placeholders with the service wallet, a query against a real test plan, and an explorer link to one of its entities. Replace friction.md's stale "no live write yet" section with what the live deploy actually hit: an unfunded wallet's unhelpful gas error, u64s rounded by JSON.parse in the sidecar, and MetaMask keys exported without 0x. --- README.md | 10 ++++++---- arkiv/friction.md | 46 +++++++++++++++++++++++++++++++++++++--------- arkiv/schema.md | 8 +++++--- 3 files changed, 48 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index b525298b..ee9d02da 100644 --- a/README.md +++ b/README.md @@ -135,13 +135,15 @@ Full writeup: [`arkiv/schema.md`](arkiv/schema.md), [`arkiv/why-arkiv.md`](arkiv [`arkiv/how-you-use-arkiv.md`](arkiv/how-you-use-arkiv.md), [`arkiv/reach.md`](arkiv/reach.md), [`arkiv/friction.md`](arkiv/friction.md). -- **Service wallet (writes every mirrored entity):** `` +- **Service wallet (writes every mirrored entity):** `0x527982184391CF04a4403E44D55e9Bb8173020Ab` - **One query anyone can run**, against `https://rpc.rabdi.db-chain.testnet.arkiv.network` - (`arkiv_query`) or through the hosted app's `GET /v0/plans/{uuid}/arkiv-suggestions`: + (`arkiv_query`) or through the hosted app's `GET /v0/plans/{uuid}/arkiv-suggestions`. This one is + a real test plan on the hosted app: ``` - arkiv.schema = str('mergit.routing_decision') AND planId = str('') AND $owner = addr() + arkiv.schema = str('mergit.routing_decision') AND planId = str('0x247b5cd9b38f436d82a6e6acf1d361d516cd19f88d38c88967eb275ba256d77f') AND $owner = addr(0x527982184391CF04a4403E44D55e9Bb8173020Ab) ORDER BY $key ASC ``` +- **One entity on the explorer** (task 1 of a draw on that plan): + [`0xc55112ad…fdb5caf`](https://rabdi.explorer.arkiv.network/entity/0xc55112adbd6cdf3e314c42816e6cc65f703e2b4f7f7b0cc848c5caa52fdb5caf) - **In the app:** the live run screen's "Suggested agents" panel, after asking for an exploring suggestion, shows a "View on Arkiv" button that reads the mirrored entities back from Arkiv live (`frontend/src/screens/live/run/SuggestAgents.tsx`). diff --git a/arkiv/friction.md b/arkiv/friction.md index 9a6a8733..5d02d501 100644 --- a/arkiv/friction.md +++ b/arkiv/friction.md @@ -58,12 +58,40 @@ different test queries were run back to back and their results were briefly misr recording anyway, since it's an easy trap when scripting several `arkiv_query` calls in a row and reading output after the fact rather than per-call. -## No live write exercised yet — but a real, verified attempt, not a guess - -`chain/arkiv/`'s sidecar, using the official JS SDK (the one confirmed above to target the right -network), reaches real on-chain gas estimation with an unfunded throwaway wallet (confirmed `0` -balance via `eth_getBalance`) and fails there — `"Execution error without revert data"` — not at -encoding, not at signing, not at the RPC connection. That is the furthest this can be verified -without a funded wallet, which needs a human with a browser wallet (`hub.arkiv.network/faucet` is -wallet-connect gated, not a plain API). No successful create yet, so no real entity key exists; the -placeholders in `schema.md` and the README stay placeholders until someone funds a wallet. +## An unfunded wallet fails at gas estimation with no hint that funds are the problem + +Before the service wallet was funded, the sidecar's `executeBatch` got as far as real on-chain gas +estimation and failed there with `"Execution error without revert data"`. Encoding, signing and the +RPC connection were all fine; the wallet had a `0` balance (`eth_getBalance`). Nothing in the error +says "insufficient funds". Funding needs a person with a browser wallet, since +`hub.arkiv.network/faucet` is gated behind wallet-connect and has no plain API. Once funded (10 +tGLM), the same code wrote with no changes. + +**Reproduce:** point the JS SDK's `createWalletClient` at Rabdi with a fresh, unfunded key and call +`executeBatch` with one create. + +## u64 attributes lose precision if they cross JSON as numbers + +The first live writes stored routing seeds a few units off. Seed `1065256257932064655` landed as +`1065256257932064640`. Arkiv stored what it was given correctly. The value was already wrong by +then: the control plane sent it to the Node sidecar as a JSON number, and `JSON.parse` rounds any +integer past 2^53 to the nearest double before the SDK's `u64()` sees it. The SDK takes a `bigint` +happily, but nothing warns that a plain number got there already rounded. We now send every u64 as a +decimal string, and the sidecar rejects a number outright. A fresh draw's seed +`3019959484170456754` reads back from Rabdi exact. + +**Reproduce:** `node -e 'console.log(JSON.parse("1065256257932064655"))'` prints +`1065256257932064600`. + +## A MetaMask-exported key has no `0x`, and viem won't take it + +MetaMask's "Show private key" gives 64 hex characters with no `0x` prefix. viem's +`privateKeyToAccount` needs the prefix, so the sidecar crash-looped on its first deploy and the +control plane only saw "sidecar unreachable". Not an Arkiv bug, but it is the first thing anyone +who follows the faucet-then-MetaMask path will hit. The sidecar now accepts either form. + +## Where it stands + +Live on the hosted app: each exploring suggestion writes one batched transaction of one entity per +task, owned by the service wallet. The run screen's "View on Arkiv" reads them back from Rabdi and +checks them against the picks on screen. The query and an entity link are in `schema.md`. diff --git a/arkiv/schema.md b/arkiv/schema.md index d2a1b1aa..f79986d3 100644 --- a/arkiv/schema.md +++ b/arkiv/schema.md @@ -72,8 +72,7 @@ not a per-requester wallet: Mergit requesters sign in with Ethereum but never ho testnet, so making them the Arkiv-level owner would mean asking them to fund a second chain to see their own suggestion history. -Service wallet address: ``. +Service wallet address: `0x527982184391CF04a4403E44D55e9Bb8173020Ab`. ## Expiry @@ -85,9 +84,12 @@ cheap. ## One query anyone can run ``` -arkiv.schema = str('mergit.routing_decision') AND planId = str('') AND $owner = addr() ORDER BY $key ASC +arkiv.schema = str('mergit.routing_decision') AND planId = str('0x247b5cd9b38f436d82a6e6acf1d361d516cd19f88d38c88967eb275ba256d77f') AND $owner = addr(0x527982184391CF04a4403E44D55e9Bb8173020Ab) ORDER BY $key ASC ``` +That `planId` is a real test plan on the hosted app; one of its entities on the explorer: +[`0xc55112ad…fdb5caf`](https://rabdi.explorer.arkiv.network/entity/0xc55112adbd6cdf3e314c42816e6cc65f703e2b4f7f7b0cc848c5caa52fdb5caf). + The `$owner` clause matters: without it, anyone could write an entity with our exact schema tag and a matching `planId` and have it show up as if it were ours (Arkiv is public and permissionless — checked live, nothing stops a third party from using any tag). Run it against