2023-07-23 15:08:43 +00:00
|
|
|
const { GraphQLError } = require('graphql')
|
2021-05-20 17:21:11 +00:00
|
|
|
const retry = require('async-retry')
|
2023-07-27 00:18:42 +00:00
|
|
|
const Prisma = require('@prisma/client')
|
2021-05-20 01:09:32 +00:00
|
|
|
|
|
|
|
async function serialize (models, call) {
|
2021-05-20 19:11:58 +00:00
|
|
|
return await retry(async bail => {
|
2021-05-20 17:21:11 +00:00
|
|
|
try {
|
2023-07-27 00:18:42 +00:00
|
|
|
const [, result] = await models.$transaction(
|
|
|
|
[models.$executeRaw`SELECT ASSERT_SERIALIZED()`, call],
|
|
|
|
{ isolationLevel: Prisma.TransactionIsolationLevel.Serializable })
|
2021-05-20 17:21:11 +00:00
|
|
|
return result
|
|
|
|
} catch (error) {
|
|
|
|
console.log(error)
|
|
|
|
if (error.message.includes('SN_INSUFFICIENT_FUNDS')) {
|
2023-07-23 15:08:43 +00:00
|
|
|
bail(new GraphQLError('insufficient funds', { extensions: { code: 'BAD_INPUT' } }))
|
2021-05-20 17:21:11 +00:00
|
|
|
}
|
|
|
|
if (error.message.includes('SN_NOT_SERIALIZABLE')) {
|
|
|
|
bail(new Error('wallet balance transaction is not serializable'))
|
|
|
|
}
|
2021-07-10 14:16:40 +00:00
|
|
|
if (error.message.includes('SN_CONFIRMED_WITHDRAWL_EXISTS')) {
|
2021-08-19 21:42:21 +00:00
|
|
|
bail(new Error('withdrawal invoice already confirmed (to withdraw again create a new invoice)'))
|
2021-07-10 14:16:40 +00:00
|
|
|
}
|
|
|
|
if (error.message.includes('SN_PENDING_WITHDRAWL_EXISTS')) {
|
2021-08-19 21:42:21 +00:00
|
|
|
bail(new Error('withdrawal invoice exists and is pending'))
|
2021-07-10 14:16:40 +00:00
|
|
|
}
|
2021-10-15 23:07:51 +00:00
|
|
|
if (error.message.includes('SN_INELIGIBLE')) {
|
|
|
|
bail(new Error('user ineligible for gift'))
|
|
|
|
}
|
2022-11-23 18:12:09 +00:00
|
|
|
if (error.message.includes('SN_UNSUPPORTED')) {
|
|
|
|
bail(new Error('unsupported action'))
|
|
|
|
}
|
|
|
|
if (error.message.includes('SN_DUPLICATE')) {
|
|
|
|
bail(new Error('duplicate not allowed'))
|
|
|
|
}
|
2021-10-15 23:07:51 +00:00
|
|
|
if (error.message.includes('SN_REVOKED_OR_EXHAUSTED')) {
|
|
|
|
bail(new Error('faucet has been revoked or is exhausted'))
|
|
|
|
}
|
2022-08-30 20:33:39 +00:00
|
|
|
if (error.message.includes('SN_INV_PENDING_LIMIT')) {
|
|
|
|
bail(new Error('too many pending invoices'))
|
|
|
|
}
|
|
|
|
if (error.message.includes('SN_INV_EXCEED_BALANCE')) {
|
|
|
|
bail(new Error('pending invoices must not cause balance to exceed 1m sats'))
|
|
|
|
}
|
2023-07-31 13:31:40 +00:00
|
|
|
if (error.message.includes('40001') || error.code === 'P2034') {
|
|
|
|
throw new Error('wallet balance serialization failure - try again')
|
|
|
|
}
|
|
|
|
if (error.message.includes('23514') || ['P2002', 'P2003', 'P2004'].includes(error.code)) {
|
|
|
|
bail(new Error('constraint failure'))
|
2022-08-30 20:33:39 +00:00
|
|
|
}
|
2021-05-20 17:21:11 +00:00
|
|
|
bail(error)
|
2021-05-20 01:09:32 +00:00
|
|
|
}
|
2021-05-20 17:21:11 +00:00
|
|
|
}, {
|
|
|
|
minTimeout: 100,
|
|
|
|
factor: 1.1,
|
|
|
|
retries: 5
|
|
|
|
})
|
2021-05-20 01:09:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = serialize
|