-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8b502b0
commit 8312933
Showing
9 changed files
with
219 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import { validateStakeAddress } from '../../../utils/validation.js'; | ||
// import { getSchemaForEndpoint } from '@blockfrost/openapi'; | ||
import { FastifyInstance, FastifyRequest } from 'fastify'; | ||
import { SQLQuery } from '../../../sql/index.js'; | ||
// import * as ResponseTypes from '../../../types/responses/accounts.js'; | ||
import * as QueryTypes from '../../../types/queries/accounts.js'; | ||
import { getDbSync, gracefulRelease } from '../../../utils/database.js'; | ||
import { isUnpaged } from '../../../utils/routes.js'; | ||
import { toJSONStream } from '../../../utils/string-utils.js'; | ||
import { handle400Custom, handle404 } from '../../../utils/error-handler.js'; | ||
|
||
async function route(fastify: FastifyInstance) { | ||
fastify.route({ | ||
url: '/accounts/:stake_address/utxos', | ||
method: 'GET', | ||
// TODO | ||
// schema: getSchemaForEndpoint('/addresses/{address}/utxos'), | ||
handler: async (request: FastifyRequest<QueryTypes.RequestAccountsQueryParameters>, reply) => { | ||
const clientDbSync = await getDbSync(fastify); | ||
|
||
try { | ||
// Check stake address format. Return 400 on non-valid stake address | ||
const isStakeAddressValid = validateStakeAddress(request.params.stake_address); | ||
|
||
if (!isStakeAddressValid) { | ||
gracefulRelease(clientDbSync); | ||
return handle400Custom(reply, 'Invalid or malformed stake address format.'); | ||
} | ||
|
||
const query404 = await clientDbSync.query<QueryTypes.ResultFound>( | ||
SQLQuery.get('accounts_404'), | ||
[request.params.stake_address], | ||
); | ||
|
||
if (query404.rows.length === 0) { | ||
return handle404(reply); | ||
} | ||
|
||
const unpaged = isUnpaged(request); | ||
const { rows } = unpaged | ||
? await clientDbSync.query<QueryTypes.AccountUtxosQuery>( | ||
SQLQuery.get('accounts_stake_address_rewards_unpaged'), | ||
[request.query.order, request.params.stake_address], | ||
) | ||
: await clientDbSync.query<QueryTypes.AccountUtxosQuery>( | ||
SQLQuery.get('accounts_stake_address_utxos'), | ||
[ | ||
request.query.order, | ||
request.query.count, | ||
request.query.page, | ||
request.params.stake_address, | ||
], | ||
); | ||
|
||
gracefulRelease(clientDbSync); | ||
|
||
const result = rows.map(row => ({ | ||
address: row.address, | ||
tx_hash: row.tx_hash, | ||
tx_index: row.tx_index, | ||
output_index: row.output_index, | ||
amount: [ | ||
{ | ||
unit: 'lovelace', | ||
quantity: row.amount_lovelace, | ||
}, | ||
...(row.amount ?? []), | ||
], | ||
block: row.block, | ||
data_hash: row.data_hash, | ||
inline_datum: row.inline_datum, | ||
reference_script_hash: row.reference_script_hash, | ||
})); | ||
|
||
if (unpaged) { | ||
// Use of Reply.raw functions is at your own risk as you are skipping all the Fastify logic of handling the HTTP response | ||
// https://www.fastify.io/docs/latest/Reference/Reply/#raw | ||
reply.raw.writeHead(200, { 'Content-Type': 'application/json' }); | ||
await toJSONStream(result, reply.raw); | ||
return reply; | ||
} else { | ||
return reply.send(result); | ||
} | ||
} catch (error) { | ||
gracefulRelease(clientDbSync); | ||
throw error; | ||
} | ||
}, | ||
}); | ||
} | ||
|
||
export default route; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
-- Same as addresses_address_utxos.sql except this has JOIN stake_address sa ON (txo.stake_address_id = sa.id) | ||
-- and additional WHERE condition sa.view = $4 | ||
SELECT txo.address AS "address", | ||
encode(tx.hash, 'hex') AS "tx_hash", | ||
txo.index AS "tx_index", | ||
txo.index AS "output_index", | ||
txo.value::TEXT AS "amount_lovelace", -- cast to TEXT to avoid number overflow | ||
( | ||
SELECT json_agg( | ||
json_build_object( | ||
'unit', | ||
CONCAT(encode(ma.policy, 'hex'), encode(ma.name, 'hex')), | ||
'quantity', | ||
mto.quantity::TEXT -- cast to TEXT to avoid number overflow | ||
) | ||
) | ||
FROM ma_tx_out mto | ||
JOIN multi_asset ma ON (mto.ident = ma.id) | ||
WHERE mto.tx_out_id = txo.id | ||
) AS "amount", | ||
encode(b.hash, 'hex') AS "block", | ||
encode(data_hash, 'hex') AS "data_hash", | ||
encode(dat.bytes, 'hex') AS "inline_datum", | ||
encode(scr.hash, 'hex') AS "reference_script_hash" | ||
FROM tx | ||
JOIN tx_out txo ON (tx.id = txo.tx_id) | ||
JOIN stake_address sa ON (txo.stake_address_id = sa.id) | ||
LEFT JOIN tx_in txi ON (txo.tx_id = txi.tx_out_id) | ||
AND (txo.index = txi.tx_out_index) | ||
JOIN block b ON (b.id = tx.block_id) | ||
LEFT JOIN datum dat ON (txo.inline_datum_id = dat.id) | ||
LEFT JOIN script scr ON (txo.reference_script_id = scr.id) | ||
WHERE txi.tx_in_id IS NULL | ||
AND sa.view = $4 | ||
ORDER BY CASE | ||
WHEN LOWER($1) = 'desc' THEN txo.id | ||
END DESC, | ||
CASE | ||
WHEN LOWER($1) <> 'desc' | ||
OR $1 IS NULL THEN txo.id | ||
END ASC | ||
LIMIT CASE | ||
WHEN $2 >= 1 | ||
AND $2 <= 100 THEN $2 | ||
ELSE 100 | ||
END OFFSET CASE | ||
WHEN $3 > 1 | ||
AND $3 < 2147483647 THEN ($3 - 1) * ( | ||
CASE | ||
WHEN $2 >= 1 | ||
AND $2 <= 100 THEN $2 | ||
ELSE 100 | ||
END | ||
) | ||
ELSE 0 | ||
END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
-- Same as addresses_address_utxos.sql except this has JOIN stake_address sa ON (txo.stake_address_id = sa.id) | ||
-- and additional WHERE condition sa.view = $4 | ||
SELECT txo.address AS "address", | ||
encode(tx.hash, 'hex') AS "tx_hash", | ||
txo.index AS "tx_index", | ||
txo.index AS "output_index", | ||
txo.value::TEXT AS "amount_lovelace", -- cast to TEXT to avoid number overflow | ||
( | ||
SELECT json_agg( | ||
json_build_object( | ||
'unit', | ||
CONCAT(encode(ma.policy, 'hex'), encode(ma.name, 'hex')), | ||
'quantity', | ||
mto.quantity::TEXT -- cast to TEXT to avoid number overflow | ||
) | ||
) | ||
FROM ma_tx_out mto | ||
JOIN multi_asset ma ON (mto.ident = ma.id) | ||
WHERE mto.tx_out_id = txo.id | ||
) AS "amount", | ||
encode(b.hash, 'hex') AS "block", | ||
encode(data_hash, 'hex') AS "data_hash", | ||
encode(dat.bytes, 'hex') AS "inline_datum", | ||
encode(scr.hash, 'hex') AS "reference_script_hash" | ||
FROM tx | ||
JOIN tx_out txo ON (tx.id = txo.tx_id) | ||
JOIN stake_address sa ON (txo.stake_address_id = sa.id) | ||
LEFT JOIN tx_in txi ON (txo.tx_id = txi.tx_out_id) | ||
AND (txo.index = txi.tx_out_index) | ||
JOIN block b ON (b.id = tx.block_id) | ||
LEFT JOIN datum dat ON (txo.inline_datum_id = dat.id) | ||
LEFT JOIN script scr ON (txo.reference_script_id = scr.id) | ||
WHERE txi.tx_in_id IS NULL | ||
AND sa.view = $4 | ||
ORDER BY CASE | ||
WHEN LOWER($1) = 'desc' THEN txo.id | ||
END DESC, | ||
CASE | ||
WHEN LOWER($1) <> 'desc' | ||
OR $1 IS NULL THEN txo.id | ||
END ASC |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters