Skip to content

Commit feead9e

Browse files
committed
error handling
1 parent 001b4e3 commit feead9e

File tree

4 files changed

+103
-94
lines changed

4 files changed

+103
-94
lines changed

tooling/sparta/packages/discord/src/slashCommands/humans/verify.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ export async function handleVerifyCommand(
3434
interaction: ChatInputCommandInteraction
3535
): Promise<void> {
3636
try {
37+
await interaction.deferReply({ flags: MessageFlags.Ephemeral });
38+
3739
const userId = interaction.user.id;
3840
const interactionToken = interaction.token;
3941
const verificationId = randomUUID();

tooling/sparta/packages/discord/src/slashCommands/operators/help.ts

Lines changed: 84 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,60 +12,120 @@ import {
1212
import { logger } from "@sparta/utils";
1313
import { NodeOperatorSubcommands } from "../../types.js";
1414

15+
// /**
16+
// * Display help information for all operator commands with reference to registration
17+
// */
18+
// export async function showOperatorHelp(
19+
// interaction: ChatInputCommandInteraction
20+
// ): Promise<string> {
21+
// try {
22+
// await interaction.deferReply({
23+
// flags: MessageFlags.Ephemeral,
24+
// });
25+
26+
// // Create a formatted embed for the command help
27+
// const helpEmbed = new EmbedBuilder()
28+
// .setTitle("🔧 Node Operator Commands")
29+
// .setDescription(
30+
// "Available commands and tools for Sparta Network node operators"
31+
// )
32+
// .setColor(0x4bb543) // Green color for operator commands
33+
// .addFields([
34+
// {
35+
// name: `/operator ${NodeOperatorSubcommands.Help}`,
36+
// value: "Display this help message with available commands",
37+
// inline: false,
38+
// },
39+
// {
40+
// name: `/operator ${NodeOperatorSubcommands.ChainInfo}`,
41+
// value: "Get current information about the Sparta Network chain status",
42+
// inline: false,
43+
// },
44+
// {
45+
// name: `/operator ${NodeOperatorSubcommands.MyStats}`,
46+
// value: "Check your validator statistics and performance\n`address` - Your validator address (required)",
47+
// inline: false,
48+
// },
49+
// {
50+
// name: `/operator ${NodeOperatorSubcommands.Register}`,
51+
// value: "Register your validator node on the discord server\n• Run without parameters for detailed registration instructions\n• Or use with:\n`address` - Your validator address\n`block-number` - Block number for verification\n`proof` - Your sync proof",
52+
// inline: false,
53+
// },
54+
// ])
55+
// .setFooter({
56+
// text: "Use these commands to manage your node operations",
57+
// })
58+
// .setTimestamp();
59+
60+
// await interaction.editReply({
61+
// embeds: [helpEmbed],
62+
// });
63+
64+
// return "Operator help information displayed successfully";
65+
// } catch (error) {
66+
// logger.error("Error displaying operator help:", error);
67+
// await interaction.editReply({
68+
// content: "Error displaying operator help information.",
69+
// });
70+
// throw error;
71+
// }
72+
// }
73+
1574
/**
16-
* Display help information for all operator commands with reference to registration
75+
* Display detailed instructions for validator registration
1776
*/
18-
export async function showOperatorHelp(
77+
export async function showRegistrationHelp(
1978
interaction: ChatInputCommandInteraction
2079
): Promise<string> {
2180
try {
2281
await interaction.deferReply({
2382
flags: MessageFlags.Ephemeral,
2483
});
2584

26-
// Create a formatted embed for the command help
27-
const helpEmbed = new EmbedBuilder()
28-
.setTitle("🔧 Node Operator Commands")
85+
// Create a registration instructions embed
86+
const registrationEmbed = new EmbedBuilder()
87+
.setTitle("📝 How to Get the Apprentice Role")
2988
.setDescription(
30-
"Available commands and tools for Sparta Network node operators"
89+
"Follow these simple steps to generate a sync proof and register your validator node on the Discord server"
3190
)
32-
.setColor(0x4bb543) // Green color for operator commands
91+
.setColor(0x4bb543) // Green color
3392
.addFields([
3493
{
35-
name: `/operator ${NodeOperatorSubcommands.Help}`,
36-
value: "Display this help message with available commands",
94+
name: "📋 Step 1: Get the latest proven block number",
95+
value: '```bash\ncurl -s -X POST -H \'Content-Type: application/json\' \\\n-d \'{"jsonrpc":"2.0","method":"node_getL2Tips","params":[],"id":67}\' \\\n<your-node>:<your-port> | jq -r ".result.proven.number"\n```\n• Replace `<your-node>:<your-port>` with your node\'s URL, for example `http://localhost:8545` or `https://mynode.example.com:8545`\n• Save this block number for the next steps\n• Example output: `12345`',
96+
inline: false,
97+
},
98+
{
99+
name: "🔍 Step 2: Generate your sync proof",
100+
value: '```bash\ncurl -s -X POST -H \'Content-Type: application/json\' \\\n-d \'{"jsonrpc":"2.0","method":"node_getArchiveSiblingPath","params":["<block-number>","<block-number>"],"id":67}\' \\\n<your-node>:<your-port> | jq -r ".result"\n```\n• Replace `<your-node>:<your-port>` with the same URL you used in Step 1\n• Replace both instances of `<block-number>` with the number from Step 1 (example: 12345)\n• This will output a long base64-encoded string - copy it completely\n• Example command with values filled in:\n```bash\ncurl -s -X POST -H \'Content-Type: application/json\' \\\n-d \'{"jsonrpc":"2.0","method":"node_getArchiveSiblingPath","params":["12345","12345"],"id":67}\' \\\nhttp://localhost:8545 | jq -r ".result"\n```',
37101
inline: false,
38102
},
39103
{
40-
name: `/operator ${NodeOperatorSubcommands.ChainInfo}`,
41-
value: "Get current information about the Sparta Network chain status",
104+
name: "✅ Step 3: Register with Discord",
105+
value: "Type the following command in this Discord server:\n```\n/operator register\n```\n**IMPORTANT**: After typing the command, Discord will display option fields that look like this:\n```\nOPTIONS\naddress Your validator address\nblock-number Block number for verification\nproof Your sync proof\n```\nClick on each option to fill in your information:\n• `address`: Your Ethereum validator address (must start with 0x, example: 0x1234567890abcdef1234567890abcdef12345678)\n• `block-number`: The block number from Step 1 (example: 12345)\n• `proof`: The complete base64 string from Step 2\n\n❗ **Common mistake**: Do not type all parameters in a single line. You must click on each option field separately to input your data.",
42106
inline: false,
43107
},
44108
{
45-
name: `/operator ${NodeOperatorSubcommands.MyStats}`,
46-
value: "Check your validator statistics and performance\n`address` - Your validator address (required)",
109+
name: "💡 Tips for Success",
110+
value: "• Ensure your node is fully synced before attempting registration\n• Double-check your validator Ethereum address format (must begin with 0x followed by 40 hex characters)\n• Make sure to copy the entire proof string without missing any characters\n• If you don't have jq installed, you can omit the `| jq` part and extract the needed values manually\n• If registration fails, try generating a new proof with a more recent block\n• Common errors: incorrect URL format, node not synced, or incomplete proof string",
47111
inline: false,
48112
},
49113
{
50-
name: `/operator ${NodeOperatorSubcommands.Start}`,
51-
value: "Register your validator node on the discord server\n• Run without parameters for detailed registration instructions\n• Or use with:\n`address` - Your validator address\n`block-number` - Block number for verification\n`proof` - Your sync proof",
114+
name: "🛠️ Troubleshooting",
115+
value: "• If you get `Connection refused`: Check that your node is running and the URL is correct\n• If your proof is invalid: Ensure your node is fully synced and try again with a newer block\n• If you can't format the commands properly: Ask for help in the support channel",
52116
inline: false,
53117
},
54-
])
55-
.setFooter({
56-
text: "Use these commands to manage your node operations",
57-
})
58-
.setTimestamp();
118+
]);
59119

60120
await interaction.editReply({
61-
embeds: [helpEmbed],
121+
embeds: [registrationEmbed],
62122
});
63123

64-
return "Operator help information displayed successfully";
124+
return "Registration instructions displayed successfully";
65125
} catch (error) {
66-
logger.error("Error displaying operator help:", error);
126+
logger.error("Error displaying registration help:", error);
67127
await interaction.editReply({
68-
content: "Error displaying operator help information.",
128+
content: "Error displaying registration instructions.",
69129
});
70130
throw error;
71131
}

tooling/sparta/packages/discord/src/slashCommands/operators/index.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
} from "../../types.js";
88
import { getValidatorStats } from "./my-info.js";
99
import { registerValidator } from "./register.js";
10-
import { showOperatorHelp } from "./help.js";
10+
import { showRegistrationHelp } from "./help.js";
1111

1212
export default {
1313
data: new SlashCommandBuilder()
@@ -32,26 +32,24 @@ export default {
3232
.addSubcommand((subcommand) =>
3333
subcommand
3434
.setName(NodeOperatorSubcommands.Start)
35-
.setDescription(
36-
"Register your validator or get registration instructions"
37-
)
35+
.setDescription("Register your validator")
3836
.addStringOption((option) =>
3937
option
4038
.setName("address")
4139
.setDescription("Your validator address")
42-
.setRequired(false)
40+
.setRequired(true)
4341
)
4442
.addStringOption((option) =>
4543
option
4644
.setName("block-number")
4745
.setDescription("Block number for verification")
48-
.setRequired(false)
46+
.setRequired(true)
4947
)
5048
.addStringOption((option) =>
5149
option
5250
.setName("proof")
5351
.setDescription("Your sync proof")
54-
.setRequired(false)
52+
.setRequired(true)
5553
)
5654
)
5755
.addSubcommand((subcommand) =>
@@ -73,7 +71,7 @@ export default {
7371
await registerValidator(interaction);
7472
break;
7573
case NodeOperatorSubcommands.Help:
76-
await showOperatorHelp(interaction);
74+
await showRegistrationHelp(interaction);
7775
break;
7876
default:
7977
await interaction.editReply({

tooling/sparta/packages/discord/src/slashCommands/operators/register.ts

Lines changed: 11 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -9,62 +9,6 @@ import { clientPromise } from "../../api/axios";
99
import { USER_ROLES } from "../../utils/roles";
1010
import { _handleNodeOperatorRoleAssignment } from "../../utils/roleAssigner";
1111

12-
/**
13-
* Display detailed instructions for validator registration
14-
*/
15-
export async function showRegistrationHelp(
16-
interaction: ChatInputCommandInteraction
17-
): Promise<string> {
18-
try {
19-
// Create a registration instructions embed
20-
const registrationEmbed = new EmbedBuilder()
21-
.setTitle("📝 How to Get the Apprentice Role")
22-
.setDescription(
23-
"Follow these simple steps to generate a sync proof and register your validator node on the Discord server"
24-
)
25-
.setColor(0x4bb543) // Green color
26-
.addFields([
27-
{
28-
name: "📋 Step 1: Get the latest proven block number",
29-
value: '```bash\ncurl -s -X POST -H \'Content-Type: application/json\' \\\n-d \'{"jsonrpc":"2.0","method":"node_getL2Tips","params":[],"id":67}\' \\\n<your-node>:<your-port> | jq -r ".result.proven.number"\n```\n• Replace `<your-node>:<your-port>` with your node\'s URL, for example `http://localhost:8545` or `https://mynode.example.com:8545`\n• Save this block number for the next steps\n• Example output: `12345`',
30-
inline: false,
31-
},
32-
{
33-
name: "🔍 Step 2: Generate your sync proof",
34-
value: '```bash\ncurl -s -X POST -H \'Content-Type: application/json\' \\\n-d \'{"jsonrpc":"2.0","method":"node_getArchiveSiblingPath","params":["<block-number>","<block-number>"],"id":67}\' \\\n<your-node>:<your-port> | jq -r ".result"\n```\n• Replace `<your-node>:<your-port>` with the same URL you used in Step 1\n• Replace both instances of `<block-number>` with the number from Step 1 (example: 12345)\n• This will output a long base64-encoded string - copy it completely\n• Example command with values filled in:\n```bash\ncurl -s -X POST -H \'Content-Type: application/json\' \\\n-d \'{"jsonrpc":"2.0","method":"node_getArchiveSiblingPath","params":["12345","12345"],"id":67}\' \\\nhttp://localhost:8545 | jq -r ".result"\n```',
35-
inline: false,
36-
},
37-
{
38-
name: "✅ Step 3: Register with Discord",
39-
value: "Type the following command in this Discord server:\n```\n/operator register\n```\n**IMPORTANT**: After typing the command, Discord will display option fields that look like this:\n```\nOPTIONS\naddress Your validator address\nblock-number Block number for verification\nproof Your sync proof\n```\nClick on each option to fill in your information:\n• `address`: Your Ethereum validator address (must start with 0x, example: 0x1234567890abcdef1234567890abcdef12345678)\n• `block-number`: The block number from Step 1 (example: 12345)\n• `proof`: The complete base64 string from Step 2\n\n❗ **Common mistake**: Do not type all parameters in a single line. You must click on each option field separately to input your data.",
40-
inline: false,
41-
},
42-
{
43-
name: "💡 Tips for Success",
44-
value: "• Ensure your node is fully synced before attempting registration\n• Double-check your validator Ethereum address format (must begin with 0x followed by 40 hex characters)\n• Make sure to copy the entire proof string without missing any characters\n• If you don't have jq installed, you can omit the `| jq` part and extract the needed values manually\n• If registration fails, try generating a new proof with a more recent block\n• Common errors: incorrect URL format, node not synced, or incomplete proof string",
45-
inline: false,
46-
},
47-
{
48-
name: "🛠️ Troubleshooting",
49-
value: "• If you get `Connection refused`: Check that your node is running and the URL is correct\n• If your proof is invalid: Ensure your node is fully synced and try again with a newer block\n• If you can't format the commands properly: Ask for help in the support channel",
50-
inline: false,
51-
},
52-
]);
53-
54-
await interaction.editReply({
55-
embeds: [registrationEmbed],
56-
});
57-
58-
return "Registration instructions displayed successfully";
59-
} catch (error) {
60-
logger.error("Error displaying registration help:", error);
61-
await interaction.editReply({
62-
content: "Error displaying registration instructions.",
63-
});
64-
throw error;
65-
}
66-
}
67-
6812
/**
6913
* Handle the "register" subcommand to verify a validator's sync proof
7014
*/
@@ -81,17 +25,22 @@ export async function registerValidator(
8125
const blockNumber = interaction.options.getString("block-number");
8226
const proof = interaction.options.getString("proof");
8327

84-
// If called without parameters, show registration help
85-
if (!address || !blockNumber || !proof) {
86-
return showRegistrationHelp(interaction);
87-
}
88-
8928
// Validate address format
90-
if (!/^0x[a-fA-F0-9]{40}$/.test(address)) {
29+
if (!address || !/^0x[a-fA-F0-9]{40}$/.test(address)) {
9130
await interaction.editReply("Invalid Ethereum address format.");
9231
return "Invalid address format";
9332
}
9433

34+
if (!blockNumber || !/^[0-9]+$/.test(blockNumber)) {
35+
await interaction.editReply("Invalid block number format.");
36+
return "Invalid block number format";
37+
}
38+
39+
if (!proof) {
40+
await interaction.editReply("Invalid proof format.");
41+
return "Invalid proof format";
42+
}
43+
9544
try {
9645
// Verify the proof using the L2InfoService
9746
const isValid = await l2InfoService.proveSynced(blockNumber, proof);

0 commit comments

Comments
 (0)