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
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Start here. Find the outcome you are working toward below, read the file on that
| Choose an attribute type, or find out why a value was rejected | `reference/atomicassets/custom-types.md` |
| Decode an attribute blob read straight from a chain table | `reference/atomicassets/serialization.md` |
| Decide which layer an attribute value comes from when template and asset disagree | `reference/atomicassets/data-precedence.md` |
| Tell a JSON number from the quoted decimal the chain prints for the same value | `reference/numeric-values-in-json.md` |
| Find out whether a chain runs V2 yet, and what V2 added | `reference/atomicassets/v2-upgrade.md` |
| Handle a token-backed asset minted before backing was deprecated | `reference/atomicassets/backing-tokens.md` |
| List an asset for sale and settle the purchase, oracle-priced sales included | `guides/sales.md` |
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

What each release of this corpus changed, one release per tag. `Corrected` comes first in every release, because a fact that was wrong is what a returning reader has to see before anything else. The other sections are `Added`, `Revalidated`, and `Removed`, in that order, and a section with nothing in it is left out.

## 2026.08.4

### Added

- `reference/numeric-values-in-json.md` records what JSON type a numeric attribute value takes on each read path: nodeos widens every float to a double on construction and prints it as a quoted seventeen-place decimal, `@wharfkit/antelope` objectifies one to a string in its own form instead (`toFixed(7)` for a float32 at 1.x, `Number.toString` for a float64, and the same shortest-round-trip form for both widths from the 2.x commit that drops the `Float32` override), and a hosted API answers with a number wherever the value was decoded from serialized bytes and with a string in that client-library form wherever it entered through the ABI action path.
- The same page records that `toFixed(7)` keeps seven decimal places rather than seven significant digits at 1.x, so a float32 value that needs more than seven fractional decimals does not survive the client library's string form there. A sample of 20,000 random values per decade found no failures at or above 1, climbing to 99 percent between 0.01 and 0.02 and 100 percent at or below 0.001, rates over a sample rather than a bound on the interval. It also records that nodeos's own seventeen fixed places bounds the string without making it lossless: a double under `5e-18` prints as zero, and a matching per-decade measurement of `toFixed(17)` round trips finds failures climbing from 27 percent to 91 percent as magnitude falls below 0.1.
- The page attributes the string-versus-number split on the ABI action path to each indexer's own decode call site (`atomicassets-api`'s own `Serializer.objectify` call against `@atomichub/antelope-ship-utils`'s, which switches to `objectifyNumericFloats` at 2.0.0) rather than to the live responses alone, and states that the change reaches new writes only, with a repair pass for rows already stored. `reference/sdk/atomicmarket.md` and `reference/atomicassets/serialization.md` change alongside it: a typed table row is a declared shape, not a runtime conversion, and a native ABI float field decodes independently of a serialized attribute's own codec.
- `reference/validation.md` pins `@atomichub/atomicassets` 2.2.0 for attribute decoding, `@atomichub/antelope-ship-utils` 1.0.1 and 2.0.0 for the decode call site that changed between them, `AntelopeIO/spring` v1.2.2 for the nodeos serialization source, and a `@wharfkit/antelope` 2.x commit for the `Float32` string-form change. The two SDK pages keep the `atomicassets-sdk` `v2.1.1` pin.

## 2026.08.3

### Corrected
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ WAX mainnet still runs the V1 `atomicassets` and `atomicmarket` contracts while

| Directory | Contents |
| --- | --- |
| `reference/` | Facts: `atomicassets/`, `atomicmarket/`, `atomictools/`, and `sdk/` directories with per-topic pages (structure, actions, tables, fees, serialization, SDK surfaces), plus one file each for the indexer, API, API streaming, media conventions, chain, and client libraries |
| `reference/` | Facts: `atomicassets/`, `atomicmarket/`, `atomictools/`, and `sdk/` directories with per-topic pages (structure, actions, tables, fees, serialization, SDK surfaces), plus one file each for the indexer, API, API streaming, media conventions, numeric JSON types, chain, and client libraries |
| `guides/` | End-to-end workflows: asset lifecycle, offers, sales, auctions, buyoffers, deposits, claim links, notification integration, contract testing with VeRT, and querying the API |
| `learning/` | The unverified tier: claims that have not been checked yet, and the gate they pass before promotion |
| `skills/` | Agent skills. `atomic-integration` routes a coding agent to the reference file its task needs. `report` writes a sanitized report about these docs into the consuming project, and never edits this repository |
Expand Down
2 changes: 1 addition & 1 deletion reference/atomicassets/serialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ An off-chain implementation needs three things, in this order:
2. **The varint/zigzag codec.** Implement `toVarintBytes`/`unsignedFromVarintBytes` and `zigzagEncode`/`zigzagDecode` exactly as described above. These are not standard varints with a sign bit baked in; zigzag is a separate transform applied only to signed types before varint-encoding.
3. **The per-type encode/decode table above**, including the array rule (varint count + repeated elements, one level only) and the identifier arithmetic (`position + 4` on encode, `identifier - 4` on decode).

To serialize an `ATTRIBUTE_MAP` for submission in a transaction (`mintasset`, `setassetdata`, `createtempl`, `setcoldata`, and similar actions all take `ATTRIBUTE_MAP` parameters that the contract itself serializes on execution; the caller passes attribute maps, not bytes), an off-chain caller does not need this codec at all: it constructs the `ATTRIBUTE_MAP` as ABI JSON per `reference/atomicassets/custom-types.md` and lets the contract's own `serialize` call do the encoding. This codec is needed off-chain specifically to decode `immutable_serialized_data` / `mutable_serialized_data` / collection `serialized_data` bytes read back from `get_table_rows`, or to reproduce the contract's stored bytes for verification. Decoding each layer with this codec is only the first step; combining template and asset layers into one effective attribute set is a separate concern covered in [Attribute data precedence](data-precedence.md).
To serialize an `ATTRIBUTE_MAP` for submission in a transaction (`mintasset`, `setassetdata`, `createtempl`, `setcoldata`, and similar actions all take `ATTRIBUTE_MAP` parameters that the contract itself serializes on execution; the caller passes attribute maps, not bytes), an off-chain caller does not need this codec at all: it constructs the `ATTRIBUTE_MAP` as ABI JSON per `reference/atomicassets/custom-types.md` and lets the contract's own `serialize` call do the encoding. This codec is needed off-chain specifically to decode `immutable_serialized_data` / `mutable_serialized_data` / collection `serialized_data` bytes read back from `get_table_rows`, or to reproduce the contract's stored bytes for verification. Decoding each layer with this codec is only the first step; combining template and asset layers into one effective attribute set is a separate concern covered in [Attribute data precedence](data-precedence.md). The JSON type a decoded value then takes is a further concern, and this codec does not settle it: an attribute arrives as whatever type its decoder returns, which for the hosted APIs and the decoding SDKs is a number. A native ABI float column and a serialized attribute are not interchangeable at `get_table_rows`, and the two never meet at this codec: `market_fee` is a plain ABI `float64` field on the `collections` row, so `get_table_rows` decodes it itself and answers a quoted decimal string directly, no codec involved. `serialized_data` on that same row (`immutable_serialized_data` / `mutable_serialized_data` on a template or asset row) is this codec's own `vector<uint8_t>`, so `get_table_rows` cannot decode it and answers undecoded bytes; a reader gets an attribute's actual value out of it only by running this codec, not by asking nodeos. See [Numeric values in JSON](../numeric-values-in-json.md).

Source: `include/atomicassets.hpp:363-421` (`schemas_s`, `templates_s`, `template_mutables_s`, `assets_s` table shapes), `include/atomicassets.hpp:458` (`config_s.collection_format`)

Expand Down
Loading
Loading