Skip to content

feat: show what a document costs, in Dash and dollars, per index - #4

Merged
QuantumExplorer merged 7 commits into
mainfrom
feat/document-cost
Sep 29, 2026
Merged

QuantumExplorer merged 7 commits into
mainfrom
feat/document-cost

Conversation

@QuantumExplorer

Copy link
Copy Markdown
Member

Basic explanation

What this does: Select a document type and the inspector shows about what creating one of its documents costs, in Dash and dollars. Cost (or details) opens the full breakdown:

  • two totals: the first document with a set of index values (it creates their trees) and a later document with the same values (it adds only its own entries);
  • the storage: the document itself, and each index on its own, split into the part it shares with other indexes (a common prefix, paid once) and the part only it adds; trees prepaid for other types' preallocated indexes; a ttl type's expiration entry;
  • the processing: the signature and identity fetch (exact), and the writes and checks (estimated for a number of stored documents you can change, with the signing key type and a fee increase);
  • what the contract charges: its action fee, a token cost, a contest's vote fund;
  • what deleting the document refunds;
  • Adjust the document: an on/off switch for each optional field and a length for each variable-size field (strings, byte arrays, arrays). Fixed-size fields (identifiers, numbers, booleans, dates) need no input. By default each variable field sits at the middle of its bounds and each optional field is present.

Where the numbers come from: Drive computes them (documentCreateCost, added by dashpay/platform#5159), with the fee rules it charges by; its tests hold the storage to what Drive charges on real inserts, byte for byte. The Dash price comes from CoinGecko (Coinbase if that fails; both allow browser requests), kept five minutes, and you can type your own.

Needs an SDK release: like the GroveDB layout (#3, which this branch builds on), documentCreateCost is not in the evo-sdk this repo pins. The inspector checks for it and says the estimate arrives with the next SDK release until the dependency is bumped. This PR's base is #3's branch.

Before and after

DPNS domain, in the inspector:

About 0.000535 DASH ($0.03) per document (0.000383 DASH ($0.02) once its index values are stored)  details

DashPay contactRequest, the storage table of the panel (values new / values stored):

The document itself                    611 B  0.000165 DASH ($0.01)     611 B
index ownerIdUserIdAndAccountRef       943 B  0.000255 DASH ($0.02)     339 B
  shared with ownerIdCreatedAt, ownerIdUserId: 465 B (paid once) + its own 478 B
index ownerIdUserId                    852 B  0.00023 DASH ($0.01)      278 B
index ownerIdCreatedAt                 808 B  0.000218 DASH ($0.01)     278 B
index userIdCreatedAt                  808 B  0.000218 DASH ($0.01)     278 B
All storage                          3,386 B  0.000914 DASH ($0.06)   1,784 B

DPNS domain also lists "Contest fund: 0.1 DASH ($6.43) when the value of parentNameAndLabel is contested", and "In the same epoch: 0.000278 DASH, a year later: 0.000264 DASH" as its refund. The marketplace listing (ttl) is priced by its lifetime, 136 credits a byte instead of 27,000, with its cleanup prepay and no refund.

With the SDK this repo pins today, the inspector says:

The cost estimate appears with the next SDK release.

What was done?

  • src/components/CostPanel.tsx (new): the breakdown, the price line with your own price, the assumptions (stored documents, key type, fee increase) and the field controls. It recomputes shortly after each change.
  • src/components/CostLine.tsx (new): the inspector's line with the approximate cost for a document of middle sizes, and a link to the details.
  • src/model/cost.ts (new): the types documentCreateCost returns, conversion to Dash and dollars, the formatting, each index on its own (sharedBytes + ownBytes), and which fields get a control.
  • src/price.ts and src/components/useDashPrice.ts (new): the Dash price from CoinGecko then Coinbase, kept five minutes, and a typed-in price remembered in this browser.
  • src/sdk/cost.ts (new) and src/sdk/local.ts (new): the cost call, feature-detected. The layout and cost loaders now share the SDK loading and contract building (src/sdk/layout.ts uses it).
  • src/App.tsx, src/components/InspectorPanel.tsx: the inspector gets the cost line and a Cost button beside GroveDB layout; in compare mode the head's version is priced (the base's when the type was removed), as for the layout.
  • README: a What a document costs section.

How Has This Been Tested?

  • npx vitest run: 99 passed. New:
    • src/model/cost.test.ts runs against costs that an SDK built from feat(drive): compute what creating a document costs for the SDKs platform#5159 computed for three examples (src/model/fixtures/document-create-costs.json): marketplace listing, DPNS domain, Yappr likes tip. It covers the formatting, the credit rate, the ttl pricing, the contest fund, each index on its own adding up to all the storage, and the fields offered a control.
    • src/price.test.ts covers CoinGecko, the fallback to Coinbase, no price and the five minute cache.
  • tsc clean, npm run build clean.
  • In the browser, with the SDK built from #5159 swapped into node_modules (not committed):
    • marketplace listing, DPNS domain and DashPay contactRequest show the inspector line and the panel, with the live CoinGecko price;
    • setting title to 120 characters and turning sku off changes the storage by the expected 43 bytes;
    • at phone width (375 px) the panel fits with no horizontal scroll.
  • With the pinned 4.2.0-beta.4, the inspector shows the "appears with the next SDK release" line (the same feature detection as the layout panel).

🤖 Generated with Claude Code

QuantumExplorer and others added 4 commits September 29, 2026 02:22
@dashevo/evo-sdk is built without dpp's validation feature, so
DataContract.fromJSON(json, true, 14) runs the contract parser but not the
document meta-schema or the parser checks gated behind that feature. The
README, the examples registry and the validation script claimed more.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A "GroveDB layout" button in the inspector opens every tree and element
Drive writes for the selected document type: the documents by id (and
revisions), and for each index the property and value trees down to the
[0] where it ends, with each layer's element (count, sum, ranked, ...),
its zero-contribution wrapper, the indexes that use it, conditions (the
null fallback of a unique index, skipIfAbsent, preallocated, time window
overlap) and a link to that kind of layer in the GroveDB structure viewer.

The layout comes from documentTypeLayout in @dashevo/evo-sdk
(dashpay/platform#5153), so it follows Drive's own rules. It is
feature-detected: with an SDK that predates it, the panel says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dashpay/platform#5153 merged with a review fix: a unique index's null
fallback no longer repeats the terminal's indexes and notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Selecting a document type shows about what one of its documents costs;
Cost opens the breakdown, computed by Drive (documentCreateCost in
@dashevo/evo-sdk, dashpay/platform#5159): the first document with a set
of index values and a later one with the same values; the storage of
the document itself and of each index on its own (the part it shares
with other indexes, paid once, and its own); prepaid trees and a ttl
type's expiration entry; the processing (exact parts marked, the rest
estimated for a number of stored documents, a key type and a fee
increase); the contract's action fee, token cost and contest fund; and
the refund on delete. "Adjust the document" gives an on/off switch per
optional field and a length per variable-size one; fixed-size fields
need no input.

The Dash price comes from CoinGecko (Coinbase if that fails), kept five
minutes, and can be typed in. Feature-detected: with an SDK that
predates documentCreateCost the inspector says so. The layout and cost
loaders share one local SDK module.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 24a3d2d4-5230-4558-b31a-8972fb63ff51


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

QuantumExplorer and others added 2 commits September 29, 2026 08:30
Brings in the inspector's JSON view (#5). The conflicts were both-sides
additions: EntityView takes both onShowLayout and version, the README
lists both layout.ts and jsonTokens.ts, and styles.css keeps both blocks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings in main's inspector JSON view (#5) through the layout branch.
The conflicts were both-sides additions: EntityView takes the layout,
cost and version props, the README lists cost.ts and jsonTokens.ts,
and styles.css keeps both blocks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@QuantumExplorer
QuantumExplorer changed the base branch from feat/document-type-layout to main September 29, 2026 01:33
Main is #3's squash (8618215), whose tree is identical to #3's last head
(1631a85), already merged here. Keeping this branch's tree resolves the
conflicts the squash created.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@QuantumExplorer
QuantumExplorer merged commit 576c2c7 into main Sep 29, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant