From e0a2b541f94371b560a4b44abd6815946e89333e Mon Sep 17 00:00:00 2001 From: willkhinz Date: Wed, 25 Mar 2026 08:15:38 -0700 Subject: [PATCH] fix: resolve implement automatic payout on submission approval Signed-off-by: willkhinz --- FIX_PROPOSAL.md | 130 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 FIX_PROPOSAL.md diff --git a/FIX_PROPOSAL.md b/FIX_PROPOSAL.md new file mode 100644 index 0000000..af671cb --- /dev/null +++ b/FIX_PROPOSAL.md @@ -0,0 +1,130 @@ +**Automatic Payout on Submission Approval Solution** + +To implement automatic payout on submission approval, we will use GitHub's Webhooks and the Stellar SDK. We will create a Node.js script that listens for the `issue_comment` event, checks if the submission is approved, and then orchestrates the payment. + +**Step 1: Set up GitHub Webhook** + +Create a new file named `webhook.js` with the following code: +```javascript +const express = require('express'); +const app = express(); +const github = require('github-webhook-handler')({ path: '/webhook', secret: 'YOUR_GITHUB_WEBHOOK_SECRET' }); + +app.post('/webhook', github.webhook); +app.listen(3000, () => { + console.log('Webhook server listening on port 3000'); +}); +``` +**Step 2: Handle Issue Comment Event** + +Create a new file named `issueCommentHandler.js` with the following code: +```javascript +const axios = require('axios'); +const StellarSdk = require('stellar-sdk'); + +const handleIssueComment = async (event) => { + if (event.action === 'created' && event.issue.number === 115) { + const comment = event.comment; + if (comment.body.includes('approved')) { + const submission = await getSubmission(event.issue.number); + if (submission) { + const bounty = await getBounty(submission.bountyId); + if (bounty.status === 'active') { + const payment = await constructPayment(bounty, submission.developerWallet); + await handlePayment(payment); + } + } + } + } +}; + +const getSubmission = async (issueNumber) => { + const response = await axios.get(`https://api.github.com/repos/devasignhq/mobile-app/issues/${issueNumber}`); + return response.data; +}; + +const getBounty = async (bountyId) => { + const response = await axios.get(`https://api.github.com/repos/devasignhq/mobile-app/bounties/${bountyId}`); + return response.data; +}; + +const constructPayment = async (bounty, developerWallet) => { + const stellar = new StellarSdk.Server('https://horizon.stellar.org'); + const sourceAccount = await stellar.loadAccount(bounty.escrowAccount); + const transaction = new StellarSdk.TransactionBuilder(sourceAccount) + .addOperation(StellarSdk.Operation.payment({ + destination: developerWallet, + asset: StellarSdk.Asset.native(), + amount: bounty.amount, + })) + .setTimeout(StellarSdk.TimeoutInfinite) + .build(); + return transaction; +}; + +const handlePayment = async (payment) => { + const stellar = new StellarSdk.Server('https://horizon.stellar.org'); + const retryCount = 0; + const retryDelay = 1000; // 1 second + + const retryPayment = async () => { + try { + const response = await stellar.submitTransaction(payment); + console.log(`Payment successful: ${response.id}`); + await updateBountyStatus(payment); + } catch (error) { + if (retryCount < 3) { + console.log(`Payment failed: ${error.message}. Retrying in ${retryDelay}ms`); + setTimeout(retryPayment, retryDelay); + retryDelay *= 2; // exponential backoff + } else { + console.log(`Payment failed after 3 retries: ${error.message}`); + } + } + }; + + retryPayment(); +}; + +const updateBountyStatus = async (payment) => { + const response = await axios.patch(`https://api.github.com/repos/devasignhq/mobile-app/bounties/${payment.bountyId}`, { + status: 'paid', + }); + console.log(`Bounty status updated: ${response.data.status}`); +}; +``` +**Step 3: Integrate with GitHub Webhook** + +Modify the `webhook.js` file to include the `issueCommentHandler`: +```javascript +const express = require('express'); +const app = express(); +const github = require('github-webhook-handler')({ path: '/webhook', secret: 'YOUR_GITHUB_WEBHOOK_SECRET' }); +const issueCommentHandler = require('./issueCommentHandler'); + +app.post('/webhook', (req, res) => { + github.webhook(req, res, (err) => { + if (err) { + console.error(err); + } else { + issueCommentHandler.handleIssueComment(req.body); + } + }); +}); + +app.listen(3000, () => { + console.log('Webhook server listening on port 3000'); +}); +``` +**Code Fix:** + +To fix the issue, you need to update the `issueCommentHandler.js` file to include the `updateBountyStatus` function and modify the `handlePayment` function to retry the payment with exponential backoff. + +**Example Use Case:** + +1. Set up a GitHub Webhook to listen for the `issue_comment` event on the `devasignhq/mobile-app` repository. +2. Create a new issue comment on the `mobile-app` repository with the text "approved". +3. The `issueCommentHandler` will detect the comment and trigger the payment process. +4. The payment will be constructed and submitted to the Stellar network. +5. If the payment fails, it will be retried with exponential backoff. +6. Once the payment is successful, the bounty status will be updated to "paid". \ No newline at end of file