From 9b40200060b93bd7d56f79eb01db5338c8263b08 Mon Sep 17 00:00:00 2001 From: atul24112001 Date: Fri, 1 Nov 2024 21:44:07 +0530 Subject: [PATCH 1/5] Minting token --- package-lock.json | 189 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + src/address.ts | 5 +- src/index.ts | 40 +++++----- src/mintTokens.ts | 61 ++++++++++++--- 5 files changed, 267 insertions(+), 29 deletions(-) diff --git a/package-lock.json b/package-lock.json index c7d7c9f..d3c0595 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "@solana/spl-token": "^0.4.9", "@solana/web3.js": "^1.95.4", "@types/express": "^5.0.0", "dotenv": "^16.4.5", @@ -67,6 +68,169 @@ "node": ">=5.10" } }, + "node_modules/@solana/buffer-layout-utils": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz", + "integrity": "sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==", + "dependencies": { + "@solana/buffer-layout": "^4.0.0", + "@solana/web3.js": "^1.32.0", + "bigint-buffer": "^1.1.5", + "bignumber.js": "^9.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@solana/codecs": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs/-/codecs-2.0.0-rc.1.tgz", + "integrity": "sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/codecs-data-structures": "2.0.0-rc.1", + "@solana/codecs-numbers": "2.0.0-rc.1", + "@solana/codecs-strings": "2.0.0-rc.1", + "@solana/options": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-core": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.0.0-rc.1.tgz", + "integrity": "sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==", + "dependencies": { + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-data-structures": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-data-structures/-/codecs-data-structures-2.0.0-rc.1.tgz", + "integrity": "sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/codecs-numbers": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-numbers": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.0.0-rc.1.tgz", + "integrity": "sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-strings": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-strings/-/codecs-strings-2.0.0-rc.1.tgz", + "integrity": "sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/codecs-numbers": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "fastestsmallesttextencoderdecoder": "^1.0.22", + "typescript": ">=5" + } + }, + "node_modules/@solana/errors": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/errors/-/errors-2.0.0-rc.1.tgz", + "integrity": "sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==", + "dependencies": { + "chalk": "^5.3.0", + "commander": "^12.1.0" + }, + "bin": { + "errors": "bin/cli.mjs" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/errors/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "engines": { + "node": ">=18" + } + }, + "node_modules/@solana/options": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/options/-/options-2.0.0-rc.1.tgz", + "integrity": "sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/codecs-data-structures": "2.0.0-rc.1", + "@solana/codecs-numbers": "2.0.0-rc.1", + "@solana/codecs-strings": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/spl-token": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.4.9.tgz", + "integrity": "sha512-g3wbj4F4gq82YQlwqhPB0gHFXfgsC6UmyGMxtSLf/BozT/oKd59465DbnlUK8L8EcimKMavxsVAMoLcEdeCicg==", + "dependencies": { + "@solana/buffer-layout": "^4.0.0", + "@solana/buffer-layout-utils": "^0.2.0", + "@solana/spl-token-group": "^0.0.7", + "@solana/spl-token-metadata": "^0.1.6", + "buffer": "^6.0.3" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.95.3" + } + }, + "node_modules/@solana/spl-token-group": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@solana/spl-token-group/-/spl-token-group-0.0.7.tgz", + "integrity": "sha512-V1N/iX7Cr7H0uazWUT2uk27TMqlqedpXHRqqAbVO2gvmJyT0E0ummMEAVQeXZ05ZhQ/xF39DLSdBp90XebWEug==", + "dependencies": { + "@solana/codecs": "2.0.0-rc.1" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.95.3" + } + }, + "node_modules/@solana/spl-token-metadata": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@solana/spl-token-metadata/-/spl-token-metadata-0.1.6.tgz", + "integrity": "sha512-7sMt1rsm/zQOQcUWllQX9mD2O6KhSAtY1hFR2hfFwgqfFWzSY9E9GDvFVNYUI1F0iQKcm6HmePU9QbKRXTEBiA==", + "dependencies": { + "@solana/codecs": "2.0.0-rc.1" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.95.3" + } + }, "node_modules/@solana/web3.js": { "version": "1.95.4", "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.95.4.tgz", @@ -281,6 +445,14 @@ "node": ">= 10.0.0" } }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "engines": { + "node": "*" + } + }, "node_modules/bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", @@ -406,6 +578,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -651,6 +834,12 @@ "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==", "license": "MIT" }, + "node_modules/fastestsmallesttextencoderdecoder": { + "version": "1.0.22", + "resolved": "https://registry.npmjs.org/fastestsmallesttextencoderdecoder/-/fastestsmallesttextencoderdecoder-1.0.22.tgz", + "integrity": "sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==", + "peer": true + }, "node_modules/file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", diff --git a/package.json b/package.json index f63f319..e0b1a4b 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "license": "ISC", "description": "", "dependencies": { + "@solana/spl-token": "^0.4.9", "@solana/web3.js": "^1.95.4", "@types/express": "^5.0.0", "dotenv": "^16.4.5", diff --git a/src/address.ts b/src/address.ts index 9739cfb..723df12 100644 --- a/src/address.ts +++ b/src/address.ts @@ -1,4 +1,5 @@ export const PRIVATE_KEY = ""; -export const PUBLIC_KEY = ""; +export const PUBLIC_KEY = "CVdndsAGyNj8BvLhtrQBLMtrwEgy53ACXFQmQMfH2MFQ"; -export const TOKEN_MINT_ADDRESS = ""; \ No newline at end of file +export const TOKEN_MINT_ADDRESS = + "4EvpeWRye9YNqsuPkAzj8xwzB4ovnLetK9A3W1j5UHYd"; diff --git a/src/index.ts b/src/index.ts index 641355f..32baa2a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,27 +1,31 @@ -require('dotenv').config(); -import express from 'express'; -import { burnTokens, mintTokens, sendNativeTokens } from './mintTokens'; +require("dotenv").config(); +import express from "express"; +import { burnTokens, mintTokens, sendNativeTokens } from "./mintTokens"; +import { PUBLIC_KEY } from "./address"; const app = express(); +app.post("/helius", async (req, res) => { + const data = req.body[0]; + const { amount, fromUserAccount, toUserAccount } = data.nativeTransfers[0]; -app.post('/helius', async(req, res) => { - const fromAddress = req.body.fromAddress; - const toAddress = req.body.toAddress; - const amount = req.body.amount; - const type = "received_native_sol"; + if (toUserAccount !== PUBLIC_KEY) { + res.json({ + message: "Processed", + }); + return; + } - if (type === "received_native_sol") { - await mintTokens(fromAddress, toAddress, amount); - } else { - // What could go wrong here? - await burnTokens(fromAddress, toAddress, amount); - await sendNativeTokens(fromAddress, toAddress, amount); - } + if (data.type === "TRANSFER") { + await mintTokens(fromUserAccount, toUserAccount, amount); + } else { + await burnTokens(fromUserAccount, toUserAccount, amount); + await sendNativeTokens(fromUserAccount, toUserAccount, amount); + } - res.send('Transaction successful'); + res.send("Transaction successful"); }); app.listen(3000, () => { - console.log('Server is running on port 3000'); -}); \ No newline at end of file + console.log("Server is running on port 3000"); +}); diff --git a/src/mintTokens.ts b/src/mintTokens.ts index 8e5a0eb..6f864a7 100644 --- a/src/mintTokens.ts +++ b/src/mintTokens.ts @@ -1,12 +1,55 @@ +import { + Connection, + Keypair, + PublicKey, + Transaction, + sendAndConfirmTransaction, +} from "@solana/web3.js"; +import { PRIVATE_KEY, TOKEN_MINT_ADDRESS } from "./address"; +import * as TokenProgram from "@solana/spl-token"; -export const mintTokens = async (fromAddress: string, toAddress: string, amount: number) => { - console.log("Minting tokens"); -} +export const mintTokens = async ( + fromAddress: string, + toAddress: string, + amount: number +) => { + const secret = new Uint8Array(PRIVATE_KEY as any); + const wallet = Keypair.fromSecretKey(secret); + const mint = new PublicKey(TOKEN_MINT_ADDRESS); -export const burnTokens = async (fromAddress: string, toAddress: string, amount: number) => { - console.log("Burning tokens"); -} + const tokenAccount = await TokenProgram.getOrCreateAssociatedTokenAccount( + getConnection(), + wallet, + mint, + wallet.publicKey + ); + + await TokenProgram.mintTo( + getConnection(), + wallet, + tokenAccount.mint, + tokenAccount.address, + wallet.publicKey, + amount + ); +}; -export const sendNativeTokens = async (fromAddress: string, toAddress: string, amount: number) => { - console.log("Sending native tokens"); -} \ No newline at end of file +export const burnTokens = async ( + fromAddress: string, + toAddress: string, + amount: number +) => { + console.log("Burning tokens"); +}; + +export const sendNativeTokens = async ( + fromAddress: string, + toAddress: string, + amount: number +) => { + console.log("Sending native tokens"); +}; + +function getConnection(): Connection { + return new Connection("https://api.devnet.solana.com"); +} From 876b0dfbb66e0ce19fe933cd15ab0ba25df5dad1 Mon Sep 17 00:00:00 2001 From: atul24112001 Date: Fri, 1 Nov 2024 21:46:11 +0530 Subject: [PATCH 2/5] Minting token --- package-lock.json | 46 +++++++++++++++++++++++++++++++++++++--------- package.json | 1 + src/mintTokens.ts | 3 ++- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index d3c0595..a4546ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@solana/spl-token": "^0.4.9", "@solana/web3.js": "^1.95.4", "@types/express": "^5.0.0", + "bs58": "^6.0.0", "dotenv": "^16.4.5", "express": "^4.21.1", "typescript": "^5.6.3" @@ -254,6 +255,22 @@ "superstruct": "^2.0.2" } }, + "node_modules/@solana/web3.js/node_modules/base-x": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.10.tgz", + "integrity": "sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/@solana/web3.js/node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, "node_modules/@swc/helpers": { "version": "0.5.13", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz", @@ -404,13 +421,9 @@ "license": "MIT" }, "node_modules/base-x": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.10.tgz", - "integrity": "sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==", - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.0.1" - } + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-5.0.0.tgz", + "integrity": "sha512-sMW3VGSX1QWVFA6l8U62MLKz29rRfpTlYdCqLdpLo1/Yd4zZwSbnUaDfciIAowAqvq7YFnWq9hrhdg1KYgc1lQ==" }, "node_modules/base64-js": { "version": "1.5.1", @@ -503,15 +516,30 @@ "text-encoding-utf-8": "^1.0.2" } }, - "node_modules/bs58": { + "node_modules/borsh/node_modules/base-x": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.10.tgz", + "integrity": "sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/borsh/node_modules/bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", - "license": "MIT", "dependencies": { "base-x": "^3.0.2" } }, + "node_modules/bs58": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-6.0.0.tgz", + "integrity": "sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==", + "dependencies": { + "base-x": "^5.0.0" + } + }, "node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", diff --git a/package.json b/package.json index e0b1a4b..63cb2c7 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "@solana/spl-token": "^0.4.9", "@solana/web3.js": "^1.95.4", "@types/express": "^5.0.0", + "bs58": "^6.0.0", "dotenv": "^16.4.5", "express": "^4.21.1", "typescript": "^5.6.3" diff --git a/src/mintTokens.ts b/src/mintTokens.ts index 6f864a7..a431c7e 100644 --- a/src/mintTokens.ts +++ b/src/mintTokens.ts @@ -8,12 +8,13 @@ import { import { PRIVATE_KEY, TOKEN_MINT_ADDRESS } from "./address"; import * as TokenProgram from "@solana/spl-token"; +import bs58 from "bs58"; export const mintTokens = async ( fromAddress: string, toAddress: string, amount: number ) => { - const secret = new Uint8Array(PRIVATE_KEY as any); + const secret = new Uint8Array(bs58.decode(PRIVATE_KEY)); const wallet = Keypair.fromSecretKey(secret); const mint = new PublicKey(TOKEN_MINT_ADDRESS); From 9add475bc583f01065b27b5be4fdc1fa88667e94 Mon Sep 17 00:00:00 2001 From: atul24112001 Date: Sat, 2 Nov 2024 00:52:57 +0530 Subject: [PATCH 3/5] assignment completed --- .gitignore | 3 +- src/address.ts | 10 +++--- src/index.ts | 57 ++++++++++++++++++++++---------- src/mintTokens.ts | 83 +++++++++++++++++++++++++++++++++++------------ 4 files changed, 111 insertions(+), 42 deletions(-) diff --git a/.gitignore b/.gitignore index 1dcef2d..8f00ef2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules -.env \ No newline at end of file +.env +dist \ No newline at end of file diff --git a/src/address.ts b/src/address.ts index 723df12..66e6073 100644 --- a/src/address.ts +++ b/src/address.ts @@ -1,5 +1,7 @@ -export const PRIVATE_KEY = ""; -export const PUBLIC_KEY = "CVdndsAGyNj8BvLhtrQBLMtrwEgy53ACXFQmQMfH2MFQ"; +export const PRIVATE_KEY = process.env.PRIVATE_KEY as string; +export const PUBLIC_KEY = process.env.PUBLIC_KEY as string; -export const TOKEN_MINT_ADDRESS = - "4EvpeWRye9YNqsuPkAzj8xwzB4ovnLetK9A3W1j5UHYd"; +export const TOKEN_MINT_ADDRESS = process.env.TOKEN_MINT_ADDRESS as string; +export const TOKEN_MINT_DECIMALS = parseInt( + process.env.TOKEN_MINT_DECIMALS || "9" +) as number; diff --git a/src/index.ts b/src/index.ts index 32baa2a..cee1a66 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,31 +1,54 @@ require("dotenv").config(); import express from "express"; import { burnTokens, mintTokens, sendNativeTokens } from "./mintTokens"; -import { PUBLIC_KEY } from "./address"; +import { PUBLIC_KEY, TOKEN_MINT_ADDRESS, TOKEN_MINT_DECIMALS } from "./address"; + +// database +const processedTransfers: { [key: string]: boolean } = {}; const app = express(); +app.use(express.json()); + app.post("/helius", async (req, res) => { - const data = req.body[0]; - const { amount, fromUserAccount, toUserAccount } = data.nativeTransfers[0]; - - if (toUserAccount !== PUBLIC_KEY) { - res.json({ - message: "Processed", - }); - return; - } + try { + const data = req.body[0]; + if (processedTransfers[data.signature]) { + res.send("Success"); + return; + } + + // I wanted to verify the signature as well but this webhook gets called very fast and the verification will + // fail for valid signature as well + + if (data.type === "TRANSFER") { + if (data.nativeTransfers.length > 0) { + const { amount, fromUserAccount, toUserAccount } = + data.nativeTransfers[0]; + + if (toUserAccount === PUBLIC_KEY) { + await mintTokens(fromUserAccount, toUserAccount, amount); + } + } else if (data.tokenTransfers.length > 0) { + const { fromUserAccount, mint, toUserAccount, tokenAmount } = + data.tokenTransfers[0]; + console.log({ tokenAmount }); + if (mint === TOKEN_MINT_ADDRESS && toUserAccount === PUBLIC_KEY) { + const amount = parseFloat(tokenAmount) * 10 ** TOKEN_MINT_DECIMALS; + await sendNativeTokens(fromUserAccount, amount); + await burnTokens(amount); + } + } + } - if (data.type === "TRANSFER") { - await mintTokens(fromUserAccount, toUserAccount, amount); - } else { - await burnTokens(fromUserAccount, toUserAccount, amount); - await sendNativeTokens(fromUserAccount, toUserAccount, amount); + processedTransfers[data.signature] = true; + } catch (error) { + console.log(error); } - res.send("Transaction successful"); + res.send("Success"); }); -app.listen(3000, () => { +app.listen(8000, () => { console.log("Server is running on port 3000"); }); diff --git a/src/mintTokens.ts b/src/mintTokens.ts index a431c7e..7a6db0c 100644 --- a/src/mintTokens.ts +++ b/src/mintTokens.ts @@ -2,6 +2,7 @@ import { Connection, Keypair, PublicKey, + SystemProgram, Transaction, sendAndConfirmTransaction, } from "@solana/web3.js"; @@ -14,43 +15,85 @@ export const mintTokens = async ( toAddress: string, amount: number ) => { + console.log("Minting token"); const secret = new Uint8Array(bs58.decode(PRIVATE_KEY)); - const wallet = Keypair.fromSecretKey(secret); + const payer = Keypair.fromSecretKey(secret); const mint = new PublicKey(TOKEN_MINT_ADDRESS); - + const recipientPublicKey = new PublicKey(fromAddress); const tokenAccount = await TokenProgram.getOrCreateAssociatedTokenAccount( getConnection(), - wallet, + payer, mint, - wallet.publicKey + recipientPublicKey ); await TokenProgram.mintTo( getConnection(), - wallet, - tokenAccount.mint, + payer, + mint, tokenAccount.address, - wallet.publicKey, + payer, amount ); }; -export const burnTokens = async ( - fromAddress: string, - toAddress: string, - amount: number -) => { - console.log("Burning tokens"); +export const burnTokens = async (amount: number) => { + console.log("Burning token"); + const secret = new Uint8Array(bs58.decode(PRIVATE_KEY)); + const payer = Keypair.fromSecretKey(secret); + const mint = new PublicKey(TOKEN_MINT_ADDRESS); + + const connection = getConnection(); + + const tokenAccount = await TokenProgram.getOrCreateAssociatedTokenAccount( + connection, + payer, + mint, + payer.publicKey + ); + await TokenProgram.burn( + connection, + payer, + tokenAccount.address, + mint, + payer.publicKey, + amount + ); }; -export const sendNativeTokens = async ( - fromAddress: string, - toAddress: string, - amount: number -) => { - console.log("Sending native tokens"); +export const sendNativeTokens = async (toAddress: string, amount: number) => { + console.log("Sending native token"); + const connection = getConnection(); + const latestBlockHash = await connection.getLatestBlockhash(); + + const secret = new Uint8Array(bs58.decode(PRIVATE_KEY)); + const payer = Keypair.fromSecretKey(secret); + + const recipientPublicKey = new PublicKey(toAddress); + + const transfer = SystemProgram.transfer({ + fromPubkey: payer.publicKey, + toPubkey: recipientPublicKey, + lamports: amount, + }); + const transaction = new Transaction(); + transaction.add(transfer); + + transaction.recentBlockhash = latestBlockHash.blockhash; + transaction.lastValidBlockHeight = latestBlockHash.lastValidBlockHeight; + + const signature = await sendAndConfirmTransaction(connection, transaction, [ + payer, + ]); + + await connection.confirmTransaction({ + signature, + blockhash: latestBlockHash.blockhash, + lastValidBlockHeight: latestBlockHash.lastValidBlockHeight, + }); + return signature; }; -function getConnection(): Connection { +export function getConnection(): Connection { return new Connection("https://api.devnet.solana.com"); } From 1b807a9090163e74b8e8774a5ae4f8bcf12137ce Mon Sep 17 00:00:00 2001 From: atul24112001 Date: Sat, 2 Nov 2024 09:30:02 +0530 Subject: [PATCH 4/5] fixed connection --- src/mintTokens.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/mintTokens.ts b/src/mintTokens.ts index 7a6db0c..f344530 100644 --- a/src/mintTokens.ts +++ b/src/mintTokens.ts @@ -94,6 +94,11 @@ export const sendNativeTokens = async (toAddress: string, amount: number) => { return signature; }; +let _connection: Connection | null = null; + export function getConnection(): Connection { - return new Connection("https://api.devnet.solana.com"); + if (!_connection) { + _connection = new Connection("https://api.devnet.solana.com"); + } + return _connection; } From 0bd2319c2100117771a70dce29a845ed010e53e0 Mon Sep 17 00:00:00 2001 From: atul24112001 Date: Sat, 2 Nov 2024 09:31:31 +0530 Subject: [PATCH 5/5] Added .env.example --- .env.example | 5 +++++ src/mintTokens.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..f3e0707 --- /dev/null +++ b/.env.example @@ -0,0 +1,5 @@ +PRIVATE_KEY="" +PUBLIC_KEY="" +TOKEN_MINT_ADDRESS="" +TOKEN_MINT_DECIMALS=9 +RPC_URL="" \ No newline at end of file diff --git a/src/mintTokens.ts b/src/mintTokens.ts index f344530..aff1cc4 100644 --- a/src/mintTokens.ts +++ b/src/mintTokens.ts @@ -98,7 +98,7 @@ let _connection: Connection | null = null; export function getConnection(): Connection { if (!_connection) { - _connection = new Connection("https://api.devnet.solana.com"); + _connection = new Connection(process.env.RPC_URL as string); } return _connection; }