Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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):** `<TODO: fill in once a funded
ARKIV_PRIVATE_KEY is set on chain/arkiv/'s deploy — see chain/arkiv/README.md>`
- **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('<a real plan_id>') AND $owner = addr(<service wallet address above>)
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`).
Expand Down
46 changes: 37 additions & 9 deletions arkiv/friction.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
8 changes: 5 additions & 3 deletions arkiv/schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -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: `<TODO: fill in once a funded ARKIV_PRIVATE_KEY is set on chain/arkiv/'s
deploy — see chain/arkiv/README.md>`.
Service wallet address: `0x527982184391CF04a4403E44D55e9Bb8173020Ab`.

## Expiry

Expand All @@ -85,9 +84,12 @@ cheap.
## One query anyone can run

```
arkiv.schema = str('mergit.routing_decision') AND planId = str('<a real plan_id from a live run>') AND $owner = addr(<the service wallet address above>) 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
Expand Down