generated from nathanwoodburn/python-webserver-template
feat: Add buy video and approved tokens list
All checks were successful
Build Docker / BuildImage (push) Successful in 36s
All checks were successful
Build Docker / BuildImage (push) Successful in 36s
This commit is contained in:
parent
1b7a35e51f
commit
afc03cd65d
2
cache/1981e30de11cf0845e8b5affb4dc75e0.json
vendored
2
cache/1981e30de11cf0845e8b5affb4dc75e0.json
vendored
@ -1 +1 @@
|
|||||||
{"timestamp": 1733399788.2365682, "result": 3939.96}
|
{"timestamp": 1733446009.8000035, "result": 3851.54}
|
2
cache/1ccff5c6f117409fea0c861aa44b8e62.json
vendored
2
cache/1ccff5c6f117409fea0c861aa44b8e62.json
vendored
@ -1 +1 @@
|
|||||||
{"timestamp": 1733399850.809605, "result": 1.22}
|
{"timestamp": 1733446072.6788523, "result": 1.18}
|
1
cache/211e25731b29590727627e042ed91ee6.json
vendored
Normal file
1
cache/211e25731b29590727627e042ed91ee6.json
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"timestamp": 1733446705.0293868, "result": [{"mint": "3NZ9JMVBmGAqocybic2c7LQCJScmgsAZ6vQqTDzcqmJh", "balance": 0.00011819, "price": 97423, "value": 11.51442437, "name": "Wrapped BTC (Wormhole)", "symbol": "wbtc"}, {"mint": "jupSoLaHXQiZZTSfEWMTRRgpnyFm8f6sZdosWBjx93v", "balance": 0.039815492, "price": 253.52, "value": 10.094023531840001, "name": "Jupiter Staked SOL", "symbol": "jupsol"}, {"mint": "7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs", "balance": 0.00255735, "price": 3851.54, "value": 9.849735819, "name": "Ethereum (Wormhole)", "symbol": "eth"}, {"mint": "27G8MtK7VtTcCHkpASjSDdkWWYfoqT6ggEuKidVJidD4", "balance": 2.402337, "price": 4.18, "value": 10.04176866, "name": "Jupiter Perpetuals Liquidity Provider Token", "symbol": "jlp"}]}
|
2
cache/29409a8a40dd2d547a7a44b8f6758f54.json
vendored
2
cache/29409a8a40dd2d547a7a44b8f6758f54.json
vendored
@ -1 +1 @@
|
|||||||
{"timestamp": 1733399788.90454, "result": 4.2}
|
{"timestamp": 1733446070.7321002, "result": 4.18}
|
2
cache/4104ed0427efe63d4ca0dead970a4391.json
vendored
2
cache/4104ed0427efe63d4ca0dead970a4391.json
vendored
@ -1 +1 @@
|
|||||||
{"timestamp": 1733399787.0462418, "result": 254.57}
|
{"timestamp": 1733446008.9807563, "result": 253.52}
|
2
cache/46c1ec7f5edb30c070003dc54e072f41.json
vendored
2
cache/46c1ec7f5edb30c070003dc54e072f41.json
vendored
@ -1 +1 @@
|
|||||||
{"timestamp": 1733399849.6811163, "result": 3.86}
|
{"timestamp": 1733446071.34895, "result": 4.24}
|
2
cache/598f5dbf97fb0d45cbc6e1a5b0a3b575.json
vendored
2
cache/598f5dbf97fb0d45cbc6e1a5b0a3b575.json
vendored
@ -1 +1 @@
|
|||||||
{"timestamp": 1733399783.5279012, "result": 240.09}
|
{"timestamp": 1733446003.3492062, "result": 239.52}
|
2
cache/6cc6c6a0b2d0654f551d33209c1fd824.json
vendored
2
cache/6cc6c6a0b2d0654f551d33209c1fd824.json
vendored
@ -1 +1 @@
|
|||||||
{"timestamp": 1733399850.0902743, "result": 4.0}
|
{"timestamp": 1733446071.701356, "result": 4.38}
|
2
cache/6eec370e2713cfc84c84e1080b8a191a.json
vendored
2
cache/6eec370e2713cfc84c84e1080b8a191a.json
vendored
@ -1 +1 @@
|
|||||||
{"timestamp": 1733399782.709279, "result": 171.95815534}
|
{"timestamp": 1733446001.4129517, "result": 183.854558203}
|
2
cache/790b28a9a21cf694ad9577ef1072ac9e.json
vendored
2
cache/790b28a9a21cf694ad9577ef1072ac9e.json
vendored
@ -1 +1 @@
|
|||||||
{"timestamp": 1733399783.1156325, "result": 0.009261758}
|
{"timestamp": 1733446002.9388597, "result": 0.00925676}
|
2
cache/a071d7bdda25c22e42ad7840f17c4b0e.json
vendored
2
cache/a071d7bdda25c22e42ad7840f17c4b0e.json
vendored
@ -1 +1 @@
|
|||||||
{"timestamp": 1733399785.692057, "result": 1.0}
|
{"timestamp": 1733446006.2181199, "result": 1.002}
|
1
cache/a099e7e540e16a185b0279b9494e5099.json
vendored
Normal file
1
cache/a099e7e540e16a185b0279b9494e5099.json
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"timestamp": 1733446007.035127, "result": 97423}
|
2
cache/a0ee60913ba556f39d128e7d7249e788.json
vendored
2
cache/a0ee60913ba556f39d128e7d7249e788.json
vendored
@ -1 +1 @@
|
|||||||
{"timestamp": 1733399850.0923588, "result": [{"mint": "jupSoLaHXQiZZTSfEWMTRRgpnyFm8f6sZdosWBjx93v", "balance": 0.039815492, "price": 254.57, "value": 10.13582979844, "name": "Jupiter Staked SOL", "symbol": "jupsol"}, {"mint": "7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs", "balance": 0.00255735, "price": 3939.96, "value": 10.075856706, "name": "Ethereum (Wormhole)", "symbol": "eth"}, {"mint": "27G8MtK7VtTcCHkpASjSDdkWWYfoqT6ggEuKidVJidD4", "balance": 2.402337, "price": 4.2, "value": 10.0898154, "name": "Jupiter Perpetuals Liquidity Provider Token", "symbol": "jlp"}, {"mint": "0x2::sui::SUI", "balance": 0.902850107, "price": 3.86, "value": 3.48500141302, "name": "Sui", "symbol": "sui"}, {"mint": "0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55::cert::CERT", "balance": 9.658874002, "price": 4.0, "value": 38.635496008, "name": "Volo Staked SUI", "symbol": "vsui"}]}
|
{"timestamp": 1733446071.70293, "result": [{"mint": "3NZ9JMVBmGAqocybic2c7LQCJScmgsAZ6vQqTDzcqmJh", "balance": 0.00011819, "price": 97423, "value": 11.51442437, "name": "Wrapped BTC (Wormhole)", "symbol": "wbtc"}, {"mint": "jupSoLaHXQiZZTSfEWMTRRgpnyFm8f6sZdosWBjx93v", "balance": 0.039815492, "price": 253.52, "value": 10.094023531840001, "name": "Jupiter Staked SOL", "symbol": "jupsol"}, {"mint": "7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs", "balance": 0.00255735, "price": 3851.54, "value": 9.849735819, "name": "Ethereum (Wormhole)", "symbol": "eth"}, {"mint": "27G8MtK7VtTcCHkpASjSDdkWWYfoqT6ggEuKidVJidD4", "balance": 2.402337, "price": 4.18, "value": 10.04176866, "name": "Jupiter Perpetuals Liquidity Provider Token", "symbol": "jlp"}, {"mint": "0x2::sui::SUI", "balance": 0.902850107, "price": 4.24, "value": 3.8280844536800003, "name": "Sui", "symbol": "sui"}, {"mint": "0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55::cert::CERT", "balance": 9.658874002, "price": 4.38, "value": 42.30586812876, "name": "Volo Staked SUI", "symbol": "vsui"}]}
|
2
cache/c652e896f57f598d23e3dbebdb815ef6.json
vendored
2
cache/c652e896f57f598d23e3dbebdb815ef6.json
vendored
@ -1 +1 @@
|
|||||||
{"timestamp": 1733399850.091789, "result": [{"mint": "0x2::sui::SUI", "balance": 0.902850107, "price": 3.86, "value": 3.48500141302, "name": "Sui", "symbol": "sui"}, {"mint": "0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55::cert::CERT", "balance": 9.658874002, "price": 4.0, "value": 38.635496008, "name": "Volo Staked SUI", "symbol": "vsui"}]}
|
{"timestamp": 1733446071.702515, "result": [{"mint": "0x2::sui::SUI", "balance": 0.902850107, "price": 4.24, "value": 3.8280844536800003, "name": "Sui", "symbol": "sui"}, {"mint": "0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55::cert::CERT", "balance": 9.658874002, "price": 4.38, "value": 42.30586812876, "name": "Volo Staked SUI", "symbol": "vsui"}]}
|
2
cache/ccf2a009e56f1b05d471a55d9c9ea8ea.json
vendored
2
cache/ccf2a009e56f1b05d471a55d9c9ea8ea.json
vendored
@ -1 +1 @@
|
|||||||
{"timestamp": 1733399850.5008185, "result": 82.815227}
|
{"timestamp": 1733446072.368228, "result": 82.815227}
|
72
server.py
72
server.py
@ -223,42 +223,46 @@ def getVaultBalance() -> int:
|
|||||||
return vaultBalance
|
return vaultBalance
|
||||||
|
|
||||||
@cache.file_cache()
|
@cache.file_cache()
|
||||||
def getTokens():
|
def getTokens(chain:str=None):
|
||||||
programID = Pubkey.from_string(
|
|
||||||
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")
|
|
||||||
|
|
||||||
tokenAccounts = solana_client.get_token_accounts_by_owner(
|
|
||||||
vault_sol_address,
|
|
||||||
TokenAccountOpts(program_id=programID)
|
|
||||||
)
|
|
||||||
|
|
||||||
tokenAccounts = tokenAccounts.value
|
|
||||||
tokens = []
|
tokens = []
|
||||||
|
|
||||||
for tokenAccount in tokenAccounts:
|
if chain == "solana" or chain == None:
|
||||||
pubkey = tokenAccount.pubkey
|
programID = Pubkey.from_string(
|
||||||
account = solana_client.get_token_account_balance(pubkey)
|
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")
|
||||||
mint = tokenAccount.account.data[:32]
|
|
||||||
mint = Pubkey(mint)
|
|
||||||
# Decode the mint
|
|
||||||
token = {
|
|
||||||
"mint": str(mint),
|
|
||||||
"balance": account.value.ui_amount
|
|
||||||
}
|
|
||||||
|
|
||||||
token["price"] = get_token_price(token["mint"])
|
tokenAccounts = solana_client.get_token_accounts_by_owner(
|
||||||
token["value"] = token["price"] * token["balance"]
|
vault_sol_address,
|
||||||
|
TokenAccountOpts(program_id=programID)
|
||||||
|
)
|
||||||
|
|
||||||
if token["value"] < 0.01:
|
tokenAccounts = tokenAccounts.value
|
||||||
continue
|
|
||||||
|
|
||||||
data = getTokenData(str(mint))
|
|
||||||
token["name"] = data["name"]
|
|
||||||
token["symbol"] = data["symbol"]
|
|
||||||
tokens.append(token)
|
|
||||||
|
|
||||||
# Get SUI tokens
|
for tokenAccount in tokenAccounts:
|
||||||
tokens.extend(getSuiTokens(vault_sui_address))
|
pubkey = tokenAccount.pubkey
|
||||||
|
account = solana_client.get_token_account_balance(pubkey)
|
||||||
|
mint = tokenAccount.account.data[:32]
|
||||||
|
mint = Pubkey(mint)
|
||||||
|
# Decode the mint
|
||||||
|
token = {
|
||||||
|
"mint": str(mint),
|
||||||
|
"balance": account.value.ui_amount
|
||||||
|
}
|
||||||
|
|
||||||
|
token["price"] = get_token_price(token["mint"])
|
||||||
|
token["value"] = token["price"] * token["balance"]
|
||||||
|
|
||||||
|
if token["value"] < 0.01:
|
||||||
|
continue
|
||||||
|
|
||||||
|
data = getTokenData(str(mint))
|
||||||
|
token["name"] = data["name"]
|
||||||
|
token["symbol"] = data["symbol"]
|
||||||
|
tokens.append(token)
|
||||||
|
|
||||||
|
if chain == "sui" or chain == None:
|
||||||
|
# Get SUI tokens
|
||||||
|
tokens.extend(getSuiTokens(vault_sui_address))
|
||||||
|
|
||||||
return tokens
|
return tokens
|
||||||
|
|
||||||
@ -370,6 +374,14 @@ def getSuiTokens(address: str):
|
|||||||
|
|
||||||
# region API Routes
|
# region API Routes
|
||||||
|
|
||||||
|
@app.route("/api/v1/tokens")
|
||||||
|
def api_tokens():
|
||||||
|
tokens = getTokens("solana")
|
||||||
|
for t in tokens:
|
||||||
|
t["url"] = f"https://explorer.solana.com/address/{t['mint']}"
|
||||||
|
|
||||||
|
return jsonify(tokens)
|
||||||
|
|
||||||
@app.route("/api/v1/token")
|
@app.route("/api/v1/token")
|
||||||
def api_token():
|
def api_token():
|
||||||
# Get number of tokens minted
|
# Get number of tokens minted
|
||||||
|
BIN
stWDBRN.bsdesign
BIN
stWDBRN.bsdesign
Binary file not shown.
@ -263,7 +263,80 @@ function sortTableByValue(tbody) {
|
|||||||
<div class="col-lg-6 order-lg-1">
|
<div class="col-lg-6 order-lg-1">
|
||||||
<div class="p-5">
|
<div class="p-5">
|
||||||
<h2 class="display-4">1. Buy tokens</h2>
|
<h2 class="display-4">1. Buy tokens</h2>
|
||||||
<p>To get started buy stWDBRN tokens at the current price to buy a percent of the vault value. The buy in value is then invested in various projects in order to increase the token's value.<br><br>Send USDC or SOL to vault.woodburn.sol and receive stWDBRN in exchange. (Note automated swaps only happen for deposits over 1 USDC)</p>
|
<p>To get started buy stWDBRN tokens at the current price to buy a percent of the vault value. The buy in value is then invested in various projects in order to increase the token's value.<br><br>Send SOL or approved tokens to vault.woodburn.sol and receive stWDBRN in exchange. (Note automated swaps only happen for deposits over 1 USDC)</p><button class="btn btn-primary" id="video-button" type="button" style="margin: 20px;">See how</button><button class="btn btn-primary" id="approved-tokens-button" type="button" style="margin: 20px;">Approved Tokens</button><div id="video-div" style="margin-top: 20px; display: none;">
|
||||||
|
<video id="video" style="max-width: 75%; height: auto;border-radius: 25px;" controls>
|
||||||
|
<source src="https://cloud.woodburn.au/s/dsaF9MHMz9s5H2q/download/Screen_Recording_20241205_235805_Phantom.mp4"
|
||||||
|
type="video/mp4">
|
||||||
|
</video>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="approved-tokens" style="margin-top: 20px; display: none;">
|
||||||
|
<h2>Approved Tokens</h2>
|
||||||
|
<p>The following tokens are approved to be used with the stWDBRN Vault.</p>
|
||||||
|
<ul id="approvedTokenList"></ul>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function toggleVideo() {
|
||||||
|
var video = document.getElementById("video-div");
|
||||||
|
var approvedtokens = document.getElementById("approved-tokens");
|
||||||
|
if (video.style.display === "none") {
|
||||||
|
video.style.display = "block";
|
||||||
|
approvedtokens.style.display = "none";
|
||||||
|
} else {
|
||||||
|
video.style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function fetchAndRenderTokens() {
|
||||||
|
try {
|
||||||
|
// Fetch data from the API
|
||||||
|
const response = await fetch('/api/v1/tokens');
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||||
|
}
|
||||||
|
const tokens = await response.json();
|
||||||
|
|
||||||
|
// Select the container where the list will be appended
|
||||||
|
const tokenList = document.getElementById('approvedTokenList');
|
||||||
|
|
||||||
|
// Loop through the tokens and create HTML for each
|
||||||
|
tokens.forEach(token => {
|
||||||
|
const listItem = document.createElement('li'); // Create a list item
|
||||||
|
const anchor = document.createElement('a'); // Create a link element
|
||||||
|
|
||||||
|
anchor.href = token.url; // Set the URL
|
||||||
|
anchor.target = '_blank'; // Open the link in a new tab
|
||||||
|
anchor.textContent = `${token.name} (${token.symbol.toUpperCase()})`; // Set the text
|
||||||
|
|
||||||
|
listItem.appendChild(anchor); // Append the anchor to the list item
|
||||||
|
tokenList.appendChild(listItem); // Append the list item to the container
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching or rendering tokens:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleApprovedTokens() {
|
||||||
|
// Fill in the approved tokens list if it isn't already
|
||||||
|
if (document.getElementById("approvedTokenList").innerHTML === "") {
|
||||||
|
fetchAndRenderTokens();
|
||||||
|
}
|
||||||
|
var approvedtokens = document.getElementById("approved-tokens");
|
||||||
|
var video = document.getElementById("video-div");
|
||||||
|
if (approvedtokens.style.display === "none") {
|
||||||
|
approvedtokens.style.display = "block";
|
||||||
|
video.style.display = "none";
|
||||||
|
} else {
|
||||||
|
approvedtokens.style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById("video-button").onclick = function () {
|
||||||
|
toggleVideo();
|
||||||
|
};
|
||||||
|
document.getElementById("approved-tokens-button").onclick = function () {
|
||||||
|
toggleApprovedTokens();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
1
tokens/3NZ9JMVBmGAqocybic2c7LQCJScmgsAZ6vQqTDzcqmJh.json
Normal file
1
tokens/3NZ9JMVBmGAqocybic2c7LQCJScmgsAZ6vQqTDzcqmJh.json
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user