Insights

546 NFTs, Provably Fair: Verify the Bored Apes XRP Club Fairdrop

On 2026-08-31(UTC), 546 Bored Apes XRP Club NFTs were distributed to the collection's holders, strictly proportional to how many each held. The amounts contain no randomness at all. The only random step — which specific apes go to which winner — was seeded by the hash of a ledger that did not exist when the rules were anchored on-chain. This page carries every value needed to re-derive the entire drop from public data, plus the one command that does it for you.

Ceremony 2026-08-31XRPL mainnetgithub.com/xrplto/bay-nft-airdrop

The drop in numbers

At ledger 106676567, 1,767 wallets held 9,451 Bored Apes XRP Club NFTs (excluding the 546 sitting in the distributor). Each holder's exact quota is 546 × holdings ÷ 9,451 — about one NFT per 17.3 held. Every holder is guaranteed the floor of that quota (277 NFTs assigned this way); the remaining 269 seats went to the largest fractional remainders, with exact ties broken by holdings (descending) then address (ascending). The result: 294 winners, 546 transfers, zero discretion. All arithmetic is exact BigInt rational math — no floats, so no rounding disputes at any collection size.

Who got which ape

All 546 assignments, exactly as plan.json records them, grouped by winner (largest allocations first). Paste your address to find yours.

Bored Apes XRP Club #312
#312
Bored Apes XRP Club #343
#343
Bored Apes XRP Club #448
#448
Bored Apes XRP Club #593
#593
Bored Apes XRP Club #1071
#1071
Bored Apes XRP Club #1182
#1182
Bored Apes XRP Club #1248
#1248
Bored Apes XRP Club #1600
#1600
Bored Apes XRP Club #1743
#1743
Bored Apes XRP Club #1819
#1819
Bored Apes XRP Club #1980
#1980
Bored Apes XRP Club #1992
#1992
Bored Apes XRP Club #2132
#2132
Bored Apes XRP Club #2217
#2217
Bored Apes XRP Club #2742
#2742
Bored Apes XRP Club #2969
#2969
Bored Apes XRP Club #2990
#2990
Bored Apes XRP Club #3138
#3138
Bored Apes XRP Club #3406
#3406
Bored Apes XRP Club #3428
#3428
Bored Apes XRP Club #3535
#3535
Bored Apes XRP Club #4217
#4217
Bored Apes XRP Club #4784
#4784
Bored Apes XRP Club #4791
#4791
Bored Apes XRP Club #4987
#4987
Bored Apes XRP Club #5282
#5282
Bored Apes XRP Club #5426
#5426
Bored Apes XRP Club #5832
#5832
Bored Apes XRP Club #6132
#6132
Bored Apes XRP Club #6364
#6364
Bored Apes XRP Club #6537
#6537
Bored Apes XRP Club #6692
#6692
Bored Apes XRP Club #6881
#6881
Bored Apes XRP Club #7113
#7113
Bored Apes XRP Club #8638
#8638
Bored Apes XRP Club #9263
#9263
Bored Apes XRP Club #9714
#9714
Bored Apes XRP Club #104
#104
Bored Apes XRP Club #263
#263
Bored Apes XRP Club #395
#395
Bored Apes XRP Club #686
#686
Bored Apes XRP Club #1147
#1147
Bored Apes XRP Club #1598
#1598
Bored Apes XRP Club #1858
#1858
Bored Apes XRP Club #2507
#2507
Bored Apes XRP Club #2715
#2715
Bored Apes XRP Club #3716
#3716
Bored Apes XRP Club #3984
#3984
Bored Apes XRP Club #4222
#4222
Bored Apes XRP Club #4548
#4548
Bored Apes XRP Club #5015
#5015
Bored Apes XRP Club #5084
#5084
Bored Apes XRP Club #5109
#5109
Bored Apes XRP Club #5538
#5538
Bored Apes XRP Club #5598
#5598
Bored Apes XRP Club #5604
#5604
Bored Apes XRP Club #5621
#5621
Bored Apes XRP Club #5681
#5681
Bored Apes XRP Club #5823
#5823
Bored Apes XRP Club #6347
#6347
Bored Apes XRP Club #6862
#6862
Bored Apes XRP Club #7093
#7093
Bored Apes XRP Club #7320
#7320
Bored Apes XRP Club #7330
#7330
Bored Apes XRP Club #7401
#7401
Bored Apes XRP Club #7402
#7402
Bored Apes XRP Club #7672
#7672
Bored Apes XRP Club #8035
#8035
Bored Apes XRP Club #8445
#8445
Bored Apes XRP Club #8521
#8521
Bored Apes XRP Club #9526
#9526
Bored Apes XRP Club #1947
#1947
Bored Apes XRP Club #2199
#2199
Bored Apes XRP Club #2842
#2842
Bored Apes XRP Club #2884
#2884
Bored Apes XRP Club #3905
#3905
Bored Apes XRP Club #4139
#4139
Bored Apes XRP Club #4669
#4669
Bored Apes XRP Club #4675
#4675
Bored Apes XRP Club #4902
#4902
Bored Apes XRP Club #5159
#5159
Bored Apes XRP Club #7490
#7490
Bored Apes XRP Club #7716
#7716
Bored Apes XRP Club #8288
#8288
Bored Apes XRP Club #8426
#8426
Bored Apes XRP Club #8435
#8435
Bored Apes XRP Club #490
#490
Bored Apes XRP Club #2044
#2044
Bored Apes XRP Club #2769
#2769
Bored Apes XRP Club #3250
#3250
Bored Apes XRP Club #3382
#3382
Bored Apes XRP Club #4409
#4409
Bored Apes XRP Club #5391
#5391
Bored Apes XRP Club #5529
#5529
Bored Apes XRP Club #5543
#5543
Bored Apes XRP Club #5578
#5578
Bored Apes XRP Club #6003
#6003
Bored Apes XRP Club #6762
#6762
Bored Apes XRP Club #7504
#7504
Bored Apes XRP Club #8568
#8568
Bored Apes XRP Club #3736
#3736
Bored Apes XRP Club #3874
#3874
Bored Apes XRP Club #4859
#4859
Bored Apes XRP Club #5269
#5269
Bored Apes XRP Club #5986
#5986
Bored Apes XRP Club #6584
#6584
Bored Apes XRP Club #6607
#6607
Bored Apes XRP Club #9566
#9566
Bored Apes XRP Club #2868
#2868
Bored Apes XRP Club #3474
#3474
Bored Apes XRP Club #3491
#3491
Bored Apes XRP Club #5234
#5234
Bored Apes XRP Club #5533
#5533
Bored Apes XRP Club #7800
#7800
Bored Apes XRP Club #8496
#8496
Bored Apes XRP Club #2562
#2562
Bored Apes XRP Club #3400
#3400
Bored Apes XRP Club #3767
#3767
Bored Apes XRP Club #6348
#6348
Bored Apes XRP Club #6669
#6669
Bored Apes XRP Club #6855
#6855
Bored Apes XRP Club #6903
#6903
Bored Apes XRP Club #416
#416
Bored Apes XRP Club #2629
#2629
Bored Apes XRP Club #4612
#4612
Bored Apes XRP Club #5061
#5061
Bored Apes XRP Club #5440
#5440
Bored Apes XRP Club #7493
#7493
Bored Apes XRP Club #9608
#9608
Bored Apes XRP Club #425
#425
Bored Apes XRP Club #2062
#2062
Bored Apes XRP Club #3756
#3756
Bored Apes XRP Club #4915
#4915
Bored Apes XRP Club #5326
#5326
Bored Apes XRP Club #7446
#7446
Bored Apes XRP Club #1203
#1203
Bored Apes XRP Club #1276
#1276
Bored Apes XRP Club #1590
#1590
Bored Apes XRP Club #2168
#2168
Bored Apes XRP Club #7546
#7546
Bored Apes XRP Club #25
#25
Bored Apes XRP Club #168
#168
Bored Apes XRP Club #537
#537
Bored Apes XRP Club #6203
#6203
Bored Apes XRP Club #7281
#7281
Bored Apes XRP Club #2914
#2914
Bored Apes XRP Club #7501
#7501
Bored Apes XRP Club #8854
#8854
Bored Apes XRP Club #9538
#9538
Bored Apes XRP Club #9832
#9832
Bored Apes XRP Club #2977
#2977
Bored Apes XRP Club #6467
#6467
Bored Apes XRP Club #6930
#6930
Bored Apes XRP Club #8745
#8745
Bored Apes XRP Club #8812
#8812
Bored Apes XRP Club #3848
#3848
Bored Apes XRP Club #5145
#5145
Bored Apes XRP Club #6861
#6861
Bored Apes XRP Club #8393
#8393
Bored Apes XRP Club #8826
#8826
Bored Apes XRP Club #259
#259
Bored Apes XRP Club #687
#687
Bored Apes XRP Club #1741
#1741
Bored Apes XRP Club #5005
#5005
Bored Apes XRP Club #9769
#9769
Bored Apes XRP Club #901
#901
Bored Apes XRP Club #1982
#1982
Bored Apes XRP Club #3648
#3648
Bored Apes XRP Club #6408
#6408
Bored Apes XRP Club #7963
#7963
Bored Apes XRP Club #2089
#2089
Bored Apes XRP Club #2494
#2494
Bored Apes XRP Club #3938
#3938
Bored Apes XRP Club #7676
#7676
Bored Apes XRP Club #8683
#8683
Bored Apes XRP Club #335
#335
Bored Apes XRP Club #489
#489
Bored Apes XRP Club #1275
#1275
Bored Apes XRP Club #6977
#6977
Bored Apes XRP Club #1860
#1860
Bored Apes XRP Club #2161
#2161
Bored Apes XRP Club #5421
#5421
Bored Apes XRP Club #5732
#5732
Bored Apes XRP Club #1382
#1382
Bored Apes XRP Club #1659
#1659
Bored Apes XRP Club #3576
#3576
Bored Apes XRP Club #6811
#6811
Bored Apes XRP Club #2752
#2752
Bored Apes XRP Club #4813
#4813
Bored Apes XRP Club #5078
#5078
Bored Apes XRP Club #6878
#6878
Bored Apes XRP Club #3087
#3087
Bored Apes XRP Club #3900
#3900
Bored Apes XRP Club #3920
#3920
Bored Apes XRP Club #7767
#7767
Bored Apes XRP Club #118
#118
Bored Apes XRP Club #1259
#1259
Bored Apes XRP Club #2740
#2740
Bored Apes XRP Club #8192
#8192
Bored Apes XRP Club #2050
#2050
Bored Apes XRP Club #2784
#2784
Bored Apes XRP Club #3216
#3216
Bored Apes XRP Club #5694
#5694
Bored Apes XRP Club #2296
#2296
Bored Apes XRP Club #4315
#4315
Bored Apes XRP Club #6021
#6021
Bored Apes XRP Club #6357
#6357
Bored Apes XRP Club #3461
#3461
Bored Apes XRP Club #6663
#6663
Bored Apes XRP Club #7173
#7173
Bored Apes XRP Club #8298
#8298
Bored Apes XRP Club #2698
#2698
Bored Apes XRP Club #5856
#5856
Bored Apes XRP Club #6005
#6005
Bored Apes XRP Club #6471
#6471
Bored Apes XRP Club #833
#833
Bored Apes XRP Club #2198
#2198
Bored Apes XRP Club #7605
#7605
Bored Apes XRP Club #7674
#7674
Bored Apes XRP Club #2564
#2564
Bored Apes XRP Club #5438
#5438
Bored Apes XRP Club #6175
#6175
Bored Apes XRP Club #7069
#7069

The ceremony record

These eleven values pin the whole ceremony. Everything else on this page — and every one of the 546 transfers — is a pure function of them.

Collectionissuer rEzbi191M5AjrucxXKZWbR5QeyfpbedBcV, taxon 1
DistributorrESvnQrpWVho8kEiHEVKXMBoiUzdkYVtDL
Snapshot ledger106676567
snapshotHashc6fa03cca4718f2207b595492795327b39e8dc0fb5fad923649baf4fd2086783
codeSha2567a7ed0330fa9fa9e5592859a8fc7c562c6eda55af31ab4d8c4b0ec7cd18836db
Commitmentb01c3a9f9b6bd9efa43acf118c7855cfc147dd5cdfad4f74502dd903a6167e93
Commitment tx52BECC0601879F136357F258FA3A14E3753A135D1C3FDB6DDEBA39A533F56FB1 — validated in ledger 106676857, 72 ledgers before the beacon
Beacon ledger106676929
Beacon ledger hash7ADFFDE4B1DBB3A4003EC6CC69374349CF2506327A3F6FA96F700C55452D5BBA
Seeded0700e7faa8051b68fa6ff15570bb07a4f6f4e6e68f35f186f2da7042068efd
transfersHashfb0e92ce51d4ff0b5d607760ec8f50ed15405d4bd766d46e9a4643e9c62229f4

The artifacts live in the open: snapshot.json (who held what), plan.json (all 546 transfers), and fairdrop.js (the algorithm — one dependency-free file whose SHA-256 is the codeSha256 above).

How the commitment locks the rules in advance

Before the beacon ledger existed, the distributor anchored a commitment on-chain: an AccountSet memo (type fairdrop/v1) whose data is the SHA-256 of this exact string — sorted keys, no whitespace:

{"beaconLedger":106676929,"codeSha256":"7a7ed0330fa9fa9e5592859a8fc7c562c6eda55af31ab4d8c4b0ec7cd18836db","snapshotHash":"c6fa03cca4718f2207b595492795327b39e8dc0fb5fad923649baf4fd2086783","version":"fairdrop-v2"}

Hash it and you get b01c3a9f9b6b…167e93— the memo's exact contents, validated in ledger 106676857 (52BECC0601879F136357F258FA3A14E3753A135D1C3FDB6DDEBA39A533F56FB1). That one memo binds three things at once: the exact holder snapshot, the exact code, and the exact entropy source — 72 ledgers before ledger 106676929 closed. Its hash was produced minutes later by the validator network, not by anyone running the drop. The operator could not know it, and after the commitment could no longer change the rules to suit it.

What the randomness decides — and what it cannot

The seed is SHA-256of the beacon ledger's hash (the 64-character uppercase hex string, hashed as ASCII). It feeds a counter stream: block i is SHA-256(seed ‖ i) with ia big-endian 64-bit counter, each block read as four 8-byte words, each word's top 53 bits divided by 2^53. That stream drives one Fisher–Yates shuffle of the 546 NFT ids (canonically sorted first, so database order cannot leak in), and the shuffled deck is dealt to winners in address order.

That is all it does. The randomness picks which specific apes land with which winner — so the operator cannot aim rare pieces at friends — but it cannot change who wins or how many anyone gets. The counts were fixed by the snapshot arithmetic before the seed existed. Anyone who re-runs the algorithm gets the identical 546 transfers: their canonical JSON hashes to the transfersHash above, byte for byte.

Verify it in one command

The verifier is dependency-free (Node 18+). It takes a few minutes, most of it re-sweeping the snapshot ledger — use --node to point it at any Clio server you trust:

git clone https://github.com/xrplto/bay-nft-airdrop && cd bay-nft-airdrop
sha256sum fairdrop.js   # must print 7a7ed0330fa9fa9e5592859a8fc7c562c6eda55af31ab4d8c4b0ec7cd18836db

node fairdrop.js verify --snapshot snapshot.json --plan plan.json \
    --node https://s2.ripple.com:51234/ \
    --commit-tx 52BECC0601879F136357F258FA3A14E3753A135D1C3FDB6DDEBA39A533F56FB1

It independently re-sweeps chain state at ledger 106676567 and reproduces snapshotHash; refetches the beacon hash and re-derives the seed; re-runs the algorithm and compares transfersHash; re-checks the allocation in exact rational arithmetic (floors, seat counts, sums, set equality, no self-transfers); and fetches the commitment memo to confirm it matches and validated before the beacon. Thirty-one checks; any failure is loud.

Check the two key hashes with nothing but Node

Don't want to run our code at all? The two load-bearing hashes take one line each.

1. The commitment

node -e 'const c=require("crypto");console.log(c.createHash("sha256").update(
JSON.stringify({beaconLedger:106676929,codeSha256:"7a7ed0330fa9fa9e5592859a8fc7c562c6eda55af31ab4d8c4b0ec7cd18836db",snapshotHash:"c6fa03cca4718f2207b595492795327b39e8dc0fb5fad923649baf4fd2086783",version:"fairdrop-v2"})
).digest("hex"))'
# → b01c3a9f9b6bd9efa43acf118c7855cfc147dd5cdfad4f74502dd903a6167e93

Compare that to the MemoData of 52BECC0601879F136357F258FA3A14E3753A135D1C3FDB6DDEBA39A533F56FB1 — fetch the transaction from any XRPL node and decode the memo hex.

2. The seed

curl -s https://s2.ripple.com:51234/ -d '{"method":"ledger","params":[{"ledger_index":106676929}]}'
# → ledger_hash 7ADFFDE4B1DBB3A4003EC6CC69374349CF2506327A3F6FA96F700C55452D5BBA

node -e 'const c=require("crypto");console.log(c.createHash("sha256").update(
"7ADFFDE4B1DBB3A4003EC6CC69374349CF2506327A3F6FA96F700C55452D5BBA").digest("hex"))'
# → ed0700e7faa8051b68fa6ff15570bb07a4f6f4e6e68f35f186f2da7042068efd

Any full-history node returns the same ledger_hash — it is consensus state, not our data.

Two commitments are on-chain — here is why

The distributor's memo history shows an earlier fairdrop/v1 commitment (66519E745E17F9881288C3EF797F26223ED9E08960DC5DBEB05AED1007011CC0, beacon 106677699, anchored in ledger 106676707). It was superseded by the final commitment to move the beacon from about an hour out to about five minutes out. The switch was decided, anchored and published before either beacon ledger validated — neither hash existed yet — so no draw was ever observed and discarded. Cherry-picking requires seeing at least one outcome; here there was never an outcome to see. Both memos are permanent public record, and the published plan binds only the final one. Same snapshot, same code, in both.

The operator log, as it happened

The ceremony ran live on 2026-08-31, and these are verbatim, timestamped excerpts from its session log — every on-chain fact (transaction hashes, ledgers, sequences, engine results) untouched and checkable against the chain. What is trimmed is internal tooling: infrastructure hostnames, file paths and operator plumbing are redacted or generalized, because a fairness proof should expose the ceremony, not the stack it ran on. Nothing removed changes a single verifiable claim.

Anchoring the commitment — twice

The first commitment set the beacon about an hour out. It was superseded minutes later by a commitment to a nearer beacon — before either beacon ledger validated, so no draw was ever observed. Both anchors, verbatim:

2026-08-31T23:05:43.984Z [execute] signing for rESvnQrpWVho8kEiHEVKXMBoiUzdkYVtDL via on-chain RegularKey rEXYhWuhUatbscRtxVv7PNSrGNUeym3dPm
2026-08-31T23:05:44.729Z [execute] commitment 8fd5185e08e997acc7ab84e31f44be04965f7572f7a2ae7907ff2b87411957df (beacon ledger 106677699)
2026-08-31T23:05:51.018Z [execute] commitment ANCHORED in ledger 106676707 — 992 ledgers before the beacon. Save this tx hash for verify --commit-tx.
--- superseded by ---
2026-08-31T23:15:21.557Z [execute] beacon margin: 74 ledgers (~5 min) — the memo must validate before that
2026-08-31T23:15:21.557Z [execute] commitment b01c3a9f9b6bd9efa43acf118c7855cfc147dd5cdfad4f74502dd903a6167e93 (beacon ledger 106676929)
2026-08-31T23:15:22.105Z [execute] submit seq=75482022 AccountSet: tesSUCCESS (52BECC0601879F136357F258FA3A14E3753A135D1C3FDB6DDEBA39A533F56FB1)
2026-08-31T23:15:29.727Z [execute] validated 52BECC0601879F136357F258FA3A14E3753A135D1C3FDB6DDEBA39A533F56FB1 in ledger 106676857: tesSUCCESS
2026-08-31T23:15:29.727Z [execute] commitment ANCHORED in ledger 106676857 — 72 ledgers before the beacon. Save this tx hash for verify --commit-tx.

Waiting for randomness to exist

A supervised one-shot process polled the validated ledger until the beacon closed:

2026-08-31T23:15:42.086Z [ceremony] ceremony start: beacon=106676929 commitTx=52BECC0601879F136357F258FA3A14E3753A135D1C3FDB6DDEBA39A533F56FB1
2026-08-31T23:17:42.124Z [ceremony] waiting for beacon: validated 106676891, 38 ledgers to go (~3 min)
2026-08-31T23:18:42.129Z [ceremony] waiting for beacon: validated 106676907, 22 ledgers to go (~1 min)
2026-08-31T23:20:42.140Z [ceremony] BEACON REACHED: validated 106676938

Plan — one second of math

The beacon hash became the seed; the full allocation followed deterministically:

2026-08-31T23:20:42.140Z [ceremony] RUN node fairdrop.js plan --snapshot snapshot.json --beacon-ledger 106676929
[fairdrop] beacon ledger 106676929 hash 7ADFFDE4B1DBB3A4003EC6CC69374349CF2506327A3F6FA96F700C55452D5BBA
[fairdrop] seed ed0700e7faa8051b68fa6ff15570bb07a4f6f4e6e68f35f186f2da7042068efd
[fairdrop] 546 nfts -> 294/1767 holders (whole shares=277, largest-remainder seats=269)
[fairdrop] transfersHash fb0e92ce51d4ff0b5d607760ec8f50ed15405d4bd766d46e9a4643e9c62229f4
2026-08-31T23:20:42.956Z [ceremony] PLAN DONE

The verify gate

Distribution was gated on the full independent re-verification — 31 checks including the chain resweep and the on-chain commitment:

2026-08-31T23:20:42.956Z [ceremony] RUN node fairdrop.js verify --snapshot snapshot.json --plan plan.json --commit-tx 52BECC0601879F136357F258FA3A14E3753A135D1C3FDB6DDEBA39A533F56FB1
PASS  snapshot reproducible from chain at pinned ledger  [rebuilt=c6fa03cca4718f22...]
PASS  transfers reproduce exactly from the seed  [rebuilt=fb0e92ce51d4ff0b...]
PASS  commitment memo matches sha256(snapshot,code,beaconLedger)
PASS  commitment validated BEFORE beacon ledger  [commit@106676857 beacon@106676929]
ALL PASS — plan is fully reproducible from public data
2026-08-31T23:21:22.297Z [ceremony] VERIFY ALL PASS — distributing

Distribution

Each batch of eight offers was submitted with consecutive sequences and polled to final validation before the next. Two node failures hit the run, and the design absorbed both. First the public node throttled the pre-scan (HTTP 503s); the executor was restarted against a full-history endpoint, found the eight offers already in flight validated on-chain, and skipped them. Late in the run that endpoint also began returning sustained 503s on validation lookups — after six retries per call the executor failed LOUDLY rather than assume, and exited. Every submitted offer was already validated on-chain: the second restart found 488 live offers, created the remaining 58, and the final audit matched all 546. terPRE_SEQ is XRPL’s retry class (an upstream that had not yet seen the preceding sequence); every such hold resolved to tesSUCCESS. Two node failures, zero lost transactions, zero wrong destinations.

2026-08-31T23:25:05.789Z [ceremony] resume: distributing via our own full-history endpoint (8 offers already on-chain, executor skips them)
2026-08-31T23:25:25.849Z [execute] plan=546 already-offered=8 already-claimed=0 to-create=538
2026-08-31T23:25:25.964Z [execute] submit seq=75482031 NFTokenCreateOffer nft…00000A9C -> r3WfR3u4yahorGBiSnfTE3SABxLYQtNyoo: tesSUCCESS (B0FD5CB2ECEF81086B2B29FC496235AF6028101DBEB66B8CAE533CD3803FBB07)
2026-08-31T23:26:07.478Z [execute] submit seq=75482040 NFTokenCreateOffer nft…00001A61 -> r3idziPApkZBJmnGq2LtvP5Skrti9uDaCx: terPRE_SEQ (0B4850C3EC85380BBE504EAB5750EEF27A87F49EE3F5ABBDD874F79D116AA94C)
2026-08-31T23:26:15.682Z [execute] validated 0B4850C3EC85380BBE504EAB5750EEF27A87F49EE3F5ABBDD874F79D116AA94C in ledger 106677024: tesSUCCESS
2026-08-31T23:44:02.957Z [execute] progress: 296/538 processed (296 ok)
2026-08-31T23:50:24.171Z [execute] progress: 464/538 processed (464 ok)
2026-08-31T23:52:24.828Z [execute] rpc tx attempt 5/6 failed (http 503) — retrying
2026-08-31T23:54:37.248Z [ceremony] CEREMONY FAILED during distribution — executor is idempotent, restart this process to resume
2026-08-31T23:55:53.648Z [ceremony] resume 2: finishing distribution via the local node (validation polling on the previous endpoint hit sustained 503s; all submitted offers are on-chain)
2026-08-31T23:55:53.834Z [execute] plan=546 already-offered=488 already-claimed=0 to-create=58
created=58 skipped(offer)=488 skipped(claimed)=0 failed=0
2026-08-31T23:56:46.760Z [ceremony] DISTRIBUTION DONE
offers matching plan: 546/546
already claimed     : 0
missing offers      : 0
wrong-destination   : 0
2026-08-31T23:57:17.745Z [ceremony] CEREMONY COMPLETE

How the NFTs actually move

XLS-20 cannot force-push an NFT into a wallet, so each transfer is a zero-cost sell offer locked to its winner: NFTokenCreateOffer with Amount "0", the tfSellNFToken flag, and Destinationset to the winner's address. Only that address can accept it — a wrong recipient cannot claim someone else's ape even in principle. Winners accept the offer in any XRPL wallet; node fairdrop.js audit-offers --plan plan.json checks that every planned transfer has its matching offer or has already been claimed on-chain.

What this does not prove

Honest limits, so the claim stays exactly as strong as it is. Beacon influence: a participant who lands transactions in the beacon ledger can influence (not choose) its hash; for deciding which ape goes to which winner the attack buys nothing worth its cost, but a high-stakes draw should use a drand round instead — the commit/verify flow is identical. The snapshot is a moment: wallets that bought after ledger 106676567 are not in this draw; the ledger index was published precisely so that is checkable. Claims are voluntary: an offer sits until its winner accepts it, and offers left unclaimed long-term may be cancelled — the plan, not the claim rate, is what the ceremony fixes.