A Python Module for interacting with Portals Marketplace API
Project description
Portals Marketplace API
This is a simple module for interacting with Portals API.
Huge thanks to boostNT for his code sample of getting authData
Installation
pip install portalsmp
Change log
- Version 1.0 - First Beta release of the module. Working on most of the functions and bug fixes. Send your feedback to my telegram
Getting started (authData)
Unlike Tonnel Marketplace, every request in Portals needs to be authenticated.
The authentication system is also more complicated. There are currently 2 ways to get authData for Portals:
Telegram Web
- Pros: easy, doesn't require Telegram login.
- Cons: authData from Telegram Web is likely to have limited time (i think its around 1-7 days), so you will need to complete all the steps over and over
- Go to web.telegram.org
- Find @portals bot
- Open developer console -> Network tab
- Open @portals mini app
- Find any request related to portals-market.com (Network tab)
- Look for "Authorization" in request headers. It must look like this: "tma (auth)". Copy it entirely with "tma" at the start.
update_auth()
- Pros: you don't need to waste your time on web.telegram.org; if auth token is expired - its not a big problem, simply use update_auth() again
- Cons: api_id, api_hash and Telegram login needed. Pyrogram used.
Make sure to have latest version of pyrogram and tgcrypto before using
- Go to my.telegram.org/auth and create app
- Copy your api_id and api_hash
- Get your authData like this:
token = asyncio.run(update_auth(api_id, api_hash)) - Use it in your code
Some examples
search(gift_name="toy bear", model="wizard", limit=10, authData=token)
[
{
"id": "65c83c42-0ab7-42cc-a46d-6158057a7216",
"tg_id": "294992",
"collection_id": "060d4cef-3a21-47e6-98fc-cd338ae0b5e0",
"external_collection_number": 41771,
"owner_id": 488711606,
"name": "Toy Bear",
"photo_url": "https://nft.fragment.com/gift/toybear-41771.large.jpg",
"price": "44",
"attributes": [
{
"type": "model",
"value": "Wizard",
"rarity_per_mille": 1.5
},
{
"type": "symbol",
"value": "Champagne",
"rarity_per_mille": 0.2
},
{
"type": "backdrop",
"value": "Silver Blue",
"rarity_per_mille": 2
}
],
"listed_at": "2025-06-12T16:28:05.550053Z",
"status": "listed",
"animation_url": "https://nft.fragment.com/gift/toybear-41771.lottie.json",
"emoji_id": "5289667857599197149",
"has_animation": true,
"floor_price": "31.43",
"unlocks_at": "2025-03-10T11:04:26Z"
},...
Can be wrapped using PortalsGift class
gift = PortalsGift(search(gift_name="toy bear", model="wizard", limit=10, authData=token)[0])
gift.id - Portals ID of the gift
gift.tg_id - Telegram ID of the gift (external_collection_number)
gift.collection_id - Portals ID of the gift collection
gift.owner_id - ID of the gift owner
gift.name - Name of the gift
gift.photo_url - Photo URL of the gift (model + bg + symbol preview)
gift.price - Price of the gift
gift.model - Model name of the gift
gift.model_rarity - Model rarity of the gift
gift.symbol - Symbol of the gift
gift.symbol_rarity - Symbol rarity of the gift
gift.backdrop - Backdrop of the gift
gift.backdrop_rarity - Backdrop rarity of the gift
gift.listed_at - Time the gift was listed
gift.status - (usually listed)
gift.animation_url - Lottie animation URL of the gift
gift.emoji_id - Telegram custom emoji ID of the gift
gift.floor_price - Floor price of the gift (not the model)
gift.unlocks_at - Time of when the gift will be available to be minted
Functionality
search()
search(sort: str="price_asc", offset: int=0, limit: int=20, gift_name: str|list="", model: str|list="", backdrop: str|list="", symbol: str|list="", min_price: int=0, max_price: int=100000, authData: str="")
- Search for gifts with any filters.
- Available sorts:
"price_asc", "price_desc", "latest", "gift_id_asc", "gift_id_desc", "model_rarity_asc", "model_rarity_desc" offsetis a "page", but a little bit different. Basically you need to multiply yourlimitby a page you want to get.- Also now available to pass a list of gift names / models etc!
giftsFloors()
giftsFloors(authData: str="") -> dict
- Returns floors for all the gifts (short names only)
myPortalsGifts()
myPortalsGifts(offset: int=0, limit: int=20, listed: bool=True, authData: str="") -> list
- Returns a list containing your owned gifts.
listed=Truefor listed gifts,listed=Falsefor unlisted gifts.
myPoints()
myPoints(authData: str="") -> dict
- Returns information about your Portals points.
myBalances()
myBalances(authdata: str="") -> dict
- Returns information about your balances.
myActivity()
myActivity(offset: int=0, limit: int=20, authData: str="") -> list
- Returns a list object with all your activities on the market.
collections()
collections(limit: int=100, authData: str="") -> list
- Returns a list object with all collection names, floors, daily volumes etc.
marketActivity()
marketActivity(sort: str="latest", offset: int=0, limit: int=20, activityType: str="", gift_name: str|list="", model: str|list="", backdrop: str|list="", symbol: str|list="", min_price: int=0, max_price: int=100000, authData: str="") -> list
- Like
saleHistory()intonnelmp - Activity types:
"", "buy", "listing", "price_update", "offer" - Available sorts:
"price_asc", "price_desc", "latest", "gift_id_asc", "gift_id_desc", "model_rarity_asc", "model_rarity_desc"
sale()
sale(nft_id: str="", price: int|float=0,authData: str="") -> dict|None
- List a single nft for sale
bulkList()
bulkList(nfts: list= [], authData: str="") -> dict
- List multiple nfts for sale
- Not tested yet
buy()
buy(nft_id: str="", owner_id: int=0, price: int|float=0, authData: str="") -> dict|None
- Buy a single nft
- Will add bulkBuy soon
makeOffer()
makeOffer(nft_id: str="", offer_price: float=0, expiration_days: int=7, authData: str="") -> dict|None
- Make offer for nft
expiration_days: either 0 or 7. 0 means no expiration, 7 - 7 days.
cancelOffer()
cancelOffer(offer_id: str="", authData: str="") -> dict|None
- Cancel offer with known offer_id
changePrice()
changePrice(nft_id: str="", price: float=0, authData: str="") -> dict|None
- Change price of the listed nft
withdrawPortals()
withdrawPortals(amount: float=0, wallet: str="", authData: str="") -> dict
- Withdraw from portals to your TON wallet
- Warning: pass
UQaddresses at your own risk. May work only withEQaddresses.
Info
currently working on detailed documentation + remaining functions + bug fixes
my telegram: t.me/perfectlystill
chat: t.me/giftsdevschat
donations:
- ton:
UQC9f1mTuu2hKuBP_0soC5RVkq2mLp8uiPBBhn69vadU7h8W
made with ❤️ by bleach
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file portalsmp-1.0-py3-none-any.whl.
File metadata
- Download URL: portalsmp-1.0-py3-none-any.whl
- Upload date:
- Size: 9.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed8e869889e506a594a987709cd656246b812f08688fab40b1fd2d15cc54fd3d
|
|
| MD5 |
3aa3e3c550a05787d7f2ce5286a3f073
|
|
| BLAKE2b-256 |
388c9842fddc176c50eebadacca7e14ad77e4190343c6632beaad9a9e64dacf0
|