101 lines
3.0 KiB
JavaScript
101 lines
3.0 KiB
JavaScript
const express = require('express');
|
|
const router = express.Router();
|
|
const cashu = require('../components/cashu');
|
|
|
|
/**
|
|
* @swagger
|
|
* /api/decode:
|
|
* post:
|
|
* summary: Decode a Cashu token
|
|
* description: Decode a Cashu token and return its content. Supports both v1 and v3 token formats.
|
|
* tags: [Token Operations]
|
|
* requestBody:
|
|
* required: true
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* $ref: '#/components/schemas/DecodeRequest'
|
|
* responses:
|
|
* 200:
|
|
* description: Token decoded successfully
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* $ref: '#/components/schemas/DecodeResponse'
|
|
* 400:
|
|
* $ref: '#/components/responses/BadRequest'
|
|
* 429:
|
|
* $ref: '#/components/responses/TooManyRequests'
|
|
* 500:
|
|
* $ref: '#/components/responses/InternalServerError'
|
|
*/
|
|
router.post('/decode', async (req, res) => {
|
|
const { token } = req.body;
|
|
|
|
if (!token) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
error: 'Token is required'
|
|
});
|
|
}
|
|
|
|
try {
|
|
if (!cashu.isValidTokenFormat(token)) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
error: 'Invalid token format. Must be a valid Cashu token'
|
|
});
|
|
}
|
|
|
|
const decoded = await cashu.parseToken(token);
|
|
const mintUrl = await cashu.getTokenMintUrl(token);
|
|
|
|
let spent = false;
|
|
try {
|
|
const spendabilityCheck = await cashu.checkTokenSpendable(token);
|
|
spent = !spendabilityCheck.spendable || spendabilityCheck.spendable.length === 0;
|
|
} catch (error) {
|
|
console.warn('Spendability check failed:', error.message);
|
|
|
|
const errorString = error.message || error.toString();
|
|
|
|
if (errorString.includes('TOKEN_SPENT:')) {
|
|
console.log('Token determined to be spent by CashuComponent');
|
|
spent = true;
|
|
} else if (errorString.includes('Token validation failed at mint:')) {
|
|
console.log('Token validation failed at mint - assuming token is still valid (might be invalid format)');
|
|
spent = false;
|
|
} else if (errorString.includes('not supported') ||
|
|
errorString.includes('endpoint not found') ||
|
|
errorString.includes('may still be valid') ||
|
|
errorString.includes('does not support spendability checking')) {
|
|
console.log('Mint does not support spendability checking - assuming token is valid');
|
|
spent = false;
|
|
} else {
|
|
console.log('Unknown error - assuming token is valid');
|
|
spent = false;
|
|
}
|
|
}
|
|
|
|
res.json({
|
|
success: true,
|
|
decoded: {
|
|
mint: decoded.mint,
|
|
totalAmount: decoded.totalAmount,
|
|
numProofs: decoded.numProofs,
|
|
denominations: decoded.denominations,
|
|
format: decoded.format,
|
|
spent
|
|
},
|
|
mint_url: mintUrl
|
|
});
|
|
} catch (error) {
|
|
res.status(400).json({
|
|
success: false,
|
|
error: error.message
|
|
});
|
|
}
|
|
});
|
|
|
|
module.exports = router;
|