Skip to content

Commit 843a1d0

Browse files
authored
[New Tx Flow] Sign Signature (#1977)
1 parent 233a876 commit 843a1d0

File tree

5 files changed

+389
-27
lines changed

5 files changed

+389
-27
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
"use client";
2+
3+
import { useState } from "react";
4+
import { Alert, Card, Icon, Link, Text } from "@stellar/design-system";
5+
6+
import { useBuildFlowStore } from "@/store/createTransactionFlowStore";
7+
8+
import { SignTransactionXdr } from "@/components/SignTransactionXdr";
9+
import { Box } from "@/components/layout/Box";
10+
import { PageHeader } from "@/components/layout/PageHeader";
11+
12+
/**
13+
* Sign step content for the single-page transaction flow.
14+
*
15+
* Wraps `<SignTransactionXdr />` to let users sign the built (or assembled)
16+
* transaction via secret key, wallet extension, hardware wallet, or raw
17+
* signature. The signed XDR is stored in the flow store so the page's
18+
* `isNextDisabled` logic picks it up automatically.
19+
*
20+
* @example
21+
* {activeStep === "sign" && <SignStepContent />}
22+
*/
23+
export const SignStepContent = () => {
24+
const { build, simulate, sign, setSignedXdr, resetAll } = useBuildFlowStore();
25+
26+
const [errorMessage, setErrorMessage] = useState<string | null>(null);
27+
28+
// Use assembled XDR (post-simulation) if available, otherwise the built XDR
29+
const xdrToSign =
30+
simulate.assembledXdr || build.soroban.xdr || build.classic.xdr;
31+
32+
return (
33+
<Box gap="md">
34+
<Box gap="md" direction="row" justify="space-between" align="center">
35+
<PageHeader heading="Sign transaction" />
36+
37+
<Text as="div" size="xs">
38+
<Link
39+
variant="primary"
40+
onClick={() => {
41+
resetAll();
42+
}}
43+
>
44+
Clear all
45+
</Link>
46+
</Text>
47+
</Box>
48+
49+
<Text size="sm" as="div">
50+
To be included in the ledger, the transaction must be signed and
51+
submitted to the network.
52+
</Text>
53+
54+
<SignTransactionXdr
55+
id="sign-step"
56+
title="Sign transaction"
57+
xdrToSign={xdrToSign || null}
58+
onDoneAction={({ signedXdr, errorMessage }) => {
59+
setSignedXdr(signedXdr ?? "");
60+
setErrorMessage(errorMessage);
61+
}}
62+
/>
63+
64+
{errorMessage ? (
65+
<Alert variant="error" placement="inline">
66+
{errorMessage}
67+
</Alert>
68+
) : null}
69+
70+
{sign.signedXdr ? (
71+
<Card>
72+
<Box gap="md">
73+
<Alert variant="success" placement="inline">
74+
Transaction signed and ready to submit.
75+
</Alert>
76+
77+
<Box gap="xxl">
78+
<Box gap="xs">
79+
<Text
80+
size="xs"
81+
weight="medium"
82+
as="div"
83+
addlClassName="SignStepContent__label"
84+
>
85+
Signed transaction (Base64 XDR)
86+
</Text>
87+
88+
<div className="SignStepContent__xdrBox">
89+
<Text
90+
size="sm"
91+
as="div"
92+
addlClassName="SignStepContent__xdrText"
93+
>
94+
{sign.signedXdr}
95+
</Text>
96+
</div>
97+
</Box>
98+
99+
<Box gap="xs" direction="row" align="center" justify="end">
100+
<Icon.InfoCircle size="md" color="var(--sds-clr-gray-08)" />
101+
<Text
102+
size="sm"
103+
weight="medium"
104+
as="div"
105+
addlClassName="SignStepContent__feeBumpText"
106+
>
107+
Want another account to pay the fee?{" "}
108+
</Text>
109+
110+
<Link
111+
addlClassName="SignStepContent__feeBumpLink"
112+
href="/transaction/fee-bump"
113+
>
114+
Wrap with fee bump
115+
</Link>
116+
</Box>
117+
</Box>
118+
</Box>
119+
</Card>
120+
) : null}
121+
</Box>
122+
);
123+
};

src/app/(sidebar)/transaction/build/page.tsx

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client";
22

3-
import { Card, Link, Text } from "@stellar/design-system";
3+
import { Card, Link } from "@stellar/design-system";
44

55
import { useBuildFlowStore } from "@/store/createTransactionFlowStore";
66

@@ -20,13 +20,15 @@ import { Operations } from "./components/Operations";
2020
import { ClassicTransactionXdr } from "./components/ClassicTransactionXdr";
2121
import { SorobanTransactionXdr } from "./components/SorobanTransactionXdr";
2222
import { SimulateStepContent } from "./components/SimulateStepContent";
23+
import { SignStepContent } from "./components/SignStepContent";
2324

2425
import "./styles.scss";
2526

2627
export default function BuildTransaction() {
2728
const {
2829
build,
2930
simulate,
31+
sign,
3032
activeStep,
3133
highestCompletedStep,
3234
setActiveStep,
@@ -71,6 +73,9 @@ export default function BuildTransaction() {
7173
// when no auth entries are present).
7274
return !simulate.simulationResultJson;
7375
}
76+
if (activeStep === "sign") {
77+
return !sign.signedXdr;
78+
}
7479
return false;
7580
};
7681

@@ -130,18 +135,17 @@ export default function BuildTransaction() {
130135
const renderBuildStep = () => (
131136
<Box gap="md">
132137
<Box gap="md" direction="row" justify="space-between" align="center">
133-
<PageHeader heading="Build transaction" as="h1" />
134-
135-
<Text as="div" size="xs">
136-
<Link
137-
variant="primary"
138-
onClick={() => {
139-
resetAll();
140-
}}
141-
>
142-
Clear all
143-
</Link>
144-
</Text>
138+
<PageHeader heading="Build transaction" />
139+
140+
<Link
141+
variant="primary"
142+
addlClassName="resetButton"
143+
onClick={() => {
144+
resetAll();
145+
}}
146+
>
147+
Clear all
148+
</Link>
145149
</Box>
146150

147151
<Card>
@@ -180,6 +184,7 @@ export default function BuildTransaction() {
180184
<Box gap="xxl">
181185
{activeStep === "build" && renderBuildStep()}
182186
{activeStep === "simulate" && <SimulateStepContent />}
187+
{activeStep === "sign" && <SignStepContent />}
183188

184189
<TransactionFlowFooter
185190
steps={steps}

src/app/(sidebar)/transaction/build/styles.scss

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@
1818
flex: 1;
1919
min-width: 0;
2020
max-width: pxToRem(738px);
21+
22+
.SignTransactionXdr {
23+
background-color: var(--sds-clr-gray-01);
24+
}
25+
26+
.resetButton {
27+
font-weight: var(--sds-fw-semi-bold);
28+
font-size: pxToRem(12px);
29+
line-height: pxToRem(20px);
30+
}
2131
}
2232

2333
&__header {
@@ -96,3 +106,42 @@
96106
}
97107
}
98108
}
109+
110+
.SignStepContent {
111+
&__label {
112+
color: var(--sds-clr-gray-09);
113+
}
114+
115+
&__xdrBox {
116+
background-color: var(--sds-clr-gray-03);
117+
border-radius: pxToRem(12px);
118+
padding: pxToRem(16px);
119+
word-break: break-all;
120+
}
121+
122+
&__xdrText {
123+
font-family: var(--sds-ff-monospace);
124+
font-size: pxToRem(14px);
125+
line-height: pxToRem(18px);
126+
letter-spacing: -0.02em;
127+
color: var(--sds-clr-gray-12);
128+
}
129+
130+
&__feeBumpRow {
131+
padding-top: pxToRem(16px);
132+
133+
.Link {
134+
font-size: pxToRem(14px);
135+
font-weight: var(--sds-fw-semi-bold);
136+
}
137+
}
138+
139+
&__feeBumpLink {
140+
font-size: pxToRem(14px);
141+
font-weight: var(--sds-fw-semi-bold);
142+
}
143+
144+
&__feeBumpText {
145+
color: var(--sds-clr-gray-09);
146+
}
147+
}

src/constants/networkLimits.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,6 @@ export const MAINNET_LIMITS: NetworkLimits = {
8383
"persistent_rent_rate_denominator": "1215",
8484
"temp_rent_rate_denominator": "2430",
8585
"live_soroban_state_size_window": [
86-
"840818491",
87-
"841068639",
88-
"841446479",
8986
"841782063",
9087
"842328511",
9188
"843152347",
@@ -112,7 +109,10 @@ export const MAINNET_LIMITS: NetworkLimits = {
112109
"857390226",
113110
"857733706",
114111
"858370470",
115-
"859165334"
112+
"859165334",
113+
"860298690",
114+
"861187506",
115+
"861245878"
116116
],
117117
"state_target_size_bytes": "3000000000",
118118
"rent_fee_1kb_state_size_low": "-17000",
@@ -151,10 +151,6 @@ export const TESTNET_LIMITS: NetworkLimits = {
151151
"persistent_rent_rate_denominator": "1215",
152152
"temp_rent_rate_denominator": "2430",
153153
"live_soroban_state_size_window": [
154-
"951003636",
155-
"951015816",
156-
"951030708",
157-
"951276294",
158154
"951720474",
159155
"951758954",
160156
"952327983",
@@ -180,7 +176,11 @@ export const TESTNET_LIMITS: NetworkLimits = {
180176
"965014487",
181177
"966506979",
182178
"967263536",
183-
"967032524"
179+
"967032524",
180+
"967454931",
181+
"967731134",
182+
"967742426",
183+
"967754862"
184184
],
185185
"state_target_size_bytes": "3000000000",
186186
"rent_fee_1kb_state_size_low": "-17000",
@@ -219,10 +219,6 @@ export const FUTURENET_LIMITS: NetworkLimits = {
219219
"persistent_rent_rate_denominator": "1215",
220220
"temp_rent_rate_denominator": "2430",
221221
"live_soroban_state_size_window": [
222-
"69820620",
223-
"69820620",
224-
"69820620",
225-
"69820932",
226222
"69822032",
227223
"69822032",
228224
"69822032",
@@ -248,7 +244,11 @@ export const FUTURENET_LIMITS: NetworkLimits = {
248244
"69833328",
249245
"69833328",
250246
"69834740",
251-
"69834740"
247+
"69834740",
248+
"69834740",
249+
"69292272",
250+
"69292272",
251+
"69292272"
252252
],
253253
"state_target_size_bytes": "3000000000",
254254
"rent_fee_1kb_state_size_low": "-17000",

0 commit comments

Comments
 (0)