forked from mito-systems/sol-mem-gen
Use BN instead of Big in create lock
This commit is contained in:
parent
e04c43baca
commit
7aa0d44f61
@ -12,7 +12,7 @@
|
||||
"@coral-xyz/anchor": "^0.30.1",
|
||||
"@fal-ai/client": "^1.2.1",
|
||||
"@google/generative-ai": "^0.21.0",
|
||||
"@solana/spl-token": "^0.3.8",
|
||||
"@solana/spl-token": "^0.3.11",
|
||||
"@solana/web3.js": "^1.78.4",
|
||||
"big.js": "^6.2.2",
|
||||
"bn.js": "^5.2.0",
|
||||
|
@ -1,15 +1,14 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { Connection} from "@solana/web3.js";
|
||||
import { createRewardLock, extractInfo } from "../../../utils/create-lock";
|
||||
|
||||
const connection = new Connection(process.env.NEXT_PUBLIC_SOLANA_RPC_URL!);
|
||||
import { createRewardLock } from "../../../utils/create-lock";
|
||||
import { extractTxInfo } from "../../../utils/extractTxInfo";
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
try {
|
||||
const { searchParams } = new URL(req.url);
|
||||
const signature = searchParams.get('signature') || '4HBtnoNUuMGpmbhD9cPiJtbxkhux31pfZs3HYud5eopAU69RaC4UbJsYdj83eafFxV6eH8pSaRgqELrwyjrWp7yz';
|
||||
|
||||
const { authority, amount } = await extractInfo(signature);
|
||||
const { authority, amount } = await extractTxInfo(signature);
|
||||
if (!authority || Number(amount) <= 0) {
|
||||
return NextResponse.json({ error: "Invalid transaction details" }, { status: 400 });
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ import {
|
||||
createAssociatedTokenAccountInstruction,
|
||||
getAssociatedTokenAddressSync,
|
||||
TOKEN_2022_PROGRAM_ID,
|
||||
TOKEN_PROGRAM_ID,
|
||||
} from '@solana/spl-token';
|
||||
import {
|
||||
AnchorProvider,
|
||||
@ -39,12 +38,6 @@ assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL);
|
||||
|
||||
const connection = new Connection(process.env.NEXT_PUBLIC_SOLANA_RPC_URL);
|
||||
|
||||
const ESCROW_USE_SPL_TOKEN = 0;
|
||||
|
||||
const MEMO_PROGRAM = new web3.PublicKey(
|
||||
"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"
|
||||
);
|
||||
|
||||
export function createLockerProgram(wallet: Wallet): Program<Locker> {
|
||||
const provider = new AnchorProvider(connection, wallet, {
|
||||
maxRetries: 3,
|
||||
@ -80,8 +73,9 @@ export interface CreateVestingPlanParams {
|
||||
// V2 instructions
|
||||
export async function createVestingPlanV2(params: CreateVestingPlanParams) {
|
||||
let {
|
||||
tokenMint,
|
||||
ownerKeypair,
|
||||
tokenMint,
|
||||
isAssertion,
|
||||
vestingStartTime,
|
||||
cliffTime,
|
||||
frequency,
|
||||
@ -183,7 +177,7 @@ export async function createVestingPlanV2(params: CreateVestingPlanParams) {
|
||||
return escrow;
|
||||
} catch (error) {
|
||||
if (error instanceof TransactionExpiredTimeoutError) {
|
||||
console.error('Transaction confirmation delayed for',error.signature);
|
||||
console.error('Transaction confirmation delayed for', error.signature);
|
||||
console.log('Confirming the transaction again...');
|
||||
const confirmedTransaction = await connection.getTransaction(error.signature, {
|
||||
commitment: 'confirmed',
|
||||
@ -191,7 +185,7 @@ export async function createVestingPlanV2(params: CreateVestingPlanParams) {
|
||||
});
|
||||
|
||||
if(confirmedTransaction === null) {
|
||||
console.error('Transaction failed for',error.signature);
|
||||
console.error('Transaction failed for', error.signature);
|
||||
}
|
||||
|
||||
return escrow;
|
||||
@ -199,66 +193,3 @@ export async function createVestingPlanV2(params: CreateVestingPlanParams) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export interface ClaimTokenParamsV2 {
|
||||
isAssertion: boolean;
|
||||
escrow: web3.PublicKey;
|
||||
recipient: web3.Keypair;
|
||||
maxAmount: BN;
|
||||
recipientToken: web3.PublicKey;
|
||||
tokenProgram: web3.PublicKey;
|
||||
}
|
||||
|
||||
export async function claimTokenV2(params: ClaimTokenParamsV2) {
|
||||
let { isAssertion, escrow, recipient, maxAmount, recipientToken } = params;
|
||||
const program = createLockerProgram(new Wallet(recipient));
|
||||
const escrowState = await program.account.vestingEscrow.fetch(escrow);
|
||||
const tokenProgram =
|
||||
escrowState.tokenProgramFlag == ESCROW_USE_SPL_TOKEN
|
||||
? TOKEN_PROGRAM_ID
|
||||
: TOKEN_2022_PROGRAM_ID;
|
||||
|
||||
const escrowToken = getAssociatedTokenAddressSync(
|
||||
escrowState.tokenMint,
|
||||
escrow,
|
||||
true,
|
||||
tokenProgram,
|
||||
ASSOCIATED_TOKEN_PROGRAM_ID
|
||||
);
|
||||
|
||||
let remainingAccountsInfo: OptionRemainingAccountsInfoData | null = null;
|
||||
let remainingAccounts: AccountMeta[] | undefined = [];
|
||||
if (tokenProgram == TOKEN_2022_PROGRAM_ID) {
|
||||
let claimTransferHookAccounts =
|
||||
await TokenExtensionUtil.getExtraAccountMetasForTransferHook(
|
||||
program.provider.connection,
|
||||
escrowState.tokenMint,
|
||||
escrowToken,
|
||||
recipientToken,
|
||||
escrow,
|
||||
TOKEN_2022_PROGRAM_ID
|
||||
);
|
||||
|
||||
[remainingAccountsInfo, remainingAccounts] = new RemainingAccountsBuilder()
|
||||
.addSlice(
|
||||
RemainingAccountsType.TransferHookEscrow,
|
||||
claimTransferHookAccounts
|
||||
)
|
||||
.build();
|
||||
}
|
||||
|
||||
const tx = await program.methods
|
||||
.claimV2(maxAmount, remainingAccountsInfo)
|
||||
.accounts({
|
||||
tokenProgram,
|
||||
tokenMint: escrowState.tokenMint,
|
||||
memoProgram: MEMO_PROGRAM,
|
||||
escrow,
|
||||
escrowToken,
|
||||
recipient: recipient.publicKey,
|
||||
recipientToken,
|
||||
} as any)
|
||||
.remainingAccounts(remainingAccounts ? remainingAccounts : [])
|
||||
.signers([recipient])
|
||||
.rpc();
|
||||
}
|
||||
|
22
src/utils/extractTxInfo.ts
Normal file
22
src/utils/extractTxInfo.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { TOKEN_PROGRAM_ID } from "@solana/spl-token";
|
||||
import { Connection } from "@solana/web3.js";
|
||||
|
||||
const connection = new Connection(process.env.NEXT_PUBLIC_SOLANA_RPC_URL!);
|
||||
|
||||
export async function extractTxInfo(transactionSignature: string) {
|
||||
const result = await connection.getParsedTransaction(transactionSignature, 'confirmed');
|
||||
if (!result) {
|
||||
throw new Error('Transaction not found');
|
||||
}
|
||||
|
||||
const transferInstruction = result.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 };
|
||||
}
|
@ -3,6 +3,7 @@ import BN from 'bn.js';
|
||||
|
||||
import { Connection } from '@solana/web3.js';
|
||||
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
||||
import { extractTxInfo } from './extractTxInfo';
|
||||
|
||||
assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL, 'SOLANA_RPC_URL is required');
|
||||
|
||||
@ -53,22 +54,7 @@ export async function verifyPayment(
|
||||
return false;
|
||||
}
|
||||
|
||||
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 { parsed } = transferInstruction;
|
||||
const { info } = parsed;
|
||||
const { amount } = info;
|
||||
const { amount } = await extractTxInfo(transactionSignature);
|
||||
|
||||
const transactionAmount = new BN(amount);
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { DataSource, EntityTarget } from 'typeorm';
|
||||
|
||||
import { Tweet } from '../entity/Tweet';
|
||||
import { createRewardLock, extractInfo } from './create-lock';
|
||||
import { createRewardLock } from './create-lock';
|
||||
import { extractTxInfo } from './extractTxInfo';
|
||||
|
||||
export async function verifySignatureInTweet(transactionSignature: string): Promise<boolean> {
|
||||
const paymentRepository = global.appDataSource.getRepository(global.entities.Payment);
|
||||
@ -34,7 +35,7 @@ export async function processTweet(txSignature: string, memeUrl: string | null)
|
||||
|
||||
try {
|
||||
if (isFourthUser) {
|
||||
const { authority, amount } = await extractInfo(txSignature);
|
||||
const { authority, amount } = await extractTxInfo(txSignature);
|
||||
|
||||
if (!authority || Number(amount) <= 0) {
|
||||
return { error: "Invalid transaction details" }
|
||||
|
Loading…
Reference in New Issue
Block a user