Conversation
Replace qli SubmitTransaction and transaction status endpoints with local PendingTransactionService backed by localStorage. Broadcast transactions via the live API. Add ApiQueryService for resolving pending transaction outcomes. Simplify transaction status computation and use template variable caching for asset transfer lookups.
Use live API endpoints to replace qli dependencies in IPO:
- GET /live/v1/ipos/active replaces GET /ipo/contracts
- GET /live/v1/ipos/{id}/bids replaces GET /Wallet/IpoContracts
- Remove unused getIpoContracts and getSmartContracts from ApiService
- getCurrentIpoBids from qli stays (no replacement yet)
…ents - Add per-contract bid fetch error tracking with retry UI - Add global error state with refresh button for failed IPO loading - Encapsulate currentIpoContracts BehaviorSubject behind setter - Validate API response parsing with safe parseInt defaults - Remove dead SmartContract interface from api.model - Simplify switchMap + of to map in observable chain - Use nullish coalescing for tickNumber fallback - Add i18n keys for error states across all 11 locales
- Replace raw address with getAddressDisplayName for consistent formatting - Link share addresses to explorer instead of copy-to-clipboard - Remove unused getSeedName method
Replace the old /Wallet/CurrentIpoBids endpoint (qubic.li) with the new /aggregation/v1/getCurrentIpoBids endpoint on a dedicated aggregation service. Create ApiAggregationService following the one-service-per-API-tree convention. Add error handling with localized messages for bids load failures and simplify the IPO bid status icon to a hardcoded trx-executed since IPO bids are always SC calls (inputType=1, amount=0).
chore: merge main into dev
…factor/replace-qli-tx-submission # Conflicts: # src/app/constants/qubic.constants.ts # src/app/services/api.service.ts
The service had 20 endpoint methods but zero call sites. The only references were administrative (an unused import in app.component.ts and a module-level provider entry), both removed. Superseded by ApiQueryService in 50ec2d0; this was a parallel implementation that was never wired up.
Cleans up translation keys that have no template references after the WebSocket bridge / QubicService removal (dcd9c57): notifyComponent.qubicLiSync notifyComponent.qubicOffline notifyComponent.qubicOnline settings.general.title ("Web Bridge" header) settings.general.webBridge.placeholder settings.general.beta.placeholder Applied uniformly across all 11 language files.
Defines 3 endpoint methods (getApprovedTransactions, getStatus, getTxStatus) but no component or service injects it. Only references were an unused import in app.component.ts and a module-level provider entry, both removed. Superseded by the local PendingTransactionService introduced in 1c0369a; this was a parallel implementation that was never wired up.
Four service imports (ApiService, ApiQueryService, ApiLiveService, ApiStatsService) and two injected constructor params (api, apiQuery) were never read. The services themselves stay — they're consumed elsewhere (e.g. updater-service.ts); only the ghost references in AppComponent were dead.
deviceInfo was assigned in checkSize() but never read anywhere (no .ts, .html or .scss references). Removed the declaration, the assignment, and the now-unused DeviceInfo type import. isMobile / isDesktop (the related fields) stay — they are read by the template class binding.
After 50ec2d0 migrated transaction/tick fetching from the archiver service to ApiQueryService, the field names in UpdaterService still carried archiver vocabulary that no longer matches the source: archiverLatestTick -> lastProcessedTick transactionArchiverLoading -> transactionsLoading The new names align with the API endpoint (getLastProcessedTick) and the local method of the same name. Only one external consumer (balance.component.ts) needed updating.
Seven services declared with @Injectable({ providedIn: 'root' }) were also redundantly listed in the AppModule providers array. The decorator alone registers them globally as singletons; the duplicate listing was vestigial pre-Angular 6 boilerplate and prevented tree-shaking for services that ever go unused (as happened with ApiArchiveService). Removed from providers: ApiService, ApiQueryService, ApiLiveService, ApiStatsService, UpdaterService, EnvironmentService, TransactionService. The corresponding imports became orphan and were dropped too. Kept in providers: AuthInterceptor (no providedIn), DecimalPipe, MAT_DIALOG_DEFAULT_OPTIONS, httpInterceptorProviders, VisibilityService, TokenService, the WalletService factory. Same singleton behavior at runtime; pattern now matches ApiAggregationService (already correctly not listed).
After 8cb059c removed the balanceTick staleness guard, updateBalance was identical to setBalance except for a trailing saveConfig(false) call. The current refresh pattern (loop setBalance over results, then a single savePublic(false) at the end) made updateBalance redundant and unreferenced. Grep across .ts/.html and string literals confirmed zero callers.
…aterService The BalanceComponent had `initialProcessedTick` / `lastProcessedTick` fields representing the start/end of the tick window being displayed. After `ce446cf` renamed UpdaterService's BehaviorSubject to `lastProcessedTick`, both classes had a field of the same name with different semantics — leading to lines like `this.lastProcessedTick = this.us.lastProcessedTick.value` where the identifier means different things on each side. Renamed the component fields to `viewStartTick` / `viewEndTick` to reflect what they actually represent: the bounds of the tick range currently being viewed (which can be a historical epoch in the "By Epoch" tab, not the chain's latest tick at all).
The remaining 'ApiService' is now a thin qubic.li-only client (auth + guest login + getOwnedAssets + IPO state store). The generic name obscured what was happening; renaming makes the qli-specific nature visible at every call site. Changes: - src/app/services/api.service.ts -> src/app/services/apis/qli/api.qli.service.ts - Class ApiService -> ApiQliService (matches sibling pattern: ApiLiveService, ApiQueryService, ApiStatsService, ApiAggregationService) - Updated 6 consumer files (import + constructor type) - Removed orphan ApiService import in qearn.service.ts (never used) api.model.ts stays at services/ root since its types are still shared with other services.
AuthResponse is the response shape of the qli /Auth/Login endpoint and has only one consumer (ApiQliService). It lived in the generic api.model.ts alongside app-domain types (Transaction, QubicAsset, NetworkBalance, etc) that have no relation to qli. Moved into the qli service folder next to ApiQliService. The shared app-domain types in api.model.ts stay where they are.
…ight
Switching epochs or seeds clears transactionsRecord immediately, then
waits on the async getTransfers call to repopulate it. During that
gap, the empty-state message ('Transactions not found') flashed
briefly even when results were about to arrive.
Added a transactionsLoading flag set true before the fetch and
cleared in the subscribe's try/finally (and in the error callback,
which was previously missing entirely). The template now shows the
empty-state message only when the list is empty AND no fetch is in
flight.
Disambiguates from UpdaterService.transactionsLoading (which is a
private polling-cycle lock with different semantics). The component
flag is the in-flight signal for a single getTransfers request that
drives the empty-state template gate; the new name reads more
naturally ("is fetching transactions") and avoids the cross-class
collision a reader could trip on.
If the user rapidly switches seeds or epochs while a getTransfers call is in flight, late responses would push transactions from the previous selection into the now-displayed list, mixing data between views. The stale response's 'finally' could also clear the loading flag while a newer fetch was still in flight, briefly re-introducing the empty-state flash that 8287579 set out to eliminate. Added a monotonic fetchSeq counter — each call increments it and captures the value at the start. The captured seq is checked at three points to ensure only the currently-active fetch mutates shared state: - Top of the success callback: discards stale responses before any writes to transactionsArchiver/transactionsRecord. - Inside the success-path 'finally': clears isFetchingTransactions only if seq === fetchSeq. Handles the case where the body's 'await Promise.all(checkAndParseAssetTransfer)' yielded while a new fetch started. - Top of the error callback: discards stale errors and skips the flag clear. Generalizes over seed switching (publicId change) and epoch navigation (viewStartTick/viewEndTick change) — anything that triggers a new fetch invalidates older in-flight ones.
Three small follow-ups noted in the latest code review: - Drop a dead conjunct in the archiver→record copy guard. transactionsRecord was cleared synchronously at the start of the method, so its length is always 0 by the time we reach that branch. The check now reads as intent: copy when there is anything to copy. - Add a matching '// stale response — a newer fetch superseded this one' comment to the error callback so a reader landing there gets the same context as the success callback. - Make the fetchSeq field type explicit (`: number = 0`) for parity with the sibling tick fields (viewStartTick / viewEndTick).
The IPO path in submitIpoTransaction was building a PendingTransaction without inputHex, losing the bid's price/quantity from local state the moment the broadcast succeeded. Other contract-call paths (asset transfers, transfer-rights) already capture inputHex via storePendingTransaction. Synthesize the same 16-byte input the chain receives (price int64-LE, quantity int16-LE, 6 bytes zero padding) and store it hex-encoded on the pending entry. Layout matches QubicHelper.createIpo. No interface change — inputHex was already optional on PendingTransaction; the IPO path was simply omitting it. Keeps the wallet's pending records protocol-faithful and gives future UI / retry flows access to the bid details without round-tripping to the chain.
Promotes the local const IPO_INPUT_TYPE = 1 in transaction.service.ts to a documented export in src/app/constants/qubic.constants.ts. Matches how other input-type constants are sourced in this codebase (via QubicDefinitions for QX_TRANSFER_ASSET_INPUT_TYPE, QUTIL_SENDMANY_INPUT_TYPE). QubicDefinitions does not currently expose an IPO input type, so we define it ourselves alongside the wallet's own constants.
The hex-encode chain Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('')
appeared twice: in encodeIpoInputHex (new IPO inputHex path) and in
storePendingTransaction (existing contract-call path). Extracted into
a private bytesToHex helper so the byte-to-hex convention lives in
one place — anyone who ever wants to change it (uppercase, spaced,
faster lookup-table encoding, etc.) has a single point to edit.
Both transaction.service.ts and apis/query/api.query.service.ts had
their own copies of byte-to-hex encoding (the same
Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('')
chain), one wrapped as bytesToHex (private), the other as base64ToHex
(private, with inline duplicated byte loop).
Moved both to a new src/app/utils/hex.utils.ts module, sitting next
to the existing shifted-hex.utils.ts. base64ToHex now delegates to
bytesToHex so the lowercase-hex convention lives in exactly one place.
Net effect: one canonical encoder, both services now consume it via
import. No behavior change.
Match the pattern used by LIVE_API_BASE_PATH and QUERY_API_BASE_PATH, and drop the duplicated path comment from api.aggregation.model.ts.
feat: replace qli tx submission
Port the explorer's getTransactionTypeDisplayLong helper into src/app/utils/transaction-type.utils.ts and use it to format the "Type" cell in the balance table. Display now reads "<label> (N)" instead of "N Standard|SC (<proc>)" and supports the "Place Bid" label for shares-auction bids and protocol input-type labels. Extends QubicStaticService to fetch /v1/general/data/protocol.json for the transaction-input-type labels and adds sharesAuctionEpoch to StaticSmartContract. Adds a per-epoch tick range cache on BalanceComponent so the tick->epoch lookup driving each row doesn't rebuild a Map and sort on every change-detection cycle.
feat: replace QLI /Wallet/Assets with aggregation batch endpoint
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.