Skip to content

feat: Implement multiple issues - formatting tests, image preview, decimals validation, PWA support (#610, #497, #515, #523)#3

Open
teslims2 wants to merge 40 commits intomainfrom
feature/all-issues-610-497-515-523
Open

feat: Implement multiple issues - formatting tests, image preview, decimals validation, PWA support (#610, #497, #515, #523)#3
teslims2 wants to merge 40 commits intomainfrom
feature/all-issues-610-497-515-523

Conversation

@teslims2
Copy link
Copy Markdown
Owner

Description

Combined implementation for multiple issues:

Changes

  • Formatting test fixes
  • Image preview functionality
  • Decimals validation (0-18 inclusive)
  • PWA configuration with manifest and service worker

closes Ejirowebfi#610 Ejirowebfi#497 Ejirowebfi#515 Ejirowebfi#523

ComputerOracle and others added 30 commits March 28, 2026 13:40
This document outlines the Token Factory contract's interface, including data structures, functions, and error types.
Closes Ejirowebfi#485

## Changes

### Error enum
- Added `Error::InvalidFeeSplit = 15`
  Returned when basis points in a split map do not sum to 10_000.

### distribute_fee helper (private)
Replaces all three direct `transfer → treasury` calls in
create_token_inner, set_metadata, and mint_tokens.
- When a split is configured: iterates the Map<Address, u32> and
  transfers each recipient their proportional share
  (amount * bps / 10_000, truncated integer division).
  Any rounding remainder is sent to treasury.
- When no split is configured: single transfer to treasury (existing
  behaviour, fully backwards-compatible).

### set_fee_split(admin, splits)
- Admin-only; rejects non-admin callers with Error::Unauthorized.
- Validates that all basis-point values sum to exactly 10_000;
  rejects with Error::InvalidFeeSplit otherwise.
- Passing an empty map clears the split (fees revert to treasury).
- Stored under a separate `split` instance-storage key so
  FactoryState layout is unchanged (no migration needed).

### get_fee_split()
- Returns the current Map<Address, u32> or an empty map if unset.

### Fee split storage design
- Kept out of FactoryState to avoid breaking the existing struct
  layout for in-place WASM upgrades.

### Tests (test.rs)
- Added `Map` to imports.
- Added `make_split` helper.
- New tests:
  - test_set_fee_split_valid
  - test_set_fee_split_invalid_sum_rejected
  - test_set_fee_split_unauthorized
  - test_set_fee_split_empty_clears_split
  - test_fee_distributed_according_to_split
  - test_fee_goes_to_treasury_when_no_split_set
  - test_fee_split_remainder_goes_to_treasury
…jirowebfi#496)

Users with too little XLM to cover the fee now see a clear warning
banner and have the submit button disabled before they can even open
the confirmation modal.

## New files

hooks/useBalanceCheck.ts
- Compares wallet.balance (from WalletContext) against a required XLM
  amount passed as a number
- Returns: hasSufficientBalance, shortfall (formatted XLM string),
  isTestnet
- When wallet is not connected, hasSufficientBalance is true (no false
  positives before the user connects)

components/UI/InsufficientBalanceWarning.tsx
- Amber alert banner: 'You need X more XLM to cover the fee'
- On testnet: renders a Friendbot button that funds the wallet and
  refreshes the balance in one click (reuses useFriendbot hook)
- Exported from components/UI/index.ts

## Components updated

TokenCreateForm, MintForm, BurnForm, SetMetadataForm
- Import useBalanceCheck(0.01) and InsufficientBalanceWarning
- Submit button gains disabled={... || !hasSufficientBalance}
- Warning banner rendered below the button when balance is insufficient

Also removed a leftover duplicate code block in TokenCreateForm that
was present in the original file.

## Acceptance criteria

- Users with insufficient balance see a clear warning before attempting
  submission ✓
- The submit button is disabled when balance is too low ✓
- Testnet users are shown a link to the Stellar testnet faucet ✓
Closes Ejirowebfi#487

## Changes

### BatchTokenParams struct (new contracttype)
Fields mirror create_token params minus fee: salt, token_wasm_hash,
name, symbol, decimals, initial_supply, max_supply.

### validate_batch_params (private helper)
Stateless validation of a single BatchTokenParams entry:
- name non-empty and <= 32 chars
- symbol non-empty and <= 12 chars
- max_supply > 0 and >= initial_supply when set
Returns InvalidParameters on any violation.

### deploy_one (private helper)
Deploys, initialises, and registers a single token from a
BatchTokenParams entry. Assumes params already validated and fee
already paid. Emits the same 'created' event as create_token.

### create_tokens_batch(creator, tokens, fee_payment)
1. Checks paused / reentrancy guard.
2. Validates ALL entries via validate_batch_params before touching
   state or charging fees — entire batch rejected on first violation.
3. Calculates total_fee = base_fee * tokens.len() (overflow-safe).
4. Rejects with InsufficientFee if fee_payment < total_fee.
5. Sets reentrancy lock, deploys each token via deploy_one.
6. On any deploy error: releases lock, saves state, returns error
   (Soroban's atomic transaction model rolls back storage writes).
7. On success: distributes fee via distribute_fee, releases lock.
Returns Vec<Address> of deployed token addresses.

### Tests (test.rs)
- Added Vec to test imports.
- Added batch_param / batch_vec helpers.
- New tests:
  - test_batch_empty_rejected
  - test_batch_insufficient_fee_rejected
  - test_batch_invalid_name_rejects_entire_batch
  - test_batch_invalid_max_supply_rejects_entire_batch
  - test_batch_fee_is_base_fee_times_count
  - test_batch_blocked_when_paused
  - test_batch_reentrancy_guard
Closes Ejirowebfi#505.

## New files

docs/deployment-vercel.md
  Step-by-step guide covering:
  1. Importing the repo into Vercel
  2. Build configuration (root dir: frontend, output: dist)
  3. All required environment variables with descriptions
  4. One-click Deploy button
  5. Custom domain setup with DNS record instructions
  6. CSP HTTP header via vercel.json
  7. Preview deployments for PRs — recommended per-environment
     variable strategy (testnet for Preview, mainnet for Production)
  8. Redeploying after a contract upgrade without a code change

vercel.json (repo root)
  Configures the Content-Security-Policy response header for all
  routes, matching the CSP already defined as a <meta> tag in
  frontend/index.html. HTTP headers take precedence and support
  frame-ancestors and other directives the meta tag cannot.

## README changes

- Add 'Deploy with Vercel' one-click badge at the top of the README
  (pre-fills env var names and links to the guide for descriptions)
- Add guide link below the Frontend Deployment code block

## Acceptance criteria

- A developer with no prior Vercel experience can deploy by following
  the guide ✓
- All required environment variables are documented ✓
- The guide is linked from the main README ✓
- Add console.error logging with stack trace in ErrorBoundary.componentDidCatch
  so errors are always captured with full component stack information

- Wrap root App (and MisconfigurationScreen) in ErrorBoundary inside main.tsx
  so any unhandled render error anywhere in the tree shows a friendly screen
  instead of a blank white page

- Add a scoped ErrorBoundary around TokenForm in CreateToken.tsx to isolate
  token form crashes from the rest of the application

The ErrorBoundary already had a user-friendly fallback UI with a 'Reload Page'
button and displays the error message; this commit wires it into the app tree
and enables error logging as required by the acceptance criteria.
Audit of the codebase confirms all acceptance criteria for Ejirowebfi#474 are met
by existing code. No new implementation was required.

What exists:
- context/ToastContext.tsx: ToastProvider, useToast hook, Toast type with
  'success' | 'error' | 'warning' | 'info' variants, auto-dismiss after
  5 000 ms, manual removeToast, toasts stacked in state array
- components/UI/ToastContainer.tsx: renders stacked toasts in a fixed
  top-right portal; uses role='region' aria-live='polite' aria-label='Notifications'
  for ARIA live-region accessibility; each item has a dismiss button with
  aria-label='Dismiss notification'
- App.tsx: ToastProvider wraps the entire app tree; <ToastContainer /> is
  rendered at the bottom of AppContent so toasts appear above all content
- MintForm.tsx: calls addToast('Tokens minted successfully', 'success') on
  success and addToast(err.message, 'error') on failure
- BurnForm.tsx: calls addToast('Tokens burned successfully', 'success') on
  success and addToast(err.message, 'error') on failure
- CreateToken.tsx / TokenForm.tsx: addToast used for deploy success, deploy
  failure, validation failure, and wallet-not-connected states
- test/ToastContext.test.tsx: unit tests covering default variant, all four
  variants, stacking, auto-dismiss at 5 s, early non-dismiss at 4 999 ms,
  manual removal, and targeted removal from a multi-toast list

Introduced in commit ea22272 (feat: add global toast notification system).
…#479)

Add update_admin(current_admin, new_admin) as the canonical admin
ownership transfer function, alongside the existing transfer_admin.

Changes to lib.rs:
- update_admin requires current_admin.require_auth() so only the
  key-holder of the current admin address can call it
- Validates current_admin matches state.admin, returns Unauthorized
  otherwise
- Rejects same-address transfers with InvalidParameters
- Writes new_admin into FactoryState and persists via save_state
  (which also extends instance TTL)
- Emits an ("adm_upd",) event with (current_admin, new_admin) payload
  so off-chain indexers can track ownership history

Changes to test.rs:
- test_update_admin: happy path — new admin is stored in state
- test_update_admin_unauthorized: stranger cannot call update_admin
- test_update_admin_same_address_fails: self-transfer returns
  InvalidParameters
- test_update_admin_old_admin_loses_access: after transfer, old admin
  is rejected by pause (admin-only op) while new admin succeeds —
  directly satisfies the acceptance criteria that old admin loses
  access and new admin gains it
…d test (Ejirowebfi#480)

Audit confirms all tasks and acceptance criteria for Ejirowebfi#480 are already
satisfied by existing contract code:

Existing implementation (no changes needed):
- FactoryState.paused: bool field (lib.rs:34)
- Error::ContractPaused = 10 variant (lib.rs:57)
- require_not_paused() guard helper (lib.rs:137-140)
- pause(admin) / unpause(admin) functions with admin check (lib.rs)
- require_not_paused called at the top of create_token (lib.rs:157),
  set_metadata (lib.rs:272), and mint_tokens (lib.rs:331)
- burn() has no pause guard — intentional, users can always exit
- test_admin_can_pause_and_unpause: verifies state toggle
- test_non_admin_cannot_pause: verifies Unauthorized for strangers
- test_create_token_blocked_when_paused: verifies ContractPaused error

Gap closed by this commit:
- test_burn_allowed_when_paused: pauses the factory, then calls burn
  and asserts it succeeds and the balance is reduced correctly —
  directly covers the acceptance criterion 'burn is still allowed
  when paused (users should be able to exit)'
…split

feat(contract): add treasury fee split mechanism (Ejirowebfi#485)
…ient-balance-warning

feat(ux): insufficient balance warning before transaction submission
…reation

feat(contract): add batch token creation (Ejirowebfi#487)
…ation-system

feat: toast notification system already implemented
feat: add update_admin function to token factory contract (Ejirowebfi#479)
…-factory

feat: pause/unpause factory implemented, add burn-while-paused test
docs: Add detailed Token Factory contract ABI reference
teslims2 and others added 10 commits March 29, 2026 12:42
- Add comprehensive tests for formatting utilities (formatXLM, truncateAddress, stroopsToXLM, xlmToStroops, round-trip)
- Fix failing tests in formatting.test.ts
- Image preview is already implemented in TokenCreateForm.tsx with validation

Closes Ejirowebfi#610
Closes Ejirowebfi#497
feat: enhance token factory with DataKey enum and update storage access
…ntegration

feat: add analytics integration spec and scaffolding (Ejirowebfi#522)
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.

Add Frontend Unit Tests for Formatting Utils

9 participants