From bbdf706b36193103000b9decd6f4f1d1b705c59f Mon Sep 17 00:00:00 2001 From: chaojun Date: Mon, 24 Jul 2023 16:40:26 +0800 Subject: [PATCH] add bounty update script to auto close the ended bounties --- .../update-bounty-status/fetchBountyState.js | 20 ++++++++ .../src/scripts/update-bounty-status/index.js | 48 +++++++++++++++++++ .../fetchChildBountyState.js | 4 ++ .../update-childbounty-status/index.js | 24 +++++----- 4 files changed, 85 insertions(+), 11 deletions(-) create mode 100644 backend/packages/server/src/scripts/update-bounty-status/fetchBountyState.js create mode 100644 backend/packages/server/src/scripts/update-bounty-status/index.js diff --git a/backend/packages/server/src/scripts/update-bounty-status/fetchBountyState.js b/backend/packages/server/src/scripts/update-bounty-status/fetchBountyState.js new file mode 100644 index 00000000..0ae3eed8 --- /dev/null +++ b/backend/packages/server/src/scripts/update-bounty-status/fetchBountyState.js @@ -0,0 +1,20 @@ +async function fetchBountyState(network, bountyIndex) { + const url = `https://${network}.subsquare.io/api/treasury/bounties/${bountyIndex}`; + console.log(`Fetch from: ${url}`); + + const resp = await fetch(url); + if (!resp.ok) { + throw new Error(`Failed to fetch bounty status from subsquare: ${resp.status}`); + } + + const data = await resp.json(); + + const bounty = data.onchainData; + const state = bounty?.state?.state; + + return { state }; +} + +module.exports = { + fetchBountyState, +}; diff --git a/backend/packages/server/src/scripts/update-bounty-status/index.js b/backend/packages/server/src/scripts/update-bounty-status/index.js new file mode 100644 index 00000000..36992a15 --- /dev/null +++ b/backend/packages/server/src/scripts/update-bounty-status/index.js @@ -0,0 +1,48 @@ +const dotenv = require("dotenv"); +dotenv.config(); + +const { Bounty } = require("../../models"); +const { BountyStatus } = require("../../utils/constants"); +const { fetchBountyState } = require("./fetchBountyState"); + +async function updateBountyToClosed(bounty) { + console.log(`Update status to Closed`); + await Bounty.updateOne( + { _id: bounty._id }, + { + status: BountyStatus.Closed, + }, + ); +} + +async function updateBountyStatus(bounty) { + console.log(`Update bounty: ${bounty.network}/${bounty.bountyIndex}`); + + const { state } = await fetchBountyState(bounty.network, bounty.bountyIndex); + + if (["Canceled", "Cancelled", "Claimed"].includes(state)) { + return await updateBountyToClosed(bounty); + } +} + +async function main() { + console.log(`Start update at:`, new Date()); + + const bounties = await Bounty.find({ + status: BountyStatus.Open, + }); + + console.log(`Updating ${bounties.length} bounties`); + + for (const bounty of bounties) { + try { + await updateBountyStatus(bounty); + } catch (e) { + console.error(e.message); + } + } +} + +main() + .catch(console.error) + .finally(() => process.exit()); diff --git a/backend/packages/server/src/scripts/update-childbounty-status/fetchChildBountyState.js b/backend/packages/server/src/scripts/update-childbounty-status/fetchChildBountyState.js index a3a2287f..09e2b470 100644 --- a/backend/packages/server/src/scripts/update-childbounty-status/fetchChildBountyState.js +++ b/backend/packages/server/src/scripts/update-childbounty-status/fetchChildBountyState.js @@ -3,6 +3,10 @@ async function fetchChildBountyState(network, parentBountyIndex, index) { console.log(`Fetch from: ${url}`); const resp = await fetch(url); + if (!resp.ok) { + throw new Error(`Failed to fetch child bounty status from subsquare: ${resp.status}`); + } + const data = await resp.json(); const childBounty = data.onchainData; diff --git a/backend/packages/server/src/scripts/update-childbounty-status/index.js b/backend/packages/server/src/scripts/update-childbounty-status/index.js index 60ea23b5..eecfdbf7 100644 --- a/backend/packages/server/src/scripts/update-childbounty-status/index.js +++ b/backend/packages/server/src/scripts/update-childbounty-status/index.js @@ -12,7 +12,7 @@ async function updateChildBountyToAwarded(childBounty, beneficiary) { { beneficiary, status: ChildBountyStatus.Awarded, - } + }, ); } @@ -22,17 +22,19 @@ async function updateChildBountyToClosed(childBounty) { { _id: childBounty._id }, { status: ChildBountyStatus.Closed, - } + }, ); } async function updateChildBountyStatus(childBounty) { - console.log(`Update child bounty: ${childBounty.network}/${childBounty.parentBountyIndex}/${childBounty.index}`); + console.log( + `Update child bounty: ${childBounty.network}/${childBounty.parentBountyIndex}/${childBounty.index}`, + ); const { beneficiary, state } = await fetchChildBountyState( childBounty.network, childBounty.parentBountyIndex, - childBounty.index + childBounty.index, ); if (["Awarded", "Claimed"].includes(state)) { @@ -49,21 +51,21 @@ async function main() { const childBounties = await ChildBounty.find({ status: { - $in: [ - ChildBountyStatus.Open, - ChildBountyStatus.Assigned, - ] - } + $in: [ChildBountyStatus.Open, ChildBountyStatus.Assigned], + }, }); console.log(`Updating ${childBounties.length} child bounties`); for (const childBounty of childBounties) { - await updateChildBountyStatus(childBounty); + try { + await updateChildBountyStatus(childBounty); + } catch (e) { + console.error(e.message); + } } } main() .catch(console.error) .finally(() => process.exit()); -