This repository was archived by the owner on Sep 8, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
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
621321d
commit c98e931
Showing
3 changed files
with
202 additions
and
1 deletion.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
import ClaimTx from '../models/ClaimTx' | ||
import { wrapAsync } from '../utils' | ||
import sdk from '@linkdrop/binance-sdk' | ||
import Table from 'cli-table' | ||
|
||
const config = require('../../config/config.json') | ||
|
||
/** | ||
* Function to check whether a `linkId` has already been claimed | ||
*/ | ||
const isClaimed = wrapAsync(async (req, res) => { | ||
const linkId = req.params.linkId | ||
|
||
// Check whether a claim tx exists in database | ||
const oldClaimTx = await ClaimTx.findOne({ | ||
linkId | ||
}) | ||
|
||
if (oldClaimTx && oldClaimTx.txHash) { | ||
return res.json({ | ||
isClaimed: true, | ||
txHash: oldClaimTx.txHash | ||
}) | ||
} else return res.json({ isClaimed: false }) | ||
}) | ||
|
||
/** | ||
* Helper function to transfer funds | ||
* @param {String} privateKey Private key to send funds from | ||
* @param {String} to Address to send funds to | ||
* @param {String} asset Asset symbol | ||
* @param {String} amount Asset amount in decimal form, e.g. 1.00000000 | ||
* @param {String} memo An optional message to send along with funds | ||
* @return {Promise<Object>) `{success, txHash, error}` | ||
*/ | ||
const transfer = async ({ privateKey, to, asset, amount, memo }) => { | ||
try { | ||
const from = sdk.utils.getAddressFromPrivateKey(privateKey) | ||
const sequence = await sdk.utils.getSequence(from) | ||
const bncClient = await sdk.utils.initBncClient(privateKey) | ||
|
||
const result = await bncClient.transfer( | ||
from, | ||
to, | ||
amount, | ||
asset, | ||
memo, | ||
sequence | ||
) | ||
|
||
if (result.status === 200) { | ||
return { success: true, txHash: result.result[0].hash } | ||
} else { | ||
return { success: false, error: result } | ||
} | ||
} catch (err) { | ||
throw new Error(err) | ||
} | ||
} | ||
|
||
const claim = wrapAsync(async (req, res) => { | ||
const { | ||
asset, | ||
amount, | ||
linkId, | ||
verifierSignature, | ||
receiverAddress, | ||
receiverSignature | ||
} = req.body | ||
|
||
const VERIFIER_ADDRESS = | ||
process.env.VERIFIER_ADDRESS || config.VERIFIER_ADDRESS | ||
const SENDER_PRIVATE_KEY = | ||
process.env.SENDER_PRIVATE_KEY || config.SENDER_PRIVATE_KEY | ||
const senderAddress = sdk.utils.getAddressFromPrivateKey(SENDER_PRIVATE_KEY) | ||
|
||
const table = new Table() | ||
|
||
// Check whether a claim tx exists in database | ||
const oldClaimTx = await ClaimTx.findOne({ | ||
linkId | ||
}) | ||
|
||
if (oldClaimTx && oldClaimTx.txHash) { | ||
table.push(['Tx hash', oldClaimTx.toObject().txHash]) | ||
|
||
console.log('\n✅ Submitted claim transaction') | ||
console.log(table.toString(), '\n') | ||
|
||
return res.json({ | ||
success: true, | ||
txHash: oldClaimTx.txHash | ||
}) | ||
} else { | ||
if ( | ||
(await LinkdropSDK.binance.checkLinkParams({ | ||
asset, | ||
amount, | ||
linkId, | ||
verifierAddress: VERIFIER_ADDRESS, | ||
verifierSignature, | ||
receiverAddress, | ||
receiverSignature, | ||
senderAddress | ||
})) === true | ||
) { | ||
try { | ||
const memo = `Linkdrop Id: ${linkId}` | ||
|
||
const { success, txHash, error } = await transfer({ | ||
privateKey: SENDER_PRIVATE_KEY, | ||
to: receiverAddress, | ||
asset, | ||
amount: sdk.utils.formatUnits(Number(amount)), | ||
memo | ||
}) | ||
|
||
if (success === true && txHash) { | ||
// Save claim tx to database | ||
const claimTx = new ClaimTx({ | ||
asset, | ||
amount, | ||
linkId, | ||
senderAddress, | ||
receiverAddress, | ||
verifierAddress: VERIFIER_ADDRESS, | ||
txHash | ||
}) | ||
|
||
const document = await claimTx.save() | ||
|
||
for (let key in claimTx.toObject()) { | ||
if (key !== '_id' && key !== '__v') { | ||
table.push([key, claimTx.toObject()[key]]) | ||
} | ||
} | ||
|
||
console.log('\n✅ Submitted claim transaction') | ||
console.log(table.toString(), '\n') | ||
|
||
asset, | ||
amount, | ||
linkId, | ||
verifierSignature, | ||
receiverAddress, | ||
receiverSignature | ||
} | ||
|
||
res.json({ | ||
success, | ||
txHash, | ||
error | ||
}) | ||
} catch (err) { | ||
console.error(err) | ||
} | ||
} | ||
} | ||
}) | ||
|
||
export default { claim, isClaimed } |
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,15 @@ | ||
import { Schema, model } from 'mongoose' | ||
|
||
const claimTxSchema = new Schema({ | ||
asset: { type: String, required: true }, | ||
amount: { type: String, required: true }, | ||
linkId: { type: String, required: true }, | ||
senderAddress: { type: String, required: true }, | ||
receiverAddress: { type: String, required: true }, | ||
verifierAddress: { type: String, required: true }, | ||
txHash: { type: String, reqiured: true } | ||
}) | ||
|
||
const ClaimTx = model('ClaimTx', claimTxSchema) | ||
|
||
export default ClaimTx |
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 |
---|---|---|
|
@@ -5,5 +5,30 @@ | |
"main": "index.js", | ||
"author": "Amir Jumaniyazov - <[email protected]>", | ||
"license": "MIT", | ||
"private": true | ||
"private": true, | ||
"dependencies": { | ||
"@binance-chain/javascript-sdk": "https://github.com/Dobrokhvalov/javascript-sdk", | ||
"@hapi/boom": "^7.4.2", | ||
"@linkdrop/sdk": "https://github.com/LinkdropProtocol/linkdrop-sdk", | ||
"axios": "^0.19.0", | ||
"cli-table": "^0.3.1", | ||
"cors": "^2.8.5", | ||
"csvtojson": "^2.0.8", | ||
"dotenv": "^8.0.0", | ||
"ethers": "^4.0.31", | ||
"express": "^4.17.1", | ||
"fast-csv": "^3.0.1", | ||
"mongoose": "^5.6.0", | ||
"morgan": "^1.9.1", | ||
"pm2": "^3.5.1", | ||
"query-string": "^6.8.1" | ||
}, | ||
"devDependencies": { | ||
"@babel/cli": "^7.4.4", | ||
"@babel/core": "^7.4.5", | ||
"@babel/node": "^7.4.5", | ||
"@babel/polyfill": "^7.4.4", | ||
"@babel/preset-env": "^7.4.5", | ||
"@babel/register": "^7.4.4", | ||
} | ||
} |