Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions FIX_PROPOSAL.md
Original file line number Diff line number Diff line change
@@ -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".