Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
340 commits
Select commit Hold shift + click to select a range
5839100
fix(sdk): give a private page reader's context provider the contract …
QuantumExplorer Nov 8, 2026
be7fba8
feat(sdk): stream a private document store's pages, many fetched at once
QuantumExplorer Nov 8, 2026
b5e2eb2
Merge branch 'feat/sdk-private-documents-send-and-scan' into feat/pla…
QuantumExplorer Nov 8, 2026
f479c94
perf(platform-wallet): read the private contact request store many pa…
QuantumExplorer Nov 8, 2026
76c5418
feat(platform-wallet): keep the private contact request read position…
QuantumExplorer Nov 8, 2026
d5db080
fix(platform-wallet): claim a contact pair for a public request as a …
QuantumExplorer Nov 8, 2026
3698f6a
fix(platform-wallet): read the private store again when an identity's…
QuantumExplorer Nov 8, 2026
f7761d0
fix(platform-wallet): release a private reservation until its payment…
QuantumExplorer Nov 8, 2026
1ebd255
fix(platform-wallet): release a private reservation once its payment …
QuantumExplorer Nov 8, 2026
3012b4e
fix(platform-wallet): save a private payment's signed transition befo…
QuantumExplorer Nov 8, 2026
0a3b859
fix(platform-wallet): adopt a reply another accept recorded once the …
QuantumExplorer Nov 8, 2026
b8e41ab
fix(sdk): refuse a private document read below protocol version 15 as…
QuantumExplorer Nov 8, 2026
8950232
Merge branch 'feat/sdk-private-documents-send-and-scan' into feat/pla…
QuantumExplorer Nov 8, 2026
afc6b7e
fix(platform-wallet): hold a contact pair across a restart before any…
QuantumExplorer Nov 8, 2026
d91c1c6
fix(sdk): name the SDK's protocol version when building a private doc…
QuantumExplorer Nov 8, 2026
0e3f521
fix(wasm-dpp2): refuse tokens set on a data contract that holds none
QuantumExplorer Nov 8, 2026
3f546c0
docs(dpp): say at the batch signing levels why the in-place change ke…
QuantumExplorer Nov 8, 2026
e710dd7
docs(sdk): say what the private contact request parser and signing le…
QuantumExplorer Nov 8, 2026
454f25c
test(sdk): check a recipient key holding another point is refused by …
QuantumExplorer Nov 8, 2026
3b68903
test(sdk): pin a private page stream's order and its cursor under a g…
QuantumExplorer Nov 8, 2026
898e8fc
fix(sdk): keep the store a private document scan was read from, and r…
QuantumExplorer Nov 8, 2026
fa18256
Merge branch 'feat/sdk-private-documents-send-and-scan' into feat/pla…
QuantumExplorer Nov 8, 2026
91d8782
fix(sdk): send a private document transition only once the network is…
QuantumExplorer Nov 9, 2026
19ab417
fix(sdk): keep each outgoing viewing key in place as scan senders are…
QuantumExplorer Nov 9, 2026
75cd978
Merge branch 'feat/sdk-private-documents-send-and-scan' into feat/pla…
QuantumExplorer Nov 9, 2026
59e047a
fix(sdk): learn a private store's chunk size only from a page that en…
QuantumExplorer Nov 9, 2026
314d957
fix(sdk): refuse a private contact request scan of a contract whose t…
QuantumExplorer Nov 9, 2026
f98c1bd
Merge branch 'feat/sdk-private-documents-send-and-scan' into feat/pla…
QuantumExplorer Nov 9, 2026
dcc0b15
fix(platform-wallet): mark a private payment started only once its re…
QuantumExplorer Nov 9, 2026
d15c5c9
fix(platform-wallet): release a dropped spend's notes until the spend…
QuantumExplorer Nov 9, 2026
0dc72a0
fix(platform-wallet): take private payment rejection notices only und…
QuantumExplorer Nov 9, 2026
757474b
fix(platform-wallet): skip the private store read only on a network v…
QuantumExplorer Nov 9, 2026
ea2a66b
feat(platform-wallet-ffi): scan the private contact request store thr…
QuantumExplorer Nov 9, 2026
df8cba5
fix(platform-wallet): release a public request's claim only by the at…
QuantumExplorer Nov 9, 2026
6c3abe0
fix(platform-wallet): drop a private contact request association with…
QuantumExplorer Nov 9, 2026
e11ef7c
fix(sdk): keep a newer contract over a registered older one
QuantumExplorer Nov 9, 2026
856fd6b
Merge branch 'feat/sdk-private-documents-send-and-scan' into feat/pla…
QuantumExplorer Nov 9, 2026
c33583a
fix(platform-wallet): read the private store again before a send once…
QuantumExplorer Nov 9, 2026
efa0fc8
fix(sdk): complete a private store chunk an older snapshot ended part…
QuantumExplorer Nov 9, 2026
baa3092
fix(sdk): gate every type 29 broadcast and refuse it with the structu…
QuantumExplorer Nov 9, 2026
40e4f57
fix(sdk): keep a newer contract in the gRPC context provider, and say…
QuantumExplorer Nov 9, 2026
f7fcc44
fix(sdk): report an identity proved before its entry as a retryable s…
QuantumExplorer Nov 9, 2026
a35fe84
Merge branch 'feat/sdk-private-documents-send-and-scan' into feat/pla…
QuantumExplorer Nov 9, 2026
7ac0059
Merge remote-tracking branch 'origin/feat/platform-wallet-private-con…
QuantumExplorer Nov 9, 2026
9640e70
fix(platform-wallet-ffi): keep a wallet removed before a private paym…
QuantumExplorer Nov 9, 2026
df84f92
feat(platform-wallet-ffi,swift-sdk): persist the private contact requ…
QuantumExplorer Nov 9, 2026
62169d3
fix(swift-example-app): keep a failed pending read apart from nothing…
QuantumExplorer Nov 9, 2026
c490a27
Merge branch 'feat/ffi-swift-private-contact-requests' into feat/kotl…
QuantumExplorer Nov 9, 2026
aa341f9
feat(kotlin-sdk,unified-sdk-jni): persist the private contact request…
QuantumExplorer Nov 9, 2026
bb6b8ec
docs(kotlin-sdk): attach the in-kind accept KDoc to its declaration
QuantumExplorer Nov 9, 2026
8dd88f8
fix(kotlin-example-app): keep a failed pending read apart from nothin…
QuantumExplorer Nov 9, 2026
342162b
feat(swift-example-app): show the private contact request scan state …
QuantumExplorer Nov 9, 2026
d5519cd
Merge branch 'feat/ffi-swift-private-contact-requests' into feat/kotl…
QuantumExplorer Nov 9, 2026
0efc887
chore(kotlin-sdk): export Room schema 16
QuantumExplorer Nov 9, 2026
808bb9b
docs(sdk): record the private contact request scan state in the parit…
QuantumExplorer Nov 9, 2026
31d393e
test(kotlin-sdk): expect Room schema 16 in the schema version test
QuantumExplorer Nov 9, 2026
b065ca3
fix(sdk): read a private contact request under an eligible alias of i…
QuantumExplorer Nov 9, 2026
4712db7
fix(sdk): fetch again a private page an older snapshot left empty, th…
QuantumExplorer Nov 9, 2026
8558e83
feat(sdk): schedule a private store's page walk from the chunk size i…
QuantumExplorer Nov 9, 2026
fdc50a2
Merge branch 'feat/sdk-private-documents-send-and-scan' into feat/pla…
QuantumExplorer Nov 9, 2026
8079cb8
feat(platform-wallet-ffi): give the private contact request outcomes …
QuantumExplorer Nov 9, 2026
e3654c2
fix(platform-wallet): wipe a private request's sealing seed when its …
QuantumExplorer Nov 9, 2026
8f7088b
docs(platform-wallet): note the ShieldedStore 'static bound in the AP…
QuantumExplorer Nov 9, 2026
e37af8e
fix(platform-wallet): keep a failed spend's notes in its guard until …
QuantumExplorer Nov 9, 2026
d768705
fix(platform-wallet): keep a private payment's rejection for the sess…
QuantumExplorer Nov 9, 2026
cc6fef5
fix(platform-wallet): hold a reloaded wallet's public contact request…
QuantumExplorer Nov 9, 2026
a3a7fc4
fix(platform-wallet): refuse a private contact request pass whose pro…
QuantumExplorer Nov 9, 2026
4386ec0
docs(sdk): say that a private request's key expiry is the identity's …
QuantumExplorer Nov 9, 2026
2b5e86f
Merge remote-tracking branch 'origin/feat/sdk-private-documents-send-…
QuantumExplorer Nov 9, 2026
41e6048
Merge remote-tracking branch 'origin/feat/platform-wallet-private-con…
QuantumExplorer Nov 9, 2026
5166952
test(platform-wallet-ffi): pin the layouts of the private contact req…
QuantumExplorer Nov 9, 2026
26bdbf7
fix(platform-wallet-ffi): require contact persistence for the private…
QuantumExplorer Nov 9, 2026
17ffe98
fix(platform-wallet-ffi): keep protocol-version refusals typed throug…
QuantumExplorer Nov 9, 2026
0f884bc
fix(platform-wallet-ffi): report a seed mismatch from the private sto…
QuantumExplorer Nov 9, 2026
7e93663
fix(swift-sdk): fail a scan-state load on a stored row that cannot cr…
QuantumExplorer Nov 9, 2026
490128a
docs(swift-sdk): describe the restored private scan state and pending…
QuantumExplorer Nov 9, 2026
289829a
fix(swift-example-app): configure the shielded store right after the …
QuantumExplorer Nov 9, 2026
edc9dd1
fix(swift-example-app): keep a code 71 refusal visible until a privat…
QuantumExplorer Nov 9, 2026
911ef5c
Merge branch 'feat/ffi-swift-private-contact-requests' into feat/kotl…
QuantumExplorer Nov 9, 2026
4f2b553
fix(kotlin-sdk): fail a scan-state load on a stored row that cannot c…
QuantumExplorer Nov 9, 2026
622677c
fix(unified-sdk-jni): tie the scan-state slots to contact persistence…
QuantumExplorer Nov 9, 2026
69c8310
docs(kotlin-sdk): describe the restored private scan state and pendin…
QuantumExplorer Nov 9, 2026
f0d7c95
fix(kotlin-example-app): configure the shielded store right after the…
QuantumExplorer Nov 9, 2026
6b3c4d4
fix(kotlin-example-app): keep a code 71 refusal visible until a priva…
QuantumExplorer Nov 9, 2026
4763d41
docs(sdk): note the scan-state load and contact dependency in the par…
QuantumExplorer Nov 9, 2026
f9d669f
fix(sdk-trusted-context-provider): keep a newer known contract over a…
QuantumExplorer Nov 9, 2026
311ae62
fix(sdk): keep a failed refresh as the cause of a private document se…
QuantumExplorer Nov 9, 2026
4e75e27
fix(sdk): read a private page against a newer contract with the type …
QuantumExplorer Nov 9, 2026
235a4f8
fix(sdk): take the network as proven below a version only on a curren…
QuantumExplorer Nov 9, 2026
03cea26
Merge branch 'feat/sdk-private-documents-send-and-scan' into feat/pla…
QuantumExplorer Nov 9, 2026
5a91dc7
fix(platform-wallet-ffi): keep a missing mnemonic as key-unavailable …
QuantumExplorer Nov 9, 2026
4c81017
fix(platform-wallet): hold an identity reloaded with an unresolved pr…
QuantumExplorer Nov 9, 2026
91678f5
feat(platform-wallet-ffi): report unrestored private payments by thei…
QuantumExplorer Nov 9, 2026
ecf621d
docs(wasm-sdk): say that a registration keeps a held contract of a hi…
QuantumExplorer Nov 9, 2026
0dc274c
fix(sdk): ask the protocol gate before refusing a private document send
QuantumExplorer Nov 9, 2026
9b8589a
test(drive-abci): export a protocol 15 epoch probe for the SDK's gate…
QuantumExplorer Nov 9, 2026
50658b5
fix(sdk): establish protocol 15 through the gate for DashPay's privat…
QuantumExplorer Nov 9, 2026
c7502c4
Merge branch 'feat/sdk-private-documents-send-and-scan' into feat/pla…
QuantumExplorer Nov 9, 2026
e027e23
Merge remote-tracking branch 'origin/feat/platform-wallet-private-con…
QuantumExplorer Nov 9, 2026
0b28e29
feat(platform-wallet-ffi): carry the unresolved private payment marke…
QuantumExplorer Nov 9, 2026
f75b945
feat(swift-sdk): store the unresolved private payment marker with the…
QuantumExplorer Nov 9, 2026
afbe1d6
feat(swift-sdk): type code 72 and read the wallet's private contact r…
QuantumExplorer Nov 9, 2026
7405033
fix(swift-example-app): show restoring private payments from the wall…
QuantumExplorer Nov 9, 2026
27f1a69
feat(platform-wallet-ffi): compute a host's effective persistence cap…
QuantumExplorer Nov 9, 2026
30b515d
Merge branch 'feat/ffi-swift-private-contact-requests' into feat/kotl…
QuantumExplorer Nov 9, 2026
c69b549
feat(kotlin-sdk,unified-sdk-jni): store the unresolved private paymen…
QuantumExplorer Nov 9, 2026
ab77510
feat(kotlin-sdk,unified-sdk-jni): type code 72 and read the wallet's …
QuantumExplorer Nov 9, 2026
c67ac29
fix(kotlin-example-app): show restoring private payments from the wal…
QuantumExplorer Nov 9, 2026
c5ccf42
test(kotlin-sdk): exercise the scan-state overrides and gate shielded…
QuantumExplorer Nov 9, 2026
7bc3a03
docs(sdk): record code 72 and the readiness getter in the parity mani…
QuantumExplorer Nov 9, 2026
3deebd5
fix(platform-wallet): fail a private payment restore closed on a save…
QuantumExplorer Nov 9, 2026
8cdeadf
fix(platform-wallet): match a recovered private request's recipient k…
QuantumExplorer Nov 9, 2026
8260a1c
fix(platform-wallet): keep a private payment's hold durable, required…
QuantumExplorer Nov 9, 2026
8738c02
Merge remote-tracking branch 'origin/feat/platform-wallet-private-con…
QuantumExplorer Nov 9, 2026
5007b7b
fix(platform-wallet-ffi): keep the private scan state only under the …
QuantumExplorer Nov 9, 2026
530b5c7
test(platform-wallet-ffi): run the accept replying in kind for a mana…
QuantumExplorer Nov 9, 2026
84c2b96
feat(platform-version): double a private document store's chunk targe…
QuantumExplorer Nov 9, 2026
5af46f3
fix(swift-sdk): fail the round when a contact request cannot be stored
QuantumExplorer Nov 9, 2026
63e1ca4
feat(swift-sdk): type code 73 and show it as a storage configuration …
QuantumExplorer Nov 9, 2026
b9fa87e
Merge branch 'feat/ffi-swift-private-contact-requests' into feat/kotl…
QuantumExplorer Nov 9, 2026
46bd798
fix(kotlin-sdk): fail the round when a contact request cannot be stored
QuantumExplorer Nov 9, 2026
3d82b5f
feat(kotlin-sdk): type code 73 and show it as a storage configuration…
QuantumExplorer Nov 9, 2026
f0c3ada
test(kotlin-sdk): require atomic changesets with the scan state in th…
QuantumExplorer Nov 9, 2026
47c02cb
docs(kotlin-sdk): attach the pending-replies KDoc to privateRepliesPe…
QuantumExplorer Nov 9, 2026
2abc9b5
docs(sdk): record code 73 and the atomic requirement in the parity ma…
QuantumExplorer Nov 9, 2026
b2af518
Merge remote-tracking branch 'origin/feat/sdk-private-documents-send-…
QuantumExplorer Nov 9, 2026
27e4173
fix(platform-wallet): fail a private payment restore on a saved trans…
QuantumExplorer Nov 9, 2026
f2b9c7d
fix(platform-wallet): keep a private contact payment reserved through…
QuantumExplorer Nov 9, 2026
d6279b0
fix(platform-wallet-ffi): report an unsupported private recovery by i…
QuantumExplorer Nov 9, 2026
acb98eb
fix(platform-wallet): free a pair rejected for good on the next priva…
QuantumExplorer Nov 9, 2026
194acb9
Merge remote-tracking branch 'origin/v5.1-dev' into feat/platform-wal…
QuantumExplorer Nov 9, 2026
2aefc16
Merge remote-tracking branch 'origin/feat/platform-wallet-private-con…
QuantumExplorer Nov 9, 2026
f7a1204
test(drive-abci): expect DashPay v3's private store at chunk power 10…
QuantumExplorer Nov 9, 2026
1de0d4b
Merge remote-tracking branch 'origin/feat/platform-wallet-private-con…
QuantumExplorer Nov 9, 2026
47468fa
docs(platform-wallet-ffi): the readiness getter consumes rejection no…
QuantumExplorer Nov 9, 2026
b4b976f
Merge remote-tracking branch 'origin/v5.1-dev' into feat/platform-wal…
QuantumExplorer Nov 9, 2026
4f3bd84
fix(platform-wallet): hold private contact request pairs from a durab…
QuantumExplorer Nov 9, 2026
1fb46dd
fix(platform-wallet-ffi): report a broadcast that may have been deliv…
QuantumExplorer Nov 9, 2026
3ad51a3
docs(platform-wallet): describe the private payment journal and maybe…
QuantumExplorer Nov 9, 2026
e312365
fix(platform-wallet): own note reservations by attempt, and save a pr…
QuantumExplorer Nov 9, 2026
a1748d9
fix(platform-wallet): replay the last private payment marker, and flu…
QuantumExplorer Nov 9, 2026
94b4c83
fix(platform-wallet-ffi): keep code 70 for genuine protocol-version r…
QuantumExplorer Nov 9, 2026
360fb00
test(platform-wallet): restore a saved private payment in both startu…
QuantumExplorer Nov 9, 2026
c16c01b
Merge remote-tracking branch 'origin/v5.1-dev' into feat/platform-wal…
QuantumExplorer Nov 9, 2026
26de923
fix(drive): drop the argument #5798 removed from add_document_for_con…
QuantumExplorer Nov 9, 2026
8728bcd
test(platform-wallet): rebind identically while a scan holds the shie…
QuantumExplorer Nov 9, 2026
1b3a37b
Merge branch 'v5.1-dev' into feat/platform-wallet-private-contact-req…
QuantumExplorer Nov 9, 2026
5c99f46
fix(platform-wallet): count no endpoint verdict as proof a shielded s…
QuantumExplorer Nov 9, 2026
94452e6
fix(platform-wallet): keep a stale restoration from reserving a disch…
QuantumExplorer Nov 9, 2026
2197ec6
fix(platform-wallet): bind a public contact request to its wallet gen…
QuantumExplorer Nov 9, 2026
8ede791
fix(platform-wallet): discharge a private payment proven expired and …
QuantumExplorer Nov 9, 2026
ac4459a
feat(sdk): stream private document pages with their proved heights
QuantumExplorer Nov 9, 2026
d0d337b
fix(sdk): give a completed private document page the lowest height of…
QuantumExplorer Nov 9, 2026
0996db2
feat(sdk): let the mock SDK report a chosen response height
QuantumExplorer Nov 9, 2026
ad25184
fix(platform-wallet): prove a private payment expired only on evidenc…
QuantumExplorer Nov 9, 2026
c81424f
fix(platform-wallet): restore a private payment's reservation through…
QuantumExplorer Nov 9, 2026
f7510b4
fix(platform-wallet): retire a never-delivered payment's record and j…
QuantumExplorer Nov 9, 2026
0e24035
fix(platform-wallet): discharge an expired private payment whose inpu…
QuantumExplorer Nov 9, 2026
92569e7
feat(sdk): let the mock SDK prove each response type at its own height
QuantumExplorer Nov 9, 2026
e5f8ed9
fix(platform-wallet): release a stranded note only on height-pinned p…
QuantumExplorer Nov 9, 2026
6789d60
fix(platform-wallet): publish a never-delivered payment's retirement …
QuantumExplorer Nov 9, 2026
5ff0302
refactor(platform-wallet): keep an unknown journal anchor height as N…
QuantumExplorer Nov 9, 2026
17497a4
fix(platform-wallet): hold an unresolved private payment's pair at th…
QuantumExplorer Nov 9, 2026
cce059d
docs(platform-wallet): tell a pinned SDK's refusal apart and list eve…
QuantumExplorer Nov 9, 2026
98aa2f2
test(platform-wallet-ffi): cover a pinned refusal with a cause and a …
QuantumExplorer Nov 9, 2026
5cf6cab
fix(platform-wallet): keep no read-back set without shielded, and syn…
QuantumExplorer Nov 9, 2026
6d0f2e9
fix(platform-wallet): free notes an earlier process reserved before a…
QuantumExplorer Nov 9, 2026
ac533fd
perf(platform-wallet): read the private store no more for an entry an…
QuantumExplorer Nov 9, 2026
7e11255
fix(platform-wallet): keep a restored wallet available on a busy rebi…
QuantumExplorer Nov 9, 2026
0754c4e
fix(platform-wallet): leave the lifecycle gate clear while the host s…
QuantumExplorer Nov 9, 2026
ea35875
fix(platform-wallet): free the deferred restore queue however its tas…
QuantumExplorer Nov 9, 2026
5987ecb
fix(platform-wallet): read the private store before a public send's l…
QuantumExplorer Nov 9, 2026
d5448b6
test(platform-wallet): resolve a pair's wallet-level hold through the…
QuantumExplorer Nov 9, 2026
2e94b35
docs(platform-wallet): list the attempt-owned reservation methods for…
QuantumExplorer Nov 9, 2026
2191099
fix(platform-wallet): hold an absent sender's pair through the commit…
QuantumExplorer Nov 9, 2026
863cf9c
test(platform-wallet): write the absent-sender test's identity change…
QuantumExplorer Nov 9, 2026
7d053ca
fix(platform-wallet): refuse removing an identity while its contact r…
QuantumExplorer Nov 9, 2026
a2630b2
feat(platform-wallet): keep the largest commitment tree the shielded …
QuantumExplorer Nov 9, 2026
192d5d8
fix(platform-wallet): prove a heightless anchor recorded by the pool'…
QuantumExplorer Nov 9, 2026
5d2084f
docs(platform-wallet): describe how heightless anchor records are rel…
QuantumExplorer Nov 9, 2026
e0f384f
fix(platform-wallet): store the private payment marker whenever it di…
QuantumExplorer Nov 9, 2026
c4e2f3a
fix(platform-wallet): refresh the sender's keys from a proved fetch b…
QuantumExplorer Nov 9, 2026
cecf62f
fix(platform-wallet): decide a public request only with keys proved a…
QuantumExplorer Nov 9, 2026
c22910b
fix(sdk): yield the lowest and highest proved heights of a private do…
QuantumExplorer Nov 10, 2026
5466247
fix(platform-wallet): keep read-back notices whose flush failed until…
QuantumExplorer Nov 10, 2026
9d385c7
fix(platform-wallet): count a rewound private store read only once it…
QuantumExplorer Nov 10, 2026
fbb4d36
fix(platform-wallet): flush read-back notices without holding their lock
QuantumExplorer Nov 10, 2026
d4d55bd
fix(platform-wallet): raise a private store read's height only by pag…
QuantumExplorer Nov 10, 2026
94d81d1
fix(platform-wallet): hold a re-created wallet's journaled private pa…
QuantumExplorer Nov 10, 2026
98b9174
Merge branch 'v5.1-dev' into feat/platform-wallet-private-contact-req…
QuantumExplorer Nov 10, 2026
23ee059
fix(platform-wallet): read the store before every contact request and…
QuantumExplorer Nov 10, 2026
aa0e2a2
fix(platform-wallet): sync the shielded recovery records to the drive…
QuantumExplorer Nov 10, 2026
c7606fc
fix(platform-wallet): drop read-back notices a backend lost and disch…
QuantumExplorer Nov 10, 2026
9b5df14
test(platform-wallet): cover forged entries, the expiry's start posit…
QuantumExplorer Nov 10, 2026
83d86fa
test(platform-wallet): cover the restoration retry before a send, its…
QuantumExplorer Nov 10, 2026
ebb0464
test(platform-wallet): cover the re-check after publication, the firs…
QuantumExplorer Nov 10, 2026
e53aa68
docs(platform-wallet): describe the wallet hold, the tail read and co…
QuantumExplorer Nov 10, 2026
4a0707b
test(platform-wallet): import the journal record type once in the pri…
QuantumExplorer Nov 10, 2026
ddcb8bd
fix(platform-wallet): discharge no settled journal record after a flu…
QuantumExplorer Nov 10, 2026
6033d65
docs(platform-wallet): name the two scan state capability bits plainly
QuantumExplorer Nov 10, 2026
df49dbe
Merge remote-tracking branch 'origin/feat/platform-wallet-private-con…
QuantumExplorer Nov 10, 2026
b3fb933
feat(platform-wallet-ffi): read a pair's hold as a send decides it, a…
QuantumExplorer Nov 10, 2026
7810485
feat(swift-sdk): type codes 74 and 75, read a pair's hold and the res…
QuantumExplorer Nov 10, 2026
9a5892b
feat(swift-example-app): open the shielded store at activation and sh…
QuantumExplorer Nov 10, 2026
5ac4e8c
Merge remote-tracking branch 'origin/feat/ffi-swift-private-contact-r…
QuantumExplorer Nov 10, 2026
50414f2
feat(sdk): bind the pair-hold read and restore failure in Kotlin, typ…
QuantumExplorer Nov 10, 2026
67d8c7e
feat(kotlin-example-app): open the shielded store at activation and s…
QuantumExplorer Nov 10, 2026
94ca8db
docs(sdk): record the pair-hold read, the restore failure and codes 7…
QuantumExplorer Nov 10, 2026
f95f634
fix(platform-wallet): keep journal records a lost flush left, carry t…
QuantumExplorer Nov 10, 2026
2fd3599
fix(platform-wallet-ffi): read the private contact readiness outside …
QuantumExplorer Nov 10, 2026
f6b2a90
Merge remote-tracking branch 'origin/feat/platform-wallet-private-con…
QuantumExplorer Nov 10, 2026
034b73d
fix(platform-wallet): save shielded spend records before broadcast an…
QuantumExplorer Nov 10, 2026
cfe7c1f
Merge branch 'v5.1-dev' into feat/platform-wallet-private-contact-req…
QuantumExplorer Nov 10, 2026
8eb1e3e
feat(platform-wallet-ffi): hand marked scan state records back as ret…
QuantumExplorer Nov 10, 2026
41fbbef
feat(swift-sdk): keep marked scan state records through a wallet's pu…
QuantumExplorer Nov 10, 2026
fb23948
fix(swift-example-app): retry a failed private payment restoration on…
QuantumExplorer Nov 10, 2026
366cef7
Merge remote-tracking branch 'origin/feat/ffi-swift-private-contact-r…
QuantumExplorer Nov 10, 2026
0a2d984
fix(platform-wallet): read the SDK's unconfirmed broadcast outcome in…
QuantumExplorer Nov 10, 2026
98b50da
feat(sdk): keep marked scan state records through a wallet's purge in…
QuantumExplorer Nov 10, 2026
00f80f6
fix(kotlin-example-app): recover before reading readiness on every Da…
QuantumExplorer Nov 10, 2026
6502e69
docs(sdk): record the retained scan state records and the refresh rec…
QuantumExplorer Nov 10, 2026
207bd72
docs(platform-wallet-ffi): note code 20's unconfirmed state transitio…
QuantumExplorer Nov 10, 2026
b9ccb36
test(sdk): give the scan state capability test's bridges the wallet l…
QuantumExplorer Nov 10, 2026
6efee07
Merge remote-tracking branch 'origin/feat/platform-wallet-private-con…
QuantumExplorer Nov 10, 2026
994d392
fix(swift-example-app): read code 20 as may have gone through on cont…
QuantumExplorer Nov 10, 2026
07f6602
Merge remote-tracking branch 'origin/feat/ffi-swift-private-contact-r…
QuantumExplorer Nov 10, 2026
c116858
fix(kotlin-example-app): read code 20 as may have gone through on con…
QuantumExplorer Nov 10, 2026
c092a62
fix(swift-example-app): keep refreshing while a deferred restoration …
QuantumExplorer Nov 10, 2026
68d9b48
Merge branch 'feat/ffi-swift-private-contact-requests' into feat/kotl…
QuantumExplorer Nov 10, 2026
2003e15
fix(kotlin-example-app): keep refreshing while a deferred restoration…
QuantumExplorer Nov 10, 2026
80e945f
fix(swift-sdk): read a kept scan state record under its stored networ…
QuantumExplorer Nov 10, 2026
0af54b2
Merge branch 'feat/ffi-swift-private-contact-requests' into feat/kotl…
QuantumExplorer Nov 10, 2026
93b2abd
fix(platform-wallet): fence contact request cleanup to the wallet gen…
QuantumExplorer Nov 10, 2026
6d6744f
fix(platform-wallet): discharge a settled private payment record only…
QuantumExplorer Nov 10, 2026
828de98
docs(platform-wallet): say which shield keeps its own broadcast handling
QuantumExplorer Nov 10, 2026
3f8a914
feat(sdk): report the height a transition's inputs were seen consumed
QuantumExplorer Nov 10, 2026
8cd8e6d
feat(sdk): sign a contact request without broadcasting it
QuantumExplorer Nov 10, 2026
e818375
fix(platform-wallet): hold a public contact request whose outcome is …
QuantumExplorer Nov 10, 2026
54ae054
feat(platform-wallet-ffi): code 76 for an unconfirmed public contact …
QuantumExplorer Nov 10, 2026
5e03e06
Merge remote-tracking branch 'origin/feat/platform-wallet-private-con…
QuantumExplorer Nov 10, 2026
e8d18c4
feat(platform-wallet-ffi): read whether a public contact request awai…
QuantumExplorer Nov 10, 2026
39fe963
feat(swift-sdk): type code 76 and read a public contact request's hold
QuantumExplorer Nov 10, 2026
7496810
fix(swift-example-app): hold a public request that may have gone thro…
QuantumExplorer Nov 10, 2026
db147f9
Merge branch 'feat/ffi-swift-private-contact-requests' into feat/kotl…
QuantumExplorer Nov 10, 2026
78bbe9c
feat(kotlin-sdk): type code 76 and read a public contact request's hold
QuantumExplorer Nov 10, 2026
9cc0f89
fix(kotlin-example-app): hold a public request that may have gone thr…
QuantumExplorer Nov 10, 2026
8a6075b
Merge branch 'v5.1-dev' into feat/ffi-swift-private-contact-requests
QuantumExplorer Nov 10, 2026
f3878ca
docs(platform-wallet-ffi): the next allocatable result code is 77
QuantumExplorer Nov 10, 2026
647239b
Merge branch 'feat/ffi-swift-private-contact-requests' into feat/kotl…
QuantumExplorer Nov 10, 2026
ec344df
Merge branch 'v5.1-dev' into feat/kotlin-private-contact-requests
QuantumExplorer Nov 10, 2026
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
284 changes: 284 additions & 0 deletions docs/sdk/sdk-parity-manifest.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,16 @@ class AppContainer(private val context: Context) {
network = sdk.network,
loadWallets = {
val activatedManager = walletManagerStore.activate(sdk.network, sdk)
// Open the shielded store before any wallet is loaded or
// created: this app's persister keeps the private contact
// request scan state, so Rust holds every wallet published
// while no store is configured (code 72) until its private
// payment journal is read, and a later bind may never come (no
// mnemonic, declined biometric). With the store open first,
// each wallet's journal is read as it is published, and the
// binds' own calls on the same path are no-ops. A failure is
// recorded and retried; the wallets stay held meanwhile.
configureShieldedStore(activatedManager)
activatedManager.loadPersistedWallets()
org.dashfoundation.example.ui.dashpay.DashPayWalletLoad(
value = activatedManager,
Expand Down Expand Up @@ -200,13 +210,60 @@ class AppContainer(private val context: Context) {
}
}

private val _shieldedStoreFailure = MutableStateFlow<String?>(null)

/**
* Why opening the active network's shielded store failed, until a later
* attempt succeeds. The DashPay screens show it while the wallet's private
* payments wait for that store, and retry it ([configureShieldedStoreAgain]).
* ← Swift `WalletManagerStore.shieldedStoreFailures`.
*/
val shieldedStoreFailure: StateFlow<String?> = _shieldedStoreFailure.asStateFlow()

/**
* Open [manager]'s network's shielded store, recording why it failed, or
* clearing that once it opens. A repeat on the same path does not wait
* on the store.
*/
private suspend fun configureShieldedStore(manager: org.dashfoundation.dashsdk.wallet.PlatformWalletManager) {
if (!shieldedService.isAvailable) return
try {
manager.configureShielded(shieldedDbPath(manager.network))
_shieldedStoreFailure.value = null
} catch (e: kotlinx.coroutines.CancellationException) {
throw e
} catch (e: Exception) {
_shieldedStoreFailure.value = e.message ?: e.toString()
android.util.Log.w(TAG, "Failed to configure the shielded store", e)
}
}

/**
* Open the active network's shielded store again and return why it
* failed, or null once it is open. On a store already open this asks the
* wallet to retry restoring every wallet whose private payments are still
* held, a restoration that failed after the store opened included; it
* never waits on a busy store (a busy store defers the restoration to a
* task).
* ← Swift `WalletManagerStore.configureShieldedAgain(_:)`.
*/
suspend fun configureShieldedStoreAgain(): String? {
val manager = walletManagerStore.activeManager.value ?: return _shieldedStoreFailure.value
configureShieldedStore(manager)
return _shieldedStoreFailure.value
}

/**
* Wallet-scoped rebind — drive the manager-wide sync loops from the
* deterministic first wallet (← iOS `rebindWalletScopedServices` in
* SwiftExampleAppApp.swift). Idempotent: `configureShielded` /
* `bindShielded` and the start-if-not-running guards make repeated calls
* (on every wallet-set change) safe.
*/
/** The per-network commitment-tree store, as iOS `ShieldedService.dbPath(for:)` names it. */
private fun shieldedDbPath(network: org.dashfoundation.dashsdk.Network): String =
java.io.File(context.filesDir, "shielded_tree_${network.networkName}.sqlite").absolutePath

private suspend fun rebindWalletScopedServices(
manager: org.dashfoundation.dashsdk.wallet.PlatformWalletManager,
) {
Expand Down Expand Up @@ -243,10 +300,7 @@ class AppContainer(private val context: Context) {
// and doesn't throw. dbPath mirrors iOS's
// `ShieldedService.dbPath(for:)` naming
// (`shielded_tree_<networkName>.sqlite`), rooted in filesDir.
val shieldedDbPath = java.io.File(
context.filesDir,
"shielded_tree_${manager.network.networkName}.sqlite",
).absolutePath
val shieldedDbPath = shieldedDbPath(manager.network)
shieldedService.bind(
manager = manager,
walletId = wallet.walletId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavHostController
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import org.dashfoundation.example.di.LocalAppContainer
import org.dashfoundation.example.di.LocalAppState
Expand Down Expand Up @@ -98,6 +100,30 @@ fun AddContactScreen(identityIdHex: String, navController: NavHostController) {
var accountLabel by remember { mutableStateOf("") }
var isSending by remember { mutableStateOf(false) }
var errorMessage by remember { mutableStateOf<String?>(null) }
// Set when an accept's private reply may have gone through (its result
// could not be confirmed): the screen only offers to close, never to
// submit again, as the send screen does for an unconfirmed spend.
var unconfirmedNotice by remember { mutableStateOf<String?>(null) }
// Whether the wallet holds the pair with the resolved recipient for a
// private request, as a send decides it (in flight, paid and not yet
// read back, or kept by the shielded store's journal until the payment is
// proven never to land), or for a public request awaiting its outcome
// (`contactRequestHolds`). While it does, Send and the collision accept
// are off and the screen offers the sync that settles it: the private
// one, which reads a landed request back, or the DashPay one, which
// settles a public request. Read from the wallet, so reopening this
// screen keeps it. A failed read keeps them off until a read succeeds.
var recipientPending by remember { mutableStateOf(PrivateRepliesPendingSnapshot()) }
// Why the shielded store could not be opened, as last read with the
// pending state; null when it is open.
var shieldedStoreFailure by remember { mutableStateOf<String?>(null) }
var isSyncingPrivate by remember { mutableStateOf(false) }
// A DashPay sync the screen started is running.
var isCheckingPublic by remember { mutableStateOf(false) }
var pendingReadVersion by remember { mutableStateOf(0) }
// The automatic refreshes made since the wallet's private payments were
// last read restored (`PrivatePaymentsRecovery.recheckDelayMs`).
var readinessRechecks by remember { mutableStateOf(0) }
var collisionRecipient by remember { mutableStateOf<ByteArray?>(null) }
var previewProfile by remember { mutableStateOf<DashPayProfile?>(null) }

Expand All @@ -107,7 +133,15 @@ fun AddContactScreen(identityIdHex: String, navController: NavHostController) {
AddMode.IDENTITY_ID -> parsedIdentityId
}
val recipientIsSelf = resolvedRecipient?.contentEquals(idBytes) == true
val canSend = resolvedRecipient != null && !recipientIsSelf && !isSending
val canSend = resolvedRecipient != null && !recipientIsSelf && !isSending &&
unconfirmedNotice == null && recipientPending.allowsSubmission(resolvedRecipient.toHex())
val recipientBlocked = resolvedRecipient != null &&
(
recipientPending.isRestoringPrivatePayments ||
recipientPending.isAwaitingOutcome(resolvedRecipient.toHex()) ||
recipientPending.isPending(resolvedRecipient.toHex()) ||
recipientPending.isUnavailable
)

// Scan-to-send: consume the QR string handed back by the scanner screen
// (the house pattern — observe the saved-state flow, then null it out).
Expand Down Expand Up @@ -168,6 +202,50 @@ fun AddContactScreen(identityIdHex: String, navController: NavHostController) {
// Cache-only profile for the preview card (local read; most unknown
// identities won't have one).
val recipientHex = resolvedRecipient?.toHex()
LaunchedEffect(recipientHex, wallet, pendingReadVersion) {
val contactIds = listOfNotNull(resolvedRecipient)
// Recovery first: the readiness shown is read after the wallet was
// asked to retry a restoration its payments still wait for.
val refreshed = PrivatePaymentsRecovery.refresh(
lastReadiness = recipientPending.readiness,
storeFailure = container.shieldedStoreFailure.value,
readReadiness = { privateContactReadiness(wallet, idBytes) },
configureAgain = { container.configureShieldedStoreAgain() },
)
shieldedStoreFailure = refreshed.storeFailure
val pendingRead = contactRequestHolds(wallet, idBytes, contactIds)
recipientPending = recipientPending
.withReadiness(refreshed.read?.readiness, refreshed.read?.restoreFailure)
.recorded(pendingRead, contactIds.map { it.toHex() })
// While the payments stay unrestored, refresh again after a pause, for
// as long as the screen is shown: a restoration the wallet deferred
// behind a busy store completes later and changes no key of this
// effect (neither a bind nor a DashPay sync ends for it).
if (PrivatePaymentsRecovery.waitForRecheck(recipientPending.readiness, readinessRechecks)) {
readinessRechecks++
pendingReadVersion++
} else if (recipientPending.readiness?.privatePaymentsRestored == true) {
readinessRechecks = 0
}
}
// Binding the shielded account restores the wallet's private payments:
// read the readiness again then.
LaunchedEffect(container.shieldedService) {
container.shieldedService.isBound.collect { pendingReadVersion++ }
}
// A deferred restoration runs once the shielded scan holding the store
// ends: refresh then too, ahead of the timer.
LaunchedEffect(container.shieldedService) {
container.shieldedService.state
.map { it.isSyncing }
.distinctUntilChanged()
.collect { syncing -> if (!syncing) pendingReadVersion++ }
}
// A DashPay sync settles a public request awaiting its outcome: read the
// recipient's holds again when one ends, the background pass included.
LaunchedEffect(manager) {
manager?.dashPaySyncIsSyncing?.collect { syncing -> if (!syncing) pendingReadVersion++ }
}
LaunchedEffect(recipientHex) {
val recipient = resolvedRecipient
val w = wallet
Expand Down Expand Up @@ -204,25 +282,89 @@ fun AddContactScreen(identityIdHex: String, navController: NavHostController) {
kickDashPaySync(scope, m)
navController.popBackStack()
} catch (e: Exception) {
errorMessage = e.message ?: "Send failed"
val outcome = ContactRequestSubmissionOutcome.of(e)
recipientPending = recipientPending.withOutcome(outcome, recipient.toHex())
when (outcome) {
// Nothing was sent: the wallet holds the pair. The screen
// shows it as pending, with the private sync, until the
// per-contact read says it is free.
ContactRequestSubmissionOutcome.PrivateRequestPending -> Unit
// Nothing was sent: the screen shows the wallet setting up
// its private payments until its readiness says restored.
ContactRequestSubmissionOutcome.PrivatePaymentsNotRestored -> Unit
// Nothing was signed: an earlier public request to the
// recipient awaits its outcome. The screen shows it being
// checked, with the DashPay sync, never a retry.
ContactRequestSubmissionOutcome.PublicRequestUnconfirmed -> kickDashPaySync(scope, m)
// Nothing was sent and nothing is pending: Send stays on,
// and sending again continues the read.
ContactRequestSubmissionOutcome.PrivateStoreNotRead ->
errorMessage = ContactRequestSubmissionOutcome.PRIVATE_STORE_NOT_READ_MESSAGE
ContactRequestSubmissionOutcome.MayHaveGoneThrough -> {
kickDashPaySync(scope, m)
unconfirmedNotice = ContactRequestSubmissionOutcome.MAY_HAVE_GONE_THROUGH_MESSAGE
}
is ContactRequestSubmissionOutcome.Failed -> errorMessage = outcome.message
}
} finally {
isSending = false
pendingReadVersion++
}
}
}

/**
* Read the private store, which settles a pending private request, then
* re-read the recipient's pending state: Send comes back once nothing is
* pending, for the user to try again.
*/
fun syncPrivateRequests() {
val w = wallet ?: return
val m = manager ?: return
isSyncingPrivate = true
scope.launch {
try {
syncPrivateContactRequests(w, m)?.let { errorMessage = it }
} finally {
isSyncingPrivate = false
pendingReadVersion++
}
}
}

/**
* Run a DashPay sync, which settles a public request awaiting its
* outcome first (attaching to one already running), then re-read the
* recipient's holds: Send comes back once the wallet frees the pair, and
* a request found is recorded as sent.
*/
fun checkPublicRequest() {
val m = manager ?: return
isCheckingPublic = true
scope.launch {
try {
attachOrStartSync(m)
} finally {
isCheckingPublic = false
pendingReadVersion++
}
}
}

fun acceptIncoming(recipient: ByteArray) {
val w = wallet ?: return
val m = manager ?: return
// A private reply to this contact may be pending in the wallet.
if (!recipientPending.allowsSubmission(recipient.toHex())) return
isSending = true
errorMessage = null
scope.launch {
try {
val ok = w.dashpay.acceptIncomingRequest(
val ok = acceptIncomingContactRequest(
wallet = w,
manager = m,
ourIdentityId = idBytes,
senderId = recipient,
signerHandle = m.signerHandle,
coreSignerHandle = m.mnemonicResolverHandle,
)
if (ok) {
kickDashPaySync(scope, m)
Expand All @@ -232,9 +374,28 @@ fun AddContactScreen(identityIdHex: String, navController: NavHostController) {
"accept it from Requests."
}
} catch (e: Exception) {
errorMessage = "Accept failed: ${e.message ?: "unknown error"}"
val outcome = ContactRequestSubmissionOutcome.of(e)
recipientPending = recipientPending.withOutcome(outcome, recipient.toHex())
when (outcome) {
ContactRequestSubmissionOutcome.MayHaveGoneThrough -> {
// Pending, not failed: the next sync settles it.
kickDashPaySync(scope, m)
unconfirmedNotice = ContactRequestSubmissionOutcome.MAY_HAVE_GONE_THROUGH_MESSAGE
}
// Nothing was signed: the screen shows the pair being
// checked, with the DashPay sync, never a retry.
ContactRequestSubmissionOutcome.PublicRequestUnconfirmed -> kickDashPaySync(scope, m)
// Nothing was sent: the screen offers the private sync.
ContactRequestSubmissionOutcome.PrivateRequestPending -> Unit
ContactRequestSubmissionOutcome.PrivatePaymentsNotRestored -> Unit
ContactRequestSubmissionOutcome.PrivateStoreNotRead ->
errorMessage = ContactRequestSubmissionOutcome.PRIVATE_STORE_NOT_READ_MESSAGE
is ContactRequestSubmissionOutcome.Failed ->
errorMessage = "Accept failed: ${outcome.message}"
}
} finally {
isSending = false
pendingReadVersion++
}
}
}
Expand Down Expand Up @@ -334,6 +495,38 @@ fun AddContactScreen(identityIdHex: String, navController: NavHostController) {
enabled = canSend,
modifier = Modifier.fillMaxWidth().testTag("dashpay.addContact.send"),
) { attemptSend() }
if (recipientBlocked) {
Text(
ContactRequestSubmissionOutcome.rowMessage(
pending = recipientPending.isPending(recipient.toHex()),
awaitingOutcome = recipientPending.isAwaitingOutcome(recipient.toHex()),
restoring = recipientPending.isRestoringPrivatePayments,
restoreFailure = recipientPending.restoreFailure,
shieldedStoreFailure = shieldedStoreFailure,
unavailable = recipientPending.isUnavailable,
error = null,
).orEmpty(),
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.testTag("dashpay.addContact.pending"),
)
// A DashPay sync settles a public request awaiting its
// outcome, and a private sync a pending private request;
// neither restores private payments, so neither is offered
// for that.
when {
recipientPending.isRestoringPrivatePayments -> Unit
recipientPending.isAwaitingOutcome(recipient.toHex()) -> TextButton(
onClick = { checkPublicRequest() },
enabled = !isCheckingPublic,
modifier = Modifier.testTag("dashpay.addContact.checkPublic"),
) { Text(if (isCheckingPublic) "Checking…" else "Check again") }
else -> TextButton(
onClick = { syncPrivateRequests() },
enabled = !isSyncingPrivate,
modifier = Modifier.testTag("dashpay.addContact.syncPrivate"),
) { Text(if (isSyncingPrivate) "Syncing private requests…" else "Sync private requests") }
}
}
}

if (errorMessage != null) {
Expand Down Expand Up @@ -366,6 +559,17 @@ fun AddContactScreen(identityIdHex: String, navController: NavHostController) {
},
)
}

unconfirmedNotice?.let { notice ->
AlertDialog(
onDismissRequest = { navController.popBackStack() },
title = { Text("Submitted") },
text = { Text(notice) },
confirmButton = {
TextButton(onClick = { navController.popBackStack() }) { Text("Done") }
},
)
}
}

@Composable
Expand Down
Loading
Loading