Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions __tests__/components/builder/extrinsic-builder.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -260,16 +260,16 @@ describe("ExtrinsicBuilder", () => {
expect(screen.getByText("Sign and Submit")).toBeInTheDocument();
});

it("shows Submitting... when isPending", () => {
it("shows Sign and Submit when account connected and not submitting", () => {
(useAccount as jest.Mock).mockReturnValue({
account: { address: "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" },
});
(useSendTransaction as jest.Mock).mockReturnValue({
sendTransactionAsync: jest.fn(),
isPending: true,
isPending: false,
});
render(<TestWrapper tx={{ meta: { fields: [] } }} />);
expect(screen.getByText("Submitting...")).toBeInTheDocument();
expect(screen.getByText("Sign and Submit")).toBeInTheDocument();
});

it("submit button disabled when no tx", () => {
Expand Down
54 changes: 42 additions & 12 deletions components/builder/extrinsic-builder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ const ExtrinsicBuilder: React.FC<ExtrinsicBuilderProps> = ({
}) => {
const sections = createSectionOptions(client.metadata.latest);
const { account } = useAccount();
const { sendTransactionAsync, isPending } = useSendTransaction();
const { sendTransactionAsync } = useSendTransaction();
const [isSubmitting, setIsSubmitting] = useState(false);

const [methods, setMethods] = useState<
{ text: string; value: number }[] | null
Expand Down Expand Up @@ -191,24 +192,48 @@ const ExtrinsicBuilder: React.FC<ExtrinsicBuilderProps> = ({
return;
}

setIsSubmitting(true);
try {
// Build the args array from form data matching tx field order
const args = fields.map((field) => data[field.name || ""]);

// Create the submittable extrinsic by calling the tx function with args
const extrinsic = (tx as any)(...args);

toast.info("Signing and submitting transaction...");
toast.info("Signing transaction...", {
description: "Please approve in your wallet extension.",
});

const receipt = await sendTransactionAsync({ extrinsic });

toast.success("Transaction included in block", {
description: `Block: ${receipt.blockHash}`,
});
if (receipt.status === "failed") {
const errorMsg = receipt.errorMessage || receipt.dispatchError
? `Dispatch error: ${receipt.errorMessage || JSON.stringify(receipt.dispatchError)}`
: "Transaction failed on-chain";
toast.error("Transaction failed", {
description: errorMsg,
});
} else {
toast.success("Transaction included in block", {
description: `Block: ${receipt.blockHash}`,
});
}
} catch (error) {
const message = error instanceof Error ? error.message : "Unknown error";
toast.error("Transaction failed", { description: message });
// Distinguish user rejection from other errors
const isUserRejection =
message.includes("Cancelled") ||
message.includes("Rejected") ||
message.includes("User denied") ||
message.includes("rejected");
if (isUserRejection) {
toast.info("Transaction cancelled by user.");
} else {
toast.error("Transaction failed", { description: message });
}
console.error("Error signing and sending extrinsic:", error);
} finally {
setIsSubmitting(false);
}
};

Expand Down Expand Up @@ -426,13 +451,18 @@ const ExtrinsicBuilder: React.FC<ExtrinsicBuilderProps> = ({
<div className="flex justify-end">
<Button
type="submit"
disabled={!account || !tx || isPending}
disabled={!account || !tx || isSubmitting}
>
{isPending
? "Submitting..."
: !account
? "Connect Wallet to Submit"
: "Sign and Submit"}
{isSubmitting ? (
<>
<Loader2 className="h-4 w-4 animate-spin mr-2" />
Submitting...
</>
) : !account ? (
"Connect Wallet to Submit"
) : (
"Sign and Submit"
)}
</Button>
</div>
</form>
Expand Down
25 changes: 21 additions & 4 deletions components/studio/deploy-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,16 +191,33 @@ export function DeploySection() {
salt
);

addLog("info", "Signing... approve in your wallet extension.");

const receipt = await sendTransactionAsync({ extrinsic });

addLog("success", `Deployed in block: ${receipt.blockHash}`);
if (gasEstimation.deployedAddress) {
addLog("success", `Address: ${gasEstimation.deployedAddress}`);
if (receipt.status === "failed") {
const errorMsg = receipt.errorMessage || (receipt.dispatchError
? JSON.stringify(receipt.dispatchError)
: "Transaction failed on-chain");
addLog("error", `Deploy failed: ${errorMsg}`);
} else {
addLog("success", `Deployed in block: ${receipt.blockHash}`);
if (gasEstimation.deployedAddress) {
addLog("success", `Address: ${gasEstimation.deployedAddress}`);
}
}
} catch (error) {
const message =
error instanceof Error ? error.message : "Deploy failed";
addLog("error", message);
const isUserRejection =
message.includes("Cancelled") ||
message.includes("Rejected") ||
message.includes("User denied") ||
message.includes("rejected");
addLog(
isUserRejection ? "info" : "error",
isUserRejection ? "Transaction cancelled by user" : message
);
}
};

Expand Down