Skip to content

Commit 94e977e

Browse files
author
Mathéo
committed
SignTransaction: handle multi-transaction signing and staking
Support signing multiple transactions in a single request, with both TransactionData[] and serialized Uint8Array[] formats. Staking transactions are signed using KeyPair.derive + transaction.sign() instead of manual SignatureProof construction. Adds a multi-transaction UI with per-transaction cards, totals, and a "Confirm transactions" button variant.
1 parent 52a8552 commit 94e977e

File tree

6 files changed

+413
-47
lines changed

6 files changed

+413
-47
lines changed

src/components/PasswordBox.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class PasswordBox extends Observable {
7979
'passwordbox-log-in': '<button class="submit" data-i18n="passwordbox-log-in">Unlock</button>',
8080
'passwordbox-log-out': '<button class="submit" data-i18n="passwordbox-log-out">Confirm logout</button>',
8181
'passwordbox-confirm-tx': '<button class="submit" data-i18n="passwordbox-confirm-tx">Confirm transaction</button>',
82+
'passwordbox-confirm-txs': '<button class="submit" data-i18n="passwordbox-confirm-txs">Confirm transactions</button>',
8283
'passwordbox-create-cashlink': '<button class="submit" data-i18n="passwordbox-create-cashlink">Create cashlink</button>',
8384
'passwordbox-show-words': '<button class="submit" data-i18n="passwordbox-show-words">Show recovery words</button>',
8485
'passwordbox-sign-msg': '<button class="submit" data-i18n="passwordbox-sign-msg">Sign message</button>',

src/lib/RequestParser.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,10 @@ class RequestParser { // eslint-disable-line no-unused-vars
212212
);
213213
}
214214

215-
if (tx.sender.equals(tx.recipient)) {
215+
// Allow sender=recipient for staking transactions (e.g., retire stake)
216+
if (tx.sender.equals(tx.recipient)
217+
&& tx.senderType !== Nimiq.AccountType.Staking
218+
&& tx.recipientType !== Nimiq.AccountType.Staking) {
216219
throw new Error('Sender and recipient must not match');
217220
}
218221

src/request/sign-transaction/SignTransaction.css

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,109 @@ nothing breaks in SignMultisigTransaction. */
157157
max-width: 100%;
158158
overflow-wrap: break-word;
159159
}
160+
161+
/* Multi-transaction styles */
162+
#confirm-transaction.multi .hide-multi {
163+
display: none;
164+
}
165+
166+
/* Show only in multi-transaction mode */
167+
#confirm-transaction .multi-only {
168+
display: none;
169+
}
170+
171+
#confirm-transaction.multi .multi-only {
172+
display: block;
173+
}
174+
175+
#confirm-transaction .multi-transaction {
176+
padding: 2rem;
177+
}
178+
179+
#confirm-transaction .multi-transaction .transaction-summary {
180+
text-align: center;
181+
padding-bottom: 1.5rem;
182+
border-bottom: 1px solid rgba(31, 35, 72, 0.1);
183+
}
184+
185+
#confirm-transaction .multi-transaction .transaction-list {
186+
max-height: 35rem; /* ~280px, allows ~4-5 compact cards */
187+
overflow-y: auto;
188+
margin: 0 -2rem;
189+
padding: 0 2rem;
190+
}
191+
192+
#confirm-transaction .transaction-card {
193+
display: flex;
194+
align-items: center;
195+
padding: 1.5rem 0;
196+
border-bottom: 1px solid rgba(31, 35, 72, 0.1);
197+
}
198+
199+
#confirm-transaction .transaction-card:last-child {
200+
border-bottom: none;
201+
}
202+
203+
#confirm-transaction .transaction-card .identicon {
204+
width: 5rem;
205+
height: 5rem;
206+
flex-shrink: 0;
207+
}
208+
209+
#confirm-transaction .transaction-card .tx-details {
210+
flex-grow: 1;
211+
margin: 0 1.5rem;
212+
overflow: hidden;
213+
min-width: 0;
214+
}
215+
216+
#confirm-transaction .transaction-card .tx-address {
217+
font-size: 1.625rem;
218+
font-family: 'Fira Mono', monospace;
219+
white-space: nowrap;
220+
overflow: hidden;
221+
text-overflow: ellipsis;
222+
opacity: 0.6;
223+
}
224+
225+
#confirm-transaction .transaction-card .tx-label {
226+
font-weight: 600;
227+
white-space: nowrap;
228+
overflow: hidden;
229+
text-overflow: ellipsis;
230+
}
231+
232+
#confirm-transaction .transaction-card .tx-value {
233+
font-weight: 600;
234+
white-space: nowrap;
235+
text-align: right;
236+
color: var(--nimiq-light-blue);
237+
}
238+
239+
#confirm-transaction .transaction-card .tx-fee {
240+
font-size: 1.5rem;
241+
opacity: 0.5;
242+
text-align: right;
243+
white-space: nowrap;
244+
}
245+
246+
#confirm-transaction .multi-transaction .transaction-totals {
247+
padding-top: 1.5rem;
248+
text-align: center;
249+
border-top: 1px solid rgba(31, 35, 72, 0.1);
250+
}
251+
252+
#confirm-transaction .multi-transaction .total-value {
253+
font-size: 4rem;
254+
font-weight: bold;
255+
}
256+
257+
#confirm-transaction .multi-transaction .total-value .nim-symbol {
258+
margin-left: 1rem;
259+
font-weight: 700;
260+
}
261+
262+
#confirm-transaction .multi-transaction .total-fees {
263+
opacity: 0.5;
264+
margin-top: 0.5rem;
265+
}

0 commit comments

Comments
 (0)