Skip to content

Commit e5b492f

Browse files
release: Nested multisig support, updated landing page, updated dependencies (#317)
* feature: Nested multisig (#310) * retry multisig detect * nested multisig example * Transfer button example * approve multisig call - Allow to choose multsig as signatory - New dropdown menu to choose signatory from multisig * Fix isNested condition and clean up (#309) * merge dev * fix nested case condition and clean up * fix tests * format --------- Co-authored-by: Carlos Medeiros <[email protected]> * Remove letter animation form home page (#312) * Remove phrase "without proper guid..." from landing page (#313) * update deps (#316) --------- Co-authored-by: Carlos Medeiros <[email protected]>
2 parents e596715 + e5d7364 commit e5b492f

23 files changed

+2042
-1051
lines changed

components/hooks/useTransactionStatus.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,29 @@ export const useTransactionStatus = <T extends GenericFunction>(
6161
hash: txDetails?.txHash,
6262
blockHash: txDetails?.blockHash,
6363
blockNumber: txDetails?.blockNumber,
64+
callData: txDetails?.callData,
65+
callHash: txDetails?.callHash,
6466
}))
6567
}, [])
6668

6769
// Run a generic transaction
6870
const runTransaction = useCallback(
6971
async (...args: Parameters<T>) => {
70-
setTxStatus({
71-
status: TransactionStatus.IS_LOADING,
72-
})
73-
await transactionFn(updateTxStatus, ...args)
74-
setIsTxFinished(true)
72+
try {
73+
setTxStatus({
74+
status: TransactionStatus.IS_LOADING,
75+
})
76+
await transactionFn(updateTxStatus, ...args)
77+
setIsTxFinished(true)
78+
} catch (error) {
79+
console.error('[useTransactionStatus] Transaction error:', error)
80+
setTxStatus({
81+
status: TransactionStatus.ERROR,
82+
statusMessage: 'An unexpected error occurred',
83+
})
84+
setIsTxFinished(true)
85+
throw error
86+
}
7587
},
7688
[transactionFn, updateTxStatus]
7789
)

components/sections/home/home-page.tsx

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ export function HomePage({
1919
subtitle = 'Simplifying your journey to the new Polkadot Universal Ledger App',
2020
animationSpeed = 1,
2121
}: HomePageProps) {
22-
const words = title.split(' ')
23-
2422
return (
2523
<div className="relative min-h-screen w-full flex items-center justify-center overflow-hidden">
2624
{/* Background with gradient and animations */}
@@ -33,31 +31,20 @@ export function HomePage({
3331
transition={{ duration: 2 / animationSpeed }}
3432
className="max-w-4xl mx-auto"
3533
>
36-
<h1 className="text-4xl sm:text-6xl md:text-7xl font-bold mb-6 tracking-tighter">
37-
{words.map((word, wordIndex) => (
38-
// biome-ignore lint/suspicious/noArrayIndexKey: word content makes index stable
39-
<span key={`word-${word}-${wordIndex}`} className="inline-block mr-4 last:mr-0">
40-
{word.split('').map((letter, letterIndex) => (
41-
<motion.span
42-
// biome-ignore lint/suspicious/noArrayIndexKey: letter content makes index stable
43-
key={`letter-${word}-${wordIndex}-${letter}-${letterIndex}`}
44-
initial={{ y: 100, opacity: 0 }}
45-
animate={{ y: 0, opacity: 1 }}
46-
transition={{
47-
delay: (wordIndex * 0.1 + letterIndex * 0.03) / animationSpeed,
48-
type: 'spring',
49-
stiffness: 150,
50-
damping: 25,
51-
}}
52-
className="inline-block text-transparent bg-clip-text
53-
bg-linear-to-r from-white to-white/80"
54-
>
55-
{letter}
56-
</motion.span>
57-
))}
58-
</span>
59-
))}
60-
</h1>
34+
<motion.h1
35+
initial={{ y: 20, opacity: 0 }}
36+
animate={{ y: 0, opacity: 1 }}
37+
transition={{
38+
duration: 1 / animationSpeed,
39+
type: 'spring',
40+
stiffness: 150,
41+
damping: 25,
42+
}}
43+
className="text-4xl sm:text-6xl md:text-7xl font-bold mb-6 tracking-tighter
44+
text-transparent bg-clip-text bg-linear-to-r from-white to-white/80"
45+
>
46+
{title}
47+
</motion.h1>
6148

6249
<motion.p
6350
initial={{ opacity: 0, y: 20 }}

components/sections/home/problem-section.tsx

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,6 @@ export default function ProblemSection() {
5151
</p>
5252
</motion.div>
5353
</div>
54-
55-
<motion.div
56-
initial={{ opacity: 0, y: 30 }}
57-
whileInView={{ opacity: 1, y: 0 }}
58-
viewport={{ once: true }}
59-
transition={{ duration: 0.8, delay: 0.4 }}
60-
className="mt-12 text-center"
61-
>
62-
<div className="inline-block px-6 py-3 rounded-full bg-red-50 text-red-700 font-medium">
63-
Without proper guidance, migration risks and frustration increase
64-
</div>
65-
</motion.div>
6654
</div>
6755
</section>
6856
)

components/sections/migrate/__tests__/synchronized-account-row-extended.test.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ vi.mock('lucide-react', () => ({
1515
!
1616
</div>
1717
),
18+
AlertTriangle: () => <div data-testid="alert-triangle"></div>,
1819
Banknote: () => <div data-testid="banknote">💰</div>,
1920
BanknoteArrowDown: () => <div data-testid="banknote-arrow-down">💰⬇</div>,
2021
Check: () => <div data-testid="check"></div>,
@@ -24,6 +25,7 @@ vi.mock('lucide-react', () => ({
2425
KeyRound: () => <div data-testid="key-round">🔑</div>,
2526
LockOpen: () => <div data-testid="lock-open">🔓</div>,
2627
Route: () => <div data-testid="route">🛣</div>,
28+
Send: () => <div data-testid="send">📤</div>,
2729
Shield: () => <div data-testid="shield">🛡</div>,
2830
Trash2: () => <div data-testid="trash2">🗑</div>,
2931
User: () => <div data-testid="user">👤</div>,
@@ -33,6 +35,7 @@ vi.mock('lucide-react', () => ({
3335
</div>
3436
),
3537
Users: () => <div data-testid="users">👥</div>,
38+
Vote: () => <div data-testid="vote">🗳</div>,
3639
X: () => <div data-testid="x"></div>,
3740
}))
3841

components/sections/migrate/__tests__/synchronized-account-row.test.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ vi.mock('@legendapp/state/react', () => ({
1111

1212
vi.mock('lucide-react', () => ({
1313
AlertCircle: () => null,
14+
AlertTriangle: () => null,
1415
Banknote: () => null,
1516
BanknoteArrowDown: () => null,
1617
Check: () => null,
@@ -20,11 +21,13 @@ vi.mock('lucide-react', () => ({
2021
KeyRound: () => null,
2122
LockOpen: () => null,
2223
Route: () => null,
24+
Send: () => null,
2325
Shield: () => null,
2426
Trash2: () => null,
2527
User: () => null,
2628
UserCog: () => null,
2729
Users: () => null,
30+
Vote: () => null,
2831
X: () => null,
2932
}))
3033

components/sections/migrate/dialogs/__tests__/approve-multisig-call-dialog.test.tsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,20 @@ vi.mock('@/lib/utils/multisig', () => ({
149149
correct: 'Call data is valid',
150150
failed: 'Validation failed',
151151
},
152+
EnhancedMultisigMember: {},
152153
getRemainingInternalSigners: vi.fn(() => []),
154+
getRemainingSigners: vi.fn(() => []),
155+
getAvailableSigners: vi.fn(() => []),
153156
validateCallData: vi.fn(() => Promise.resolve({ isValid: true })),
154157
}))
155158

156159
vi.mock('@/state/ledger', () => ({
157160
ledgerState$: {
161+
apps: {
162+
apps: {
163+
get: vi.fn(() => []),
164+
},
165+
},
158166
approveMultisigCall: vi.fn(),
159167
synchronizeAccount: vi.fn(),
160168
},
@@ -306,8 +314,8 @@ describe('ApproveMultisigCallDialog', () => {
306314
render(<ApproveMultisigCallDialog {...defaultProps} />)
307315

308316
// Check for key form elements
309-
expect(screen.getAllByTestId('dialog-field')).toHaveLength(6) // Multisig Address, Call Hash, Approvers, Deposit, Network, Signer
310-
expect(screen.getAllByTestId('dialog-label')).toHaveLength(6)
317+
expect(screen.getAllByTestId('dialog-field')).toHaveLength(7) // Multisig Address, Call Hash, Call Hash (for sharing), Approvers, Deposit, Network, Signer
318+
expect(screen.getAllByTestId('dialog-label')).toHaveLength(7)
311319
expect(screen.getAllByTestId('select')).toHaveLength(2)
312320
expect(screen.getByTestId('transaction-dialog-footer')).toBeInTheDocument()
313321
})
@@ -507,15 +515,16 @@ describe('ApproveMultisigCallDialog', () => {
507515
const switchElement = screen.getByTestId('switch')
508516
expect(switchElement).toHaveAttribute('id', 'final-approval-switch')
509517

510-
const infoIcon = screen.getByTestId('info-icon')
511-
expect(infoIcon).toHaveAttribute('aria-label', 'Info')
518+
const infoIcons = screen.getAllByTestId('info-icon')
519+
expect(infoIcons.length).toBeGreaterThan(0)
520+
expect(infoIcons[0]).toHaveAttribute('aria-label', 'Info')
512521
})
513522

514523
it('should have proper form labels', () => {
515524
render(<ApproveMultisigCallDialog {...defaultProps} />)
516525

517526
const labels = screen.getAllByTestId('dialog-label')
518-
expect(labels).toHaveLength(6)
527+
expect(labels).toHaveLength(7)
519528
})
520529
})
521530
})

0 commit comments

Comments
 (0)