dev@locazia: view track api endpoints
This commit is contained in:
parent
a836196a47
commit
66cef7836d
|
|
@ -20,7 +20,9 @@ from app.api.routes.node_storage import s_api_v1_storage_post, s_api_v1_storage_
|
||||||
from app.api.routes.account import s_api_v1_account_get
|
from app.api.routes.account import s_api_v1_account_get
|
||||||
from app.api.routes._blockchain import s_api_v1_blockchain_send_new_content_message, \
|
from app.api.routes._blockchain import s_api_v1_blockchain_send_new_content_message, \
|
||||||
s_api_v1_blockchain_send_purchase_content_message
|
s_api_v1_blockchain_send_purchase_content_message
|
||||||
from app.api.routes.content import s_api_v1_content_list
|
from app.api.routes.content import s_api_v1_content_list, s_api_v1_content_view
|
||||||
|
from app.api.routes.tonconnect import s_api_v1_tonconnect_new, s_api_v1_tonconnect_logout
|
||||||
|
|
||||||
|
|
||||||
app.add_route(s_index, "/", methods=["GET", "OPTIONS"])
|
app.add_route(s_index, "/", methods=["GET", "OPTIONS"])
|
||||||
app.add_route(s_favicon, "/favicon.ico", methods=["GET", "OPTIONS"])
|
app.add_route(s_favicon, "/favicon.ico", methods=["GET", "OPTIONS"])
|
||||||
|
|
@ -34,6 +36,9 @@ app.add_route(s_api_platform_metadata, "/api/platform-metadata.json", methods=["
|
||||||
|
|
||||||
app.add_route(s_api_v1_auth_twa, "/api/v1/auth.twa", methods=["POST", "OPTIONS"])
|
app.add_route(s_api_v1_auth_twa, "/api/v1/auth.twa", methods=["POST", "OPTIONS"])
|
||||||
|
|
||||||
|
app.add_route(s_api_v1_tonconnect_new, "/api/v1/tonconnect.new", methods=["GET", "OPTIONS"])
|
||||||
|
app.add_route(s_api_v1_tonconnect_logout, "/api/v1/tonconnect.logout", methods=["POST", "OPTIONS"])
|
||||||
|
|
||||||
app.add_route(s_api_v1_storage_post, "/api/v1/storage", methods=["POST", "OPTIONS"])
|
app.add_route(s_api_v1_storage_post, "/api/v1/storage", methods=["POST", "OPTIONS"])
|
||||||
app.add_route(s_api_v1_storage_get, "/api/v1/storage/<file_hash>", methods=["GET", "OPTIONS"])
|
app.add_route(s_api_v1_storage_get, "/api/v1/storage/<file_hash>", methods=["GET", "OPTIONS"])
|
||||||
app.add_route(s_api_v1_storage_decode_cid, "/api/v1/storage.decodeContentId/<content_id>", methods=["GET", "OPTIONS"])
|
app.add_route(s_api_v1_storage_decode_cid, "/api/v1/storage.decodeContentId/<content_id>", methods=["GET", "OPTIONS"])
|
||||||
|
|
@ -44,6 +49,7 @@ app.add_route(s_api_v1_blockchain_send_new_content_message, "/api/v1/blockchain.
|
||||||
app.add_route(s_api_v1_blockchain_send_purchase_content_message, "/api/v1/blockchain.sendPurchaseContentMessage", methods=["POST", "OPTIONS"])
|
app.add_route(s_api_v1_blockchain_send_purchase_content_message, "/api/v1/blockchain.sendPurchaseContentMessage", methods=["POST", "OPTIONS"])
|
||||||
|
|
||||||
app.add_route(s_api_v1_content_list, "/api/v1/content.list", methods=["GET", "OPTIONS"])
|
app.add_route(s_api_v1_content_list, "/api/v1/content.list", methods=["GET", "OPTIONS"])
|
||||||
|
app.add_route(s_api_v1_content_view, "/api/v1/content.view/<content_address>", methods=["GET", "OPTIONS"])
|
||||||
|
|
||||||
|
|
||||||
@app.exception(BaseException)
|
@app.exception(BaseException)
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,11 @@ async def s_api_v1_auth_twa(request):
|
||||||
assert known_user, "User not created"
|
assert known_user, "User not created"
|
||||||
|
|
||||||
new_user_key = await known_user.create_api_token_v1(request.ctx.db_session, "USER_API_V1")
|
new_user_key = await known_user.create_api_token_v1(request.ctx.db_session, "USER_API_V1")
|
||||||
|
|
||||||
|
connected_wallet_data = known_user.wallet_connection(request.ctx.db_session)
|
||||||
|
|
||||||
return response.json({
|
return response.json({
|
||||||
'user': known_user.json_format(),
|
'user': known_user.json_format(),
|
||||||
|
'connected_wallet': connected_wallet_data.json_format() if connected_wallet_data else None,
|
||||||
'auth_v1_token': new_user_key['auth_v1_token']
|
'auth_v1_token': new_user_key['auth_v1_token']
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ from sanic import response
|
||||||
|
|
||||||
from app.core.logger import make_log
|
from app.core.logger import make_log
|
||||||
from app.core.models.node_storage import StoredContent
|
from app.core.models.node_storage import StoredContent
|
||||||
|
from app.core.models.keys import KnownKey
|
||||||
|
from app.core.models.content.user_content import UserContent
|
||||||
|
|
||||||
|
|
||||||
async def s_api_v1_content_list(request):
|
async def s_api_v1_content_list(request):
|
||||||
|
|
@ -24,3 +26,39 @@ async def s_api_v1_content_list(request):
|
||||||
result[content_json["cid"]] = content_json
|
result[content_json["cid"]] = content_json
|
||||||
|
|
||||||
return response.json(result)
|
return response.json(result)
|
||||||
|
|
||||||
|
|
||||||
|
async def s_api_v1_content_view(request, content_address: str):
|
||||||
|
# content_address can be CID or TON address
|
||||||
|
r_content = StoredContent.from_cid(request.ctx.db_session, content_address)
|
||||||
|
content = r_content.open_content(request.ctx.db_session)
|
||||||
|
|
||||||
|
opts = {}
|
||||||
|
if content['encrypted_content'].key_id:
|
||||||
|
known_key = request.ctx.db_session.query(KnownKey).filter(
|
||||||
|
KnownKey.id == content
|
||||||
|
).first()
|
||||||
|
if known_key:
|
||||||
|
opts['key_hash'] = known_key.seed_hash
|
||||||
|
|
||||||
|
have_access = False
|
||||||
|
if request.ctx.user:
|
||||||
|
user_wallet_address = request.ctx.user.wallet_address(request.ctx.db_session)
|
||||||
|
have_access = (
|
||||||
|
(content.owner_address == user_wallet_address)
|
||||||
|
or bool(request.ctx.db_session.query(UserContent).filter_by(owner_address=user_wallet_address, status='active',
|
||||||
|
content_id=content.id).first())
|
||||||
|
)
|
||||||
|
|
||||||
|
display_options = {
|
||||||
|
'content_url': content['decrypted_content'].web_url + (
|
||||||
|
'?seconds_limit=30' if not have_access else ''
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json({
|
||||||
|
**opts,
|
||||||
|
'encrypted': content['encrypted_content'].json_format(),
|
||||||
|
'display_options': display_options
|
||||||
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from aiogram.utils.web_app import safe_parse_webapp_init_data
|
||||||
|
from sanic import response
|
||||||
|
|
||||||
|
from app.core._blockchain.ton.connect import TonConnect, unpack_wallet_info, WalletConnection
|
||||||
|
from app.core._config import TELEGRAM_API_KEY
|
||||||
|
from app.core.models.user import User
|
||||||
|
from app.core.logger import make_log
|
||||||
|
|
||||||
|
|
||||||
|
async def pause_ton_connection(ton_connect: TonConnect):
|
||||||
|
if ton_connect.connected:
|
||||||
|
ton_connect._sdk_client.pause_connection()
|
||||||
|
|
||||||
|
|
||||||
|
async def s_api_v1_tonconnect_new(request):
|
||||||
|
if not request.ctx.user:
|
||||||
|
return response.json({"error": "User not found"}, status=400)
|
||||||
|
|
||||||
|
wallet_app_name = request.args.get("wallet_app_name", "tonkeeper")
|
||||||
|
|
||||||
|
db_session = request.ctx.db_session
|
||||||
|
user = request.ctx.user
|
||||||
|
memory = request.ctx.memory
|
||||||
|
ton_connect, ton_connection = TonConnect.by_user(db_session, user)
|
||||||
|
await ton_connect.restore_connection()
|
||||||
|
make_log("TonConnect_API", f"SDK connected?: {ton_connect.connected}", level='info')
|
||||||
|
if ton_connect.connected:
|
||||||
|
return response.json({"error": "Already connected"}, status=400)
|
||||||
|
|
||||||
|
connection_link = await ton_connect.new_connection(wallet_app_name)
|
||||||
|
ton_connect.connected
|
||||||
|
memory.add_task(pause_ton_connection, ton_connect, delay_s=60 * 3)
|
||||||
|
make_log("TonConnect_API", f"New connection link for {wallet_app_name}: {connection_link}", level='debug')
|
||||||
|
return response.json({
|
||||||
|
"connection_link": connection_link,
|
||||||
|
"wallet_app_name": wallet_app_name
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
async def s_api_v1_tonconnect_logout(request):
|
||||||
|
if not request.ctx.user:
|
||||||
|
return response.json({"error": "User not found"}, status=400)
|
||||||
|
|
||||||
|
db_session = request.ctx.db_session
|
||||||
|
user = request.ctx.user
|
||||||
|
memory = request.ctx.memory
|
||||||
|
|
||||||
|
wallet_connections = db_session.query(WalletConnection).filter(
|
||||||
|
WalletConnection.user_id == user.id,
|
||||||
|
WalletConnection.invalidated == False
|
||||||
|
).all()
|
||||||
|
for wallet_connection in wallet_connections:
|
||||||
|
wallet_connection.invalidated = True
|
||||||
|
|
||||||
|
db_session.commit()
|
||||||
|
return response.json({"success": True})
|
||||||
|
|
||||||
|
|
@ -96,16 +96,9 @@ async def t_inline_query_node_content(query: types.InlineQuery, memory=None, use
|
||||||
|
|
||||||
content_list = []
|
content_list = []
|
||||||
content = db_session.query(StoredContent).filter_by(hash=cid.content_hash_b58).first()
|
content = db_session.query(StoredContent).filter_by(hash=cid.content_hash_b58).first()
|
||||||
decrypted_content = None
|
content_prod = content.open_content(db_session)
|
||||||
if content:
|
encrypted_content = content_prod['encrypted_content']
|
||||||
if content.encrypted:
|
decrypted_content = content_prod['decrypted_content']
|
||||||
decrypted_content = db_session.query(StoredContent).filter_by(id=content.decrypted_content_id).first()
|
|
||||||
else:
|
|
||||||
decrypted_content = content
|
|
||||||
|
|
||||||
if not decrypted_content:
|
|
||||||
make_log("OwnedContent", f"Can't get decrypted content: {content.id}", level='warning')
|
|
||||||
return await query.answer(content_list, cache_time=1)
|
|
||||||
|
|
||||||
decrypted_content_meta = decrypted_content.json_format()
|
decrypted_content_meta = decrypted_content.json_format()
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -25,3 +25,13 @@ class WalletConnection(AlchemyBase):
|
||||||
|
|
||||||
user = relationship('User', uselist=False, back_populates='wallet_connections', foreign_keys=[user_id])
|
user = relationship('User', uselist=False, back_populates='wallet_connections', foreign_keys=[user_id])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ton_balance(self):
|
||||||
|
return round(int(self.meta.get('wallet_ton_balance', 0)) / 1e9, 9)
|
||||||
|
|
||||||
|
def json_format(self):
|
||||||
|
return {
|
||||||
|
'version': self.meta.get('wallet_contract_version', 'uv'), # uv = unknown version
|
||||||
|
'address': self.wallet_address,
|
||||||
|
'ton_balance': self.meta.get('wallet_ton_balance', 0),
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue