Skip to content

Commit

Permalink
update readme + formatter to use num_format, remvoe last ts files
Browse files Browse the repository at this point in the history
  • Loading branch information
gaetbout committed Nov 10, 2023
1 parent cd08255 commit 1767d90
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 168 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

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

97 changes: 84 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,95 @@
# StarkWhaleAlert

Project
Make a tweet when transfer of at leasst X
uses alchemy RPC get_Events
starknetJS
coincap io conversion token <=> $ value https://docs.coincap.io/
[![Twitter URL](https://img.shields.io/twitter/url.svg?label=Follow%20%40StarkWhaleAlert&style=social&url=https%3A%2F%2Ftwitter.com%2FStarkWhaleAlert)]( https://twitter.com/StarkWhaleAlert)

This is a script aimed to track all transfers above a threshold done on Starknet.
If such a transfer is detected it'll post a tweet.

## Overview

Here is how the script works:
1. Fetch last processed block number from file and the last block produced by the network.
- If no new block ⇒ Stop
- If it is too much behind ⇒ Stop: probably something went wrong.
- Otherwise ⇒ Continue
2. For each token:
1. Get all `Transfer` events from last processed block to current network block.
2. Filter events to only keep the ones above the threshold:
- If none ⇒ Proceed to next token
- If any ⇒ Tweet
3. Set last processed block to last block produced by the network


To create the tweet the text needs to be formatted involving multiple steps:
- Format the token value
- Fetch it's USD value and format it
- Format the from and to:
- Can be bridging to L1
- Can be bridging to L2
- Can be someone with a StarknetID
- Can be one of the known addresses (e.g.: Layerswap, Jediswap, ...)
- If none of the previous ⇒ Shorten the address to have something like `0x123...4567`
- Put a reference to the transaction involving the transfer available on a block explorer


## Installation
use `cargo install --path crates/crate-name`
**Prerequisite: have Rust and Cargo installed**

Build both binaries:
```shell
cargo build
```

Run a specific binary using:
```shell
cargo run --bin bin_name
```

Build for a linux environment from a mac using:
```shell
cargo build --bin starkwhale_alert --release --target=x86_64-unknown-linux-gnu
```

## Setup

### Twitter
First create a new project on:
https://developer.twitter.com/en/portal/dashboard
Remember to save the `CLIENT_ID` and `CLIENT_SECRET` somehwere, you'll need it later.
In the **App info** section fill the Callback URI with `http://127.0.0.1:3000/callback`.
You can fill the required `Website URL` with anything you want it doesn't matter.

build for linux: `cargo build --bin starkwhale_alert --release --target=x86_64-unknown-linux-gnu`
Then run:
```shell
cargo run --bin twitter_login
```
You can now open http://127.0.0.1:3000/login in your browser and authorize the application. It should redirect you to a page where you can see your token. Copy the whole page, create a file named `token.json` in the [db folder](./db/) and paste inside that file.

### Setup the .env
This script is using:
- Infura as a node provider
- Coincap to fetch the USD value of a token
- Here is where you paste the twitter `CLIENT_ID` and `CLIENT_SECRET`

Feel free to tweak the code to use another RPC or API to fetch the USD value.

## Contribution
### Run the bot
Once everything is setup you can try the bot using:
```shell
cargo run --bin starkwhale_alert
```

analyse is there to help and analyse a token to find out what would be the best lower bound
Strict minimum to work with
If you want to build the binary, add the release flag:
```shell
cargo build --bin starkwhale_alert --release
```
You can now find the binary at `./target/release/starkwhale_alert`

## TODO
The first time you run the script, the block might be out of date and it'll tell you to restart the script using an option:
```shell
./starkwhale_alert -s
```
This will update the block file to the latest block.

- Have a DB with a correspondancy wallet address <==> to actual (like binance, starkgate, 0x0, etc etc,)
- A way of automatically adjusting the threshold?
After this step you are all setup.
I setup nodecron to run this script every 5 minutes.
3 changes: 2 additions & 1 deletion crates/starkwhale-alert/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ log = "0.4.20"
chrono = "0.4.29"
dotenv_codegen = "0.15.0"
num-bigint = "0.4.4"
openssl = { version = "0.10", features = ["vendored"] }
openssl = { version = "0.10", features = ["vendored"] }
num-format = "0.4.4"
28 changes: 9 additions & 19 deletions crates/starkwhale-alert/src/formatter.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use bigdecimal::{FromPrimitive, ToPrimitive};
use num_bigint::BigUint;
use num_format::{Locale, ToFormattedString};
use starknet::core::types::{EmittedEvent, FieldElement};
use std::ops::Div;

Expand All @@ -12,28 +13,16 @@ pub async fn get_formatted_text(emitted_event: EmittedEvent, token: &Token) -> S
emitted_event.data[2].try_into().expect("Error: low"),
emitted_event.data[3].try_into().expect("Error: high"),
);
// TODO No need to use this one yet?
amount = to_rounded(amount, token.decimals);
let amount_string = amount
.to_string()
.as_bytes()
.rchunks(3)
.rev()
.map(std::str::from_utf8)
.collect::<Result<Vec<&str>, _>>()
.unwrap()
.join(".");
let amount_string = amount.to_u128().unwrap().to_formatted_string(&Locale::en);
let rate = api::fetch_coin(token.rate_api_id).await.unwrap();
let rate = BigUint::new(vec![(rate * 10000_f64).to_u32().unwrap()]);
let usd_value = (amount * rate).div(BigUint::new(vec![10000]));
let usd_value_string = usd_value
.to_string()
.as_bytes()
.rchunks(3)
.rev()
.map(std::str::from_utf8)
.collect::<Result<Vec<&str>, _>>()
.to_u128()
.unwrap()
.join(".");
.to_formatted_string(&Locale::en);

let first_line = format!(
"{:} #{} {} ({} USD)",
Expand Down Expand Up @@ -138,9 +127,10 @@ mod tests {
.unwrap(),
};
let response = get_formatted_text(emitted_event, &USDC).await;
println!("{response}");
assert!(
response
== "1.000.000 #USDC $ (1.000.000 USD)\n0x6e1...b3ce bridged to Starknet L2\nhttps://starkscan.co/tx/0x732b09d901fb0075d283ac23cbaae4f8c486123a88a621eeaa05d0b5ddfb8d8",
== "1,000,000 #USDC $ (1,000,000 USD)\n0x6e1...b3ce bridged to Starknet L2\nhttps://starkscan.co/tx/0x732b09d901fb0075d283ac23cbaae4f8c486123a88a621eeaa05d0b5ddfb8d8",
"Should be https://twitter.com/StarkWhaleAlert/status/1703701997629722850"
);
}
Expand Down Expand Up @@ -180,7 +170,7 @@ mod tests {
let response = get_formatted_text(emitted_event, &USDC).await;
assert!(
response
== "1.000.000 #USDC $ (1.000.000 USD)\n0x6e1...b3ce bridged to Ethereum L1\nhttps://starkscan.co/tx/0x732b09d901fb0075d283ac23cbaae4f8c486123a88a621eeaa05d0b5ddfb8d8",
== "1,000,000 #USDC $ (1,000,000 USD)\n0x6e1...b3ce bridged to Ethereum L1\nhttps://starkscan.co/tx/0x732b09d901fb0075d283ac23cbaae4f8c486123a88a621eeaa05d0b5ddfb8d8",
"Should be correct"
);
}
Expand Down Expand Up @@ -223,7 +213,7 @@ mod tests {
let response = get_formatted_text(emitted_event, &USDC).await;
assert!(
response
== "1.000.000 #USDC $ (1.000.000 USD)\nFrom 0x6e1...b3ce to 0x6e1...b3ce\nhttps://starkscan.co/tx/0x732b09d901fb0075d283ac23cbaae4f8c486123a88a621eeaa05d0b5ddfb8d8",
== "1,000,000 #USDC $ (1,000,000 USD)\nFrom 0x6e1...b3ce to 0x6e1...b3ce\nhttps://starkscan.co/tx/0x732b09d901fb0075d283ac23cbaae4f8c486123a88a621eeaa05d0b5ddfb8d8",
"Should be correct"
);
}
Expand Down
4 changes: 2 additions & 2 deletions crates/starkwhale-alert/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ async fn main() -> Result<(), Box<dyn Error>> {
if last_network_block > last_processed_block + 100 {
// TODO Send mail
info!(
"Local is {} blocks behind (current: {}). To resync use option -r",
"Local is {} blocks behind (current: {}). To sync use option -s",
last_network_block - last_processed_block,
last_network_block
);
let args: Vec<String> = env::args().collect();
if args.contains(&String::from("-r")) {
if args.contains(&String::from("-s")) {
info!("Updating to latest block...\n");
db::set_last_processed_block(last_network_block).await;
}
Expand Down
2 changes: 1 addition & 1 deletion db/block.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"last_processed_block": 364110
"last_processed_block": 389785
}
80 changes: 0 additions & 80 deletions scripts/index.ts

This file was deleted.

52 changes: 0 additions & 52 deletions scripts/twitterLogin.ts

This file was deleted.

0 comments on commit 1767d90

Please sign in to comment.