nimiq-branding-cli 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/FEATURES.md +113 -0
  2. package/package.json +4 -15
  3. package/registry/components/account-header/html/account-header.css +343 -0
  4. package/registry/components/account-header/html/account-header.html +90 -0
  5. package/registry/components/account-header/html/demo.html +99 -0
  6. package/registry/components/account-header/vue/AccountHeader.vue +109 -0
  7. package/registry/components/account-list/html/account-list.css +178 -0
  8. package/registry/components/account-list/html/account-list.html +61 -0
  9. package/registry/components/account-list/html/demo.html +79 -0
  10. package/registry/components/account-list/vue/AccountList.vue +389 -0
  11. package/registry/components/account-ring/html/account-ring.css +77 -0
  12. package/registry/components/account-ring/html/account-ring.html +30 -0
  13. package/registry/components/account-ring/html/demo.html +50 -0
  14. package/registry/components/account-ring/vue/AccountRing.vue +94 -0
  15. package/registry/components/address-display/html/address-display.css +49 -0
  16. package/registry/components/address-display/html/address-display.html +6 -0
  17. package/registry/components/address-display/html/demo.html +65 -0
  18. package/registry/components/address-display/vue/AddressDisplay.vue +109 -0
  19. package/registry/components/address-input/html/address-input.css +128 -0
  20. package/registry/components/address-input/html/address-input.html +32 -0
  21. package/registry/components/address-input/html/demo.html +48 -0
  22. package/registry/components/address-input/vue/AddressInput.vue +648 -0
  23. package/registry/components/amount/html/amount.css +10 -0
  24. package/registry/components/amount/html/amount.html +8 -0
  25. package/registry/components/amount/html/demo.html +29 -0
  26. package/registry/components/amount/vue/Amount.vue +199 -0
  27. package/registry/components/amount-input/html/amount-input.css +57 -0
  28. package/registry/components/amount-input/html/amount-input.html +47 -0
  29. package/registry/components/amount-input/html/demo.html +116 -0
  30. package/registry/components/amount-input/vue/AmountInput.vue +186 -0
  31. package/registry/components/amount-with-fee/html/amount-with-fee.css +71 -0
  32. package/registry/components/amount-with-fee/html/amount-with-fee.html +33 -0
  33. package/registry/components/amount-with-fee/html/demo.html +102 -0
  34. package/registry/components/amount-with-fee/vue/AmountInput.vue +184 -0
  35. package/registry/components/amount-with-fee/vue/AmountWithFee.vue +126 -0
  36. package/registry/components/app-showcase-card/html/app-showcase-card.css +127 -0
  37. package/registry/components/app-showcase-card/html/app-showcase-card.html +41 -0
  38. package/registry/components/app-showcase-card/html/demo.html +43 -0
  39. package/registry/components/app-showcase-card/vue/AppShowcaseCard.vue +92 -0
  40. package/registry/components/backup-banner/html/backup-banner.css +45 -0
  41. package/registry/components/backup-banner/html/backup-banner.html +13 -0
  42. package/registry/components/backup-banner/html/demo.html +29 -0
  43. package/registry/components/backup-banner/vue/BackupBanner.vue +105 -0
  44. package/registry/components/balance-distribution/html/balance-distribution.css +96 -0
  45. package/registry/components/balance-distribution/html/balance-distribution.html +26 -0
  46. package/registry/components/balance-distribution/html/demo.html +32 -0
  47. package/registry/components/balance-distribution/vue/BalanceDistribution.vue +321 -0
  48. package/registry/components/buttons/html/buttons.css +443 -0
  49. package/registry/components/buttons/html/buttons.html +10 -0
  50. package/registry/components/buttons/html/demo.html +27 -0
  51. package/registry/components/buttons/vue/NqButton.vue +25 -0
  52. package/registry/components/card/html/card.css +23 -0
  53. package/registry/components/card/html/card.html +14 -0
  54. package/registry/components/card/html/demo.html +25 -0
  55. package/registry/components/card/vue/NqCard.vue +28 -0
  56. package/registry/components/close-button/html/close-button.css +32 -0
  57. package/registry/components/close-button/html/close-button.html +6 -0
  58. package/registry/components/close-button/html/demo.html +25 -0
  59. package/registry/components/close-button/vue/CloseButton.vue +44 -0
  60. package/registry/components/consensus-icon/html/consensus-icon.css +119 -0
  61. package/registry/components/consensus-icon/html/consensus-icon.html +13 -0
  62. package/registry/components/consensus-icon/html/demo.html +20 -0
  63. package/registry/components/consensus-icon/vue/ConsensusIcon.vue +154 -0
  64. package/registry/components/copyable/html/copyable.css +90 -0
  65. package/registry/components/copyable/html/copyable.html +18 -0
  66. package/registry/components/copyable/html/demo.html +111 -0
  67. package/registry/components/copyable/vue/Copyable.vue +205 -0
  68. package/registry/components/fiat-amount/html/demo.html +16 -0
  69. package/registry/components/fiat-amount/html/fiat-amount.css +4 -0
  70. package/registry/components/fiat-amount/html/fiat-amount.html +5 -0
  71. package/registry/components/fiat-amount/vue/FiatAmount.vue +282 -0
  72. package/registry/components/hero-section/html/demo.html +87 -0
  73. package/registry/components/hero-section/html/hero-section.css +136 -0
  74. package/registry/components/hero-section/html/hero-section.html +71 -0
  75. package/registry/components/hero-section/vue/HeroSection.vue +87 -0
  76. package/registry/components/honeycomb-band/html/demo.html +55 -0
  77. package/registry/components/honeycomb-band/html/honeycomb-band.css +109 -0
  78. package/registry/components/honeycomb-band/html/honeycomb-band.html +39 -0
  79. package/registry/components/honeycomb-band/vue/HoneycombBand.vue +195 -0
  80. package/registry/components/identicon/html/demo.html +48 -0
  81. package/registry/components/identicon/html/identicon.css +10 -0
  82. package/registry/components/identicon/html/identicon.html +21 -0
  83. package/registry/components/identicon/vue/Identicon.vue +89 -0
  84. package/registry/components/label-input/html/demo.html +80 -0
  85. package/registry/components/label-input/html/label-input.css +28 -0
  86. package/registry/components/label-input/html/label-input.html +32 -0
  87. package/registry/components/label-input/vue/LabelInput.vue +169 -0
  88. package/registry/components/loading-spinner/html/demo.html +53 -0
  89. package/registry/components/loading-spinner/html/loading-spinner.css +45 -0
  90. package/registry/components/loading-spinner/html/loading-spinner.html +7 -0
  91. package/registry/components/loading-spinner/vue/LoadingSpinner.vue +53 -0
  92. package/registry/components/page-body/html/demo.html +51 -0
  93. package/registry/components/page-body/html/page-body.css +7 -0
  94. package/registry/components/page-body/html/page-body.html +6 -0
  95. package/registry/components/page-body/vue/PageBody.vue +19 -0
  96. package/registry/components/page-footer/html/demo.html +48 -0
  97. package/registry/components/page-footer/html/page-footer.css +12 -0
  98. package/registry/components/page-footer/html/page-footer.html +5 -0
  99. package/registry/components/page-footer/vue/PageFooter.vue +22 -0
  100. package/registry/components/page-header/html/demo.html +51 -0
  101. package/registry/components/page-header/html/page-header.css +74 -0
  102. package/registry/components/page-header/html/page-header.html +18 -0
  103. package/registry/components/page-header/vue/PageHeader.vue +119 -0
  104. package/registry/components/payment-info-line/html/demo.html +74 -0
  105. package/registry/components/payment-info-line/html/payment-info-line.css +340 -0
  106. package/registry/components/payment-info-line/html/payment-info-line.html +73 -0
  107. package/registry/components/payment-info-line/vue/Account.vue +185 -0
  108. package/registry/components/payment-info-line/vue/PaymentInfoLine.vue +477 -0
  109. package/registry/components/payment-info-line/vue/Timer.vue +319 -0
  110. package/registry/components/price-chart/html/demo.html +36 -0
  111. package/registry/components/price-chart/html/price-chart.css +107 -0
  112. package/registry/components/price-chart/html/price-chart.html +28 -0
  113. package/registry/components/price-chart/vue/PriceChart.vue +258 -0
  114. package/registry/components/qr-code/html/demo.html +52 -0
  115. package/registry/components/qr-code/html/qr-code.css +4 -0
  116. package/registry/components/qr-code/html/qr-code.html +49 -0
  117. package/registry/components/qr-code/vue/QrCode.vue +72 -0
  118. package/registry/components/search-bar/html/demo.html +52 -0
  119. package/registry/components/search-bar/html/search-bar.css +147 -0
  120. package/registry/components/search-bar/html/search-bar.html +36 -0
  121. package/registry/components/search-bar/vue/SearchBar.vue +301 -0
  122. package/registry/components/select-bar/html/demo.html +47 -0
  123. package/registry/components/select-bar/html/select-bar.css +35 -0
  124. package/registry/components/select-bar/html/select-bar.html +40 -0
  125. package/registry/components/select-bar/vue/SelectBar.vue +89 -0
  126. package/registry/components/slider-toggle/html/demo.html +92 -0
  127. package/registry/components/slider-toggle/html/slider-toggle.css +74 -0
  128. package/registry/components/slider-toggle/html/slider-toggle.html +13 -0
  129. package/registry/components/slider-toggle/vue/SliderToggle.vue +280 -0
  130. package/registry/components/small-page/html/demo.html +33 -0
  131. package/registry/components/small-page/html/small-page.css +10 -0
  132. package/registry/components/small-page/html/small-page.html +10 -0
  133. package/registry/components/small-page/vue/SmallPage.vue +23 -0
  134. package/registry/components/status-alert/html/demo.html +53 -0
  135. package/registry/components/status-alert/html/status-alert.css +143 -0
  136. package/registry/components/status-alert/html/status-alert.html +24 -0
  137. package/registry/components/status-alert/vue/StatusAlert.vue +175 -0
  138. package/registry/components/status-screen/html/demo.html +49 -0
  139. package/registry/components/status-screen/html/status-screen.css +225 -0
  140. package/registry/components/status-screen/html/status-screen.html +25 -0
  141. package/registry/components/status-screen/vue/StatusScreen.vue +453 -0
  142. package/registry/components/swap-balance-bar/html/demo.html +100 -0
  143. package/registry/components/swap-balance-bar/html/swap-balance-bar.css +397 -0
  144. package/registry/components/swap-balance-bar/html/swap-balance-bar.html +77 -0
  145. package/registry/components/swap-balance-bar/vue/SwapBalanceBar.vue +961 -0
  146. package/registry/components/timer/html/demo.html +100 -0
  147. package/registry/components/timer/html/timer.css +102 -0
  148. package/registry/components/timer/html/timer.html +92 -0
  149. package/registry/components/timer/vue/Timer.vue +299 -0
  150. package/registry/components/toast-notification/html/demo.html +207 -0
  151. package/registry/components/toast-notification/html/toast-notification.css +153 -0
  152. package/registry/components/toast-notification/html/toast-notification.html +59 -0
  153. package/registry/components/toast-notification/vue/ToastNotification.vue +241 -0
  154. package/registry/components/tooltip/html/demo.html +153 -0
  155. package/registry/components/tooltip/html/tooltip.css +128 -0
  156. package/registry/components/tooltip/html/tooltip.html +14 -0
  157. package/registry/components/tooltip/vue/Tooltip.vue +503 -0
  158. package/registry/components/transaction-list/html/demo.html +88 -0
  159. package/registry/components/transaction-list/html/transaction-list.css +244 -0
  160. package/registry/components/transaction-list/html/transaction-list.html +73 -0
  161. package/registry/components/transaction-list/vue/TransactionList.vue +125 -0
  162. package/scripts/capture-misc-refs.mjs +100 -0
package/FEATURES.md ADDED
@@ -0,0 +1,113 @@
1
+ # Supporting Features Roadmap
2
+
3
+ Interactive widgets/flows across Nimiq's apps and sites that this CLI can scaffold as
4
+ ready-made features (beyond single components). Surveyed 2026-06-11 from live sites +
5
+ upstream sources. Full data: `references/supporting-features.json`.
6
+
7
+ ## High priority
8
+
9
+ ### Hub onboarding / connect-wallet (signup, login, choose address)
10
+ - **Where:** https://hub.nimiq.com popup via @nimiq/hub-api — source: upstream/hub/src/views/OnboardingSelector.vue, Signup.vue, Login.vue, ChooseAddress.vue, ConnectAccount.vue
11
+ - **Screenshots:** need it
12
+ - The universal 'Connect with Nimiq' flow every third-party app starts with: OnboardingMenu (create account / login / Ledger), IdenticonSelector avatar picker, ChooseAddress address selector. Composes hub components OnboardingMenu.vue, IdenticonSelector.vue, StatusScreen.vue plus @nimiq/vue-components (SmallPage, PageHeader/Body, AccountSelector). A CLI scaffold = drop-in 'connect wallet' button + callback handling.
13
+ - **Built from:** `hub/src/views/OnboardingSelector.vue`, `hub/src/views/ChooseAddress.vue`, `hub/src/components/OnboardingMenu.vue`, `hub/src/components/IdenticonSelector.vue`, `@nimiq/hub-api`, `@nimiq/vue-components AccountSelector`
14
+
15
+ ### Checkout / payment flow (Hub checkout)
16
+ - **Where:** https://hub.nimiq.com checkout via hub-api; docs at nimiq.github.io/hub — source: upstream/hub/src/views/Checkout.vue + CheckoutTransmission.vue
17
+ - **Screenshots:** need it
18
+ - Multi-currency payment sheet: currency cards (CheckoutCardNimiq/Bitcoin/Ethereum/External), CheckoutManualPaymentDetails (pay-by-address+QR fallback), PaymentInfoLine + Timer from @nimiq/vue-components, CurrencyInfo, StatusScreen success/error. This is THE merchant-facing feature (woocommerce-gateway-nimiq builds on it). CLI scaffold = 'accept NIM/BTC/ETH payment' page with callback verification.
19
+ - **Built from:** `hub/src/views/Checkout.vue`, `hub/src/components/CheckoutCardNimiq.vue`, `hub/src/components/CheckoutCardBitcoin.vue`, `hub/src/components/CheckoutCardEthereum.vue`, `hub/src/components/CheckoutManualPaymentDetails.vue`, `@nimiq/vue-components PaymentInfoLine + Timer + QrCode`
20
+
21
+ ### Cashlink create / manage / claim
22
+ - **Where:** Hub views + wallet entry points — upstream/hub/src/views/CashlinkCreate.vue, CashlinkManage.vue, CashlinkReceive.vue; wallet/src/components/CashlinkButton.vue; github.com/nimiq/cashlink-generator (bulk tool)
23
+ - **Screenshots:** have it (cashlink tx-detail modal in nimiq-branding-skill/screenshots/nimiq-wallet-app/Screenshot 2026-03-13 at 9.42.56 PM.png; create/claim screens still needed)
24
+ - Signature Nimiq feature: send NIM via shareable link, no recipient address needed. Create flow (amount + message + fee), manage (copy/share/cancel link), receive/claim flow with CashlinkSparkle celebration animation. Wallet send modal offers 'Create a Cashlink' when address unavailable; cashlink txs render specially in the tx list. High reuse for tipping, airdrops, promo apps.
25
+ - **Built from:** `hub/src/views/CashlinkCreate.vue`, `hub/src/views/CashlinkManage.vue`, `hub/src/views/CashlinkReceive.vue`, `hub/src/lib/Cashlink.ts`, `hub/src/components/CashlinkSparkle.vue`, `wallet/src/components/CashlinkButton.vue`
26
+
27
+ ### Staking calculator
28
+ - **Where:** https://www.nimiq.com/staking-calculator/ (nimiq.com website; not in local upstream clones)
29
+ - **Screenshots:** have it (nimiq-branding-skill/screenshots/staking-calculator/nimiq.com-staking-calculator-desktop.png + -mobile.png)
30
+ - Standalone marketing-grade widget: NIM amount + duration inputs -> projected rewards/APY output, branded slider UI. Self-contained (only needs supply/reward-curve math + current staked ratio from network), making it the easiest high-visual feature to scaffold for any community/validator site.
31
+ - **Built from:** `nimiq.com website widget (no local source)`, `reward-curve math from core-rs-albatross economics`, `validators-api for live staked supply`
32
+
33
+ ### Staking flow + validator picker
34
+ - **Where:** wallet.nimiq.com — upstream/wallet/src/components/staking/ (26 components)
35
+ - **Screenshots:** have it partially (staked-balance card + 'NimiqHub Staking 10.1% p.a.' row in nimiq-wallet-app/Screenshot ...9.42.22 PM.png; validator list page still needed)
36
+ - Full multi-page StakingModal wizard: StakingWelcomePage -> StakingValidatorPage (validator list with ValidatorListItem, ValidatorFilter, ValidatorScoreDetails star-ratings, ValidatorIcon/IconStack) -> StakingGraphPage (AmountSlider over balance + reward projection StakingGraph) -> StakingRewardsPage/Chart. Backed by github.com/nimiq/validators-api ('helping stakers choose where to stake'). The validator-picker subcomponent alone is valuable for pool/validator websites (e.g. stakenimiq.com).
37
+ - **Built from:** `wallet/src/components/staking/StakingModal.vue`, `StakingValidatorPage.vue`, `ValidatorListItem.vue`, `ValidatorFilter.vue`, `ValidatorScoreDetails.vue`, `AmountSlider.vue`, `StakingGraph.vue`, `StakingRewardsChart.vue`, `nimiq/validators-api`
38
+
39
+ ### QR scan + pay (request links / receive)
40
+ - **Where:** wallet.nimiq.com — upstream/wallet/src/components/modals/ScanQrModal.vue + ReceiveModal.vue; libs github.com/nimiq/qr-scanner (2.9k stars) + qr-creator
41
+ - **Screenshots:** have it (receive modal w/ request-link in ...9.42.34 PM.png; send modal w/ QR-scan entry + cashlink CTA in ...9.42.44 PM.png)
42
+ - Two halves: (1) ScanQrModal using @nimiq/vue-components QrScanner (camera scan, parses nimiq:/bitcoin:/polygon payment URIs and routes to the right send flow); (2) ReceiveModal showing identicon + chunked address + QR + 'Create request link' (amount-encoded payment URI). Both libs are standalone MIT packages, so this scaffolds cleanly into any PoS/payment app (NimiPay, Gateflo).
43
+ - **Built from:** `wallet/src/components/modals/ScanQrModal.vue`, `wallet/src/components/modals/ReceiveModal.vue`, `@nimiq/vue-components QrScanner + QrCode`, `nimiq/qr-scanner`, `nimiq/qr-creator`, `payment URI parser in wallet/src/lib`
44
+
45
+ ### Transaction history with fiat conversion + CSV export
46
+ - **Where:** wallet.nimiq.com — upstream/wallet/src/components/TransactionList.vue, TransactionListItem.vue, FiatConvertedAmount.vue, modals/HistoryExportModal.vue
47
+ - **Screenshots:** have it (mobile tx list with fiat values in nimiq-wallet-app/Screenshot ...9.42.22 PM.png)
48
+ - Virtual-scrolled, month-grouped tx list with identicon avatars, contact-label resolution, cashlink/swap badges, historic fiat value per tx (via @nimiq/utils FiatApi rates), search bar, and CSV export modal. Per-currency variants exist (BtcTransactionList, UsdcTransactionList, UsdtTransactionList) sharing the pattern. Any wallet-adjacent or accounting app wants this.
49
+ - **Built from:** `wallet/src/components/TransactionList.vue`, `TransactionListItem.vue`, `FiatConvertedAmount.vue`, `SearchBar.vue`, `modals/TransactionModal.vue`, `modals/HistoryExportModal.vue`, `@nimiq/utils FiatApi`
50
+
51
+ ### Identicon generator / avatar picker
52
+ - **Where:** github.com/nimiq/identicons (MIT) + @nimiq/vue-components Identicon.vue + hub IdenticonSelector.vue; reference doc already at nimiq-branding-skill/references/identicons.md
53
+ - **Screenshots:** have it (identicons visible in all wallet screenshots; documented in nimiq-branding-skill/references/identicons.md)
54
+ - Deterministic hexagon avatar from any Nimiq address — the most recognizable Nimiq brand element. Two scaffold targets: plain Identicon renderer (address -> SVG) and the hub's IdenticonSelector 'choose your avatar' onboarding carousel. Tiny dependency, used by literally every Nimiq app.
55
+ - **Built from:** `nimiq/identicons`, `@nimiq/vue-components Identicon.vue + AccountRing.vue`, `hub/src/components/IdenticonSelector.vue`, `wallet IdenticonButton.vue + IdenticonStack.vue`
56
+
57
+ ## Medium priority
58
+
59
+ ### Swap UI (NIM <-> BTC <-> USDC/USDT via Fastspot)
60
+ - **Where:** wallet.nimiq.com Trade > Swap — upstream/wallet/src/components/swap/ (SwapModal.vue, SwapBalanceBar.vue, SwapAnimation.vue, SwapFeesTooltip.vue, SwapNotification.vue)
61
+ - **Screenshots:** need it (only disabled Swap button visible in ...9.41.06 PM.png)
62
+ - Atomic-swap UI: dual AmountInputs with live quote, draggable SwapBalanceBar showing post-swap balance split, SwapFeesTooltip fee breakdown, full-screen SwapAnimation during HTLC execution, background SwapNotification. Visually excellent but tightly coupled to Fastspot API + @nimiq/fastspot-api + hub setupSwap — scaffold as UI shell with pluggable quote provider. Directly relevant to Hashmark-style apps.
63
+ - **Built from:** `wallet/src/components/swap/SwapModal.vue`, `SwapBalanceBar.vue`, `SwapAnimation.vue`, `SwapFeesTooltip.vue`, `@nimiq/fastspot-api`, `hub setupSwap/RefundSwap views`
64
+
65
+ ### Buy/Sell fiat on-ramp (Moonpay, Simplex, Coinify, OASIS bank swap)
66
+ - **Where:** wallet.nimiq.com Buy flow — upstream/wallet/src/components/modals/BuyOptionsModal.vue, BuyCryptoModal.vue, SellCryptoModal.vue, MoonpayModal.vue, SimplexModal.vue, CoinifyModal.vue, TradeModal.vue; OASIS marketing page nimiq.com/oasis
67
+ - **Screenshots:** have it partially (OASIS marketing page nimiq-website/nimiq.com-oasis-desktop+mobile.png; the actual buy-options modal still needed)
68
+ - Provider-chooser pattern: BuyOptionsModal geo-gates providers via useGeoIp + CountrySelector/CountryFlag, then opens provider webview modals (Moonpay/Simplex/Coinify) or the OASIS SEPA bank-swap TradeModal (SwapSepaFundingInstructions, BankCheckInput, KYC components). Scaffold value is the chooser shell + provider-modal pattern; the providers themselves need API keys/contracts, and OASIS availability has been limited — hence medium.
69
+ - **Built from:** `wallet/src/components/modals/BuyOptionsModal.vue`, `MoonpayModal.vue`, `SimplexModal.vue`, `CoinifyModal.vue`, `TradeModal.vue`, `CountrySelector.vue`, `swap/SwapSepaFundingInstructions.vue`, `BankCheckInput.vue`, `kyc/`
70
+
71
+ ### Address book / contacts
72
+ - **Where:** wallet.nimiq.com — upstream/wallet/src/components/ContactBook.vue, ContactShortcuts.vue, UsdcContactBook.vue + stores/Contacts.ts
73
+ - **Screenshots:** have it partially (Contacts entry point in send modal screenshot ...9.42.44 PM.png; open contact book still needed)
74
+ - Identicon-driven contact list: add/edit/delete with LabelInput, recent-recipient shortcuts row in the send flow, contact resolution in tx history. Small, self-contained (localStorage store), reusable in any send-money UI.
75
+ - **Built from:** `wallet/src/components/ContactBook.vue`, `ContactShortcuts.vue`, `stores/Contacts.ts`, `@nimiq/vue-components Identicon + LabelInput`, `modals/AddressSelectorModal.vue`
76
+
77
+ ### Amount input with live fiat sync
78
+ - **Where:** wallet/src/components/AmountInput.vue + AmountMenu.vue + FiatConvertedAmount.vue; @nimiq/vue-components AmountInput + AmountWithFee + FiatAmount
79
+ - **Screenshots:** need it
80
+ - Auto-scaling NIM amount input with currency-flip (enter in fiat or NIM), max-button, and live conversion line. Foundational sub-widget for send/swap/staking/checkout — worth scaffolding once as a shared primitive since the wallet version is richer than the base vue-components one.
81
+ - **Built from:** `wallet/src/components/AmountInput.vue`, `AmountMenu.vue`, `FiatConvertedAmount.vue`, `@nimiq/vue-components AmountWithFee`, `@nimiq/utils CurrencyInfo + FiatApi`
82
+
83
+ ### Network consensus indicator + network map
84
+ - **Where:** wallet.nimiq.com network view — upstream/wallet/src/components/ConsensusIcon.vue, NetworkStats.vue, NetworkMap.vue, NetworkMapPeerList.vue, modals/NetworkInfoModal.vue
85
+ - **Screenshots:** need it
86
+ - Two tiers: (a) ConsensusIcon — small animated connecting/syncing/established indicator every light-client app should show (pairs with @nimiq/core web client); (b) the full maplibre world NetworkMap with peer list + NetworkStats (uses nimiq-ui packages/nimiq-maplibre-styles). Scaffold (a) as high-value default, (b) as optional showpiece.
87
+ - **Built from:** `wallet/src/components/ConsensusIcon.vue`, `NetworkStats.vue`, `NetworkMap.vue`, `NetworkMapPeerList.vue`, `nimiq-ui/packages/nimiq-maplibre-styles`, `stores/Network.ts`
88
+
89
+ ## Low priority
90
+
91
+ ### Price chart / portfolio balance distribution
92
+ - **Where:** wallet.nimiq.com sidebar — upstream/wallet/src/components/PriceChart.vue, LineChart.vue, BalanceDistribution.vue, AccountBalance.vue
93
+ - **Screenshots:** have it (left sidebar in nimiq-wallet-app/Screenshot ...9.41.06 PM.png and wallet.nimiq.com-desktop.png)
94
+ - Sidebar sparkline price charts (NIM/BTC with 24h delta) and the BalanceDistribution bar splitting portfolio across currencies/addresses. Nice-to-have dashboard garnish; visible in held wallet screenshots.
95
+ - **Built from:** `wallet/src/components/PriceChart.vue`, `LineChart.vue`, `BalanceDistribution.vue`, `AccountBalance.vue`, `stores/Fiat.ts`
96
+
97
+ ### Fee selector
98
+ - **Where:** upstream/wallet/src/components/FeeSelector.vue (used in BTC send flow; SendModalFooter for NIM)
99
+ - **Screenshots:** need it
100
+ - Free/standard/express SelectBar with live fee-in-fiat preview. Marginal for NIM (fees ~0, mostly hidden) — really only matters for BTC sends, so low priority for a Nimiq-branding CLI.
101
+ - **Built from:** `wallet/src/components/FeeSelector.vue`, `@nimiq/vue-components SelectBar`, `lib/BitcoinTransactionUtils.ts estimateFees`
102
+
103
+ ### Vote / governance UI
104
+ - **Where:** https://nimiq.com/vote — github.com/nimiq/vote (Vue + TypeScript + Pug, MIT)
105
+ - **Screenshots:** need it
106
+ - Community-decision app: choice ranking/weighting UI where vote weight = NIM balance, signed via Hub signMessage/transaction. Niche (only used for occasional community-wide decisions) and the repo is stylistically older (Stylus/Pug), so low priority unless the CLI targets DAO-ish use cases.
107
+ - **Built from:** `nimiq/vote repo (not cloned locally)`, `@nimiq/hub-api signTransaction/chooseAddress`
108
+
109
+ ### Browser-wallet onboarding extras (welcome tour, backup nag, testnet faucet)
110
+ - **Where:** upstream/wallet/src/components/modals/WelcomeModal.vue, MigrationWelcomeModal.vue, BackupModal.vue (warning banner visible in screenshots), TestnetFaucet.vue, UpdateNotification.vue
111
+ - **Screenshots:** have it partially (backup warning banner + multisig promo modal in ...9.40.54 PM.png / ...9.41.06 PM.png)
112
+ - Supporting onboarding chrome around the wallet: first-run welcome/tour modal, persistent 'no forgot password — Backup' warning banner, release-notes/update notification, and a testnet faucet widget (handy for any Nimiq dev-demo app the CLI scaffolds). Individually small; bundle as an 'app shell extras' template.
113
+ - **Built from:** `wallet/src/components/modals/WelcomeModal.vue`, `modals/BackupModal.vue`, `TestnetFaucet.vue`, `UpdateNotification.vue`, `AnnouncementBox.vue`, `StatusScreen.vue`
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "nimiq-branding-cli",
3
- "version": "1.0.0",
4
- "description": "nq pixel-verified Nimiq UI component registry + CLI. 39 components (Vue 3 + plain HTML) diffed against the real Nimiq apps, plus the team's real asset library. Unofficial community tool.",
3
+ "version": "1.0.1",
4
+ "description": "nq \u2014 pixel-verified Nimiq UI component registry + CLI. 39 components (Vue 3 + plain HTML) diffed against the real Nimiq apps, plus the team's real asset library. Unofficial community tool.",
5
5
  "type": "module",
6
6
  "bin": {
7
- "nq": "bin/nq.js"
7
+ "nq": "./bin/nq.js"
8
8
  },
9
9
  "scripts": {
10
10
  "verify": "node scripts/verify.mjs",
@@ -36,16 +36,5 @@
36
36
  "scaffolding",
37
37
  "crypto",
38
38
  "ui"
39
- ],
40
- "files": [
41
- "bin/",
42
- "assets/",
43
- "scripts/verify.mjs",
44
- "scripts/snap.mjs",
45
- "NOTICE.md",
46
- "registry/index.json",
47
- "registry/components/*/meta.json",
48
- "registry/components/*/html/",
49
- "registry/components/*/vue/"
50
39
  ]
51
- }
40
+ }
@@ -0,0 +1,343 @@
1
+ /* Nimiq Account Header (wallet AddressOverview header)
2
+ Requires the legacy nimiq-style CSS (html{font-size:8px}, --nimiq-* vars,
3
+ .nq-button-pill / .nq-button-s / .nq-icon) + Mulish & Fira Mono fonts.
4
+ Composition of: AddressOverview.vue (.active-address + .actions),
5
+ SearchBar.vue, StakingButton.vue (+ green CTA tooltip), StakingIcon.vue,
6
+ vue-components Tooltip.vue (bottom subset).
7
+ All selectors namespaced under .account-header. */
8
+
9
+ .account-header {
10
+ /* wallet themes.scss defaults */
11
+ --bg-primary: var(--nimiq-white);
12
+ --text-16: rgba(31, 35, 72, 0.16);
13
+ --text-22: rgba(31, 35, 72, 0.22);
14
+ --light-blue-40: rgba(5, 130, 202, 0.4);
15
+ --body-size: 2rem;
16
+ --h1-size: 3rem;
17
+ --large-button-size: 2rem;
18
+ --attr-duration: 300ms;
19
+ /* AddressOverview.vue layout vars (default: 1440px) */
20
+ --padding: 4rem;
21
+ --padding-bottom: 6rem;
22
+
23
+ display: flex;
24
+ flex-direction: column;
25
+ position: relative;
26
+ background: var(--bg-primary);
27
+ color: var(--nimiq-blue);
28
+ font-family: 'Mulish', sans-serif;
29
+ /* composition chrome: room for the staking CTA tooltip (overlays the
30
+ transaction list in the wallet) */
31
+ padding-bottom: 9rem;
32
+ }
33
+
34
+ /* wallet global utilities */
35
+ .account-header .flex-row { display: flex; flex-direction: row; }
36
+ .account-header .ml-auto { margin-left: auto; }
37
+
38
+ /* ---- active address row ---- */
39
+ .account-header .active-address {
40
+ flex-shrink: 0;
41
+ align-items: center;
42
+ padding: calc(var(--padding) + 2rem);
43
+ padding-right: calc(var(--padding) + 4rem);
44
+ padding-bottom: var(--padding-bottom);
45
+ }
46
+
47
+ .account-header .active-address .identicon-wrapper {
48
+ position: relative;
49
+ margin-right: 4rem;
50
+ }
51
+
52
+ .account-header .active-address .identicon {
53
+ height: 11.25rem;
54
+ width: 11.25rem;
55
+ margin: -0.625rem 0; /* size identicon to be 90x80 px */
56
+ flex-shrink: 0;
57
+ }
58
+ .account-header .identicon img { width: 100%; height: 100%; }
59
+
60
+ .account-header .active-address .meta {
61
+ flex-grow: 1;
62
+ min-width: 0;
63
+ }
64
+ .account-header .active-address .meta .flex-row { align-items: center; }
65
+
66
+ .account-header .active-address .address,
67
+ .account-header .active-address .label {
68
+ flex-grow: 1;
69
+ overflow: hidden;
70
+ white-space: nowrap;
71
+ }
72
+
73
+ .account-header .active-address .label,
74
+ .account-header .active-address .amount {
75
+ --size: var(--h1-size);
76
+ font-size: var(--size);
77
+ margin-top: 0.25rem;
78
+ }
79
+
80
+ .account-header .active-address .address,
81
+ .account-header .active-address .fiat-amount {
82
+ --size: var(--body-size);
83
+ font-size: var(--size);
84
+ opacity: 0.5;
85
+ }
86
+
87
+ .account-header .active-address .label {
88
+ font-weight: 600;
89
+ margin-bottom: 0.75rem;
90
+ margin-right: 3rem;
91
+ mask: linear-gradient(90deg, white, white calc(100% - 3rem), rgba(255,255,255, 0));
92
+ }
93
+
94
+ .account-header .active-address .address {
95
+ word-spacing: -0.2em;
96
+ font-family: 'Fira Mono', monospace;
97
+ transition: opacity .3s var(--nimiq-ease);
98
+ }
99
+
100
+ .account-header .active-address .copyable {
101
+ padding: 0.5rem 1rem;
102
+ margin-left: -1rem;
103
+ min-width: 0;
104
+ margin-right: 3rem;
105
+ }
106
+
107
+ .account-header .active-address .fiat-amount { margin-left: auto; }
108
+
109
+ .account-header .active-address .amount,
110
+ .account-header .active-address .fiat-amount { flex-shrink: 0; }
111
+
112
+ .account-header .active-address .amount {
113
+ font-weight: bold;
114
+ margin-bottom: 0.5rem;
115
+ white-space: nowrap;
116
+ }
117
+
118
+ .account-header .active-address .fiat-amount {
119
+ font-weight: 600;
120
+ line-height: 1;
121
+ }
122
+
123
+ /* ---- actions row ---- */
124
+ .account-header .actions {
125
+ position: relative;
126
+ justify-content: space-between;
127
+ align-items: center;
128
+ gap: 1rem;
129
+ margin: 0 var(--padding) 2rem;
130
+ padding: 0 3rem 0 2rem;
131
+ }
132
+ .account-header .actions button { flex-shrink: 0; }
133
+ .account-header .actions .nq-button-pill { white-space: nowrap; }
134
+
135
+ .account-header .actions .vertical-separator {
136
+ background: rgba(31, 35, 72, 0.15);
137
+ border-radius: 2rem;
138
+ width: 1.5px;
139
+ height: 3rem;
140
+ margin: 0.625rem .5rem 0.625rem 2rem;
141
+ }
142
+
143
+ .account-header .send,
144
+ .account-header .receive {
145
+ margin: 0 0.5rem;
146
+ align-items: center;
147
+ padding: 1.125rem 2rem;
148
+ height: unset;
149
+ line-height: 1;
150
+ border-radius: 500px;
151
+ font-size: var(--large-button-size);
152
+ }
153
+ .account-header .send .nq-icon,
154
+ .account-header .receive .nq-icon {
155
+ width: 1.5rem;
156
+ height: 1.5rem;
157
+ margin-right: 1rem;
158
+ }
159
+ .account-header .send { margin-left: 1.5rem; }
160
+ .account-header .send .nq-icon { transform: rotateZ(-90deg); }
161
+ .account-header .receive { margin-right: 0; }
162
+ .account-header .receive .nq-icon { transform: rotateZ(90deg); }
163
+
164
+ /* ---- search bar ---- */
165
+ .account-header .actions .container {
166
+ width: 100%;
167
+ min-width: 5.5rem;
168
+ }
169
+ .account-header .search-bar {
170
+ --default-sb-width: clamp(5.5rem, 100%, 30rem);
171
+ position: relative;
172
+ display: flex;
173
+ flex-direction: row;
174
+ align-items: center;
175
+ width: 100%;
176
+ cursor: text;
177
+ padding: 0.75rem 0;
178
+ min-width: var(--default-sb-width);
179
+ max-width: var(--default-sb-width);
180
+ }
181
+ .account-header .search-bar::after {
182
+ content: '';
183
+ position: absolute;
184
+ top: 0; right: 0; bottom: 0; left: 0;
185
+ box-shadow: inset 0 0 0 0.1875rem var(--text-16);
186
+ border-radius: 500px;
187
+ transition: box-shadow var(--attr-duration) var(--nimiq-ease);
188
+ }
189
+ .account-header .search-bar:hover::after {
190
+ box-shadow: inset 0 0 0 0.1875rem var(--text-22);
191
+ }
192
+ .account-header .search-bar:focus-within { color: var(--nimiq-light-blue); }
193
+ .account-header .search-bar:focus-within > svg { opacity: 1; }
194
+ .account-header .search-bar:focus-within::after {
195
+ box-shadow: inset 0 0 0 0.1875rem var(--light-blue-40);
196
+ }
197
+ .account-header .search-bar > svg {
198
+ flex-grow: 0;
199
+ margin-left: 1.75rem;
200
+ margin-right: 1rem;
201
+ flex-shrink: 0;
202
+ opacity: 0.4;
203
+ width: 1.75rem;
204
+ height: 1.75rem;
205
+ transition: opacity var(--attr-duration) var(--nimiq-ease);
206
+ }
207
+ .account-header .search-bar input {
208
+ font-family: inherit;
209
+ font-weight: 600;
210
+ color: inherit;
211
+ flex-grow: 1;
212
+ border: 0;
213
+ line-height: 2.75rem;
214
+ font-size: var(--body-size);
215
+ margin: 0;
216
+ padding: 0;
217
+ padding-right: 4rem;
218
+ background: none;
219
+ min-width: 0;
220
+ }
221
+ .account-header .search-bar input:focus { outline: none; }
222
+ .account-header .search-bar input::placeholder {
223
+ font-weight: normal;
224
+ color: inherit;
225
+ opacity: 0.4;
226
+ }
227
+
228
+ /* ---- staking button + green CTA tooltip ---- */
229
+ .account-header .staking-button {
230
+ position: relative;
231
+ height: 6.75rem;
232
+ margin: -1.25rem 0;
233
+ }
234
+ .account-header .staking-button svg { font-size: 6.75rem; }
235
+ .account-header .staking-button.show-text {
236
+ display: flex;
237
+ align-items: center;
238
+ }
239
+ .account-header .stake {
240
+ display: block;
241
+ background-color: transparent;
242
+ border: 0;
243
+ cursor: pointer;
244
+ padding: 0;
245
+ }
246
+ .account-header .show-text .stake {
247
+ display: flex;
248
+ align-items: center;
249
+ height: 4.25rem;
250
+ border-radius: 20rem;
251
+ padding-right: 1.875rem;
252
+ justify-content: center;
253
+ }
254
+ .account-header .show-text .stake .staking-icon {
255
+ margin-right: -1rem;
256
+ margin-left: -.5rem;
257
+ }
258
+
259
+ .account-header .staking-icon { font-size: 0; }
260
+ .account-header .staking-icon path:nth-child(1),
261
+ .account-header .staking-icon path:nth-child(2),
262
+ .account-header .staking-icon path:nth-child(4) { opacity: 0; }
263
+
264
+ /* tooltip base (bottom-position subset of vue-components Tooltip) */
265
+ .account-header .tooltip {
266
+ display: inline-block;
267
+ position: relative;
268
+ line-height: 1;
269
+ }
270
+ .account-header .tooltip .trigger {
271
+ position: relative;
272
+ display: inline-block;
273
+ vertical-align: bottom;
274
+ text-decoration: none;
275
+ outline: none;
276
+ cursor: default;
277
+ color: inherit;
278
+ }
279
+ .account-header .tooltip .trigger::after {
280
+ opacity: 0;
281
+ content: '';
282
+ display: block;
283
+ position: absolute;
284
+ width: 2.25rem;
285
+ height: 2rem;
286
+ left: calc(50% - 1.125rem);
287
+ mask-image: url('data:image/svg+xml,<svg viewBox="0 0 18 16" xmlns="http://www.w3.org/2000/svg"><path d="M9 7.12c-.47 0-.93.2-1.23.64L3.2 14.29A4 4 0 0 1 0 16h18a4 4 0 0 1-3.2-1.7l-4.57-6.54c-.3-.43-.76-.64-1.23-.64z" fill="white"/></svg>');
288
+ transition: opacity .3s var(--nimiq-ease), .3s visibility;
289
+ transition-delay: 16ms;
290
+ visibility: hidden;
291
+ z-index: 1000;
292
+ }
293
+ .account-header .tooltip[class*='position-bottom'] .trigger::after {
294
+ top: 100%;
295
+ background: var(--background, var(--nimiq-blue));
296
+ }
297
+ .account-header .tooltip.shown .trigger::after {
298
+ opacity: 1;
299
+ visibility: visible;
300
+ }
301
+ .account-header .tooltip .tooltip-box {
302
+ contain: layout paint style;
303
+ position: absolute;
304
+ color: white;
305
+ background: var(--background, var(--nimiq-blue-bg));
306
+ padding: 1.5rem;
307
+ border-radius: .5rem;
308
+ font-size: 1.75rem;
309
+ line-height: 1.5;
310
+ font-weight: 600;
311
+ box-shadow: 0 1.125rem 2.275rem rgba(0, 0, 0, 0.11);
312
+ z-index: 999;
313
+ }
314
+ .account-header .tooltip[class*='position-bottom'] .tooltip-box {
315
+ transform: translateY(2rem);
316
+ }
317
+
318
+ /* green staking CTA tooltip (StakingButton.vue .staking-feature-tip) */
319
+ .account-header .tooltip.staking-feature-tip,
320
+ .account-header .tooltip.staking-feature-tip .trigger {
321
+ position: absolute;
322
+ top: 50%;
323
+ left: 50%;
324
+ transform: translate(-50%, -50%);
325
+ height: 100%;
326
+ width: 100%;
327
+ z-index: 3;
328
+ }
329
+ .account-header .tooltip.staking-feature-tip .trigger::after {
330
+ background-color: var(--nimiq-green);
331
+ transform: translateY(calc(-1rem + 1px));
332
+ }
333
+ .account-header .tooltip.staking-feature-tip .tooltip-box {
334
+ background: var(--nimiq-green-bg);
335
+ color: white;
336
+ font-size: 1.75rem;
337
+ font-style: normal;
338
+ font-weight: 700;
339
+ line-height: 140%;
340
+ padding: 0.5rem 1rem;
341
+ white-space: nowrap;
342
+ transform: translateY(1rem);
343
+ }
@@ -0,0 +1,90 @@
1
+ <!-- Nimiq Account Header (wallet AddressOverview header).
2
+ Include account-header.css + legacy nimiq-style CSS + Mulish & Fira Mono fonts.
3
+ The identicon img starts on the hexagon placeholder and is swapped to the
4
+ generated iqon by the pinned @nimiq/iqons recipe below (deterministic per address).
5
+ Remove the .staking-feature-tip <span> to hide the green CTA tooltip.
6
+ The root reserves 9rem bottom padding for the tooltip (in the wallet it
7
+ overlays the transaction list below). -->
8
+ <div class="account-header">
9
+
10
+ <div class="active-address flex-row">
11
+ <div class="identicon-wrapper">
12
+ <div class="identicon" data-address="NQ87 JY9X JUEE HA17 JNBB HPGM 5ETQ VT1G CVN2">
13
+ <img src='data:image/svg+xml,<svg width="64" height="64" viewBox="0 -4 64 64" fill="none" xmlns="http://www.w3.org/2000/svg"><path opacity=".1" d="M62.3 25.4L49.2 2.6A5.3 5.3 0 0 0 44.6 0H18.4c-1.9 0-3.6 1-4.6 2.6L.7 25.4c-1 1.6-1 3.6 0 5.2l13.1 22.8c1 1.6 2.7 2.6 4.6 2.6h26.2c1.9 0 3.6-1 4.6-2.6l13-22.8c1-1.6 1-3.6.1-5.2z" fill="url(%23identicon_radial)"/><defs><radialGradient id="identicon_radial" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-63.0033 0 0 -56 63 56)"><stop stop-color="%23260133"/><stop offset="1" stop-color="%231F2348"/></radialGradient></defs></svg>' alt="Nimiq identicon">
14
+ </div>
15
+ </div>
16
+ <div class="meta">
17
+ <div class="flex-row">
18
+ <div class="label">Indigo Address</div>
19
+ <span class="amount">995 <span class="currency nim">NIM</span></span>
20
+ </div>
21
+ <div class="flex-row">
22
+ <div class="copyable">
23
+ <div class="address">NQ87 JY9X JUEE HA17 JNBB HPGM 5ETQ VT1G CVN2</div>
24
+ </div>
25
+ <span class="fiat-amount">$0.50</span>
26
+ </div>
27
+ </div>
28
+ </div>
29
+
30
+ <div class="actions flex-row">
31
+ <div class="container">
32
+ <div class="search-bar">
33
+ <svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
34
+ <circle cx="6" cy="6" r="5" stroke="currentColor" stroke-width="2" />
35
+ <path d="M13.31 14.73a1 1 0 001.42-1.42l-1.42 1.42zM8.3 9.7l5.02 5.02 1.42-1.42L9.7 8.3 8.29 9.71z" fill="currentColor" />
36
+ </svg>
37
+ <input type="text" placeholder="Search transactions">
38
+ </div>
39
+ </div>
40
+
41
+ <div class="flex-row ml-auto">
42
+ <div class="staking-button show-text">
43
+ <span class="tooltip staking-feature-tip position-bottom-center shown">
44
+ <a href="javascript:void(0);" tabindex="0" class="trigger"></a>
45
+ <div class="tooltip-box" style="top: 100%; left: 50%; transform: translate(-50%, 1rem);">
46
+ Earn NIM every month by staking your NIM
47
+ </div>
48
+ </span>
49
+ <button class="stake nq-button-pill green">
50
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 140 140" class="nq-icon staking-icon">
51
+ <path opacity=".6" fill="none" stroke="#21bca5" stroke-width="3.02" d="M70 22h0a48 48 0 0148 48v0a48 48 0 01-48 48h0a48 48 0 01-48-48v0a48 48 0 0148-48z"/>
52
+ <path opacity=".4" fill="none" stroke="#21bca5" stroke-width="3.02" d="M70 12h0a58 58 0 0158 58h0a58 58 0 01-58 58h0a58 58 0 01-58-58h0a58 58 0 0158-58z" />
53
+ <path opacity=".2" fill="none" stroke="none" stroke-width="3.02" d="M70 2.25h0A67.75 67.75 0 01137.75 70v0A67.75 67.75 0 0170 137.75h0A67.75 67.75 0 012.25 70v0A67.75 67.75 0 0170 2.25z" />
54
+ <path d="M70 28.23a41.76 41.76 0 110 83.52 41.76 41.76 0 110-83.52z" fill="none"/>
55
+ <path d="M70.71 69.1v21.56m18.71-26.11c0 12.4-6.31 18.89-18.71 18.89 0-17.56 5.28-18.89 18.71-18.89zM54.18 53.98c0 13.33 4.13 20.07 16.53 20.07 0-13.43-1.03-20.07-16.53-20.07z" fill="none" stroke="#fff" stroke-width="4.0316" stroke-linecap="round" stroke-linejoin="round"/>
56
+ </svg>
57
+ <span class="stake-text">Stake</span>
58
+ </button>
59
+ </div>
60
+
61
+ <div class="vertical-separator"></div>
62
+
63
+ <button class="send nq-button-pill light-blue flex-row">
64
+ <svg class="nq-icon" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg"><path d="M10,1l5,5l-5,5" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><line x1="14" y1="6" x2="1" y2="6" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
65
+ Send
66
+ </button>
67
+ <button class="receive nq-button-s flex-row">
68
+ <svg class="nq-icon" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg"><path d="M10,1l5,5l-5,5" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><line x1="14" y1="6" x2="1" y2="6" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
69
+ Receive
70
+ </button>
71
+ </div>
72
+ </div>
73
+
74
+ </div>
75
+
76
+ <script type="module">
77
+ /* pinned identicon recipe — see registry/components/identicon */
78
+ import Iqons from 'https://cdn.jsdelivr.net/npm/@nimiq/iqons@1.6.0/dist/iqons.min.js';
79
+ // Identicon sprite: the REAL @nimiq/iqons@1.6.0 iqons.min.svg is vendored at ../../../../assets/img/iqons.min.svg
80
+ // (consumer projects: `nq add` copies it to ./nimiq/assets/img/iqons.min.svg). The iqons LIBRARY import
81
+ // above stays on the jsdelivr pin — it is code, not artwork. The CDN sprite (byte-identical content)
82
+ // is only the fallback when the local copy is unreachable (e.g. file:// contexts that block fetch).
83
+ const localIqonsSprite = '../../../../assets/img/iqons.min.svg';
84
+ const cdnIqonsSprite = 'https://cdn.jsdelivr.net/npm/@nimiq/iqons@1.6.0/dist/iqons.min.svg';
85
+ Iqons.svgPath = await fetch(localIqonsSprite, { method: 'HEAD' }).then((r) => (r.ok ? localIqonsSprite : cdnIqonsSprite)).catch(() => cdnIqonsSprite);
86
+
87
+ for (const el of document.querySelectorAll('.identicon[data-address]')) {
88
+ el.querySelector('img').src = await Iqons.toDataUrl(el.dataset.address);
89
+ }
90
+ </script>