Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.env
.local_keys
/node_modules
./balance-validator/.env
./balance-validator/sheet.csv
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,8 @@ This script helps to transfer specified amount of tokens to target address passe
#### `updateTokenMetadata.ts`

This [updateTokenMetadata](./scripts/updateTokenMetadata.ts) script helps to update metadata of token if we need to rectify anything.

#### `balance-validator.py`

This [balance-validator](./balance-validator/balance-validator.py) script helps spl-token community admins to implement various gamifications with token holders
inititaly this script provides a filtering mechanism based on wallet address token holding balance but can be expanded to other features.
2 changes: 2 additions & 0 deletions balance-validator/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.env
/sheet.csv
20 changes: 20 additions & 0 deletions balance-validator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## 🛠️ How to run

1. Install required packages
```bash
pip install requirements.txt
```

2. #### Setting up script
- Open the [script](./mbcValidator.py)
- Ref [example.env](./example.env) to setup required env variables.

3. #### Run script

```bash
python mbcValidator.py
```

>**Note:** It would ask input csv name and output csv name


100 changes: 100 additions & 0 deletions balance-validator/balance-validator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import csv
import requests
import json
from dotenv import load_dotenv
import os

load_dotenv()



def getTokenBal(walletAddress):
url = os.getenv('SOL_RPC_URL')
SPL_SPL_TOKEN_ADDRESS = os.getenv('SPL_TOKEN_ADDRESS')

TOKEN_PROGRAM_ID = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"

payload = {
"id": 1,
"jsonrpc": "2.0",
"method": "getTokenAccountsByOwner",
"params": [
walletAddress,
{"programId": TOKEN_PROGRAM_ID},
{"encoding": "jsonParsed"},
],
}

headers = {"accept": "application/json", "content-type": "application/json"}

try:
response = requests.post(url, json=payload, headers=headers)
response.raise_for_status()
except requests.exceptions.RequestException as e:
print(f"Error fetching balance for wallet {walletAddress}: {e}")
return None

try:
response_data = json.loads(response.text)
except json.JSONDecodeError as e:
print(f"Error decoding JSON response for wallet {walletAddress}: {e}")
return None

if "result" in response_data and len(response_data["result"]["value"]) > 0:
for tokens in response_data["result"]["value"]:
if tokens["account"]["data"]["parsed"]["info"]["mint"] == SPL_SPL_TOKEN_ADDRESS:
brokieBal = tokens["account"]["data"]["parsed"]["info"]["tokenAmount"]["uiAmount"]
return brokieBal
else:
print(f"No accounts found for wallet {walletAddress}")
return None


def writeResultsToCSV(results,output_file_path):
with open(output_file_path,mode="a",newline="",encoding="utf-8") as csvfile:
fieldNames = ['Address','TelegramID','Balance','SolScanUrl']
writer = csv.DictWriter(csvfile,fieldnames=fieldNames)

writer.writeheader()
for result in results:
writer.writerow(result)


def filterMBC(csv_file_path,minAmountHolding):
solscan_account_lookup_url="https://solscan.io/account/"
results = []
with open(csv_file_path, mode="r", encoding="utf-8") as csfile:
reader = csv.DictReader(csfile)
print("Filtering MBC Defaulters")
for row in reader:
if row['InGroup?']:
print(f"checking wallet:{row['SOLWalletAddress']}")
TargetTokenBal = getTokenBal(row['SOLWalletAddress'])
if TargetTokenBal is not None:
if TargetTokenBal < minAmountHolding:
result ={'Address':row["SOLWalletAddress"],'TelegramID':row['TelegramID'],'Balance':TargetTokenBal,'SolScanUrl':solscan_account_lookup_url+row["SOLWalletAddress"]}
results.append(result)
else:
print(f"Error: Could not fetch balance for wallet {row['SOLWalletAddress']}. Skipping.")

return results



input_file_name = input("Enter the input file name: ")
output_file_name = input("Enter the name of output file: ")

output_file_path = os.getenv('OUTPUT_FILE_PATH')
input_file_path = os.getenv('INPUT_FILE_PATH')


input_file = input_file_path+input_file_name+'.csv'

# Declare min amount that you want to configure
minAmountHolding = 1000000
results = filterMBC(input_file,minAmountHolding)

output_file = (output_file_path+output_file_name+'.csv')
writeResultsToCSV(results,output_file)


4 changes: 4 additions & 0 deletions balance-validator/example.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
SOL_RPC_URL=
SPL_TOKEN_ADDRESS=
OUTPUT_FILE_PATH='./'
INPUT_FILE_PATH='./'
6 changes: 6 additions & 0 deletions balance-validator/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
certifi==2024.2.2
charset-normalizer==3.3.2
idna==3.7
python-dotenv==1.0.1
requests==2.31.0
urllib3==2.2.1
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"@typescript-eslint/eslint-plugin": "^7.3.1",
"@typescript-eslint/parser": "^7.3.1",
"eslint": "^8.57.0",
"husky": "^8.0.3",
"husky": "^8.0.0",
"lint-staged": "^15.2.2",
"prettier": "^3.2.5",
"ts-node": "^10.9.1",
Expand Down