mirror of
https://github.com/chainstacklabs/pumpfun-bonkfun-bot.git
synced 2026-07-27 15:27:44 +00:00
feat: update rest of scripts with creator fee
This commit is contained in:
+133
-273
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"transaction": [
|
||||
"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",
|
||||
"base64"
|
||||
],
|
||||
"meta": {
|
||||
@@ -8,187 +8,85 @@
|
||||
"status": {
|
||||
"Ok": null
|
||||
},
|
||||
"fee": 115000,
|
||||
"fee": 1500000,
|
||||
"preBalances": [
|
||||
1299959000,
|
||||
2005440908,
|
||||
0,
|
||||
20558783,
|
||||
4696550893895,
|
||||
13463471281,
|
||||
377180764,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
297249326667618,
|
||||
1,
|
||||
57019670,
|
||||
4441807831495,
|
||||
2039280,
|
||||
1,
|
||||
1141440,
|
||||
323296939,
|
||||
2500000,
|
||||
1141440,
|
||||
1,
|
||||
934087680,
|
||||
1141440,
|
||||
1141440,
|
||||
290898417,
|
||||
1461600,
|
||||
731913600,
|
||||
1009200,
|
||||
0
|
||||
137104014
|
||||
],
|
||||
"postBalances": [
|
||||
162455200,
|
||||
1461600,
|
||||
24558783,
|
||||
1101231920,
|
||||
1686928628,
|
||||
0,
|
||||
4696553593895,
|
||||
13760771281,
|
||||
377329414,
|
||||
2039280,
|
||||
15616720,
|
||||
69019670,
|
||||
4441810655845,
|
||||
2039280,
|
||||
297249337667618,
|
||||
1,
|
||||
1,
|
||||
1141440,
|
||||
323296939,
|
||||
2500000,
|
||||
1141440,
|
||||
1,
|
||||
934087680,
|
||||
1141440,
|
||||
1141440,
|
||||
290898417,
|
||||
1461600,
|
||||
731913600,
|
||||
1009200,
|
||||
0
|
||||
137104014
|
||||
],
|
||||
"innerInstructions": [
|
||||
{
|
||||
"index": 3,
|
||||
"instructions": [
|
||||
{
|
||||
"programIdIndex": 9,
|
||||
"programIdIndex": 12,
|
||||
"accounts": [
|
||||
0,
|
||||
1
|
||||
],
|
||||
"data": "11114XtYk9gGfZoo968fyjNUYQJKf9gdmkGoaoBpzFv4vyaSMBn3VKxZdv7mZLzoyX5YNC",
|
||||
"stackHeight": 2
|
||||
},
|
||||
{
|
||||
"programIdIndex": 14,
|
||||
"accounts": [
|
||||
1
|
||||
],
|
||||
"data": "2zt6UCCHp66bJGRS4G7bTsjdxFh6FQ9sBEyRfGyPQKxYisAw",
|
||||
"stackHeight": 2
|
||||
},
|
||||
{
|
||||
"programIdIndex": 9,
|
||||
"accounts": [
|
||||
0,
|
||||
3
|
||||
],
|
||||
"data": "11112npZeiggj74jpdjnyaoXKQznZSuR59vRrSV7vxdg9g2eRJ4seDwRwaQLDUqBNSEnrB",
|
||||
"stackHeight": 2
|
||||
},
|
||||
{
|
||||
"programIdIndex": 15,
|
||||
"accounts": [
|
||||
0,
|
||||
4,
|
||||
3,
|
||||
1,
|
||||
9,
|
||||
14
|
||||
],
|
||||
"data": "1",
|
||||
"stackHeight": 2
|
||||
},
|
||||
{
|
||||
"programIdIndex": 14,
|
||||
"accounts": [
|
||||
1
|
||||
16
|
||||
],
|
||||
"data": "84eT",
|
||||
"stackHeight": 3
|
||||
"stackHeight": 2
|
||||
},
|
||||
{
|
||||
"programIdIndex": 9,
|
||||
"accounts": [
|
||||
0,
|
||||
4
|
||||
5
|
||||
],
|
||||
"data": "11119os1e9qSs2u7TsThXqkBSRVFxhmYaFKFZ1waB2X7armDmvK3p5GmLdUxYdg3h7QSrL",
|
||||
"stackHeight": 3
|
||||
"stackHeight": 2
|
||||
},
|
||||
{
|
||||
"programIdIndex": 14,
|
||||
"programIdIndex": 12,
|
||||
"accounts": [
|
||||
4
|
||||
5
|
||||
],
|
||||
"data": "P",
|
||||
"stackHeight": 3
|
||||
"stackHeight": 2
|
||||
},
|
||||
{
|
||||
"programIdIndex": 14,
|
||||
"accounts": [
|
||||
4,
|
||||
1
|
||||
],
|
||||
"data": "6R9wJMnJhbG9ZQYKJuVP2PB6vT2C61iaQx6VwGbPagDmk",
|
||||
"stackHeight": 3
|
||||
},
|
||||
{
|
||||
"programIdIndex": 13,
|
||||
"programIdIndex": 12,
|
||||
"accounts": [
|
||||
5,
|
||||
1,
|
||||
11,
|
||||
0,
|
||||
11,
|
||||
9
|
||||
16
|
||||
],
|
||||
"data": "sCA7VhscVFkCjwGP776CKweeQ17GA3y6hoefZyQZ7igmWRvSXA49qEc3vT7wBUxVA13HoHqvXDFZ4UuibYrj1fSiqN7Hw2T1PxZfuF1ebruak4VwaCoseJMTaoCSRGbUZZSf",
|
||||
"stackHeight": 2
|
||||
},
|
||||
{
|
||||
"programIdIndex": 9,
|
||||
"accounts": [
|
||||
0,
|
||||
5
|
||||
],
|
||||
"data": "3Bxs4bhMrSrmPkVD",
|
||||
"stackHeight": 3
|
||||
},
|
||||
{
|
||||
"programIdIndex": 9,
|
||||
"accounts": [
|
||||
5
|
||||
],
|
||||
"data": "9krTDUMpjBo4wxLP",
|
||||
"stackHeight": 3
|
||||
},
|
||||
{
|
||||
"programIdIndex": 9,
|
||||
"accounts": [
|
||||
5
|
||||
],
|
||||
"data": "SYXsBkG6yKW2wWDcW8EDHR6D3P82bKxJGPpM65DD8nHqBfMP",
|
||||
"stackHeight": 3
|
||||
},
|
||||
{
|
||||
"programIdIndex": 14,
|
||||
"accounts": [
|
||||
1,
|
||||
4,
|
||||
11
|
||||
],
|
||||
"data": "6ApXSNCamGdm",
|
||||
"stackHeight": 2
|
||||
},
|
||||
{
|
||||
"programIdIndex": 14,
|
||||
"accounts": [
|
||||
1,
|
||||
11
|
||||
],
|
||||
"data": "31tb",
|
||||
"stackHeight": 2
|
||||
},
|
||||
{
|
||||
"programIdIndex": 10,
|
||||
"accounts": [
|
||||
17
|
||||
],
|
||||
"data": "7iazyA59wwtAStxsqtCeosLjmdhF7YPNeRh62abjnRpjo8BFJQyM79SCTR8EdrQNP4pFWzB9LRwFM7eYmn6zhAZ8UjEWrgARNaSmjuLGwaXuB6CQiRHZ2XpENVyDtB5adZ2hqDvmbGzTNsMd9CvgKxusSLTGhhW5Y7b4jvGji585fx1Bq3XKBg6Zr1mCNjcVFzQ45dRSbDad9ZQaVjDLSHMRVuwNvhvLM3RQCJLhyo4e6S156JeFmweeAp7HqHvGw3fVitNxwbrmnU8MsJ9",
|
||||
"data": "6UhFp3r3cKbQWwHQYPuDqtb5CAdjXP45vy8Z8DQwgGRSQ",
|
||||
"stackHeight": 2
|
||||
}
|
||||
]
|
||||
@@ -196,54 +94,52 @@
|
||||
{
|
||||
"index": 4,
|
||||
"instructions": [
|
||||
{
|
||||
"programIdIndex": 14,
|
||||
"accounts": [
|
||||
1
|
||||
],
|
||||
"data": "84eT",
|
||||
"stackHeight": 2
|
||||
},
|
||||
{
|
||||
"programIdIndex": 9,
|
||||
"accounts": [
|
||||
0,
|
||||
6
|
||||
2
|
||||
],
|
||||
"data": "11119os1e9qSs2u7TsThXqkBSRVFxhmYaFKFZ1waB2X7armDmvK3p5GmLdUxYdg3h7QSrL",
|
||||
"data": "3Bxs4eMeB358Cb5h",
|
||||
"stackHeight": 2
|
||||
},
|
||||
{
|
||||
"programIdIndex": 14,
|
||||
"accounts": [
|
||||
6
|
||||
],
|
||||
"data": "P",
|
||||
"stackHeight": 2
|
||||
},
|
||||
{
|
||||
"programIdIndex": 14,
|
||||
"accounts": [
|
||||
6,
|
||||
1
|
||||
],
|
||||
"data": "6dhk2iczksvz6s1rFHcSMywmmwmB1z7XmGVUbnAVDoyj7",
|
||||
"stackHeight": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"index": 5,
|
||||
"instructions": [
|
||||
{
|
||||
"programIdIndex": 14,
|
||||
"programIdIndex": 10,
|
||||
"accounts": [
|
||||
15,
|
||||
7,
|
||||
16,
|
||||
3,
|
||||
8,
|
||||
5,
|
||||
0,
|
||||
9,
|
||||
12,
|
||||
4,
|
||||
6,
|
||||
18,
|
||||
10
|
||||
],
|
||||
"data": "AJTQ2h9DXrBo1MiibpgfkQHmpSKmNnQgP",
|
||||
"stackHeight": 2
|
||||
},
|
||||
{
|
||||
"programIdIndex": 12,
|
||||
"accounts": [
|
||||
8,
|
||||
5,
|
||||
3
|
||||
],
|
||||
"data": "3LUFBVrqeiX9",
|
||||
"stackHeight": 2
|
||||
"data": "3SpdELLWnXkK",
|
||||
"stackHeight": 3
|
||||
},
|
||||
{
|
||||
"programIdIndex": 9,
|
||||
"accounts": [
|
||||
0,
|
||||
4
|
||||
],
|
||||
"data": "3Bxs4VLT5WjmR4oh",
|
||||
"stackHeight": 3
|
||||
},
|
||||
{
|
||||
"programIdIndex": 9,
|
||||
@@ -251,8 +147,8 @@
|
||||
0,
|
||||
3
|
||||
],
|
||||
"data": "3Bxs3zyALUmzCtNB",
|
||||
"stackHeight": 2
|
||||
"data": "3Bxs46HNXQ8jq79R",
|
||||
"stackHeight": 3
|
||||
},
|
||||
{
|
||||
"programIdIndex": 9,
|
||||
@@ -260,16 +156,16 @@
|
||||
0,
|
||||
7
|
||||
],
|
||||
"data": "3Bxs4Z7Wb6tTKEWB",
|
||||
"stackHeight": 2
|
||||
"data": "3Bxs4TJNecvxKcVV",
|
||||
"stackHeight": 3
|
||||
},
|
||||
{
|
||||
"programIdIndex": 10,
|
||||
"accounts": [
|
||||
17
|
||||
18
|
||||
],
|
||||
"data": "2K7nL28PxCW8ejnyCeuMpbXaZKMjMgWS9mpWYzdhxxxazMRueEhr8dhzoSv8cJB4QmssgbcPVf7uHyA7xpBWFRc9qBGRzEzUtR1t2P8uGyxRepqEGGoak55qnosFUyXaDoRPdY3r2GR952e4KnxiYyGBD4epcJmcs5akyXSEueVSCuYxtXDaCp7HgAoy",
|
||||
"stackHeight": 2
|
||||
"data": "2zjR1PvPvgqdhPdZLxuWCL7GiE5h1bKn4ziAcRd2FBFaC3kf2EYsG31a2aigsk9mgAfieqmo561JLMNk2uSKF65QKzv64GtLAULg9zNrDFfLe7DrBDcgQBwTwRqqLVkWBrksYNBFeyBeSPwcQe5DNEEqwfSowV6pk2t9QuN6JDSpxRegP8ekTV5zwc3ytD2hSo7wu9s4ynRb5ccHwRaoy9Lzm7M66sikRLa74mXuFzdjzGuq454PDDP8eqUSWxt1ddTchsUvqsAnv92vMN2BLu7XZ3UcTv96fz8KrV93qqHSsNwfKdCsY7QMwxbCE7R",
|
||||
"stackHeight": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -277,72 +173,15 @@
|
||||
"logMessages": [
|
||||
"Program ComputeBudget111111111111111111111111111111 invoke [1]",
|
||||
"Program ComputeBudget111111111111111111111111111111 success",
|
||||
"Program 11111111111111111111111111111111 invoke [1]",
|
||||
"Program 11111111111111111111111111111111 success",
|
||||
"Program ComputeBudget111111111111111111111111111111 invoke [1]",
|
||||
"Program ComputeBudget111111111111111111111111111111 success",
|
||||
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P invoke [1]",
|
||||
"Program log: Instruction: Create",
|
||||
"Program 11111111111111111111111111111111 invoke [2]",
|
||||
"Program 11111111111111111111111111111111 invoke [1]",
|
||||
"Program 11111111111111111111111111111111 success",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
|
||||
"Program log: Instruction: InitializeMint2",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2780 of 238190 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program 11111111111111111111111111111111 invoke [2]",
|
||||
"Program 11111111111111111111111111111111 success",
|
||||
"Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL invoke [2]",
|
||||
"Program log: Create",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]",
|
||||
"Program log: Instruction: GetAccountDataSize",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 1595 of 212794 compute units",
|
||||
"Program return: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA pQAAAAAAAAA=",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program 11111111111111111111111111111111 invoke [3]",
|
||||
"Program 11111111111111111111111111111111 success",
|
||||
"Program log: Initialize the associated token account",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]",
|
||||
"Program log: Instruction: InitializeImmutableOwner",
|
||||
"Program log: Please upgrade to SPL Token 2022 for immutable owner support",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 1405 of 206181 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]",
|
||||
"Program log: Instruction: InitializeAccount3",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4214 of 202297 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL consumed 21990 of 219769 compute units",
|
||||
"Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL success",
|
||||
"Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s invoke [2]",
|
||||
"Program log: IX: Create Metadata Accounts v3",
|
||||
"Program 11111111111111111111111111111111 invoke [3]",
|
||||
"Program 11111111111111111111111111111111 success",
|
||||
"Program log: Allocate space for the account",
|
||||
"Program 11111111111111111111111111111111 invoke [3]",
|
||||
"Program 11111111111111111111111111111111 success",
|
||||
"Program log: Assign the account to the owning program",
|
||||
"Program 11111111111111111111111111111111 invoke [3]",
|
||||
"Program 11111111111111111111111111111111 success",
|
||||
"Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s consumed 37631 of 181110 compute units",
|
||||
"Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s success",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
|
||||
"Program log: Instruction: MintTo",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4492 of 140964 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
|
||||
"Program log: Instruction: SetAuthority",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2911 of 134325 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P invoke [2]",
|
||||
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P consumed 2003 of 127301 compute units",
|
||||
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P success",
|
||||
"Program data: G3KpTd7rY3YDAAAAZG9kAwAAAERPREcAAABodHRwczovL2NmLWlwZnMuY29tL2lwZnMvUW1ZMW0yb3doakJaenkxTXRoWW1XaW4zWHdHaW1HS1dDNVp3TlhQQ2JiYUIxa75Oab9+zoJi5E/7feiMCGSkHpgBjBAk2HT/Omepbi/vO7+83IaPqzQCmuexYmfBKhW99pBf1HY/TQqasw1nKrv2MdL3xlA70bgIpTlRVYJ5yU7c4gCGkVyzuRpXUJYvmg==",
|
||||
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P consumed 126103 of 249550 compute units",
|
||||
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P success",
|
||||
"Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL invoke [1]",
|
||||
"Program log: Create",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
|
||||
"Program log: Instruction: GetAccountDataSize",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 1569 of 118084 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 1569 of 93653 compute units",
|
||||
"Program return: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA pQAAAAAAAAA=",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program 11111111111111111111111111111111 invoke [2]",
|
||||
@@ -351,55 +190,76 @@
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
|
||||
"Program log: Instruction: InitializeImmutableOwner",
|
||||
"Program log: Please upgrade to SPL Token 2022 for immutable owner support",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 1405 of 111497 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 1405 of 87066 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
|
||||
"Program log: Instruction: InitializeAccount3",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4188 of 107617 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4188 of 83184 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL consumed 20301 of 123447 compute units",
|
||||
"Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL consumed 21837 of 100550 compute units",
|
||||
"Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL success",
|
||||
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P invoke [1]",
|
||||
"Program log: Instruction: Buy",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
|
||||
"Program log: Instruction: Transfer",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 81505 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program 11111111111111111111111111111111 invoke [2]",
|
||||
"Program 11111111111111111111111111111111 success",
|
||||
"Program b1oomGGqPKGD6errbyfbVMBuzSC8WtAAYo8MwNafWW1 invoke [1]",
|
||||
"Program log: Powered by https://telegram.bloombot.app",
|
||||
"Program 11111111111111111111111111111111 invoke [2]",
|
||||
"Program 11111111111111111111111111111111 success",
|
||||
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P invoke [2]",
|
||||
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P consumed 2003 of 69417 compute units",
|
||||
"Program log: Instruction: Buy",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]",
|
||||
"Program log: Instruction: Transfer",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 49415 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program 11111111111111111111111111111111 invoke [3]",
|
||||
"Program 11111111111111111111111111111111 success",
|
||||
"Program 11111111111111111111111111111111 invoke [3]",
|
||||
"Program 11111111111111111111111111111111 success",
|
||||
"Program 11111111111111111111111111111111 invoke [3]",
|
||||
"Program 11111111111111111111111111111111 success",
|
||||
"Program data: vdt/007mYe5E+dQlVubfmlZx8g4Yr7VZS6dIqY5CCXXxzYTAYMWwbyBwuBEAAAAAT+SenZMEAAABcFi8Lm3PgW7X4XZm7q8+G4Jf4IaSLzptQdkNfSFrd2m6oSNoAAAAALHaOjAKAAAAgP3BigudAgCxLhc0AwAAAIBlrz56ngEA16qPsGDYKRtMTUddr/diyWvcDazrNsAS6tEu06lIQWFfAAAAAAAAAJ4YKwAAAAAAkJajVbvLxqgCZ/z53+NIXoh5GMXQLRXjoGjmO6GR/6UFAAAAAAAAAKpEAgAAAAAA",
|
||||
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P invoke [3]",
|
||||
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P consumed 2006 of 33261 compute units",
|
||||
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P success",
|
||||
"Program data: vdt/007mYe6+Tmm/fs6CYuRP+33ojAhkpB6YAYwQJNh0/zpnqW4v7wCrkEEAAAAAKeutVYQiAAAB9jHS98ZQO9G4CKU5UVWCeclO3OIAhpFcs7kaV1CWL5oKQsNmAAAAAABXtD0HAAAA1yQq8l6tAwAAq5BBAAAAANeMF6bNrgIA",
|
||||
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P consumed 37457 of 103146 compute units",
|
||||
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P success"
|
||||
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P consumed 40072 of 70491 compute units",
|
||||
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P success",
|
||||
"Program b1oomGGqPKGD6errbyfbVMBuzSC8WtAAYo8MwNafWW1 consumed 48895 of 78713 compute units",
|
||||
"Program b1oomGGqPKGD6errbyfbVMBuzSC8WtAAYo8MwNafWW1 success"
|
||||
],
|
||||
"preTokenBalances": [
|
||||
{
|
||||
"accountIndex": 8,
|
||||
"mint": "5eFg3giaX2c3RydHvx1S3yEKpYjBuwtLUsmbAAG9pump",
|
||||
"uiTokenAmount": {
|
||||
"uiAmount": 667654902.731215,
|
||||
"decimals": 6,
|
||||
"amount": "667654902731215",
|
||||
"uiAmountString": "667654902.731215"
|
||||
},
|
||||
"owner": "7Q1e26aB8kpyamjKPCt5oD73b2Hx7nAEjAMUwfHmZy7G",
|
||||
"programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
|
||||
}
|
||||
],
|
||||
"preTokenBalances": [],
|
||||
"postTokenBalances": [
|
||||
{
|
||||
"accountIndex": 4,
|
||||
"mint": "Dosp4t6w5kDzAgBQBMEsZSUNzdwTC5zHYiVZQqMKpump",
|
||||
"accountIndex": 5,
|
||||
"mint": "5eFg3giaX2c3RydHvx1S3yEKpYjBuwtLUsmbAAG9pump",
|
||||
"uiTokenAmount": {
|
||||
"uiAmount": 962048231.511255,
|
||||
"uiAmount": 5032051.139663,
|
||||
"decimals": 6,
|
||||
"amount": "962048231511255",
|
||||
"uiAmountString": "962048231.511255"
|
||||
"amount": "5032051139663",
|
||||
"uiAmountString": "5032051.139663"
|
||||
},
|
||||
"owner": "52EdRamuJQsj94DnpLBguCfXx8cGbyJiFBL5n1hmP5Ln",
|
||||
"owner": "8ZZ97eWp2k8gfoK2Jk2WQcdofk9hyJpEGDPGiqFryH1S",
|
||||
"programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
|
||||
},
|
||||
{
|
||||
"accountIndex": 6,
|
||||
"mint": "Dosp4t6w5kDzAgBQBMEsZSUNzdwTC5zHYiVZQqMKpump",
|
||||
"accountIndex": 8,
|
||||
"mint": "5eFg3giaX2c3RydHvx1S3yEKpYjBuwtLUsmbAAG9pump",
|
||||
"uiTokenAmount": {
|
||||
"uiAmount": 37951768.488745,
|
||||
"uiAmount": 662622851.591552,
|
||||
"decimals": 6,
|
||||
"amount": "37951768488745",
|
||||
"uiAmountString": "37951768.488745"
|
||||
"amount": "662622851591552",
|
||||
"uiAmountString": "662622851.591552"
|
||||
},
|
||||
"owner": "Ha3MnRTxb5iGbXkjCTF2VyLPSsbCaNG4ZaJkHaoQWqJ9",
|
||||
"owner": "7Q1e26aB8kpyamjKPCt5oD73b2Hx7nAEjAMUwfHmZy7G",
|
||||
"programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
|
||||
}
|
||||
],
|
||||
@@ -408,7 +268,7 @@
|
||||
"writable": [],
|
||||
"readonly": []
|
||||
},
|
||||
"computeUnitsConsumed": 184311
|
||||
"computeUnitsConsumed": 71182
|
||||
},
|
||||
"version": 0
|
||||
"version": "legacy"
|
||||
}
|
||||
@@ -2,14 +2,11 @@ import asyncio
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
import websockets
|
||||
from solders.pubkey import Pubkey
|
||||
|
||||
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
||||
|
||||
from core.pubkeys import PumpAddresses
|
||||
|
||||
PUMP_PROGRAM = Pubkey.from_string("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P")
|
||||
WSS_ENDPOINT = os.environ.get("SOLANA_NODE_WSS_ENDPOINT")
|
||||
|
||||
|
||||
@@ -30,7 +27,7 @@ async def listen_for_transactions():
|
||||
"id": 1,
|
||||
"method": "blockSubscribe",
|
||||
"params": [
|
||||
{"mentionsAccountOrProgram": str(PumpAddresses.PROGRAM)},
|
||||
{"mentionsAccountOrProgram": str(PUMP_PROGRAM)},
|
||||
{
|
||||
"commitment": "confirmed",
|
||||
"encoding": "base64",
|
||||
@@ -42,7 +39,7 @@ async def listen_for_transactions():
|
||||
},
|
||||
)
|
||||
await websocket.send(subscription_message)
|
||||
print(f"Subscribed to blocks mentioning program: {PumpAddresses.PROGRAM}")
|
||||
print(f"Subscribed to blocks mentioning program: {PUMP_PROGRAM}")
|
||||
|
||||
while True:
|
||||
try:
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
"""
|
||||
Module for checking the status of a token's bonding curve on the Solana network using
|
||||
the Pump.fun program. It allows querying the bonding curve state and completion status.
|
||||
|
||||
Note: creator fee upgrade introduced updates in bonding curve structure.
|
||||
https://github.com/pump-fun/pump-public-docs/blob/main/docs/PUMP_CREATOR_FEE_README.md
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
@@ -8,7 +11,7 @@ import os
|
||||
import struct
|
||||
from typing import Final
|
||||
|
||||
from construct import Flag, Int64ul, Struct
|
||||
from construct import Bytes, Flag, Int64ul, Struct
|
||||
from dotenv import load_dotenv
|
||||
from solana.rpc.async_api import AsyncClient
|
||||
from solders.pubkey import Pubkey
|
||||
@@ -37,7 +40,7 @@ class BondingCurveState:
|
||||
token_total_supply: Total token supply in the curve
|
||||
complete: Whether the curve has completed and liquidity migrated
|
||||
"""
|
||||
_STRUCT = Struct(
|
||||
_STRUCT_1 = Struct(
|
||||
"virtual_token_reserves" / Int64ul,
|
||||
"virtual_sol_reserves" / Int64ul,
|
||||
"real_token_reserves" / Int64ul,
|
||||
@@ -46,9 +49,33 @@ class BondingCurveState:
|
||||
"complete" / Flag,
|
||||
)
|
||||
|
||||
# Struct after creator fee update has been introduced
|
||||
# https://github.com/pump-fun/pump-public-docs/blob/main/docs/PUMP_CREATOR_FEE_README.md
|
||||
_STRUCT_2 = Struct(
|
||||
"virtual_token_reserves" / Int64ul,
|
||||
"virtual_sol_reserves" / Int64ul,
|
||||
"real_token_reserves" / Int64ul,
|
||||
"real_sol_reserves" / Int64ul,
|
||||
"token_total_supply" / Int64ul,
|
||||
"complete" / Flag,
|
||||
"creator" / Bytes(32), # Added new creator field - 32 bytes for Pubkey
|
||||
)
|
||||
|
||||
def __init__(self, data: bytes) -> None:
|
||||
parsed = self._STRUCT.parse(data[8:])
|
||||
self.__dict__.update(parsed)
|
||||
"""Parse bonding curve data."""
|
||||
if data[:8] != EXPECTED_DISCRIMINATOR:
|
||||
raise ValueError("Invalid curve state discriminator")
|
||||
|
||||
if len(data) < 150:
|
||||
parsed = self._STRUCT_1.parse(data[8:])
|
||||
self.__dict__.update(parsed)
|
||||
|
||||
else:
|
||||
parsed = self._STRUCT_1.parse(data[8:])
|
||||
self.__dict__.update(parsed)
|
||||
# Convert raw bytes to Pubkey for creator field
|
||||
if hasattr(self, 'creator') and isinstance(self.creator, bytes):
|
||||
self.creator = Pubkey.from_bytes(self.creator)
|
||||
|
||||
|
||||
def get_associated_bonding_curve_address(
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
from solders.pubkey import Pubkey
|
||||
|
||||
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
||||
|
||||
from core.pubkeys import PumpAddresses, SystemAddresses
|
||||
|
||||
# Global constants
|
||||
PUMP_PROGRAM = Pubkey.from_string("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P")
|
||||
SYSTEM_TOKEN_PROGRAM = Pubkey.from_string("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")
|
||||
SYSTEM_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM = Pubkey.from_string(
|
||||
"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
|
||||
)
|
||||
|
||||
def get_bonding_curve_address(mint: Pubkey, program_id: Pubkey) -> tuple[Pubkey, int]:
|
||||
"""
|
||||
@@ -24,10 +23,10 @@ def find_associated_bonding_curve(mint: Pubkey, bonding_curve: Pubkey) -> Pubkey
|
||||
derived_address, _ = Pubkey.find_program_address(
|
||||
[
|
||||
bytes(bonding_curve),
|
||||
bytes(SystemAddresses.TOKEN_PROGRAM),
|
||||
bytes(SYSTEM_TOKEN_PROGRAM),
|
||||
bytes(mint),
|
||||
],
|
||||
SystemAddresses.ASSOCIATED_TOKEN_PROGRAM,
|
||||
SYSTEM_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM,
|
||||
)
|
||||
return derived_address
|
||||
|
||||
@@ -39,7 +38,7 @@ def main():
|
||||
mint = Pubkey.from_string(mint_address)
|
||||
|
||||
bonding_curve_address, bump = get_bonding_curve_address(
|
||||
mint, PumpAddresses.PROGRAM
|
||||
mint, PUMP_PROGRAM
|
||||
)
|
||||
|
||||
# Calculate the associated bonding curve
|
||||
@@ -56,7 +55,7 @@ def main():
|
||||
print("-" * 50)
|
||||
|
||||
except ValueError as e:
|
||||
print(f"Error: Invalid address format - {str(e)}")
|
||||
print(f"Error: Invalid address format - {e!s}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -26,7 +26,7 @@ def decode_instruction(ix_data, ix_def):
|
||||
if arg["type"] == "u64":
|
||||
value = struct.unpack_from("<Q", ix_data, offset)[0]
|
||||
offset += 8
|
||||
elif arg["type"] == "publicKey":
|
||||
elif arg["type"] == "pubkey":
|
||||
value = ix_data[offset : offset + 32].hex()
|
||||
offset += 32
|
||||
elif arg["type"] == "string":
|
||||
@@ -76,9 +76,8 @@ def decode_transaction(tx_data, idl):
|
||||
program_id = str(account_keys[ix.program_id_index])
|
||||
print(f"\nInstruction {idx}:")
|
||||
print(f"Program ID: {program_id}")
|
||||
print(f"IDL program address: {idl['metadata']['address']}")
|
||||
|
||||
if program_id == idl["metadata"]["address"]:
|
||||
if program_id == "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P": # Pump Fun Program
|
||||
ix_data = bytes(ix.data)
|
||||
discriminator = struct.unpack("<Q", ix_data[:8])[0]
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@ import base64
|
||||
import json
|
||||
import struct
|
||||
|
||||
from construct import Flag, Int64ul, Struct
|
||||
from construct import Bytes, Flag, Int64ul, Struct
|
||||
from solders.pubkey import Pubkey
|
||||
|
||||
LAMPORTS_PER_SOL = 1_000_000_000
|
||||
TOKEN_DECIMALS = 6
|
||||
@@ -10,7 +11,7 @@ EXPECTED_DISCRIMINATOR = struct.pack("<Q", 6966180631402821399)
|
||||
|
||||
|
||||
class BondingCurveState:
|
||||
_STRUCT = Struct(
|
||||
_STRUCT_1 = Struct(
|
||||
"virtual_token_reserves" / Int64ul,
|
||||
"virtual_sol_reserves" / Int64ul,
|
||||
"real_token_reserves" / Int64ul,
|
||||
@@ -19,9 +20,33 @@ class BondingCurveState:
|
||||
"complete" / Flag,
|
||||
)
|
||||
|
||||
# Struct after creator fee update has been introduced
|
||||
# https://github.com/pump-fun/pump-public-docs/blob/main/docs/PUMP_CREATOR_FEE_README.md
|
||||
_STRUCT_2 = Struct(
|
||||
"virtual_token_reserves" / Int64ul,
|
||||
"virtual_sol_reserves" / Int64ul,
|
||||
"real_token_reserves" / Int64ul,
|
||||
"real_sol_reserves" / Int64ul,
|
||||
"token_total_supply" / Int64ul,
|
||||
"complete" / Flag,
|
||||
"creator" / Bytes(32), # Added new creator field - 32 bytes for Pubkey
|
||||
)
|
||||
|
||||
def __init__(self, data: bytes) -> None:
|
||||
parsed = self._STRUCT.parse(data[8:])
|
||||
self.__dict__.update(parsed)
|
||||
"""Parse bonding curve data."""
|
||||
if data[:8] != EXPECTED_DISCRIMINATOR:
|
||||
raise ValueError("Invalid curve state discriminator")
|
||||
|
||||
if len(data) < 150:
|
||||
parsed = self._STRUCT_1.parse(data[8:])
|
||||
self.__dict__.update(parsed)
|
||||
|
||||
else:
|
||||
parsed = self._STRUCT_1.parse(data[8:])
|
||||
self.__dict__.update(parsed)
|
||||
# Convert raw bytes to Pubkey for creator field
|
||||
if hasattr(self, 'creator') and isinstance(self.creator, bytes):
|
||||
self.creator = Pubkey.from_bytes(self.creator)
|
||||
|
||||
|
||||
def calculate_bonding_curve_price(curve_state: BondingCurveState) -> float:
|
||||
@@ -41,7 +66,7 @@ def decode_bonding_curve_data(raw_data: str) -> BondingCurveState:
|
||||
|
||||
|
||||
# Load the JSON data
|
||||
with open("learning-examples/raw_bondingCurve_from_getAccountInfo.json", "r") as file:
|
||||
with open("learning-examples/raw_bondingCurve_from_getAccountInfo.json") as file:
|
||||
json_data = json.load(file)
|
||||
|
||||
# Extract the base64 encoded data
|
||||
|
||||
@@ -76,7 +76,7 @@ for ix in instructions:
|
||||
if "parsed" in ix:
|
||||
print(f"Parsed instruction: {ix['program']} - {ix['parsed']['type']}")
|
||||
print(f"Info: {json.dumps(ix['parsed']['info'], indent=2)}")
|
||||
elif program_id == idl["metadata"]["address"]:
|
||||
elif program_id == "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P": # Pump Fun Program
|
||||
matching_instruction = find_matching_instruction(accounts, data)
|
||||
if matching_instruction:
|
||||
decoded_data = decode_instruction_data(
|
||||
|
||||
@@ -69,6 +69,7 @@ def parse_market_account_data(data):
|
||||
("pool_base_token_account", "pubkey"),
|
||||
("pool_quote_token_account", "pubkey"),
|
||||
("lp_supply", "u64"),
|
||||
("coin_creator", "pubkey")
|
||||
]
|
||||
|
||||
try:
|
||||
|
||||
@@ -37,7 +37,6 @@ LAMPORTS_PER_SOL = 1_000_000_000
|
||||
UNIT_PRICE = 10_000_000
|
||||
UNIT_BUDGET = 100_000
|
||||
|
||||
# RPC endpoint
|
||||
RPC_ENDPOINT = os.environ.get("SOLANA_NODE_RPC_ENDPOINT")
|
||||
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ async def get_market_data(market_address: Pubkey):
|
||||
("pool_base_token_account", "pubkey"),
|
||||
("pool_quote_token_account", "pubkey"),
|
||||
("lp_supply", "u64"),
|
||||
("coin_creator", "pubkey"),
|
||||
]
|
||||
|
||||
for field_name, field_type in fields:
|
||||
|
||||
@@ -0,0 +1,323 @@
|
||||
"""
|
||||
WORK IN PROGRESS
|
||||
|
||||
This module provides functionality to:
|
||||
- Find market addresses by token mint.
|
||||
- Fetch and parse market data from PUMP AMM pools.
|
||||
- Calculate token prices in AMM pools.
|
||||
- Create associated token accounts (ATAs) idempotently.
|
||||
- Sell tokens on the PUMP AMM with slippage protection.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
import struct
|
||||
|
||||
import base58
|
||||
from dotenv import load_dotenv
|
||||
from solana.rpc.async_api import AsyncClient
|
||||
from solana.rpc.commitment import Confirmed
|
||||
from solana.rpc.types import MemcmpOpts, TxOpts
|
||||
from solders.compute_budget import set_compute_unit_limit, set_compute_unit_price
|
||||
from solders.instruction import AccountMeta, Instruction
|
||||
from solders.keypair import Keypair
|
||||
from solders.message import Message
|
||||
from solders.pubkey import Pubkey
|
||||
from solders.transaction import VersionedTransaction
|
||||
from spl.token.instructions import get_associated_token_address
|
||||
|
||||
load_dotenv()
|
||||
|
||||
# Configuration constants
|
||||
RPC_ENDPOINT = os.environ.get("SOLANA_NODE_RPC_ENDPOINT")
|
||||
TOKEN_MINT = Pubkey.from_string("8XNrSusWrzYpizYXJb5yeB66AWX1cfQ86SBJFqVTpump")
|
||||
PRIVATE_KEY = base58.b58decode(os.environ.get("SOLANA_PRIVATE_KEY"))
|
||||
PAYER = Keypair.from_bytes(PRIVATE_KEY)
|
||||
SLIPPAGE = 0.25 # Slippage tolerance (25%) - the maximum price movement you'll accept
|
||||
|
||||
TOKEN_DECIMALS = 6
|
||||
BUY_DISCRIMINATOR = bytes.fromhex("66063d1201daebea28") # Program instruction identifier for the sell function
|
||||
|
||||
# Solana system addresses and program IDs
|
||||
SOL = Pubkey.from_string("So11111111111111111111111111111111111111112")
|
||||
PUMP_AMM_PROGRAM_ID = Pubkey.from_string("pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA")
|
||||
PUMP_SWAP_GLOBAL_CONFIG = Pubkey.from_string("ADyA8hdefvWN2dbGGWFotbzWxrAvLW83WG6QCVXvJKqw")
|
||||
PUMP_PROTOCOL_FEE_RECIPIENT = Pubkey.from_string("7VtfL8fvgNfhz17qKRMjzQEXgbdpnHHHQRh54R9jP2RJ")
|
||||
PUMP_PROTOCOL_FEE_RECIPIENT_TOKEN_ACCOUNT = Pubkey.from_string("7GFUN3bWzJMKMRZ34JLsvcqdssDbXnp589SiE33KVwcC")
|
||||
SYSTEM_TOKEN_PROGRAM = Pubkey.from_string("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")
|
||||
SYSTEM_PROGRAM = Pubkey.from_string("11111111111111111111111111111111")
|
||||
SYSTEM_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM = Pubkey.from_string("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL")
|
||||
PUMP_SWAP_EVENT_AUTHORITY = Pubkey.from_string("GS4CU59F31iL7aR2Q8zVS8DRrcRnXX1yjQ66TqNVQnaR")
|
||||
LAMPORTS_PER_SOL = 1_000_000_000
|
||||
COMPUTE_UNIT_PRICE = 10_000 # Price in micro-lamports per compute unit
|
||||
COMPUTE_UNIT_BUDGET = 100_000 # Maximum compute units to use
|
||||
|
||||
|
||||
async def get_market_address_by_base_mint(client: AsyncClient, base_mint_address: Pubkey, amm_program_id: Pubkey) -> Pubkey:
|
||||
"""Find the market address for a given token mint.
|
||||
|
||||
Searches for the AMM pool that contains the specified token as its base token.
|
||||
|
||||
Args:
|
||||
client: Solana RPC client instance
|
||||
base_mint_address: Address of the token mint you want to find the market for
|
||||
amm_program_id: Address of the AMM program
|
||||
|
||||
Returns:
|
||||
The Pubkey of the market (AMM pool) for the token
|
||||
"""
|
||||
base_mint_bytes = bytes(base_mint_address)
|
||||
offset = 43 # Offset where the base_mint field is stored in the account data structure
|
||||
filters = [
|
||||
MemcmpOpts(offset=offset, bytes=base_mint_bytes)
|
||||
]
|
||||
|
||||
response = await client.get_program_accounts(
|
||||
amm_program_id,
|
||||
encoding="base64",
|
||||
filters=filters
|
||||
)
|
||||
|
||||
market_address = [account.pubkey for account in response.value][0]
|
||||
return market_address
|
||||
|
||||
async def get_market_data(client: AsyncClient, market_address: Pubkey) -> dict:
|
||||
"""Fetch and parse market data from the blockchain.
|
||||
|
||||
Retrieves and deserializes the data stored in the market account.
|
||||
|
||||
Args:
|
||||
client: Solana RPC client instance
|
||||
market_address: Address of the market (AMM pool) to fetch data for
|
||||
|
||||
Returns:
|
||||
Dictionary containing the parsed market data
|
||||
"""
|
||||
response = await client.get_account_info(market_address, encoding="base64")
|
||||
data = response.value.data
|
||||
parsed_data: dict = {}
|
||||
|
||||
# Start after the 8-byte discriminator
|
||||
offset = 8
|
||||
# Define the structure of the market account data
|
||||
fields = [
|
||||
("pool_bump", "u8"),
|
||||
("index", "u16"),
|
||||
("creator", "pubkey"),
|
||||
("base_mint", "pubkey"),
|
||||
("quote_mint", "pubkey"),
|
||||
("lp_mint", "pubkey"),
|
||||
("pool_base_token_account", "pubkey"),
|
||||
("pool_quote_token_account", "pubkey"),
|
||||
("lp_supply", "u64"),
|
||||
("coin_creator", "pubkey")
|
||||
]
|
||||
|
||||
for field_name, field_type in fields:
|
||||
if field_type == "pubkey":
|
||||
value = data[offset:offset + 32]
|
||||
parsed_data[field_name] = base58.b58encode(value).decode("utf-8")
|
||||
offset += 32
|
||||
elif field_type in {"u64", "i64"}:
|
||||
value = struct.unpack("<Q", data[offset:offset + 8])[0] if field_type == "u64" else struct.unpack("<q", data[offset:offset + 8])[0]
|
||||
parsed_data[field_name] = value
|
||||
offset += 8
|
||||
elif field_type == "u16":
|
||||
value = struct.unpack("<H", data[offset:offset + 2])[0]
|
||||
parsed_data[field_name] = value
|
||||
offset += 2
|
||||
elif field_type == "u8":
|
||||
value = data[offset]
|
||||
parsed_data[field_name] = value
|
||||
offset += 1
|
||||
|
||||
return parsed_data
|
||||
|
||||
def find_coin_creator_vault(coin_creator: Pubkey) -> Pubkey:
|
||||
derived_address, _ = Pubkey.find_program_address(
|
||||
[
|
||||
b"creator_vault",
|
||||
bytes(coin_creator)
|
||||
],
|
||||
PUMP_AMM_PROGRAM_ID,
|
||||
)
|
||||
return derived_address
|
||||
|
||||
async def calculate_token_pool_price(client: AsyncClient, pool_base_token_account: Pubkey, pool_quote_token_account: Pubkey) -> float:
|
||||
"""Calculate the price of tokens in the pool.
|
||||
|
||||
Fetches the balance of tokens in the pool and calculates the price ratio.
|
||||
|
||||
Args:
|
||||
client: Solana RPC client instance
|
||||
pool_base_token_account: Address of the pool's base token account (your token)
|
||||
pool_quote_token_account: Address of the pool's quote token account (SOL)
|
||||
|
||||
Returns:
|
||||
The price of the base token in terms of the quote token (usually SOL)
|
||||
"""
|
||||
base_balance_resp = await client.get_token_account_balance(pool_base_token_account)
|
||||
quote_balance_resp = await client.get_token_account_balance(pool_quote_token_account)
|
||||
|
||||
# Extract the UI amounts (human-readable with decimals)
|
||||
base_amount = float(base_balance_resp.value.ui_amount)
|
||||
quote_amount = float(quote_balance_resp.value.ui_amount)
|
||||
|
||||
token_price = quote_amount / base_amount
|
||||
|
||||
return token_price
|
||||
|
||||
def create_ata_idempotent_ix(payer_pubkey: Pubkey) -> Instruction:
|
||||
"""Create an instruction to create an Associated Token Account (ATA) if it doesn't exist.
|
||||
|
||||
This creates an instruction that will create an Associated Token Account for SOL
|
||||
if it doesn't already exist.
|
||||
|
||||
Args:
|
||||
payer_pubkey: The public key of the account that will pay for the creation
|
||||
|
||||
Returns:
|
||||
An instruction to create the ATA
|
||||
"""
|
||||
associated_token_address = get_associated_token_address(payer_pubkey, SOL)
|
||||
|
||||
instruction_accounts = [
|
||||
AccountMeta(pubkey=payer_pubkey, is_signer=True, is_writable=True),
|
||||
AccountMeta(pubkey=associated_token_address, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=payer_pubkey, is_signer=True, is_writable=True),
|
||||
AccountMeta(pubkey=SOL, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=SYSTEM_PROGRAM, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=SYSTEM_TOKEN_PROGRAM, is_signer=False, is_writable=False),
|
||||
]
|
||||
|
||||
# The data for creating an ATA idempotently is just a single byte with value 1
|
||||
# Check the details here:
|
||||
# https://github.com/solana-program/associated-token-account/blob/main/program/src/instruction.rs
|
||||
data = bytes([1])
|
||||
return Instruction(SYSTEM_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM, data, instruction_accounts)
|
||||
|
||||
async def sell_pump_swap(client: AsyncClient, pump_fun_amm_market: Pubkey, payer: Keypair,
|
||||
base_mint: Pubkey, user_base_token_account: Pubkey,
|
||||
user_quote_token_account: Pubkey, pool_base_token_account: Pubkey,
|
||||
pool_quote_token_account: Pubkey, coin_creator_vault_authority: Pubkey,
|
||||
coin_creator_vault_ata: Pubkey,slippage: float = 0.25) -> str | None:
|
||||
"""Sell tokens on the PUMP AMM.
|
||||
|
||||
This function sells all tokens in the user's token account with the specified slippage tolerance.
|
||||
|
||||
Args:
|
||||
client: Solana RPC client instance
|
||||
pump_fun_amm_market: Address of the AMM market
|
||||
payer: Keypair of the transaction signer and token seller
|
||||
base_mint: Address of the token mint being sold
|
||||
user_base_token_account: Address of the user's token account for the token being sold
|
||||
user_quote_token_account: Address of the user's SOL token account
|
||||
pool_base_token_account: Address of the pool's token account for the token being sold
|
||||
pool_quote_token_account: Address of the pool's SOL token account
|
||||
slippage: Maximum acceptable price slippage, as a decimal (0.25 = 25%)
|
||||
|
||||
Returns:
|
||||
Transaction signature if successful, None otherwise
|
||||
"""
|
||||
# Calculate token price
|
||||
token_price_sol = await calculate_token_pool_price(client, pool_base_token_account, pool_quote_token_account)
|
||||
print(f"Price per Token: {token_price_sol:.20f} SOL")
|
||||
|
||||
# Calculate minimum SOL output with slippage protection
|
||||
amount = token_balance
|
||||
min_sol_output = float(token_balance_decimal) * float(token_price_sol)
|
||||
slippage_factor = 1 - slippage
|
||||
min_sol_output = int((min_sol_output * slippage_factor) * LAMPORTS_PER_SOL)
|
||||
|
||||
print(f"Selling {token_balance_decimal} tokens")
|
||||
print(f"Minimum SOL output: {min_sol_output / LAMPORTS_PER_SOL:.10f} SOL")
|
||||
|
||||
# Define all accounts needed for the sell instruction
|
||||
accounts = [
|
||||
AccountMeta(pubkey=pump_fun_amm_market, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=payer.pubkey(), is_signer=True, is_writable=True),
|
||||
AccountMeta(pubkey=PUMP_SWAP_GLOBAL_CONFIG, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=base_mint, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=SOL, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=user_base_token_account, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=user_quote_token_account, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=pool_base_token_account, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=pool_quote_token_account, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=PUMP_PROTOCOL_FEE_RECIPIENT, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=PUMP_PROTOCOL_FEE_RECIPIENT_TOKEN_ACCOUNT, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=SYSTEM_TOKEN_PROGRAM, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=SYSTEM_TOKEN_PROGRAM, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=SYSTEM_PROGRAM, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=SYSTEM_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=PUMP_SWAP_EVENT_AUTHORITY, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=PUMP_AMM_PROGRAM_ID, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=coin_creator_vault_ata, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=coin_creator_vault_authority, is_signer=False, is_writable=False),
|
||||
]
|
||||
|
||||
data = BUY_DISCRIMINATOR + struct.pack("<Q", amount) + struct.pack("<Q", min_sol_output)
|
||||
|
||||
compute_limit_ix = set_compute_unit_limit(COMPUTE_UNIT_BUDGET)
|
||||
compute_price_ix = set_compute_unit_price(COMPUTE_UNIT_PRICE)
|
||||
|
||||
create_ata_ix = create_ata_idempotent_ix(
|
||||
payer_pubkey=payer.pubkey(),
|
||||
)
|
||||
|
||||
sell_ix = Instruction(PUMP_AMM_PROGRAM_ID, data, accounts)
|
||||
|
||||
blockhash_resp = await client.get_latest_blockhash()
|
||||
recent_blockhash = blockhash_resp.value.blockhash
|
||||
|
||||
msg = Message.new_with_blockhash(
|
||||
[compute_limit_ix, compute_price_ix, create_ata_ix, sell_ix],
|
||||
payer.pubkey(),
|
||||
recent_blockhash
|
||||
)
|
||||
|
||||
tx_sell = VersionedTransaction(
|
||||
message=msg,
|
||||
keypairs=[payer]
|
||||
)
|
||||
|
||||
try:
|
||||
tx_sig = await client.send_transaction(
|
||||
tx_sell,
|
||||
opts=TxOpts(skip_preflight=True, preflight_commitment=Confirmed),
|
||||
)
|
||||
|
||||
tx_hash = tx_sig.value
|
||||
print(f"Transaction sent: https://explorer.solana.com/tx/{tx_hash}")
|
||||
await client.confirm_transaction(tx_hash, commitment="confirmed")
|
||||
|
||||
print("Transaction confirmed")
|
||||
return tx_hash
|
||||
except Exception as e:
|
||||
print(f"Error sending transaction: {e!s}")
|
||||
return None
|
||||
|
||||
|
||||
async def main():
|
||||
"""Main function to execute the token selling process."""
|
||||
async with AsyncClient(RPC_ENDPOINT) as client:
|
||||
market_address = await get_market_address_by_base_mint(client, TOKEN_MINT, PUMP_AMM_PROGRAM_ID)
|
||||
market_data = await get_market_data(client, market_address)
|
||||
coin_creator_vault_authority = find_coin_creator_vault(Pubkey.from_string(market_data["coin_creator"]))
|
||||
coin_creator_vault_ata = get_associated_token_address(coin_creator_vault_authority, SOL)
|
||||
|
||||
await sell_pump_swap(
|
||||
client,
|
||||
market_address,
|
||||
PAYER,
|
||||
TOKEN_MINT,
|
||||
get_associated_token_address(PAYER.pubkey(), TOKEN_MINT),
|
||||
get_associated_token_address(PAYER.pubkey(), SOL),
|
||||
Pubkey.from_string(market_data["pool_base_token_account"]),
|
||||
Pubkey.from_string(market_data["pool_quote_token_account"]),
|
||||
coin_creator_vault_authority,
|
||||
coin_creator_vault_ata,
|
||||
SLIPPAGE
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -108,6 +108,7 @@ async def get_market_data(client: AsyncClient, market_address: Pubkey) -> dict:
|
||||
("pool_base_token_account", "pubkey"),
|
||||
("pool_quote_token_account", "pubkey"),
|
||||
("lp_supply", "u64"),
|
||||
("coin_creator", "pubkey")
|
||||
]
|
||||
|
||||
for field_name, field_type in fields:
|
||||
@@ -130,6 +131,16 @@ async def get_market_data(client: AsyncClient, market_address: Pubkey) -> dict:
|
||||
|
||||
return parsed_data
|
||||
|
||||
def find_coin_creator_vault(coin_creator: Pubkey) -> Pubkey:
|
||||
derived_address, _ = Pubkey.find_program_address(
|
||||
[
|
||||
b"creator_vault",
|
||||
bytes(coin_creator)
|
||||
],
|
||||
PUMP_AMM_PROGRAM_ID,
|
||||
)
|
||||
return derived_address
|
||||
|
||||
async def calculate_token_pool_price(client: AsyncClient, pool_base_token_account: Pubkey, pool_quote_token_account: Pubkey) -> float:
|
||||
"""Calculate the price of tokens in the pool.
|
||||
|
||||
@@ -186,7 +197,8 @@ def create_ata_idempotent_ix(payer_pubkey: Pubkey) -> Instruction:
|
||||
async def sell_pump_swap(client: AsyncClient, pump_fun_amm_market: Pubkey, payer: Keypair,
|
||||
base_mint: Pubkey, user_base_token_account: Pubkey,
|
||||
user_quote_token_account: Pubkey, pool_base_token_account: Pubkey,
|
||||
pool_quote_token_account: Pubkey, slippage: float = 0.25) -> str | None:
|
||||
pool_quote_token_account: Pubkey, coin_creator_vault_authority: Pubkey,
|
||||
coin_creator_vault_ata: Pubkey,slippage: float = 0.25) -> str | None:
|
||||
"""Sell tokens on the PUMP AMM.
|
||||
|
||||
This function sells all tokens in the user's token account with the specified slippage tolerance.
|
||||
@@ -245,6 +257,8 @@ async def sell_pump_swap(client: AsyncClient, pump_fun_amm_market: Pubkey, payer
|
||||
AccountMeta(pubkey=SYSTEM_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=PUMP_SWAP_EVENT_AUTHORITY, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=PUMP_AMM_PROGRAM_ID, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=coin_creator_vault_ata, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=coin_creator_vault_authority, is_signer=False, is_writable=False),
|
||||
]
|
||||
|
||||
data = SELL_DISCRIMINATOR + struct.pack("<Q", amount) + struct.pack("<Q", min_sol_output)
|
||||
@@ -294,6 +308,8 @@ async def main():
|
||||
async with AsyncClient(RPC_ENDPOINT) as client:
|
||||
market_address = await get_market_address_by_base_mint(client, TOKEN_MINT, PUMP_AMM_PROGRAM_ID)
|
||||
market_data = await get_market_data(client, market_address)
|
||||
coin_creator_vault_authority = find_coin_creator_vault(Pubkey.from_string(market_data["coin_creator"]))
|
||||
coin_creator_vault_ata = get_associated_token_address(coin_creator_vault_authority, SOL)
|
||||
|
||||
await sell_pump_swap(
|
||||
client,
|
||||
@@ -304,6 +320,8 @@ async def main():
|
||||
get_associated_token_address(PAYER.pubkey(), SOL),
|
||||
Pubkey.from_string(market_data["pool_base_token_account"]),
|
||||
Pubkey.from_string(market_data["pool_quote_token_account"]),
|
||||
coin_creator_vault_authority,
|
||||
coin_creator_vault_ata,
|
||||
SLIPPAGE
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user