Skip to content
Merged
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
19 changes: 16 additions & 3 deletions payment-dashboard/src/views/RegistrationPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,27 @@ function RegistrationPage({
let signerAddress;
try {
const message = `register:${normalizedUsername}:${userPublicKey}`;

const result = await freighterApi.signMessage(message, {
address: userPublicKey,
});
if (result.error) throw new Error(result.error);
signature = result.signedMessage;
signerAddress = result.signerAddress;

if (result && result.error) throw new Error(result.error);

// Extract the signature properly!
// It returns the string directly, but we check both formats just in case.
signature = typeof result === 'string' ? result : result.signedMessage;

if (!signature) {
throw new Error("Failed to capture signature from Freighter.");
}

// Freighter signs using the currently connected wallet
signerAddress = userPublicKey;

} catch (err) {
setStatusMessage(err.message || "Signature request cancelled.", "error");
setIsSubmitting(false);
return;
}

Expand Down
15 changes: 12 additions & 3 deletions stellar-payment-platform/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const STELLAR_TAG_DOMAIN = process.env.STELLAR_TAG_DOMAIN;

const allowedOrigins = [
'http://localhost:5173',
'http://localhost:3000',
'https://stellar-tags.vercel.app',
STELLAR_TAG_DOMAIN,
];
Expand Down Expand Up @@ -348,7 +349,15 @@ const verifyFreighterRegistrationSignature = ({
throw new Error('Invalid message signature format.');
}

if (!keypair.verify(Buffer.from(message, 'utf8'), signatureBuffer)) {
// --- SEP-0053 Verification Logic ---
// Freighter adds a specific prefix and hashes the payload before signing
const prefix = Buffer.from('Stellar Signed Message:\n', 'utf8');
const messageBytes = Buffer.from(message, 'utf8');
const payload = Buffer.concat([prefix, messageBytes]);
const messageHash = crypto.createHash('sha256').update(payload).digest();

// Verify against the hashed payload, not the raw string!
if (!keypair.verify(messageHash, signatureBuffer)) {
const error = new Error('Signature verification failed.');
error.statusCode = 401;
throw error;
Expand Down Expand Up @@ -470,8 +479,8 @@ app.post('/register', async (req, res, next) => {
}
} else {
const claimedSigner = verifyFreighterRegistrationSignature({
username: normalizedUsername,
address,
username: req.body.username,
address: req.body.address, // Make sure this is using the raw body too!
signature,
signerAddress,
});
Expand Down
Loading