diff --git a/package.json b/package.json index 0e529b2..ca13f85 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,9 @@ "description": "Raydium SDK V2 demo.", "license": "GPL-3.0", "dependencies": { - "@raydium-io/raydium-sdk-v2": "0.1.93-alpha", + "@raydium-io/raydium-sdk-v2": "0.1.95-alpha", "@solana/spl-token": "^0.4.6", + "@solana/web3.js": "^1.95.8", "@triton-one/yellowstone-grpc": "^1.2.0", "@types/jsonfile": "^6.1.4", "bs58": "^5.0.0", @@ -24,4 +25,4 @@ "clean": "tsc --build --clean", "dev": "ts-node" } -} \ No newline at end of file +} diff --git a/src/other/formatSwapInfo.ts b/src/other/formatSwapInfo.ts new file mode 100644 index 0000000..b4b5cef --- /dev/null +++ b/src/other/formatSwapInfo.ts @@ -0,0 +1,99 @@ +import { AMM_V4, CLMM_PROGRAM_ID, CREATE_CPMM_POOL_PROGRAM } from "@raydium-io/raydium-sdk-v2"; +import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; +import { PublicKey } from '@solana/web3.js'; +import { connection } from "../config"; + +function checkProgramId(id: PublicKey) { + if (id.equals(AMM_V4)) return 'ammV4' + if (id.equals(CLMM_PROGRAM_ID)) return 'clmm' + if (id.equals(CREATE_CPMM_POOL_PROGRAM)) return 'cpmm' + return undefined +} + +export async function formatSwapInfo(txid: string) { + const txinfo = await connection.getParsedTransaction(txid, { maxSupportedTransactionVersion: 0 }) + + if (txinfo === null) throw Error('fetch tx info error') + + if (txinfo.meta?.err) throw Error('tx error') + + for (let indexIns = 0; indexIns < txinfo.transaction.message.instructions.length; indexIns++) { + const itemIns = txinfo.transaction.message.instructions[indexIns] + + const innerIns = ((txinfo.meta?.innerInstructions ?? []).find(i => i.index === indexIns)?.instructions ?? []) as any[] + + const type = checkProgramId(itemIns.programId) + + if (type && innerIns.length >= 2 && innerIns[0].programId.equals(TOKEN_PROGRAM_ID) && innerIns[1].programId.equals(TOKEN_PROGRAM_ID)) { + const transfer1 = innerIns[0] + const transfer2 = innerIns[1] + const transferSource1 = transfer1.parsed.info.source + + const transferAmount1 = transfer1.parsed.info.amount ?? transfer1.parsed.info.tokenAmount.amount + const transferAmount2 = transfer2.parsed.info.amount ?? transfer2.parsed.info.tokenAmount.amount + + if (type === 'ammV4') { + // @ts-ignore + const swapType = itemIns.accounts[4].toString() === transferSource1 ? 'A to B' : 'B to A' + + console.log({ + type, + // @ts-ignore + poolId: itemIns.accounts[1].toString(), + + inputAmount: swapType === 'A to B' ? transferAmount1 : transferAmount2, + outputAmount: swapType === 'A to B' ? transferAmount1 : transferAmount2, + }) + } else { + console.log({ + type, + // @ts-ignore + poolId: itemIns.accounts[type === 'clmm' ? 2 : 3].toString(), + + inputAmount: transferAmount1, + outputAmount: transferAmount2, + }) + } + } + + for (let innerIndexIns = 0; innerIndexIns < innerIns.length; innerIndexIns++) { + const innerItemIns = innerIns[innerIndexIns] + + const lastInnerItemIns = innerIns.slice(innerIndexIns + 1) + + const innerType = checkProgramId(innerItemIns.programId) + + if (innerType && lastInnerItemIns.length >= 2 && lastInnerItemIns[0].programId.equals(TOKEN_PROGRAM_ID) && lastInnerItemIns[1].programId.equals(TOKEN_PROGRAM_ID)) { + const transfer1 = lastInnerItemIns[0] + const transfer2 = lastInnerItemIns[1] + const transferSource1 = transfer1.parsed.info.source + + const transferAmount1 = transfer1.parsed.info.amount ?? transfer1.parsed.info.tokenAmount.amount + const transferAmount2 = transfer2.parsed.info.amount ?? transfer2.parsed.info.tokenAmount.amount + + if (innerType === 'ammV4') { + // @ts-ignore + const swapType = innerItemIns.accounts[4].toString() === transferSource1 ? 'A to B' : 'B to A' + + console.log({ + type: innerType, + // @ts-ignore + poolId: innerItemIns.accounts[1].toString(), + + inputAmount: swapType === 'A to B' ? transferAmount1 : transferAmount2, + outputAmount: swapType === 'A to B' ? transferAmount1 : transferAmount2, + }) + } else { + console.log({ + type: innerType, + // @ts-ignore + poolId: innerItemIns.accounts[innerType === 'clmm' ? 2 : 3].toString(), + + inputAmount: transferAmount1, + outputAmount: transferAmount2, + }) + } + } + } + } +} diff --git a/yarn.lock b/yarn.lock index 23ed9d8..6253c5b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -278,10 +278,10 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== -"@raydium-io/raydium-sdk-v2@0.1.93-alpha": - version "0.1.93-alpha" - resolved "https://registry.yarnpkg.com/@raydium-io/raydium-sdk-v2/-/raydium-sdk-v2-0.1.93-alpha.tgz#9178bf33ff8698f65d2ff84852db21356b252b71" - integrity sha512-FPoFIU0ntgCcyPMDSCQPGrUDegfelGVRsYLJDH+zdC46BXZUE4osubdFF/OZo16cRlNJQ/1t+sWcjGdWRsJbwg== +"@raydium-io/raydium-sdk-v2@0.1.95-alpha": + version "0.1.95-alpha" + resolved "https://registry.yarnpkg.com/@raydium-io/raydium-sdk-v2/-/raydium-sdk-v2-0.1.95-alpha.tgz#75fe4386f534b2b0d9fb12b8efa08377ee4c8dbf" + integrity sha512-+u7yxo/R1JDysTCzOuAlh90ioBe2DlM2Hbcz/tFsxP/YzmnYQzShvNjcmc0361a4zJhmlrEJfpFXW0J3kkX5vA== dependencies: "@solana/buffer-layout" "^4.0.1" "@solana/spl-token" "^0.4.8" @@ -562,6 +562,27 @@ rpc-websockets "^9.0.2" superstruct "^2.0.2" +"@solana/web3.js@^1.95.8": + version "1.95.8" + resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.95.8.tgz#2d49abda23f7a79a3cc499ab6680f7be11786ee1" + integrity sha512-sBHzNh7dHMrmNS5xPD1d0Xa2QffW/RXaxu/OysRXBfwTp+LYqGGmMtCYYwrHPrN5rjAmJCsQRNAwv4FM0t3B6g== + dependencies: + "@babel/runtime" "^7.25.0" + "@noble/curves" "^1.4.2" + "@noble/hashes" "^1.4.0" + "@solana/buffer-layout" "^4.0.1" + agentkeepalive "^4.5.0" + bigint-buffer "^1.1.5" + bn.js "^5.2.1" + borsh "^0.7.0" + bs58 "^4.0.1" + buffer "6.0.3" + fast-stable-stringify "^1.0.0" + jayson "^4.1.1" + node-fetch "^2.7.0" + rpc-websockets "^9.0.2" + superstruct "^2.0.2" + "@swc/helpers@^0.5.11": version "0.5.11" resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.11.tgz#5bab8c660a6e23c13b2d23fcd1ee44a2db1b0cb7" @@ -2852,16 +2873,7 @@ ssri@^9.0.0: dependencies: minipass "^3.1.1" -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -2886,14 +2898,7 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -3190,16 +3195,7 @@ widest-line@^4.0.1: dependencies: string-width "^5.0.1" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==