Skip to content
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
34e8de6
feat(builder): enable Midnight ecosystem in UI and feature flags
pasevin Oct 9, 2025
3013cf2
feat(ui): centralize Midnight icon and restore TypeScript declarations
pasevin Oct 9, 2025
bcd297c
Merge branch 'main' into feat/plat-6568-midnight-adapter-wallet-conne…
pasevin Oct 9, 2025
dada67d
Merge branch 'main' into feat/plat-6568-midnight-adapter-wallet-conne…
pasevin Oct 10, 2025
b6de87d
fix(builder): typo
pasevin Oct 10, 2025
ffe3dd9
Merge branch 'main' into feat/plat-6568-midnight-adapter-wallet-conne…
pasevin Oct 10, 2025
3d35f8b
feat(adapter-midnight): event-driven wallet with Lace implementation
pasevin Oct 11, 2025
2c0cc91
Merge branch 'main' into feat/plat-6568-midnight-adapter-wallet-conne…
pasevin Oct 11, 2025
b5378df
docs(common): finalize Midnight adapter spec, plan, checklists, and t…
pasevin Oct 12, 2025
394976a
docs(common): update stacked branch plan in spec header
pasevin Oct 12, 2025
2e9ec0e
test(adapter-midnight): add wallet connection tests, enable vitest co…
pasevin Oct 12, 2025
eab7653
chore(adapter-midnight): add changeset for wallet tests and vitest co…
pasevin Oct 12, 2025
60c2405
docs(common): update branch strategy in plan/tasks
pasevin Oct 12, 2025
86dc232
chore(deps): refresh pnpm-lock.yaml after adapter-midnight devDeps up…
pasevin Oct 12, 2025
38023db
test(builder): update ecosystem feature flag tests to include Midnigh…
pasevin Oct 12, 2025
de4cab1
chore(builder): set Midnight enabled by default in ecosystem registry
pasevin Oct 12, 2025
a4b74c5
Update packages/adapter-midnight/src/wallet/utils/SafeMidnightCompone…
pasevin Oct 14, 2025
befe221
Update packages/adapter-midnight/src/wallet/hooks/useMidnightWallet.ts
pasevin Oct 14, 2025
fabc38f
chore(adapter-midnight): formatting
pasevin Oct 14, 2025
8a925ec
chore(builder): reinstate type-check in build script
pasevin Oct 14, 2025
f02184e
docs(adapter-midnight): replace MidnightWalletProvider with MidnightW…
pasevin Oct 14, 2025
b0bd624
build(builder): add scoped typecheck script and keep build vite-only
pasevin Oct 14, 2025
a67385b
build(common): standardize on typecheck script; remove duplicate type…
pasevin Oct 14, 2025
232ceab
fix(adapter-midnight): address PR feedback — extract constants, remov…
pasevin Oct 14, 2025
e06cfc3
Midnight v1 – 02 Ingestion: contract artifacts + loader (#206)
pasevin Nov 4, 2025
2e421ea
fix(deps): override ua-parser-js to v1.0.41 to avoid AGPL license
pasevin Nov 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .changeset/file-upload-field-component.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
'@openzeppelin/ui-builder-ui': minor
'@openzeppelin/ui-builder-types': patch
'@openzeppelin/ui-builder-renderer': patch
---

Add FileUploadField component with drag-and-drop support

- Add new FileUploadField component to UI package with comprehensive file upload functionality
- Implement drag-and-drop file upload with visual feedback states
- Add file size validation with customizable limits
- Add file type validation via accept prop
- Include optional base64 conversion for storage
- Provide visual feedback for upload states (idle, processing, success, error)
- Full accessibility support with ARIA attributes and keyboard navigation
- Integration with React Hook Form for validation
- Add file-upload field type to types package
- Register FileUploadField in renderer field registry

Usage: Designed primarily for uploading contract artifacts (ZIP files) in Midnight adapter, but suitable for any file upload needs across the application.

14 changes: 14 additions & 0 deletions .changeset/midnight-contract-ingestion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
'@openzeppelin/ui-builder-adapter-midnight': minor
'@openzeppelin/ui-builder-app': patch
'@openzeppelin/ui-builder-storage': patch
'@openzeppelin/ui-builder-utils': patch
'@openzeppelin/ui-builder-ui': patch
---

Midnight adapter contract ingestion and shared gating

- Midnight: move loading to contract/loader; return contractDefinitionArtifacts; keep adapter thin.
- Builder: replace local required-field gating with shared utils (getMissingRequiredContractInputs); remove redundant helper.
- Utils: add contractInputs shared helpers and tests.
- Storage/App/UI: persist and rehydrate contractDefinitionArtifacts; auto-save triggers on artifact changes.
5 changes: 5 additions & 0 deletions .changeset/midnight-refactor-bytes-size.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@openzeppelin/ui-builder-adapter-midnight': patch
---

Refactor to use shared `getBytesSize` function from `@openzeppelin/ui-builder-utils` instead of local implementation. This ensures consistent bytes size parsing across all adapters and reduces code duplication.
36 changes: 36 additions & 0 deletions .changeset/midnight-wallet-event-driven-architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
'@openzeppelin/ui-builder-adapter-midnight': minor
---

# Refactor Midnight wallet management to event-driven architecture with polling-based event emulation

**Architecture Changes:**

- Refactored wallet implementation to mirror Stellar adapter structure
- Introduced `LaceWalletImplementation` class for core wallet logic
- Added `midnightWalletImplementationManager` singleton pattern
- Created `MidnightWalletUiRoot` as the primary provider component
- Removed unnecessary `MidnightWalletProvider` wrapper for consistency
- Implemented facade functions in `connection.ts` for high-level wallet operations

**Event Emulation:**

- Lace Midnight DAppConnectorWalletAPI lacks native `onAccountChange` events
- Implemented polling-based event emulation via `api.state()` with exponential backoff
- Adaptive polling intervals: 2s initial, 5s when connected, up to 15s on errors
- Polling pauses when document is hidden (tab inactive) to reduce intrusive popups
- Polling starts only when listeners subscribe, stops when all unsubscribe

**UX Improvements:**

- Fixed repeated wallet popup issue by preventing multiple `enable()` calls
- Added `connectInFlight` guard against React Strict Mode double-effects and rapid clicks
- Implemented focus/blur heuristics to detect user dismissal of unlock popup
- 60s fallback timeout prevents infinite loading state in edge cases
- Auto-reconnect on page load for seamless UX with already-enabled wallets

**Documentation:**

- Added comprehensive inline comments explaining design decisions and limitations
- Created wallet module README documenting architecture and implementation details
- Documented all workarounds needed due to Lace API limitations
5 changes: 5 additions & 0 deletions .changeset/midnight-wallet-tests-and-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@openzeppelin/ui-builder-adapter-midnight': patch
---

Add wallet connection unit tests and Vitest configuration; fix adapter imports to use local configuration barrel. Remove temporary test seam to align with other adapters.
28 changes: 28 additions & 0 deletions .changeset/runtime-secret-feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
'@openzeppelin/ui-builder-types': minor
'@openzeppelin/ui-builder-ui': minor
'@openzeppelin/ui-builder-builder': minor
'@openzeppelin/ui-builder-renderer': minor
'@openzeppelin/ui-builder-adapter-midnight': minor
---

Implement runtime-only secret field support with dual-credential execution

- Add FunctionBadge, FunctionDecoration, and FunctionDecorationsMap types to types/adapters/ui-enhancements.ts
- Extend ContractAdapter.signAndBroadcast to accept optional runtimeApiKey and runtimeSecret parameters
- Add adapterBinding field to FormFieldType for adapter-specific credential binding
- Implement Banner component for reusable notification/warning display in ui package
- Add runtimeSecret field type with adapter-driven UI rendering in builder:
- Hide "Field Type" dropdown for runtime secret fields
- Hide "Required Field" toggle for runtime secret fields
- Make "Field Label" span full width when Field Type is hidden
- Add security warning banner when hardcoded values are used
- Extract runtime secret display logic into separate components (RuntimeSecretFieldDisplay, ParameterFieldDisplay)
- Extract field header (icon, label, delete button) into FieldHeader component
- Implement reusable hooks for function notes (useGetFunctionNote) and execution validation (useExecutionValidation)
- Create FunctionNoteSection and RuntimeSecretButton components for modular form customization
- Add runtimeSecretExtractor utility for clean credential handling during transaction execution
- Support hardcoded readonly runtime secrets with proper field extraction
- Implement FunctionDecorationsService in adapter-midnight for organizer-only circuit detection
- Fix private state overlay to handle provider storage misses gracefully
- Update transaction execution flow to pass both relayer API keys and adapter-specific secrets
5 changes: 5 additions & 0 deletions .changeset/utils-bytes-size-helper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@openzeppelin/ui-builder-utils': minor
---

Add `getBytesSize` utility function to extract size from `Bytes<N>` type strings. This function parses type strings like "Bytes<32>" and returns the size as a number, or undefined for dynamic types like "Uint8Array". Useful for validating fixed-size byte arrays in adapters.
8 changes: 8 additions & 0 deletions .eslint/rules/no-extra-adapter-methods.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ module.exports = {
const interfaceMethods = [
'networkConfig',
'initialAppServiceKitName',
'getNetworkServiceForms',
'validateNetworkServiceConfig',
'testNetworkServiceConnection',
'loadContract',
'loadContractWithMetadata',
'getWritableFunctions',
Expand Down Expand Up @@ -70,6 +73,8 @@ module.exports = {
'getExportableWalletConfigFiles',
'getSupportedContractDefinitionProviders',
'getContractDefinitionInputs',
'getRuntimeFieldBinding',
'getFunctionDecorations',
'getRelayers',
'getRelayer',
'getRelayerOptionsComponent',
Expand All @@ -80,6 +85,9 @@ module.exports = {
'compareContractDefinitions',
'validateContractDefinition',
'hashContractDefinition',
'getExportBootstrapFiles',
'getArtifactPersistencePolicy',
'prepareArtifactsForFunction',
];

// Common standard methods and properties that are allowed
Expand Down
16 changes: 16 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
node_modules/
dist/
build/
out/
coverage/
*.min.js
.next/
.nuxt/
.output/
.cache/
.turbo/
.vercel/
.netlify/
exports/
packages/builder/test-results/

7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ yarn.lock
# pnpm-lock.yaml - uncomment if using npm or yarn instead of pnpm
# pnpm-lock.yaml
.pnpm-debug.log*
.pnpm-store/
.packed-packages/

# Build outputs
dist/
Expand All @@ -27,6 +29,11 @@ packages/builder/test-results/
# Test exports
exports/

# Generated patches in packages
# Source of truth is root patches/ directory
# These are generated by scripts/sync-patches-to-adapters.js
packages/*/patches/

# Environment variables
.env
.env.local
Expand Down
16 changes: 16 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
node_modules/
dist/
build/
out/
coverage/
exports/
package-lock.json
yarn.lock
pnpm-lock.yaml
.next/
.nuxt/
.output/
.cache/
.turbo/
.vercel/
.netlify/
# Build outputs
dist/
build/
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ RUN pnpm install --frozen-lockfile || (echo "Install failed, clearing caches and
RUN --mount=type=secret,id=etherscan_api_key \
sh -c 'if [ -f /run/secrets/etherscan_api_key ]; then \
export VITE_APP_CFG_SERVICE_ETHERSCANV2_API_KEY=$(cat /run/secrets/etherscan_api_key) && \
NODE_OPTIONS="--max-old-space-size=8192" pnpm -r build; \
pnpm build; \
else \
echo "Warning: Building without Etherscan API key" && \
NODE_OPTIONS="--max-old-space-size=8192" pnpm -r build; \
pnpm build; \
fi'

# Runtime stage - using a slim image for a smaller footprint
Expand Down
Loading
Loading