Skip to content

New price sourcing - #17

Merged
QuantumExplorer merged 2 commits into
developfrom
feature/price-sourcing
Dec 1, 2018
Merged

New price sourcing#17
QuantumExplorer merged 2 commits into
developfrom
feature/price-sourcing

Conversation

@podkovyrin

Copy link
Copy Markdown
Contributor

@QuantumExplorer
QuantumExplorer merged commit 5726128 into develop Dec 1, 2018
@podkovyrin
podkovyrin deleted the feature/price-sourcing branch December 1, 2018 07:09
llbartekll added a commit that referenced this pull request May 21, 2026
PR 1 of the row #16 migration (new-user identity + DPNS username from
DashSync to SwiftDashSDK). Scaffolding only, behind a disabled
`DASHPAY_SWIFT_SDK_REGISTRATION` flag — nothing calls these files yet,
DashSync remains the live path. PR 2 wires `DWDashPayModel.m` +
`DWCheckExistenceUsernameValidationRule.m` into the new path.

Migration doc updates (re-verified 2026-05-20):

- Row #16 / #17 / #19 flipped to 🟢 ready; row #18 flipped from 🔴 to
  🟡 (SDK APIs exist, no example walkthrough). Earlier "6+ FFI signature
  mismatches" claim resolved upstream via 33fde4e67f (cbindgen ABI),
  e22f816a2e (asset-lock proofs), c556a86db2 (KeychainSigner sweep),
  e9e56f3636 (account_index plumbed through).
- Hard Blockers: struck through #16 with the four resolving commits.
- Recommended order Wave 3 marked unblocked for #16/#17/#19.

New files in `DashWallet/Sources/Infrastructure/SwiftDashSDK/Identity/`:

- `DWRegistrationPhaseAdapter.swift` — pure mapping collapsing the SDK's
  5 internal phases (controller phase + `PersistentAssetLock.statusRaw`)
  onto the existing 3-state `DWDPRegistrationState` UI enum. Unit-tested.
- `DWIdentityRegistrationController.swift` — `@MainActor ObservableObject`
  phase holder (idle / preparingKeys / inFlight / completed / failed),
  ported from the SwiftExampleApp reference and stripped to a pure state
  carrier (v1 pins identityIndex=0; coordinator drives transitions).
- `DWIdentityAuthorizer.swift` — async PIN/biometric gate wrapping
  `DSAuthenticationManager.authenticate`. Mirrors the private
  `SendAuthorizer` pattern from `WalletSendService.swift:129-172`.
- `DWIdentityRegistrationCoordinator.swift` — `@MainActor` singleton
  orchestrating the full chain: PIN gate → `prePersistIdentityKeysForRegistration`
  → `registerIdentityWithFunding` → `registerDpnsName`. Polls
  `PersistentAssetLock.statusRaw` every 0.5s while `.inFlight` for the
  3-state UI mapping. Mirrors success into
  `DWGlobalOptions.dashpayUsername` + `dashpayRegistrationCompleted` so
  the 87 existing Obj-C identity-read sites keep working until row #17
  migrates them individually.
- `DWIdentityRegistrationBridge.swift` — `@objc @mainactor @objcMembers`
  facade for `DWDashPayModel.m` / `DWCheckExistenceUsernameValidationRule.m`.
  Cached `@objc` state mirrored from the coordinator via one
  `Publishers.CombineLatest($phase, $assetLockStatus)` subscription
  (passing emitted values directly avoids the `@Published` willSet
  re-read race). Posts `DWDashPayRegistrationStatusUpdatedNotification`
  on every transition.

Tests: `DashWalletTests/DWRegistrationPhaseAdapterTests.swift` — 12 cases
covering the full mapping matrix plus the failure-classification edge.

Project file:
- `DASHPAY_SWIFT_SDK_REGISTRATION=0` appended to all 5 GCC blocks that
  already contain `DASHPAY=1` (defined-but-falsy; PR 3 flips per-config).
- New Swift files registered on the `dashpay` target only — they reference
  DashPay-only Obj-C symbols (`DWDP_MIN_BALANCE_TO_CREATE_USERNAME`,
  `DWGlobalOptions.dashpayUsername` / `dashpayRegistrationCompleted`),
  which don't exist in the `dashwallet` target build.
- Test file registered on the `DashWalletTests` target.

v1 scope (documented for follow-up):
- Invitations stay on DashSync (no SDK equivalent for
  `DSBlockchainInvitation`).
- Existing DashSync identities not migrated — keys live in DashSync's
  keychain, not in `WalletStorage`. Future "import identity" stage.
- No crash-resume via `resumeIdentityWithAssetLock` (deferred to v2).
- Platform Payment funding path (`registerIdentityFromAddresses`) not
  wired — users with Platform credits but no Core balance still see the
  0.03 Dash error.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
llbartekll added a commit that referenced this pull request May 21, 2026
PR 2 of the row #16 migration. With `DASHPAY_SWIFT_SDK_REGISTRATION` still
at `0`, every `#if` branch is unselected, every `#else` is byte-identical
to pre-PR-1 behavior — no runtime change. Flipping the flag (PR 3, testnet
only) activates the new path end-to-end.

`DWIdentityRegistrationBridge.swift`:

- Add `@objc public static let stateChangedNotification` (a new internal
  name, `DWIdentityRegistrationBridgeStateChangedNotification`) and have
  `refreshFromCoordinator(...)` post it instead of the canonical
  `DWDashPayRegistrationStatusUpdatedNotification` it was posting in PR 1.
  Reason: NSNotificationCenter delivers in registration order, so existing
  UI consumers of the canonical name (`HomeViewModel.swift:855`,
  `MainTabbarController.swift:129`, `DWUserProfileContainerView.m:93`)
  could fire before `DWDashPayModel` updated its `registrationStatus` and
  read stale model state. Now only `DWDashPayModel` observes the bridge,
  mirrors state, and posts the canonical notification — single ordered
  hop. Docstring on `wireCoordinatorObservation` updated to reflect this.

`DashWallet/Sources/UI/Home/Models/DWDashPayModel.m`:

- Add an observer in `init` for the bridge's `stateChangedNotification`,
  guarded by `#if DASHPAY_SWIFT_SDK_REGISTRATION`.
- New selector `bridgeRegistrationStateChanged:` (also `#if`-guarded)
  that reads the bridge's cached `@objc` state, mirrors it into
  `self.registrationStatus` / `self.lastRegistrationError`, and posts
  the canonical notification. On `bridge.isCompleted` it intentionally
  does NOT call `completeRegistration` because that method nils
  `DWGlobalOptions.dashpayUsername` (assuming
  `wallet.defaultBlockchainIdentity.currentDashpayUsername` becomes the
  source of truth), but the SDK path has no DashSync identity — nil-ing
  would make `self.username` permanently nil and break the 87 downstream
  Obj-C identity-read sites until row #17 migrates them. Mirrors the
  other success effects (`shouldShowInvitationsBadge = YES`, clear
  `registrationStatus`, post canonical) inline.
- `createUsername:invitation:` routes the new-user no-invitation case
  (`wallet.defaultBlockchainIdentity == nil`) through
  `[DWIdentityRegistrationBridge.shared startCreateUsername:completion:]`
  under `#if`. Existing-identity case falls through to unchanged
  DashSync code. Invitation branch (lines 135-168) untouched.
- The bridge completion is a safety net for early-exit failures that
  don't reach a terminal-phase notification — SDK preconditions
  (no wallet / no network / no model container) throw before the
  controller is wired, and auth-cancel calls `resetState()` which
  clears `bridge.currentUsername` before the model observer reads it.
  In those cases `dashpayUsername` (cached at line 131) would stay set
  forever. The completion clears it and surfaces the error when
  `registrationStatus == nil` (i.e. the notification path didn't
  surface a failed state). For mid-flight failures the notification
  path already wrote a `.failed` status, so the early-return preserves
  that UI state.

`DashPay/Presentation/Setup/CreateUsername/Models/DWCheckExistenceUsernameValidationRule.m`:

- Conditional `#import "dashwallet-Swift.h"` under
  `#if DASHPAY_SWIFT_SDK_REGISTRATION`.
- Wrap the body of `performValidationWithUsername:` in `#if / #else`.
  The `#if` branch calls
  `[DWIdentityRegistrationBridge.shared checkAvailability:completion:]`
  with the same `DWUsernameValidationRuleResult` semantics
  (available=Valid, taken=InvalidCritical, error=Error). The `#else`
  keeps the existing `DSIdentitiesManager.searchIdentityByDashpayUsername:`
  call unchanged (the `DSIdentitiesManager *manager` local moves into
  the `#else` block since the new path doesn't need it). The
  `MOCK_DASHPAY` early-return and the debounce mechanism in
  `validateText:` are preserved across both branches; the
  `self.username == username` guard inside the completion handles
  stale-result discarding.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
llbartekll added a commit that referenced this pull request May 21, 2026
End-to-end verified on testnet 2026-05-20 — first DashPay identity
created from dashwallet-ios via SwiftDashSDK
(identity `5150b96d…`, name `433v2gnfdggdfs.dash`). The full coordinator
chain — PIN gate → `prePersistIdentityKeysForRegistration` →
`registerIdentityWithFunding` → `registerDpnsName` — completed cleanly
with `PersistentAssetLock` transitioning `1 → 2 → 4` (Broadcast →
InstantSendLocked → Consumed) on a funded testnet wallet.

Three things land in this commit:

1. **Form rewire** — `CreateUsernameViewModel.submitUsernameRequest`
   was running mock code (write a fake `UsernameRequest` DTO with a
   random UUID identity to `UsernameRequestsDAOImpl.shared`, set
   `UsernamePrefs.shared.requestedUsernameId`, sleep 2s, return true).
   The actual `dashPayModel.createUsername(...)` call was commented
   out. Replaced with the real call; the mock DAO write,
   `joinDashPayDismissed` toggle, and fake sleep are gone. Signature
   now takes `dashPayModel: DWDashPayProtocol` — the SwiftUI view
   already holds it via `@State var dashPayModel: DWDashPayProtocol`,
   so both call sites in `CreateUsernameView` (the simple Continue
   path at line 143 and the post-verify-identity confirm-spend path
   at line 206) just thread it through.

2. **`checkIfBlocked` short-circuit** — was sleeping 2s and setting
   `usernameBlockedRule = .warning`, which forced the user through
   the contested-username "verify identity" sheet on Continue. The
   sheet's voting-prompt copy + verify-identity proof URL flow is
   out of scope for the SDK v1 migration (contested-username
   resolution lives in the SDK's
   `dpnsGetContestedVoteState` / `dpnsGetCurrentContests` APIs but
   we don't surface them yet). Set `.valid` directly so Continue
   hits the simple submit path. Real DPNS availability detection
   lives in `DWIdentityRegistrationBridge.checkAvailability` and is
   exercised by the legacy `DWCheckExistenceUsernameValidationRule`
   flow if/when that flow becomes the active UI.

3. **Flag flip to `=1`** — `DASHPAY_SWIFT_SDK_REGISTRATION=0` →
   `DASHPAY_SWIFT_SDK_REGISTRATION=1` in all 5 GCC preprocessor
   blocks that contain `DASHPAY=1`. Same value everywhere; not
   scoped per-configuration. Combined with the earlier PR 1
   (`b91c0a144`) + PR 2 (`5291371f4`) wiring, this activates the
   SDK code path end-to-end. `dashwallet` target is unaffected
   (new files only registered on the `dashpay` target).

`DASHSYNC_MIGRATION.md` updates:

- Row #16 Status column flipped from `—` → `🌗 Flipped` and a new
  detailed "Where we are" entry added at the top of the doc with
  commit hashes (`b91c0a144`, `5291371f4`, and this one), the
  testnet verification identity ID + name, and the known v1 gaps
  (orphan asset-lock on crash, half-state on DPNS-failure retry,
  Platform Payment funding still unwired).

**Out of scope** (separate stages):

- Invitation branch (`DSBlockchainInvitation.acceptInvitation:`)
  stays on DashSync — no SDK equivalent.
- Existing DashSync identities (very rare in this branch state)
  fall through to the unchanged DashSync path. Future "import
  DashSync identity into SwiftDashSDK" stage needed.
- Contested-username voting flow bypassed.
- Platform Payment funding (`registerIdentityFromAddresses`) — users
  with Platform credits but no Core balance still see the 0.03
  Dash form check.
- Cleanup of the now-dead mock viewmodel fields
  (`currentUsernameRequest`, `hasUsernameRequest`,
  `fetchUsernameRequestData`, `cancelRequest`, `updateRequest`,
  `hasRequests(for:)`, the `dao` + `prefs` properties) — separate
  cleanup PR.
- Row #17 (`DSBlockchainIdentity` read-site migration, 87 files)
  is now unblocked but separate.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
llbartekll added a commit that referenced this pull request May 25, 2026
After PR 5 ships SwiftDashSDK identity registration (including
Platform-Payment funding), a wallet whose only identity lives in
SwiftData's `PersistentIdentity` — with no DashSync
`defaultBlockchainIdentity` reconstruction — was invisible to the
home-screen nav-bar avatar. Row #17 proper migrates the ~89 other
DashSync `DSBlockchainIdentity` read sites across DashPay UI; this
focused stage closes only the user-visible avatar gap so the SDK
identity flow is exercisable end-to-end without waiting for the
full read-site migration.

- `DWDashPayProtocol.hasIdentity` (new) — OR of DashSync's
  `defaultBlockchainIdentity != nil` and
  `DWGlobalOptions.dashpayRegistrationCompleted`. Consumers that
  only need "does this wallet have a DashPay identity?" read this
  instead of unwrapping a `DSBlockchainIdentity`. Implemented in
  `DWDashPayModel`. The legacy `blockchainIdentity` getter is
  unchanged and still returns nil for SDK-only identities — row
  #17 proper migrates each consumer individually.

- `HomeViewController` avatar visibility consults `hasIdentity` in
  both the legacy `homeView(_:didUpdateProfile:)` delegate callback
  and a new `refreshIdentityAvatar()` helper. The helper is called
  from three places: viewDidLoad (seed on launch for re-launch with
  an existing identity), the legacy delegate, and a new observer on
  `DWDashPayRegistrationStatusUpdated` (so SDK registrations
  surface live without waiting for a DashSync delegate fire). The
  original `DWDPAvatarView` + `UIBarButtonItem(customView:)` +
  `UITapGestureRecognizer` shape is preserved unchanged.

- `HomeViewController.profileAction()` branches on the underlying
  `DSBlockchainIdentity` object. DashSync-side identities continue
  to open `RootEditProfileViewController` (byte-equivalent to the
  pre-change behavior). SwiftDashSDK-only identities open the new
  read-only `SDKIdentityProfileSheet` instead — the legacy editor
  unwraps `DSBlockchainIdentity` properties and would crash on a
  nil identity, so it isn't safe for the SDK path until row #17
  proper migrates it.

- `SDKIdentityProfileSheet` (new SwiftUI view, dashpay target
  only) shows the registered username (placeholder avatar + first
  initial), the 32-byte identity ID as monospaced hex with a
  copy-to-clipboard button, the wallet's Platform-credit balance
  (read from `SwiftDashSDKWalletState.platformPaymentCredits` via
  the PR 5 surface), and a hint that editing is coming in a future
  update. Registered on the `dashpay` target only — matches the
  Identity/ pattern from PR 1.

What stays for row #17 proper (out of scope here):
- The avatar's per-user rendering (letter / branded color / DashPay
  profile image inside `DWDPAvatarView`) is still driven by
  `DSBlockchainIdentity`. SDK-only identities get the avatar
  view's default placeholder — a dash-blue circle with no letter.
- `DWEditProfileViewController`, `DWCurrentUserProfileView`,
  `DWDPUpdateProfileModel` and the other ~85 DashSync-reading
  sites stay as-is.
- Contact request flows (`DWDashPayModel.m:260,273` crash on nil
  identity if invoked from contacts UI; that UI isn't reachable
  from the avatar tap on SDK-only identities).
- DashPay profile writes (`createDashPayProfile`/`updateDashPayProfile`).

Deliberately untouched (per ongoing debug needs):
- `MainMenuViewController` FIXME debug edits — restore before
  shipping.
- `JoinDashPayViewModel.checkUsername()` state derivation.
- `HomeViewModel.checkJoinDashPay()` banner gating.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
llbartekll added a commit that referenced this pull request May 25, 2026
Centralise DashPay current-user reads behind DWCurrentUserIdentityInfo
and route profile writes through SwiftDashSDK. Row #17 stage A already
surfaced SDK identities on the home-screen avatar + tap — this commit
finishes the in-scope read sites (avatar render, profile display,
invitation link, payment-side identity gate) and the profile editor's
write path. Pre-existing DashSync identities (rare in this branch)
keep working via fallbacks; full retirement lands with Row #25.

New infrastructure (dashpay target):
- DWCurrentUserIdentityInfo: @objc @mainactor lookup. Snapshot of
  (username, displayName, avatarURL, publicMessage, identityIdHex)
  invalidated on DWDashPayRegistrationStatusUpdated and
  DWIdentityRegistrationBridge.stateChangedNotification. Resolves
  PersistentIdentity from SwiftData, reads via
  wallet.managedIdentity(identityId:) → getDpnsNames() +
  getDashPayProfile(). Falls back to DWGlobalOptions.dashpayUsername
  for the post-register sync gap.
- DWProfileUpdateCoordinator: async @mainactor write path with PIN
  gate, KeychainSigner, and create-vs-update verb flip on cache-
  mismatch error from the SDK.
- DWProfileUpdateBridge: @objc completion-based facade. JPEG-encodes
  the cropped UIImage at quality 0.8 for DashPayProfileUpdate.avatarBytes.

Migrated reads:
- DWDPAvatarView: configureAsCurrentUser. Contact-side
  setBlockchainIdentity: kept for Row #18.
- DWEditProfileAvatarView: setImageForCurrentUser.
- DWCurrentUserProfileView: reloadFromCurrentUser. The legacy
  setBlockchainIdentity: setter now forwards to it. reloadAttributedData
  reads via a new DWCurrentUserTitleSubtitleAttributedString free
  function alongside the existing DSBlockchainIdentity+DWDisplayTitleSubtitle
  category.
- DWEditProfileViewController: displayName / aboutMe / avatar URL all
  prefill from the helper. Drops the non-MOCK assertion that
  blockchainIdentity is non-nil. unsavedAvatarImage retains the
  cropped UIImage so the SDK write path can hand bytes downstream.
- DWInvitationLinkBuilder: inviter profile fields from the helper.
- DWDashPayModel.username: prefer helper, fall back to DashSync +
  DWGlobalOptions.
- DWPayModel.refreshOptions: DashPay send-button gate via
  helper.hasIdentity.

Migrated write:
- DWDPUpdateProfileModel.updateWithDisplayName:aboutMe:avatarURLString:avatarImage:
  branches on wallet.defaultBlockchainIdentity. non-nil → legacy
  DashSync sign-and-publish. nil → DWProfileUpdateBridge. The new
  avatarImage parameter threads from RootEditProfileViewControllerDelegate
  through HomeViewController + MainMenuViewController's DelegateInternal.
- SDKIdentityProfileSheet: optional onEditTapped callback drives a
  new Edit button. HomeViewController.profileAction chains into
  RootEditProfileViewController on the tap so SDK identities can
  edit their profile end-to-end now.

Out of scope (Row #18 / Row #25 / future):
- DWUserProfileHeaderView, InvitationBottomView, DWNotificationsProvider,
  DWDashPayContactsUpdater, DWDashPayContactsActions — contact-side
  rendering and contacts subsystem.
- DWPaymentProcessor + DWPaymentOutput+DWView identity reads — pass
  DSBlockchainIdentity into deeper BIP-70 / friend-status machinery.
- Contested-name voting (still bypassed since PR 3).

Carveouts preserved untouched per user request:
- MainMenuViewController FIXME: TEMPORARY debug edits
- JoinDashPayViewModel.checkUsername
- HomeViewModel.checkJoinDashPay

Verified: dashpay scheme builds clean. End-to-end testnet verification
pending; the read paths render via the helper's snapshot + SDWebImage
URL load, and the write path calls into the existing SDK profile
APIs proven by the SwiftExampleApp.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
llbartekll added a commit that referenced this pull request May 28, 2026
- Mark "Known SDK issues §1" (`could not decode data contracts query`)
  as RESOLVED 2026-05-27 via the Platform protocol v11 pin
  (`SwiftDashSDKHost.swift` → `SDK(network: protocolVersion: 11)`,
  backed by upstream PR #3734).
- Row #17 stage B "Where we are": drop the "blocked by upstream
  SwiftDashSDK bug" caveat; profile editing is end-to-end verified.
- Row #17 functional-table row: same cleanup.
- Row #18a entry: rephrase the "status view comes back once
  upstream is fixed" line — it's now a scope/product decision, not
  a blocker.
- Add a new "Where we are" entry covering the v11 pin + DPNS lookup
  finalisation: `usernames: [String]` exposure, cold-launch cache
  fix, wallet-side query, Edit Profile entry-point gate on
  `hasIdentity`, tab-bar restore workaround, and the
  `DASHPAY_SWIFT_SDK_REGISTRATION` flag retirement.
- Row #19 (DPNS lookup) flips from "—" to 🌗 Flipped; consumers
  column splits availability check (done) vs. prefix search
  (`DWUserSearchModel`, travels with #18 because the consumer
  factory expects `DSBlockchainIdentity`).
- Wave 3 row: update from "not started" to "Flipped for #16/#17/#19,
  #18 still pending".
- Row #16 "Where we are": flag retirement footnote so a future
  reader doesn't grep for it and find only stale references.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

2 participants