Skip to content

Commit

Permalink
Leeloo Dallas Multipay - Sentinel mutli-send transactor. Batch coin s…
Browse files Browse the repository at this point in the history
…ending.
  • Loading branch information
freQniK committed Aug 17, 2024
1 parent e7dbdbb commit 14466f9
Show file tree
Hide file tree
Showing 9 changed files with 329 additions and 0 deletions.
Binary file added .DS_Store
Binary file not shown.
20 changes: 20 additions & 0 deletions .github/workflows/tg-notify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: tg-notify
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Update status
uses: appleboy/telegram-action@master
with:
to: ${{ secrets.TELEGRAM_TO }}
token: ${{ secrets.TELEGRAM_TOKEN }}
message: | #https://help.github.com/en/actions/reference/contexts-and-expression-syntax-for-github-actions#github-context
${{ github.actor }} created commit:
Commit message: ${{ github.event.head_commit.message }}
Repository: ${{ github.repository }}
Branch: ${{ github.ref_name }}
See changes: https://github.com/${{ github.repository }}/commit/${{github.sha}}
97 changes: 97 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,99 @@
# MultiPay

A Sentinel DVPN Multipay Transactor

This will run in a loop and prompt you for sentinel wallet addresses and amounts that you would like to send in single transaction (batch sending) based on the seed phrase you specify in the scrtxxs file.

# Installation

* requires sentinel-sdk

* requires >= python 3.10

To install the dependency:

```shell
pip install sentinel-sdk
```

Clone the repository

```shell
git clone https://github.com/MathNodes/MultiPay
```

# Configuration

Within the repository directory, edit the **scrtxxs.py** to your specific parameters.

* WalletName - The name you will give your sending wallet in the krygin

* HotWalletPW - The Password for your wallet in the keyring

* WalletSeed - The seed phrase of the sending wallet if not already in the keyring. leave blank if you already imported this wallet once before

# Run

To run the MultiPay script do the following:

```shell
python3 SentinelMultiPay.py
```

and follow the on screen prompts

# Logs & Keyring

The log file will be in the following folders

OS X:

```shell
/Users/username/.meile-multi-pay/multipay.log
```

Linux:

```shell
/home/username/.meile-multi-pay/multipay.log
```

This is also the folder the encrypted keyring will reside in.

# Donations

Because we are working on a small grant with no VC funding, any additional contributions to our developer team is more than certainly welcomed. It will help fund future releases.

## BTC (Bitcoin)

```
bc1qtvc9l3cr9u4qg6uwe6pvv7jufvsnn0xxpdyftl
```

![BTC](./img/BTC.png)

## DVPN (Sentinel)

```
sent12v8ghhg98e2n0chyje3su4uqlsg75sh4lwcyww
```

![dvpn](./img/DVPN.png)

## XMR (Monero)

```
87qHJPU5dZGWaWzuoC3My5SgoQSuxh4sHSv1FXRZrQ9XZHWnfC33EX1NLv5HujpVhbPbbF9RcXXD94byT18HonAQ75b9dyR
```

![xmr](./img/XMR.png)

## ARRR (Pirate Chain)

```
zs1gn457262c52z5xa666k77zafqmke0hd60qvc38dk48w9fx378h4zjs5rrwnl0x8qazj4q3x4svz
```



![ARRR](./img/ARRR.png)
184 changes: 184 additions & 0 deletions SentinelMultiPay.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#!/bin/env python3

import scrtxxs
import requests
import sys
from os import path, mkdir
from urllib.parse import urlparse
from bip_utils import Bip39SeedGenerator, Bip44, Bip44Coins

from sentinel_sdk.sdk import SDKInstance
from sentinel_sdk.types import TxParams
from keyrings.cryptfile.cryptfile import CryptFileKeyring
from sentinel_protobuf.cosmos.base.v1beta1.coin_pb2 import Coin
import ecdsa
import hashlib
import bech32
from mospy import Transaction
from grpc import RpcError

from datetime import datetime

MNAPI = "https://api.sentinel.mathnodes.com"
NODEAPI = "/sentinel/nodes/%s"
GRPC = scrtxxs.GRPC
SSL = True
VERSION = 20240817.0234
SATOSHI = 1000000

class MultiPay():
def __init__(self, keyring_passphrase, wallet_name, seed_phrase = None):
self.wallet_name = wallet_name

if seed_phrase:
seed_bytes = Bip39SeedGenerator(seed_phrase).Generate()
bip44_def_ctx = Bip44.FromSeed(seed_bytes, Bip44Coins.COSMOS).DeriveDefaultPath()
privkey_obj = ecdsa.SigningKey.from_string(bip44_def_ctx.PrivateKey().Raw().ToBytes(), curve=ecdsa.SECP256k1)
pubkey = privkey_obj.get_verifying_key()
s = hashlib.new("sha256", pubkey.to_string("compressed")).digest()
r = hashlib.new("ripemd160", s).digest()
five_bit_r = bech32.convertbits(r, 8, 5)
account_address = bech32.bech32_encode("sent", five_bit_r)
print(account_address)
self.keyring = self.__keyring(keyring_passphrase)
self.keyring.set_password("meile-multi-pay", wallet_name, bip44_def_ctx.PrivateKey().Raw().ToBytes().hex())
else:
self.keyring = self.__keyring(keyring_passphrase)

private_key = self.keyring.get_password("meile-multi-pay", self.wallet_name)

grpcaddr, grpcport = urlparse(GRPC).netloc.split(":")

self.sdk = SDKInstance(grpcaddr, int(grpcport), secret=private_key, ssl=SSL)

self.logfile = open(path.join(scrtxxs.KeyringDIR, "multipay.log"), "a+")

now = datetime.now()
self.logfile.write(f"\n---------------------------{now}---------------------------\n")

def __keyring(self, keyring_passphrase: str):
if not path.isdir(scrtxxs.KeyringDIR):
mkdir(scrtxxs.KeyringDIR)

kr = CryptFileKeyring()
kr.filename = "keyring.cfg"
kr.file_path = path.join(scrtxxs.KeyringDIR, kr.filename)
kr.keyring_key = keyring_passphrase
return kr

def __get_balance(self, address):
CoinDict = {'dvpn' : 0, 'scrt' : 0, 'dec' : 0, 'atom' : 0, 'osmo' : 0}
#CoinDict = {'tsent' : 0, 'scrt' : 0, 'dec' : 0, 'atom' : 0, 'osmo' : 0}
endpoint = "/bank/balances/" + address
try:
r = requests.get(MNAPI + endpoint)
coinJSON = r.json()
except:
return None

print(coinJSON)
try:
for coin in coinJSON['result']:
if "udvpn" in coin['denom']:
CoinDict['dvpn'] = int(coin['amount'])
except Exception as e:
print(str(e))
return None
return CoinDict

def SendDVPNs(self, addr_amts):
balance = self.__get_balance(self.sdk._account.address)
wallet_balance = int(balance.get("dvpn", 0))

amt = 0

# Sum total amount
for amount in addr_amts.values():
amt += int(amount)

if wallet_balance < int(amt):
self.logfile.write(f"[sp]: Balance is too low, required: {amt}udvpn, found: {wallet_balance}udvpn\n")
return False

tx_params = TxParams(
gas=300000,
gas_multiplier=1.15,
fee_amount=30000,
denom="udvpn"
)

tx = Transaction(
account=self.sdk._account,
fee=Coin(denom=tx_params.denom, amount=f"{tx_params.fee_amount}"),
gas=tx_params.gas,
protobuf="sentinel",
chain_id="sentinelhub-2",
)


for addr,udvpn in addr_amts.items():
tx.add_msg(
tx_type='transfer',
sender=self.sdk._account,
receipient=addr,
amount=udvpn,
denom="udvpn",
)

self.sdk._client.load_account_data(account=self.sdk._account)

if tx_params.gas == 0:
self.sdk._client.estimate_gas(
transaction=tx, update=True, multiplier=tx_params.gas_multiplier
)

tx_height = 0
try:
tx = self.sdk._client.broadcast_transaction(transaction=tx)

except RpcError as rpc_error:
details = rpc_error.details()
print("details", details)
print("code", rpc_error.code())
print("debug_error_string", rpc_error.debug_error_string())
self.logfile.write("[sp]: RPC ERROR. ")
return False

if tx.get("log", None) is None:
tx_response = self.sdk.nodes.wait_for_tx(tx["hash"])
tx_height = tx_response.get("txResponse", {}).get("height", 0) if isinstance(tx_response, dict) else tx_response.tx_response.height

message = f"Succefully sent {amt}udvpn at height: {tx_height} distributed by {addr_amts}" if tx.get("log", None) is None else tx["log"]
self.logfile.write(f"[sp]: {message}\n")
return True


if __name__ == "__main__":
mp = MultiPay(scrtxxs.HotWalletPW, scrtxxs.WalletName, scrtxxs.WalletSeed)

SendDict = {}

print(f"Leeloo Dallas Multipay - A DVPN multipay transactor - by freQniK - version: 5th Element {VERSION}\n\n")
print("You will be presented with a loop to enter Sentinel wallet addresses and amt. When finished, enter 'done'")
while True:
addr = input("Enter wallet address: ")
if addr.upper() == "DONE":
break
amt = input("Enter dvpn amt to send to wallet: ")

SendDict[addr] = str(int(float(amt) / SATOSHI))

print("The following addresses will receive these repsective amounts: ")
print(SendDict)
answer = input("Would you iike to continue (Y/n): ")
if answer.upper() == "Y":
if mp.SendDVPNs(SendDict):
print("Transaction completed successfully. Please check the log file")
print(f"{scrtxxs.KeyringDIR}/multipay.log")
else:
print("Something went wrong. Please check the log file.")
print(f"{scrtxxs.KeyringDIR}/multipay.log")
else:
sys.exit(0)


Binary file added img/ARRR.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/BTC.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/DVPN.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/XMR.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions scrtxxs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'''
You need to edit the following variables below with your desired values:
WalletName - Whatever you want to name the wallet in the keyring
HotWalletPW - Passowrd for your wallet in the keyring
WalletSeed - Seed if it is a new wallet, o/w it will pull from the keyring the WalletName
'''


import pwd
import os

import platform

pltform = platform.system()

if pltform == "Darwin":
KeyringDIR = "/Users/" + str(pwd.getpwuid(os.getuid())[0]) + "/.meile-multi-pay"
else:
KeyringDIR = "/home/" + str(pwd.getpwuid(os.getuid())[0]) + "/.meile-multi-pay"

WalletName = ""
HotWalletPW = ""
WalletSeed = ""
GRPC = "https://grpc.bluefren.xyz:443"


0 comments on commit 14466f9

Please sign in to comment.