A potential STEEM challenge
I am thinking lately of running, in the near future, my own, not so big challenge, where I ask people around to do a STEEM power up above a minimum threshold and then I'll be supporting some of those users with an upvote (or more upvotes if I like their content in general) to their active post/s or comment/s.
The second requirement would be for those applying to have not made any power down in the last year.
As I am not a developer and I couldn't find how to easily query the STEEM blockchain for that, I had to spend a few hours "interacting" with AI and doing the so called "Vibe Coding".
Firstly, I had to communicate with AI to establish what is the fastest way to query the blockchain as at first it was suggesting I use the legacy API methods and fetching info dated one year ago is very slow.
Then the AI suggested I use the SDS by @steemchiller.
After iterating with AI for another couple of hours, I finally got to this Python script.
Strangely, the scripts AI generates never, really never work from the first time, at least for me, and I have to return the errors to it, then it says "you're right, this has to be changed to..." and I have to make more iterations. Thinking more of it, this has its economical logic - people need to make more /paid/ calls to AI. Anyway. Still, vibe coding is fun. Saves so much time. Poor entry-level developers!
I'm tagging @moecki here too, I trust you both, guys, please take a look at the script if I can rely on it to take those decision about who qualifies. I realize it is the season where people go on well deserved long holidays so there isn't any urgency, whenever you guys have time, or just ignore this, if you're too busy. I tested it with several accounts I follow, and to my observations, the results are accurate.
I saw in the posts of steemchiller about the SDS two URLs mentioned - sds.steemworld.org and sds0.steemworld.org and I guess I should use sds.steemworld.org ? I tried both, couldn't see any difference in the results or the execution speed.
To test how fast the power ups are counted for, I did a symbolic power up of 11.111 STEEM and it virtually took seconds before the script printed this in my console:
2025-06-15 21:45:15+00:00 --> 3.814 STEEM (Power Up) from du-finanzbot
2025-06-26 15:21:30+00:00 --> 1.268 STEEM (Power Up) from lifetrail
2025-08-13 10:08:39+00:00 --> 11.111 STEEM (Power Up) from lifetrail
No power downs for the last year, actually, I haven't powered down at all so far.
Here the full script:
import requests
from datetime import datetime, timedelta, timezone
def get_global_properties():
url = "https://api.steemit.com"
payload = {
"jsonrpc": "2.0",
"method": "condenser_api.get_dynamic_global_properties",
"params": [],
"id": 1
}
response = requests.post(url, json=payload)
result = response.json()['result']
fund_steem = float(result['total_vesting_fund_steem'].split()[0])
total_vests = float(result['total_vesting_shares'].split()[0])
return fund_steem, total_vests
def convert_vests_to_steem(vesting_shares, fund_steem, total_vests):
vests = float(vesting_shares.split()[0])
return (vests / total_vests) * fund_steem
def fetch_power_downs(account, start_ts, end_ts, fund_steem, total_vests):
url = f"https://sds.steemworld.org/account_history_api/getHistoryByOpTypesTime/{account}/withdraw_vesting/{start_ts}-{end_ts}"
response = requests.get(url)
data = response.json()
rows = data['result']['rows']
power_downs = []
for row in rows:
timestamp = row[1]
op_data = row[6][1]
vesting_shares = op_data['vesting_shares']
dt = datetime.fromtimestamp(timestamp, timezone.utc)
steem_amount = convert_vests_to_steem(vesting_shares, fund_steem, total_vests)
power_downs.append((dt, steem_amount))
return power_downs
def fetch_power_ups(account, start_ts, end_ts):
url = f"https://sds.steemworld.org/account_history_api/getHistoryByOpTypesTime/{account}/transfer_to_vesting/{start_ts}-{end_ts}"
response = requests.get(url)
data = response.json()
rows = data['result']['rows']
power_ups = []
for row in rows:
timestamp = row[1]
op_data = row[6][1]
steem_amount = float(op_data['amount'].split()[0])
sender = op_data['from']
dt = datetime.fromtimestamp(timestamp, timezone.utc)
power_ups.append((dt, steem_amount, sender))
return power_ups
# Main execution
account = 'lifetrail'
now_ts = int(datetime.now().timestamp())
one_year_ago_ts = int((datetime.now() - timedelta(days=365)).timestamp())
fund_steem, total_vests = get_global_properties()
power_downs = fetch_power_downs(account, one_year_ago_ts, now_ts, fund_steem, total_vests)
power_ups = fetch_power_ups(account, one_year_ago_ts, now_ts)
# Combine and sort all events
all_events = [(dt, steem, 'Power Down', None) for dt, steem in power_downs] + \
[(dt, steem, 'Power Up', sender) for dt, steem, sender in power_ups]
all_events.sort(key=lambda x: x[0])
# Print results
for dt, steem, label, sender in all_events:
if label == 'Power Up':
print(f"{dt} --> {steem:.3f} STEEM ({label}) from {sender}")
else:
print(f"{dt} --> {steem:.3f} STEEM ({label})")
Here are some of our favorite quotes to motivate you to not give up and keep up the good work!
"Success isn't always about greatness. It's about consistency. Consistent hard work leads to success. Greatness will come."
By Dwayne Johnson
"Success seems to be connected with action. Successful people keep moving. They make mistakes, but they don't quit."
By Conrad Hilton
"Character cannot be developed in ease and quiet. Only through experience of trial and suffering can the soul be strengthened, vision cleared, ambition inspired and success achieved."
By Helen Keller
"I've come to believe that each of us has a personal calling that's as unique as a fingerprint and that the best way to succeed is to discover what you love and then find a way to offer it to others in the form of service, working hard and also allowing the energy of the universe to lead you."
By Oprah Winfrey
"Most of the important things in the world have been accomplished by people who have kept on trying when there seemed to be no hope at all."
By Dale Carnegie
Our journey here continues and we hope to find lots of new friends and interesting content and accounts on Steemit!
If you got up to this point, please receive some positive vibes and thoughts from us. Have a great day!
Copyright LifeTrail 2023
Divider by Rebecca Read from Pixabay
I don't have much time for details at the moment, so here are just my brief thoughts:
account_history_api
unfortunately only returns limited data. As you can see, it does not return all your PowerUps within the year.transfers_api.getTransfersByTypeTime
. This allows you to get PowerUps and PowerDowns with one query: https://sds0.steemworld.org/describeMethod/transfers_api.getTransfersdynamic_global_properties
of SDS: https://sds0.steemworld.org/steem_requests_api/condenser_api.get_dynamic_global_properties0.00 SBD,
29.92 STEEM,
29.92 SP
Your input is very helpful!
The ways you suggest to change it will optimize it and make the script dependable on one service instead of two, ergo faster and better. I'll have it modified in the next days and I'll share the result.
Do you recommend I use sds0. over just sds.? Any difference you aware of?
Thanks so much!
0.00 SBD,
0.86 STEEM,
0.86 SP
There are no differences at the moment.
sds and sds1 are the stable versions. I think sds is primarily used for steemworld.
Changes are installed on sds0 first. If everything goes well, it goes live on sds and sds1. As there are currently no new changes, all instances have the same status.
0.00 SBD,
0.09 STEEM,
0.09 SP
In addition to Moecki's comment, I played around with the query syntax:
For Power-Up:
https://sds0.steemworld.org/transfers_api/getTransfers/{"type":"transfer_to_vesting","to":"lifetrail","fromTime":"1723593324","orderDir":"ASC"}/800
- direct call via URLFor Power-Down:
https://sds0.steemworld.org/transfers_api/getTransfers/{"type":"withdraw_vesting","from":"upvu","fromTime":"1723593324","orderDir":"ASC"}/800
- direct call via URLTo convert VESTS to STEEM, you can use
steem_per_share
from this call:https://sds0.steemworld.org/steem_requests_api/getSteemProps
Maybe that's useful for you.