forked from mito-systems/sol-mem-gen
Create lock on every fourth twitter post
This commit is contained in:
parent
df914a7f39
commit
30e906bb14
@ -1,52 +1,9 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
|
||||
import { createLock } from "../../../utils/create-lock";
|
||||
import { TOKEN_PROGRAM_ID } from "@solana/spl-token";
|
||||
import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes";
|
||||
import { BN } from "bn.js";
|
||||
import Big from 'big.js';
|
||||
import { Connection} from "@solana/web3.js";
|
||||
import { createRewardLock, extractInfo } from "../../../utils/create-lock";
|
||||
|
||||
const connection = new Connection(process.env.NEXT_PUBLIC_SOLANA_RPC_URL!);
|
||||
|
||||
async function extractInfo(transactionSignature: string) {
|
||||
const transaction = await connection.getParsedTransaction(transactionSignature, 'confirmed');
|
||||
if (!transaction) {
|
||||
throw new Error('Transaction not found');
|
||||
}
|
||||
|
||||
const transferInstruction = transaction.transaction.message.instructions.find(
|
||||
(instr) => 'parsed' in instr && instr.programId.equals(TOKEN_PROGRAM_ID)
|
||||
);
|
||||
|
||||
if (!transferInstruction || !('parsed' in transferInstruction)) {
|
||||
throw new Error('Transfer instruction not found');
|
||||
}
|
||||
|
||||
const { info: { amount, authority } } = transferInstruction.parsed;
|
||||
return { authority, amount };
|
||||
}
|
||||
|
||||
async function createRewardLock(authority: string, amount: string) {
|
||||
const { WSOL_LOCKER_PRIVATE_KEY, CLIFF_TIME, WSOL_MINT, NEXT_PUBLIC_MTM_TOKEN_MINT, REWARD_MULTIPLIER } = process.env;
|
||||
if (!WSOL_LOCKER_PRIVATE_KEY || !CLIFF_TIME || !WSOL_MINT || !NEXT_PUBLIC_MTM_TOKEN_MINT || !REWARD_MULTIPLIER) {
|
||||
throw new Error('Missing required environment variables');
|
||||
}
|
||||
|
||||
const duration = new BN(CLIFF_TIME).add(new BN(Math.floor(Date.now() / 1000)));
|
||||
const tokenLockerKeypair = Keypair.fromSecretKey(bs58.decode(WSOL_LOCKER_PRIVATE_KEY));
|
||||
const recipientPublicKey = new PublicKey(authority);
|
||||
|
||||
const url = `https://api.jup.ag/price/v2?ids=${NEXT_PUBLIC_MTM_TOKEN_MINT}&vsToken=${WSOL_MINT}`;
|
||||
const response = await fetch(url);
|
||||
const { data } = await response.json();
|
||||
|
||||
const priceWSOLFor1MTM = new Big(data[NEXT_PUBLIC_MTM_TOKEN_MINT].price).toFixed(9);
|
||||
const mtmAmount = new Big(amount).div(new Big(10).pow(6));
|
||||
const wsolAmount = new BN(new Big(mtmAmount).times(priceWSOLFor1MTM).times(new Big(10).pow(9)).times(REWARD_MULTIPLIER).toFixed(0));
|
||||
|
||||
return createLock(tokenLockerKeypair, recipientPublicKey, duration, wsolAmount);
|
||||
}
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
try {
|
||||
const { searchParams } = new URL(req.url);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
import { saveTweet, verifySignatureInTweet } from '../../../utils/verifyTweet';
|
||||
import { createRewardLock, extractInfo } from '../../../utils/create-lock';
|
||||
|
||||
export async function POST(req: NextRequest): Promise<NextResponse> {
|
||||
try {
|
||||
@ -30,8 +31,17 @@ export async function POST(req: NextRequest): Promise<NextResponse> {
|
||||
}
|
||||
|
||||
const { isFourthUser } = await saveTweet({ transactionSignature: txSignature, url: memeUrl });
|
||||
|
||||
if (isFourthUser) {
|
||||
createTokenLockForRecipient();
|
||||
const { authority, amount } = await extractInfo(txSignature);
|
||||
|
||||
if (!authority || Number(amount) <= 0) {
|
||||
return NextResponse.json({ error: "Invalid transaction details" }, { status: 400 });
|
||||
}
|
||||
|
||||
const escrow = await createRewardLock(authority, amount);
|
||||
return NextResponse.json({ success: true, data: { escrow } });
|
||||
|
||||
}
|
||||
|
||||
return NextResponse.json({ success: isVerified, message: 'Tweet verified' })
|
||||
@ -59,8 +69,3 @@ const extractData = (tweet: string | object) => {
|
||||
handle: handleMatch ? handleMatch[1] : null,
|
||||
};
|
||||
};
|
||||
|
||||
// TODO: Implement function to create lock for a recipient
|
||||
const createTokenLockForRecipient = () => {
|
||||
console.log('Lock created');
|
||||
}
|
||||
|
@ -2,12 +2,13 @@ import assert from 'assert';
|
||||
import BN from 'bn.js';
|
||||
import 'dotenv/config';
|
||||
import bs58 from 'bs58';
|
||||
import Big from 'big.js';
|
||||
|
||||
import * as anchor from "@coral-xyz/anchor";
|
||||
import {
|
||||
TOKEN_PROGRAM_ID,
|
||||
} from "@solana/spl-token";
|
||||
import { Connection, PublicKey } from "@solana/web3.js";
|
||||
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
|
||||
|
||||
import { createVestingPlanV2 } from '../locker-utils';
|
||||
|
||||
@ -64,3 +65,42 @@ export async function createLock(tokenLockerKeypair: anchor.web3.Keypair, recipi
|
||||
|
||||
return escrow;
|
||||
}
|
||||
|
||||
export async function extractInfo(transactionSignature: string) {
|
||||
const transaction = await connection.getParsedTransaction(transactionSignature, 'confirmed');
|
||||
if (!transaction) {
|
||||
throw new Error('Transaction not found');
|
||||
}
|
||||
|
||||
const transferInstruction = transaction.transaction.message.instructions.find(
|
||||
(instr) => 'parsed' in instr && instr.programId.equals(TOKEN_PROGRAM_ID)
|
||||
);
|
||||
|
||||
if (!transferInstruction || !('parsed' in transferInstruction)) {
|
||||
throw new Error('Transfer instruction not found');
|
||||
}
|
||||
|
||||
const { info: { amount, authority } } = transferInstruction.parsed;
|
||||
return { authority, amount };
|
||||
}
|
||||
|
||||
export async function createRewardLock(authority: string, amount: string) {
|
||||
const { WSOL_LOCKER_PRIVATE_KEY, CLIFF_TIME, WSOL_MINT, NEXT_PUBLIC_MTM_TOKEN_MINT, REWARD_MULTIPLIER } = process.env;
|
||||
if (!WSOL_LOCKER_PRIVATE_KEY || !CLIFF_TIME || !WSOL_MINT || !NEXT_PUBLIC_MTM_TOKEN_MINT || !REWARD_MULTIPLIER) {
|
||||
throw new Error('Missing required environment variables');
|
||||
}
|
||||
|
||||
const duration = new BN(CLIFF_TIME).add(new BN(Math.floor(Date.now() / 1000)));
|
||||
const tokenLockerKeypair = Keypair.fromSecretKey(bs58.decode(WSOL_LOCKER_PRIVATE_KEY));
|
||||
const recipientPublicKey = new PublicKey(authority);
|
||||
|
||||
const url = `https://api.jup.ag/price/v2?ids=${NEXT_PUBLIC_MTM_TOKEN_MINT}&vsToken=${WSOL_MINT}`;
|
||||
const response = await fetch(url);
|
||||
const { data } = await response.json();
|
||||
|
||||
const priceWSOLFor1MTM = new Big(data[NEXT_PUBLIC_MTM_TOKEN_MINT].price).toFixed(9);
|
||||
const mtmAmount = new Big(amount).div(new Big(10).pow(6));
|
||||
const wsolAmount = new BN(new Big(mtmAmount).times(priceWSOLFor1MTM).times(new Big(10).pow(9)).times(REWARD_MULTIPLIER).toFixed(0));
|
||||
|
||||
return createLock(tokenLockerKeypair, recipientPublicKey, duration, wsolAmount);
|
||||
}
|
||||
|
@ -4,8 +4,6 @@ import BN from 'bn.js';
|
||||
import { Connection } from '@solana/web3.js';
|
||||
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
||||
|
||||
import { Payment } from '../entity/Payment';
|
||||
|
||||
assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL, 'SOLANA_RPC_URL is required');
|
||||
|
||||
const SOLANA_RPC_URL = process.env.NEXT_PUBLIC_SOLANA_RPC_URL;
|
||||
@ -44,6 +42,7 @@ export async function markSignatureAsUsed(transactionSignature: string): Promise
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: Verify that payment receiver is correct
|
||||
export async function verifyPayment(
|
||||
transactionSignature: string,
|
||||
tokenAmount: BN,
|
||||
|
Loading…
Reference in New Issue
Block a user