api – Frontend API package
Initialization module for API v2 package.
api.client – API client module
HTTP client for the ASA Stats backend (replaces in-process engine calls).
Every function here calls the closed backend over HTTP, authenticating with this
deployment’s credential (ASASTATS_API_KEY). This is the only seam between the
open app and the proprietary engine.
- exception api.client.BackendError[source]
Bases:
ExceptionRaised when the ASA Stats backend returns a non-success response.
- api.client.engine_request(scope, method, path, allowed_scopes, **kwargs)[source]
Call a scoped engine endpoint on behalf of a widget.
The widget builds its own
path; this primitive adds the deployment credential (via_request()) and refuses any scope the widget did not declare in its manifestengine_endpoints.- Parameters:
scope (str) – engine scope this call requires, e.g. “historic:evaluate”
method (str) – HTTP method
path (str) – engine path beneath the API root
allowed_scopes (list) – the widget manifest’s declared engine endpoints
- Returns:
requests.Response
- api.client.export_status(bundle)[source]
Return processing/finished status + report filename for
bundle.
- api.client.fetch_account_holdings(address, allowed_scopes)[source]
Return a single address’ opted-in holdings via the account:holdings scope.
The backend returns a mapping of asset id to
{name, unit, decimals, amount}(ALGO is id 0); every key present is, by definition, opted in.Defense-in-depth: the only caller already constrains address to w{58}, but encode the path segment so this helper can’t be misused to traverse.
- Parameters:
address (str) – single Algorand address
allowed_scopes (list) – the widget manifest’s declared engine endpoints
- Returns:
dict
- api.client.fetch_asset_matches(query, allowed_scopes)[source]
Return ranked asset metadata matches via the assets:lookup scope.
- Parameters:
query (str) – asset id, unit, or name/unit prefix
allowed_scopes (list) – the widget manifest’s declared engine endpoints
- Returns:
list
- api.client.fetch_capabilities()[source]
Return this deployment’s capabilities, e.g. {“permission”: <int>}.
- api.client.fetch_serialized_account(value, addresses='')[source]
Return serialized_data for a single address or a bundle.
- Parameters:
value – single address, or the bundle hash (this app’s local id)
addresses – space-joined addresses for multi-address bundles
api.data – API data module
Module containing public API constants.
api.helpers – API helper functions module
Module containing api app post-processing helpers.
- api.helpers.convert_account_values_to_usd(serialized_data, pricealgo)[source]
Return serialized account’s data with all the values converted to USD.
- Parameters:
serialized_data (dict) – serialized account’s data
pricealgo (str) – ALGO price in USDC
- Returns:
dict
- api.helpers.convert_asaitems_values_to_usd(asaitems, pricealgo)[source]
Return ASA items collection with all the values converted to USD.
- Parameters:
asaitems (list) – serialized evaluated account’s ASA items collection
pricealgo (str) – ALGO price in USDC
- Returns:
list
- api.helpers.convert_items_values_to_usd(items, pricealgo, process_keys=['value'])[source]
Return collection of dictionaries with all the “values” keys converted to USD.
- Parameters:
items (list) – collection of dictionaries having value key
pricealgo (str) – ALGO price in USDC
- Returns:
list
- api.helpers.convert_nftcollections_values_to_usd(nftcollections, pricealgo)[source]
Return serialized account’s NFT collections with all the values converted to USD.
- Parameters:
nftcollections (list) – serialized evaluated account’s NFT collections
pricealgo (str) – ALGO price in USDC
- Returns:
list
- api.helpers.extract_account_entities(serialized_data)[source]
Return all programs, providers and NFT markets instances found in account’s data.
- Parameters:
serialized_data (dict) – serialized account’s data
- Variables:
programs – collection of all dApp programs found in account
- Returns:
dict
- api.helpers.extract_account_headers(serialized_data)[source]
Return only ASA item and NFT collections headers from provided serialized data.
- Parameters:
serialized_data (dict) – serialized account’s data
- Returns:
dict
- api.helpers.extract_asaitem(asset_id, asaitems)[source]
Return ASA item collection for provided asset_id from provided serialized data.
- Parameters:
asset_id (int) – Algorand standard asset identifier
asaitems (dict) – serialized evaluated account’s ASA items collection
- Returns:
dict
- api.helpers.extract_asaitems_headers(asaitems)[source]
Return only ASA item headers from provided ASA items serialized data.
- Parameters:
asaitems (dict) – serialized evaluated account’s ASA items collection
- Returns:
list generator
- api.helpers.extract_asaitems_program(program, asaitems)[source]
Return only ASA item programs defined by program slug.
- Parameters:
program (str) – dApp program slug
asaitems (dict) – serialized evaluated account’s ASA items collection
- Returns:
dict generator
- api.helpers.extract_asaitems_program_type(program_type, asaitems)[source]
Return only ASA item programs which type is defined by provided program_type.
- Parameters:
program_type (str) – DeFi program type
asaitems (dict) – serialized evaluated account’s ASA items collection
- Returns:
dict generator
- api.helpers.extract_asaitems_provider(provider, asaitems)[source]
Return only ASA item programs from provided dApp provider.
- Parameters:
provider (str) – unique dApp provider slug
asaitems (dict) – serialized evaluated account’s ASA items collection
- Returns:
dict generator
- api.helpers.extract_nftcollection(collection, nftcollections)[source]
Return NFT collection item for provided collection from provided data.
- Parameters:
collection (str) – NFT collection name
nftcollections (dict) – serialized evaluated account’s NFT collections
- Returns:
dict
- api.helpers.extract_nftcollections_headers(nftcollections)[source]
Return only NFT collections headers from provided serialized NFT collections.
- Parameters:
nftcollections (dict) – serialized evaluated account’s NFT collections
- Returns:
list generator
- api.helpers.extract_nftcollections_market(market, nftcollections)[source]
Return only NFT collections having items from provided NFT market.
- Parameters:
market (str) – unique NFT market slug
nftcollections (dict) – serialized evaluated account’s NFT collections
- Returns:
dict generator
- api.helpers.extract_nftcollections_sale_type(sale_type, nftcollections)[source]
Return only NFT collections which sale type is defined by provided sale_type.
- Parameters:
sale_type (str) – NFT sale type
nftcollections (dict) – serialized evaluated account’s NFT collections
- Returns:
dict generator
- api.helpers.extract_nftitem(nft_id, nftcollections)[source]
Return NFT item for provided nft_id from provided serialized data.
- Parameters:
nft_id (int) – Algorand standard asset identifier
nftcollections (dict) – serialized evaluated account’s NFT collections
- Returns:
dict
- api.helpers.extract_nftitems_from_nftcollections(nftcollections)[source]
Return all NFT items from provided serialized NFT collections data.
- Parameters:
nftcollections (dict) – serialized evaluated account’s NFT collections
- Returns:
dict generator
- api.helpers.extract_nftitems_headers(nftitems)[source]
Return only NFT items headers from provided serialized NFT items.
- Parameters:
nftitems (dict) – serialized evaluated account’s NFT items
- Returns:
dict generator
- api.helpers.extract_nftitems_market(market, nftitems)[source]
Return only NFT items having entries from provided NFT market.
- Parameters:
market (str) – unique NFT market slug
nftitems (dict) – serialized evaluated account’s NFT items
- Returns:
list
- api.helpers.extract_nftitems_sale_type(sale_type, nftitems)[source]
Return only NFT items which sale type is defined by provided sale_type.
- Parameters:
sale_type (str) – NFT sale type
nftitems (dict) – serialized evaluated account’s NFT items
- Returns:
list
- api.helpers.extract_top_account_items(serialized_data, limit)[source]
Return top valued limit number of ASA and/or NFT collections items for account.
- Parameters:
serialized_data (dict) – serialized account’s data
limit (str) – limit number of returned items to this number
- Variables:
asaitems – serialized evaluated account’s ASA items collection
nftcollections – serialized evaluated account’s NFT collections
items – combined ASA and NFT collections items
boundary – maximum value that shouldn’t be included in top items
- Returns:
dict
- api.helpers.get_lib_doc_excludes()[source]
Return list of all classes where docstrings is omitted from API schema.
- Returns:
list
- api.helpers.preprocessing_filter_spec(endpoints)[source]
Return list of all endpoint taht should be included in API scheme.
- Variables:
filtered – list of all enpoints to include in schema
- Returns:
list
- api.helpers.validate_address(value)[source]
Raise ValidationError if value isn’t a valid public Algorand address.
- Variables:
value – public Algorand address
- Returns:
str
- api.helpers.validate_bundle(value)[source]
Return value if it contains a collection of Algorand addresses.
Raise ValidationError if it doesn’t.
- Parameters:
value (str) – collection of Algorand addresses or .algo names
- Variables:
addresses – collection of addresses and .algo names
- Returns:
str
- api.helpers.validate_nfd_name(nfd_name)[source]
Return bundle or public Algorand address connected with provided NFD name.
Raise ValidationError if provided value doesn’t represent a valid NFD name.
- Parameters:
nfd_name (str) – NFD .algo name
- Variables:
addresses – collection of public Algorand addresses
- Returns:
str
- api.helpers.validate_raw_addresses(raw)[source]
Return collection of public Algorand addresses or single address from raw.
Raise ValidationError if provided value isn’t valid.
- Parameters:
raw (str) – collection of public Algorand addre4sses and/or NFD .algo names
- Variables:
collection – collection of public Algorand addresses
- Returns:
str
api.main – API main module
Module containing public functions for API v2 package.
- api.main.account_entities(serialized_data)[source]
Return all programs, providers and NFT markets instances found in account’s data.
- Parameters:
serialized_data (dict) – serialized account’s data
- Returns:
list
- api.main.fetch_and_serialize_account(value, addresses)[source]
Fetch and serialize an account for a single address or a bundle.
valueis the URL path segment as the visitor supplied it — a single address, or a bundle hash that may be an ancient (pre-sort) bookmark. For bundles we recompute the canonical hash so the engine’sbundle_from_addressescross-check matches regardless of which historical hash they arrived with. A single address is passed through unchanged.- Parameters:
value (str) – single address, or the bundle hash
addresses (str) – space-joined addresses for a multi-address bundle
- api.main.filtered_asaitem(asset_id, serialized_data, query_params)[source]
Return ASA item collection for provided asset_id from provided serialized data.
- Parameters:
asset_id (int) – Algorand standard asset identifier
serialized_data (dict) – serialized account’s data
query_params (
QueryDict) – additional filtering conditions
- Variables:
asaitem – serialized ASA item collection
- Returns:
dict
- api.main.filtered_nftcollection(collection, serialized_data, query_params)[source]
Return NFT icollection item for provided collection from provided data.
- Parameters:
collection (str) – NFT collection name
serialized_data (dict) – serialized account’s data
query_params (
QueryDict) – additional filtering conditions
- Variables:
nftcollection – serialized NFT collection
- Returns:
dict
- api.main.filtered_nftitem(nft_id, serialized_data, query_params)[source]
Return NFT item for provided nft_id from provided serialized data.
- Parameters:
nft_id (int) – Algorand standard asset identifier
serialized_data (dict) – serialized account’s data
query_params (
QueryDict) – additional filtering conditions
- Variables:
nftitem – serialized NFT item collection
- Returns:
dict
- api.main.processed_account(serialized_data, query_params)[source]
Return processed account data based on values from query_params.
- Parameters:
serialized_data (dict) – serialized evaluated account’s data
query_params (
QueryDict) – additional filtering conditions
- Variables:
limit – limit number of returned ASA items to this number
- Returns:
dict
- api.main.processed_asaitems(serialized_data, query_params)[source]
Return processed ASA items collection based on values from query_params.
- Parameters:
serialized_data (dict) – serialized account’s data
query_params (
QueryDict) – additional filtering conditions
- Variables:
asaitems – serialized evaluated account’s ASA items collection
provider – unique dApp provider slug
program – unique dApp program slug
program_type – dApp program type
limit – limit number of returned ASA items to this number
- Returns:
dict
- api.main.processed_nftcollections(serialized_data, query_params)[source]
Return processed NFT collections based on values from query_params.
- Parameters:
serialized_data (dict) – serialized account’s data
query_params (
QueryDict) – additional filtering conditions
- Variables:
nftcollections – serialized evaluated account’s NFT collections
market – unique NFT market slug
sale_type – NFT sale type
limit – limit number of returned NFT collections to this number
- Returns:
list
- api.main.processed_nftitems(serialized_data, query_params)[source]
Return processed NFT items based on values from query_params.
- Parameters:
serialized_data (dict) – serialized account’s data
query_params (
QueryDict) – additional filtering conditions
- Variables:
nftitems – serialized evaluated account’s NFT items
market – unique NFT market slug
sale_type – NFT sale type
limit – limit number of returned NFT collections to this number
- Returns:
dict
api.permissions – API permissions module
Module containing core app’s custom permission classes.
api.serializers – API serializers module
Module containing api app’s serializers.
- class api.serializers.AccountInfoSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize account information object.
- Variables:
AccountInfoSerializer.addresses – collection of public addresses
AccountInfoSerializer.bundle – unique hash for public Algorand addresses
AccountInfoSerializer.values_in – currency of all serialized values fields
AccountInfoSerializer.online – does any address participate in consensus
AccountInfoSerializer.points – total number of Algoland points
- class api.serializers.AsaItemProgramSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize asset dApp program object.
- Variables:
AsaItemProgramSerializer.program – program’s serializer
AsaItemProgramSerializer.value – asset’s value in ALGO
AsaItemProgramSerializer.amount – asset’s amount
AsaItemProgramSerializer.proxy – placeholder
AsaItemProgramSerializer.distribution – user’s program distribution serializer
AsaItemProgramSerializer.linked – serilazer of data linked to ASA item program
- to_representation(instance)[source]
Return collection of non-empty field-value pairs.
- Parameters:
instance (
AsaItemProgramSerializer) – ASA item program’s serializer instance- Variables:
result – ASA item program serializer’s field name and value pairs
- Returns:
dict
- class api.serializers.AsaItemSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize account’s ASA item.
- Variables:
AsaItemSerializer.value – asset’s total value in ALGO
AsaItemSerializer.asset – asset’s serializer
AsaItemSerializer.amount – asset’s total amount
AsaItemSerializer.price – ASA’s price in ALGO
AsaItemSerializer.programs – collection of asset’s program serializers
- class api.serializers.AsaLinkSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize dApp program object.
- Variables:
AsaLinkSerializer.provider – link’s provider serializer
AsaLinkSerializer.link – link to ASA page on provider’s website
AsaLinkSerializer.title – link’s description
- class api.serializers.AsaProgramSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize dApp program object.
- Variables:
AsaProgramSerializer.type – program’s type
AsaProgramSerializer.name – program’s name
AsaProgramSerializer.provider – program’s provider
AsaProgramSerializer.url – program’s URL
AsaProgramSerializer.code – unique program’s code
- to_representation(instance)[source]
Return collection of non-empty field-value pairs.
- Parameters:
instance (
AsaProgramSerializer) – ASA program’s serializer instance- Variables:
result – ASA program serializer’s field name and value pairs
- Returns:
dict
- class api.serializers.AsaSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize ASA object.
- Variables:
AsaSerializer.id – asset’s unique identifier
AsaSerializer.name – asset’s name
AsaSerializer.unit – asset’s unit name
AsaSerializer.total – asset’s total supply
AsaSerializer.decimals – asset’s number of digits after decimal point
AsaSerializer.url – asset’s URL field
AsaSerializer.links – asset’s offchain links
- class api.serializers.BundleHashFromAddressesSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize collection of addresses and .algo names.
- Variables:
BundleRetrieveSerializer.addresses – collection of public Algorand addresses
- class api.serializers.BundleHashSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize bundle hash.
- Variables:
BundleRetrieveSerializer.bundle – unique hash for public Algorand addresses
- class api.serializers.DistributionLinkSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize dApp program distribution link object.
- Variables:
DistributionLinkSerializer.provider – program distribution’s provider
DistributionLinkSerializer.text – program distribution’s link text
DistributionLinkSerializer.url – program distribution’s URL
- class api.serializers.DistributionSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize asset dApp program distribution object.
- Variables:
DistributionSerializer.value – asset’s value in ALGO
DistributionSerializer.amount – asset’s amount
DistributionSerializer.links – program distribution link serializer
- class api.serializers.EntitiesSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize account’s programs, providers, and markets.
- Variables:
EntitiesSerializer.programs – account’s dApp programs
EntitiesSerializer.providers – account’s dApp providers
EntitiesSerializer.markets – account’s NFT markets
- class api.serializers.EvaluatedAccountSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize evaluated account.
- Variables:
EvaluatedAccountSerializer.account_info – extra account data serializer
EvaluatedAccountSerializer.system_info – system info object serializer
EvaluatedAccountSerializer.total – total values and prices serializer
EvaluatedAccountSerializer.asaitems – collection of ASA item serializers
EvaluatedAccountSerializer.nfts – NFT collection serializers
EvaluatedAccountSerializer.notevals – collection of Noteval serializers
- class api.serializers.LinkedDataSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize data linked to ASA program item.
- Variables:
LinkedDataSerializer.provider – linked data’s provider serializer
LinkedDataSerializer.text – linked data accompanied text
LinkedDataSerializer.link – link to provider’s website
LinkedDataSerializer.value – asset’s value in ALGO
LinkedDataSerializer.amount – asset’s amount
LinkedDataSerializer.balance – asset’s balance
LinkedDataSerializer.info – addintional information for linked data
LinkedDataSerializer.id – unique identifier for linked data
- to_representation(instance)[source]
Return collection of non-empty field-value pairs.
- Parameters:
instance (
LinkedDataSerializer) – linked data’s serializer instance- Variables:
result – linked data serializer’s field name and value pairs
- Returns:
dict
- class api.serializers.NfdNameSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize .algo name.
- Variables:
NfdNameSerializer.nfd_name – NFD .algo name
- class api.serializers.NftCollectionSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize NFT object.
- Variables:
NftCollectionSerializer.value – NFT collection’s value in ALGO
NftCollectionSerializer.name – NFT’s collection name
NftCollectionSerializer.amount – total number of NFTs in collection
NftCollectionSerializer.nfts – collection’s NFT item serializers
NftCollectionSerializer.floor – collection’s minimum price listing
- class api.serializers.NftCurrencySerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize NFT currency object.
- Variables:
NftCurrencySerializer.amount – currency’s amount
NftCurrencySerializer.asset – asset’s serializer
- class api.serializers.NftItemSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize user’s NFT item object.
- Variables:
NftItemSerializer.value – NFT’s value in ALGO
NftItemSerializer.nft – NFT serializer
NftItemSerializer.amount – NFT’s amount
NftItemSerializer.price – NFT’s price in ALGO
- class api.serializers.NftListingSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize NFT listing object.
- Variables:
NftListingSerializer.price – NFT’s listed price in ALGO
NftListingSerializer.market – NFT market provider’s serializer
NftListingSerializer.link – link to listed NFT’s page on NFT market website
NftListingSerializer.currency – NFT listing’s currency object
- class api.serializers.NftPurchaseSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize NFT purchase object.
- Variables:
NftPurchaseSerializer.price – NFT’s listed price in ALGO
NftPurchaseSerializer.market – NFT market provider’s serializer
NftPurchaseSerializer.link – link to transaction’s page in blockchain explorer
NftPurchaseSerializer.epoch – seconds since epoch when purchase happened
NftPurchaseSerializer.currency – NFT purchase’s currency object
- class api.serializers.NftSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize NFT object.
- Variables:
NftSerializer.id – unique NFT identifier
NftSerializer.name – NFT’s name
NftSerializer.unit – NFT’s unit name
NftSerializer.total – NFT’s total supply
NftSerializer.decimals – NFT’s number of digits after decimal point
NftSerializer.creator – NFT’s creator address
NftSerializer.image – relative path to NFT’s image representation
NftSerializer.thumbnail – relative path to NFT’s thumbnail
NftSerializer.urls – NFTs URL serializers
NftSerializer.listings – NFT’s listing serializer
NftSerializer.last_purchase – NFT’s last purchase serializer
NftSerializer.max_purchase – NFT’s maximum purchase serializer
NftSerializer.title – NFT’s title metadata
NftSerializer.description – NFT’s description attribute
NftSerializer.rarity – NFT’s rarity attribute
NftSerializer.traits – NFT’s traits serializers
- to_representation(instance)[source]
Return collection of non-empty field-value pairs.
- Parameters:
instance (
AsaItemProgramSerializer) – ASA item program’s serializer instance- Variables:
result – ASA item program serializer’s field name and value pairs
- Returns:
dict
- class api.serializers.NftTraitSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize NFT trait object.
- Variables:
NftTraitSerializer.name – NFT trait name
NftTraitSerializer.value – NFT trait value
- class api.serializers.NftUrlSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize NFT URL object.
- Variables:
NftUrlSerializer.typ – NFT URL type
NftUrlSerializer.url – URL value
- class api.serializers.NotevalItemSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize not-evaluated asset object.
- Variables:
NotevalItemSerializer.asset – asset’s serializer
NotevalItemSerializer.amount – asset’s amount
NotevalItemSerializer.programs – collection of asset’s program serializers
- class api.serializers.ProviderSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize dApp provider.
- Variables:
ProviderSerializer.name – provider’s unique name
ProviderSerializer.info – provider’s information
- to_representation(instance)[source]
Return collection of non-empty field-value pairs.
- Parameters:
instance (
ProviderSerializer) – provider’s serializer instance- Variables:
result – provider serializer’s field name and value pairs
- Returns:
dict
- class api.serializers.SystemInfoSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize system information object.
- Variables:
SystemInfoSerializer.warning – system’s warning message
SystemInfoSerializer.information – system’s information message
- to_representation(instance)[source]
Return collection of non-empty field-value pairs.
- Parameters:
instance (
SystemInfoSerializer) – system information’s serializer instance- Variables:
result – system information serializer’s field name and value pairs
- Returns:
dict
- class api.serializers.TotalSerializer(*args, **kwargs)[source]
Bases:
SerializerSerialize total object.
- Variables:
TotalSerializer.algo – total ALGO amount
TotalSerializer.asa – total value of ASAs in ALGO
TotalSerializer.nft – total value of NFTs in ALGO
TotalSerializer.total – total account value in ALGO
TotalSerializer.totalusdc – total account value in USDC
TotalSerializer.priceusdc – current ALGO price in USDC
TotalSerializer.pricealgo – current USDC price in ALGO
TotalSerializer.noteval – total number of not evaluated assets
TotalSerializer.totalwonft – account’s total value without NFTs in ALGO
TotalSerializer.totalwonftusdc – account’s total value without NFTs in USDC
api.structs – API data structures module
Module containing API data structures.
- class api.structs.AccountInfo(addresses, bundle, values_in, online, points)
Bases:
tuple- addresses
Alias for field number 0
- bundle
Alias for field number 1
- online
Alias for field number 3
- points
Alias for field number 4
- values_in
Alias for field number 2
- class api.structs.AsaItem(value, asset, amount, price, programs)
Bases:
tuple- amount
Alias for field number 2
- asset
Alias for field number 1
- price
Alias for field number 3
- programs
Alias for field number 4
- value
Alias for field number 0
- class api.structs.AsaItemProgram(program, value, amount, proxy, distribution, linked)
Bases:
tuple- amount
Alias for field number 2
- distribution
Alias for field number 4
- linked
Alias for field number 5
- program
Alias for field number 0
- proxy
Alias for field number 3
- value
Alias for field number 1
- class api.structs.AsaLink(provider, link, title)
Bases:
tuple- link
Alias for field number 1
- provider
Alias for field number 0
- title
Alias for field number 2
- class api.structs.AsaProgram(type, name, provider, url, code)
Bases:
tuple- code
Alias for field number 4
- name
Alias for field number 1
- provider
Alias for field number 2
- type
Alias for field number 0
- url
Alias for field number 3
- class api.structs.Distribution(value, amount, link)
Bases:
tuple- amount
Alias for field number 1
- link
Alias for field number 2
- value
Alias for field number 0
- class api.structs.DistributionLink(provider, text, url)
Bases:
tuple- provider
Alias for field number 0
- text
Alias for field number 1
- url
Alias for field number 2
- class api.structs.Entities(programs, providers, markets)
Bases:
tuple- markets
Alias for field number 2
- programs
Alias for field number 0
- providers
Alias for field number 1
- class api.structs.LinkedData(provider, text, link, value, amount, balance, info, id)
Bases:
tuple- amount
Alias for field number 4
- balance
Alias for field number 5
- id
Alias for field number 7
- info
Alias for field number 6
- link
Alias for field number 2
- provider
Alias for field number 0
- text
Alias for field number 1
- value
Alias for field number 3
- class api.structs.LpFarming(code, name, baselink)
Bases:
tuple- baselink
Alias for field number 2
- code
Alias for field number 0
- name
Alias for field number 1
- class api.structs.LpProvider(code, name, baselink)
Bases:
tuple- baselink
Alias for field number 2
- code
Alias for field number 0
- name
Alias for field number 1
- class api.structs.Nft(id, name, unit, total, decimals, creator, image, thumbnail, urls, listings, floor, last_purchase, max_purchase, title, description, rarity, traits)
Bases:
tuple- creator
Alias for field number 5
- decimals
Alias for field number 4
- description
Alias for field number 14
- floor
Alias for field number 10
- id
Alias for field number 0
- image
Alias for field number 6
- last_purchase
Alias for field number 11
- listings
Alias for field number 9
- max_purchase
Alias for field number 12
- name
Alias for field number 1
- rarity
Alias for field number 15
- thumbnail
Alias for field number 7
- title
Alias for field number 13
- total
Alias for field number 3
- traits
Alias for field number 16
- unit
Alias for field number 2
- urls
Alias for field number 8
- class api.structs.NftCollection(value, name, amount, nfts)
Bases:
tuple- amount
Alias for field number 2
- name
Alias for field number 1
- nfts
Alias for field number 3
- value
Alias for field number 0
- class api.structs.NftCurrency(amount, asset)
Bases:
tuple- amount
Alias for field number 0
- asset
Alias for field number 1
- class api.structs.NftItem(value, nft, amount, price)
Bases:
tuple- amount
Alias for field number 2
- nft
Alias for field number 1
- price
Alias for field number 3
- value
Alias for field number 0
- class api.structs.NftListing(price, market, link, currency)
Bases:
tuple- currency
Alias for field number 3
- link
Alias for field number 2
- market
Alias for field number 1
- price
Alias for field number 0
- class api.structs.NftPurchase(price, market, link, epoch, currency)
Bases:
tuple- currency
Alias for field number 4
- epoch
Alias for field number 3
- link
Alias for field number 2
- market
Alias for field number 1
- price
Alias for field number 0
- class api.structs.NftTrait(name, value)
Bases:
tuple- name
Alias for field number 0
- value
Alias for field number 1
- class api.structs.NftUrl(typ, url)
Bases:
tuple- typ
Alias for field number 0
- url
Alias for field number 1
- class api.structs.Provider(name, info)
Bases:
tuple- info
Alias for field number 1
- name
Alias for field number 0
- class api.structs.SystemInfo(warning, information)
Bases:
tuple- information
Alias for field number 1
- warning
Alias for field number 0
- class api.structs.Total(algo, asa, nft, total, totalusdc, priceusdc, pricealgo, noteval, totalwonft, totalwonftusdc)
Bases:
tuple- algo
Alias for field number 0
- asa
Alias for field number 1
- nft
Alias for field number 2
- noteval
Alias for field number 7
- pricealgo
Alias for field number 6
- priceusdc
Alias for field number 5
- total
Alias for field number 3
- totalusdc
Alias for field number 4
- totalwonft
Alias for field number 8
- totalwonftusdc
Alias for field number 9
api.urls – API URL configuration module
api.views – API views module
api.widgets – API widgets module
Module containing classes and functions for accessing API through widgets system.
- class api.widgets.BearerAuth[source]
Bases:
AuthBaseRequests auth class adding the widgets API bearer token to a request.
- api.widgets.bundle_and_addresses_from_path(url_path, force_bundle=True)[source]
Return bundle and Algorand addresses defined by provided url_path.
- Parameters:
url_path (str) – address or bundle value found in URL
- Variables:
bundle – hash made from public Algorand addresses
addresses – space separated collection of public Algorand addresses
- Returns:
two-tuple
- api.widgets.widgets_api_view(endpoint, filter='')[source]
Fetch and return decoded JSON from a widgets API endpoint.
- Parameters:
endpoint (str) – API endpoint path segment to request
filter (str) – optional query string appended to the request URL
- Variables:
api_url – fully qualified URL the request is sent to
response – HTTP response returned by the widgets API
- Returns:
dict
api.tests – API unit-tests package
Initialization module for api package unit tests.
config – Main configuration package
Initialization module for frontend project.
config.asgi – Asynchronous application module
ASGI config for website project.
It exposes the ASGI callable as a module-level variable named application.
For more information on this file, see https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/
config.routing – Application routing module
Website websocket routes configuration module.
config.settings – Project settings package
Initialization module for Django settings.
config.settings.base – Base settings
Django settings for the website project.
Generated by ‘django-admin startproject’ using Django 3.2.9.
For more information on this file, see https://docs.djangoproject.com/en/3.2/topics/settings/
For the full list of settings and their values, see https://docs.djangoproject.com/en/3.2/ref/settings/
config.settings.development – Development settings
Django settings module used in development.
config.settings.production – Production settings
config.settings.testing – Testing settings
config.sitemaps – Sitemaps configuration module
- class config.sitemaps.PrioritizedStaticViewSitemap[source]
Bases:
StaticViewSitemapStatic pages sitemap creator class for pages with highest priority.
Add a datetime object as the third value in tuple for pubdate different than PUBLISHING_DATE-
- Variables:
PrioritizedStaticViewSitemap.priority – defaults to highest priority
PrioritizedStaticViewSitemap.protocol – defines presented protocol
- priority = 1.0
- protocol = 'http'
- class config.sitemaps.StaticViewSitemap[source]
Bases:
SitemapStatic pages sitemap creator class.
Priority 1.0 means higher priority relative to site.
- Variables:
StaticViewSitemap.priority – defaults to 0.5
StaticViewSitemap.protocol – presented protocol (‘https’ or ‘http’)
changefreq – defines frequency for crawlers, “daily”, “weekly”, …
- changefreq = 'daily'
- items()[source]
Set static pages names to include in sitemap file.
Add a datetime object as the third value in tuple for pubdate different than PUBLISHING_DATE-
- Returns:
tuple of page names
- lastmod(args)[source]
Return date when page in args changed.
We set it to constant value if date isn’t set in args. If there’s a third element in tuple we return it if it’s a datetime object.
- Returns:
datetime
- location(args)[source]
Return reversed url for given page slug and eventual argument.
- Parameters:
args (string, (string,)) – name, (args)
- Returns:
page url
- priority = 0.5
- protocol = 'http'
config.urls – Main website URL configuration module
config.wsgi – WSGI application module
WSGI config for website project.
It exposes the WSGI callable as a module-level variable named application.
For more information on this file, see https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/
config.tests – Project unit-tests package
Initialization module for main project unit tests.
core – Main application package
Initialization module for core app package.
core.apps – Main application configuration module
Module containing core app configuration.
core.context_processors – Context processors module
Inject this deployment’s backend capabilities (Gate A) into every template.
- core.context_processors.deployment_capabilities(request)[source]
Return {“deployment_capabilities”: {“permission”: <int>, …}}.
Cached briefly so we don’t hit the backend on every request. On failure we return a zero-permission stub so gated links simply don’t render.
core.exportpermissions – Export permissions module
Size-scaled tier gate shared by the browsing user (Gate B) and the deployment (Gate A).
Permission is a single integer (on-chain for users; returned by the backend capabilities endpoint for the deployment) compared against tier thresholds, with the required tier rising as the bundle’s address count grows.
- core.exportpermissions.tier_allows(permission_value, size, limits=None)[source]
Return True if
permission_valuemay export a bundle ofsize.Free (no-tier) users may export up to the
freelimit; paid tiers extend it.permission_valueisNonefor a no-tier user, which is allowed within the free range and rejected beyond it.- Parameters:
permission_value – integer permission (user’s or deployment’s) or None
size – number of Algorand addresses in the bundle
limits – address-count limits per tier; resolved from settings if None
- Returns:
bool
core.forms – Main application forms module
Module containing code dealing with core app’s forms.
- class core.forms.AddressForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None, bound_field_class=None)[source]
Bases:
FormForm class for entering Algorand address(es) and/or ANS/NFD name(s).
- Variables:
AddressForm.address – field holding Algorand address or ANS/NFD name
AddressForm.bundle – field holding multiple Algorand addresses or ANS/NFD names
- base_fields = {'address': <django.forms.fields.CharField object>, 'bundle': <django.forms.fields.CharField object>}
- clean()[source]
Raise ValidationError if address field isn’t a valid Algorand address.
Return address or multiple addresses separated by spaces.
- Variables:
data – multiple entries data from bundle field
address_data – data from address field
bundle – parsed collection of addresses
- Returns:
str
- declared_fields = {'address': <django.forms.fields.CharField object>, 'bundle': <django.forms.fields.CharField object>}
- property media
Return all media required to render the widgets on this form.
- class core.forms.BaseBundleNameForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, instance=None, use_required_attribute=None, renderer=None)[source]
Bases:
ModelFormBase model form class for creating and editing bundle names.
- Variables:
name – field holding bundle’s name
addresses – field holding bundle’s addresses
public – field indicating if bundle’s name is publicly available
- class Meta[source]
Bases:
object- error_messages = {'addresses': {'max_length': 'Too long addresses field', 'required': 'A public Algorand address is required'}, 'name': {'max_length': 'Bundle name should contain no more than 50 characters', 'required': 'This field is required'}}
- fields = ('name', 'addresses', 'public')
- model
alias of
BundleName
- base_fields = {'addresses': <django.forms.fields.CharField object>, 'name': <django.forms.fields.CharField object>, 'public': <django.forms.fields.BooleanField object>}
- clean()[source]
Raise ValidationError if addresses field doesn’t contain valid addresses
or if integrity checks have failed.
- Returns:
dict
- declared_fields = {'addresses': <django.forms.fields.CharField object>, 'name': <django.forms.fields.CharField object>, 'public': <django.forms.fields.BooleanField object>}
- property media
Return all media required to render the widgets on this form.
- class core.forms.CustomSignupForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None, bound_field_class=None)[source]
Bases:
FormSubclass of :class`Form` with overridden Form.signup method.
- base_fields = {}
- declared_fields = {}
- property media
Return all media required to render the widgets on this form.
- class core.forms.DeactivateProfileForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None, bound_field_class=None)[source]
Bases:
FormForm class for deactivating current user.
Only requirement is to correctly populate captcha field. User object is taken from the request object.
- Variables:
captcha – field holding value that is going to be compared with captcha
- base_fields = {'captcha': <captcha.fields.CaptchaField object>}
- deactivate_profile(request)[source]
Logout and deactivate given request’s user in database.
- Parameters:
request (
HttpRequest) – http request
- declared_fields = {'captcha': <captcha.fields.CaptchaField object>}
- property media
Return all media required to render the widgets on this form.
- class core.forms.ExportDownloadForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None, bound_field_class=None)[source]
Bases:
FormForm class for downloading compressed file with CSV file(s) inside.
- Variables:
ExportDownloadForm.agree – field user needs to check to proceeed
- base_fields = {'agree': <django.forms.fields.BooleanField object>}
- declared_fields = {'agree': <django.forms.fields.BooleanField object>}
- property media
Return all media required to render the widgets on this form.
- class core.forms.ExportForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None, bound_field_class=None)[source]
Bases:
FormForm class for entering arguments for CSV files processing.
- Variables:
ExportForm.provider – field holding tax software provider
ExportForm.use_mve – field indicating use of maximum value engine
ExportForm.non_zero – field indicating adding additional non-tero values CSV file
- base_fields = {'non_zero': <django.forms.fields.BooleanField object>, 'provider': <django.forms.fields.ChoiceField object>, 'use_mve': <django.forms.fields.BooleanField object>}
- clean()[source]
Raise ValidationError if provider isn’t Koinly.
- Variables:
provider – provider field’s value
- declared_fields = {'non_zero': <django.forms.fields.BooleanField object>, 'provider': <django.forms.fields.ChoiceField object>, 'use_mve': <django.forms.fields.BooleanField object>}
- property media
Return all media required to render the widgets on this form.
- class core.forms.ProfileBundleNameForm(for_profile, *args, **kwargs)[source]
Bases:
BaseBundleNameFormForm class for creating and editing bundle names.
- base_fields = {'addresses': <django.forms.fields.CharField object>, 'name': <django.forms.fields.CharField object>, 'public': <django.forms.fields.BooleanField object>}
- declared_fields = {'addresses': <django.forms.fields.CharField object>, 'name': <django.forms.fields.CharField object>, 'public': <django.forms.fields.BooleanField object>}
- property media
Return all media required to render the widgets on this form.
- class core.forms.ProfileExplorerForm(*args, **kwargs)[source]
Bases:
ModelFormForm for choosing the profile’s preferred blockchain explorer.
Explorer choices come from the explorer registry (Allo first), so adding a provider there surfaces it here with no change to this form. The right to submit this form is gated on the Intro tier; the view enforces that and the template renders the control disabled (routing a click to subscriptions) for users below it.
- base_fields = {'preferred_explorer': <django.forms.fields.CharField object>}
- declared_fields = {}
- property media
Return all media required to render the widgets on this form.
- class core.forms.ProfileFormSet(data=None, files=None, instance=None, save_as_new=False, prefix=None, queryset=None, **kwargs)
Bases:
ProfileInlineFormFormset for editing profile’s data. It is instantiated together with
UpdateUserFormform instance in the common user/profile editing process.- absolute_max = 1001
- can_delete = True
- can_delete_extra = True
- can_order = False
- edit_only = False
- extra = 3
- fk = <django.db.models.fields.related.OneToOneField: user>
- form
alias of
ProfileForm
- max_num = 1
- min_num = 0
- renderer = None
- validate_max = False
- validate_min = False
- class core.forms.ProfileInlineForm(data=None, files=None, instance=None, save_as_new=False, prefix=None, queryset=None, **kwargs)[source]
Bases:
BaseInlineFormSetForm class for editing user profile’s data.
- Variables:
permission – user’s permission on website
- address = <django.forms.fields.CharField object>
- class core.forms.ProfileRouterForm(*args, **kwargs)[source]
Bases:
ModelFormForm for choosing the profile’s preferred smart router.
Router choices are discovered (manifests with
category = "swap"), so a newly added router widget appears here with no change to this form.- base_fields = {'preferred_router': <django.forms.fields.CharField object>}
- declared_fields = {}
- property media
Return all media required to render the widgets on this form.
- class core.forms.UpdateUserForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, instance=None, use_required_attribute=None, renderer=None)[source]
Bases:
ModelFormModel form class for editing user’s data.
- class Meta[source]
Bases:
object- error_messages = {'first_name': {'max_length': 'User name is limited to 30 characters only'}, 'last_name': {'max_length': 'User last name is limited to 150 characters only'}}
- fields = ('first_name', 'last_name')
- labels = {'first_name': 'First name', 'last_name': 'Last name'}
- model
alias of
User
- base_fields = {'first_name': <django.forms.fields.CharField object>, 'last_name': <django.forms.fields.CharField object>}
- declared_fields = {}
- property media
Return all media required to render the widgets on this form.
core.helpers – Main application helpers module
Module containing core app helper functions.
- core.helpers.addresses_from_raw(raw, address_data='', max_bundle_size=5)[source]
Return address or multiple addresses separated by spaces.
Raise ValidationError if raw content isn’t a valid Algorand address.
- Variables:
raw – multiple entries data from bundle field
address_data – data from address field
bundle – parsed collection of addresses
- Parameters:
max_bundle_size (int) – maximum allowed addresses count in bundle
- Returns:
str
- core.helpers.check_export_status(url_value)[source]
Return tax data from cache for provided url_value.
- Parameters:
url_value (str) – address or bundle value found in url
- Returns:
dict
- core.helpers.check_forbidden_addresses(value)[source]
Raiose 404 error if value contains any forbidden address.
- Parameters:
value (str) – space delimited addresses
- core.helpers.check_public_bundles()[source]
Check and add new and delete obsolete public bundle name filenames.
Return collection of updated bundle names.
- Parameters:
bundlenames (list) – collection of all instances of public bundle names
- Variables:
hashes – collection of all public bundle name hashes
filenames – collection of all existing filenames/hashes found on disk
missing – collection of public bundle name hashes not found on disk
obsolete – collection of filenames that aren’t valid public bundle names
- Returns:
list
- core.helpers.context_with_consolidated_data(context, serialized_data)[source]
Update provided context with consolidated data created from serialized_data.
- Parameters:
context (dict) – object containing all the data needed for rendering
serialized_data (dict) – serialized account’s data
- Variables:
context["distchart"] – data for rendering top ASA distribution chart
context["ratiochart"] – data for rendering ALGO/ASA/NFT chart
context["nftfloorchart"] – data for rendering NFT floors chart
context["consolidated"] – consolidated view totals
- Returns:
dict
- core.helpers.format_addresses_limit_help_text(bundlename)[source]
Return formatted help text for provided bundle instance.
- Parameters:
bundlename (
core.models.BundleName) – bundle name instance- Variables:
help_text – addresses field’s help text
limit_public – number of addresses allowed in a public bundle
public_help_text – addresses field’s help text related to public bundle
- core.helpers.prepare_tax_context(context, url_value)[source]
Prepare tax context object for provided url_value.
- Parameters:
context (dict) – object containing all the data needed for rendering
url_value (str) – address or bundle value found in url
- Variables:
typ – type of entry (address or bundle)
addresses – address(es) value found in url
- Returns:
dict
- core.helpers.reset_export(url_value)[source]
Reset cache data for provided url_value and call zip deletion consumer task.
- Parameters:
url_value (str) – address or bundle value found in url
- core.helpers.start_export(url_value, addresses, request, **kwargs)[source]
Start addresss processing task and record it.
- Parameters:
url_value (str) – address or bundle value found in url
addresses (str) – public Algorand addresses separated by spaces
request (
django.http.HttpRequest) – Django request object
core.management – Project management commands package
core.middleware – Application middleware module
Module containing core app’s custom middlewares.
- class core.middleware.CustomMinifyHtmlMiddleware(get_response: Callable[[HttpRequest], HttpResponseBase] | Callable[[HttpRequest], Awaitable[HttpResponseBase]])[source]
Bases:
MinifyHtmlMiddlewareCustom configuration for django-minify-html middleware.
- minify_args = {'allow_noncompliant_unquoted_attribute_values': False, 'allow_removing_spaces_between_attributes': False, 'keep_closing_tags': True, 'minify_css': False, 'minify_doctype': False, 'minify_js': False}
core.migrations – Core application database migrations package
core.models – Main application ORM module
Module containing website’s ORM models.
- class core.models.BundleName(*args, **kwargs)[source]
Bases:
ModelUser’s bundle names distincted by name field.
- exception DoesNotExist
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned
Bases:
MultipleObjectsReturned
- addresses
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- bundle
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- bundlename()[source]
Return self instance for generic templating purposes.
Some templates call ‘object.bundlename’ so this approach is convenient
- Returns:
- can_access_historic_widget()[source]
Return True if historic data for bundle can be accessed by user.
- Returns:
Boolean
- property class_name
Return lowercased class name to be used in templates.
- Returns:
str
- created
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- get_next_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=True, **kwargs)
- get_next_by_modified(*, field=<django.db.models.fields.DateTimeField: modified>, is_next=True, **kwargs)
- get_previous_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=False, **kwargs)
- get_previous_by_modified(*, field=<django.db.models.fields.DateTimeField: modified>, is_next=False, **kwargs)
- id
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- is_eligible_public_bundlename()[source]
Return whether this bundle name may be made public.
TODO: implement and test TODO: check if user subscription expired as that’s the only way how user can be ineligible.
- Returns:
bool
- modified
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- name
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- objects = <django.db.models.manager.Manager object>
- profile
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- profile_id
- public
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- property short_created
Return short string representation of created value.
- Returns:
str
- property short_modified
Return short string representation of modified value.
- Returns:
str
- property size
Return number of addresses in bundle.
- Returns:
int
- property str_created
Return universal string representation of created value.
- Returns:
str
- property str_modified
Return universal string representation of modified value.
- Returns:
str
- class core.models.Profile(*args, **kwargs)[source]
Bases:
ModelApp’s connection to main django user model.
- exception DoesNotExist
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned
Bases:
MultipleObjectsReturned
- address
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- property algorand_address
Return this profile’s Algorand address.
Native Algorand wallets store their base32 address directly and it is returned unchanged. EVM/xChain wallets store the
0xEVM address; its deterministic Algorand logicsig counterpart is derived on demand via the xChain helper. Returns an empty string when no address is set.- Variables:
address – the raw stored address
- Returns:
an Algorand address (or empty string)
- Return type:
str
- auth_method
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- authorized
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- authorized_at
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- bundle_size_limit(instance=None)[source]
Return maximum bundle size for profile based on bundle name instance.
- Parameters:
instance (
BundleName) – bundle name instance- Variables:
current_sum – total count of bundle names for currently processed limit
count – currently processed bundle name limit’s allowed bundle names number
size – currently processed bundle name limit’s allowed addresses number
- Returns:
int
- bundle_size_limit_for_public()[source]
Return maximum public bundle size for profile.
- Variables:
current_sum – total count of bundle names for currently processed limit
count – currently processed bundle name limit’s allowed bundle names number
size – currently processed bundle name limit’s allowed addresses number
- Returns:
int
- bundlename_by_name(name)[source]
Return profile’s bundle name instance having provided name.
- Parameters:
name (str) – unique bundle name
- Returns:
- bundlename_set
Accessor to the related objects manager on the reverse side of a many-to-one relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Parent.childrenis aReverseManyToOneDescriptorinstance.Most of the implementation is delegated to a dynamically defined manager class built by
create_forward_many_to_many_manager()defined below.
- bundlename_system_reserved_url_path_check(name)[source]
Raise Validation error if provided ‘name’ holds system reserved URL.
- Parameters:
name (str) – bundle name to check
- can_access_authorize()[source]
Return True if user is allowed to access authorize page.
- Returns:
Boolean
- can_access_explorer_setting()[source]
Return True if the user may choose a preferred explorer.
Available from the Intro subscription tier upward; below that the settings page shows the option disabled and routes a click to the subscriptions page.
- Returns:
Boolean
- can_access_historic_widget(size)[source]
Return True if historic data for bundle can be accessed by user.
- Parameters:
size (int) – number of Algorand addresses in the bundle
- Returns:
Boolean
- can_add_bundle_name()[source]
Return True if user is allowed to create another bundle name.
- Variables:
count – total number of already created bundle names
limits – collection of pre-defined bundle configuration limits for tier
- Returns:
Boolean
- can_add_public_bundle_name(instance_id, addresses)[source]
Return True if user is allowed to create another public bundle name.
- Parameters:
instance_id (int) – bundle name instance ID
addresses (str) – collection of public Algorand addresses separated by spaces
- Variables:
bundlename – bundle name instance
limit – maximum number of addresses in public bundle for user
bundlenames – profile’s bundle names collection
count – total number of already created bundle names
limits – collection of pre-defined bundle configuration limits for tier
- Returns:
Boolean
- can_use_bundle_names()[source]
Return True if user is allowed to use created bundle names.
- Variables:
bundlenames – profile’s bundle names collection
total_count – total number of already created bundle names
tier_name – user’s subscription tier name
limits – collection of pre-defined bundle configuration limits for tier
current_sum – total count of bundle names for currently processed limit
count – currently processed bundle name limit’s number allowed bundle names
- Returns:
Boolean
- check_votes_and_permission()[source]
Check and possibly update profile with new votes and permission values.
- Variables:
result – provider’s (votes, permission) pair, or None
votes – user’s governance votes count
permission – user’s permission on website
- currency
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- get_auth_method_display(*, field=<django.db.models.fields.CharField: auth_method>)
- id
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- integrity_check_for_bundlename(instance_id, cleaned_data)[source]
Raise Validation error if cleaned_data holds duplicate name or addresses.
- Parameters:
instance_id (int) – bundle name instance ID
cleaned_data (dict) – model form’s cleaned data
- Variables:
name – bundle name
addresses – collection of public Algorand addresses separated by spaces
- integrity_check_for_public_bundlename(instance_id, cleaned_data)[source]
Raise Validation error if cleaned_data holds reserved public name
or if user’s limit is reached.
- Parameters:
instance_id (int) – bundle name instance ID
cleaned_data (dict) – model form’s cleaned data
- Variables:
name – bundle name
addresses – collection of public Algorand addresses separated by spaces
- linked_addresses
Accessor to the related objects manager on the reverse side of a many-to-one relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Parent.childrenis aReverseManyToOneDescriptorinstance.Most of the implementation is delegated to a dynamically defined manager class built by
create_forward_many_to_many_manager()defined below.
- property name
Return user/profile name made depending on data fields availability.
- Returns:
str
- objects = <django.db.models.manager.Manager object>
- permission
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- preferred_explorer
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- preferred_explorer_or_default()[source]
Return the chosen explorer key, or the default when unset/unknown.
Permission is intentionally not re-checked here: the right to change this setting is gated on the settings page (Intro tier), but a value already saved keeps applying. Mirrors
preferred_router_or_default().- Returns:
str
- preferred_router
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- preferred_router_or_default()[source]
Return the chosen swap router id, or the first available default.
Imported lazily to avoid a models <-> widget-registry import cycle.
- Returns:
str
- profile()[source]
Return self instance for generic templating purposes.
It is accessed by ‘object.profile’ in some templates.
- Returns:
- show_sort_and_filter()[source]
Return True if sorting and filtering panel should be presented to user.
- Returns:
Boolean
- update_authorized(proof, method='escrow')[source]
Record an authorization proof and best-effort refresh permission.
The authorization is always persisted; a failing permission refresh is logged and swallowed so the authorization is never lost. Permission then reconciles on the next login (post_login) or a later refresh.
- Parameters:
proof (str) – provenance string (escrow txid, or the consumed nonce)
method (str) – one of “escrow”, “algorand_wallet”, “evm_xchain”
- Variables:
refreshed – whether the permission refresh completed
- Returns:
True if permission was refreshed, False to reconcile later
- Return type:
bool
- user
Accessor to the related object on the forward side of a one-to-one relation.
In the example:
class Restaurant(Model): place = OneToOneField(Place, related_name='restaurant')
Restaurant.placeis aForwardOneToOneDescriptorinstance.
- user_id
- votes
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
core.permission_provider – Permission provider module
Pluggable permission backend for the open frontend.
The frontend depends only on this abstraction. The ASA Stats on-chain implementation
(or any deployer’s alternative) is named by the PERMISSION_PROVIDER setting
and resolved lazily, so the open repo imports no deployment-specific code and
boots even when that backend is not installed.
- class core.permission_provider.PermissionProvider[source]
Bases:
objectDefault no-op permission backend.
Deployers subclass this and point
settings.PERMISSION_PROVIDERat their subclass to plug in a real backend. Every method degrades safely so a deployment with no provider keeps working and never has user data reset.- subscriptions(address)[source]
Return render-ready subscription data for the profile page.
- Parameters:
address (str) – public Algorand address
- Returns:
render-ready collection, or None when there is nothing to show
- core.permission_provider.get_permission_provider()[source]
Return the configured permission provider instance, built once.
Resolves
settings.PERMISSION_PROVIDERlazily on first call, so the frontend imports no deployment-specific module unless one is configured.- Variables:
dotted – dotted path to the provider class, or None
- Returns:
core.permission_providers – Permission providers package
Initialization module for project’s permission_providers package.
core.permission_providers.permissiondapp – Permission dApp module
ASA Stats permission provider backed by the permission-dapp submodule.
This is ASA-Stats deployment glue. It is imported only when
settings.PERMISSION_PROVIDER names it, so the open frontend never imports it
(nor the permission-dapp submodule) unless this deployment configures it. The
permission-dapp repo stays a pure, standalone smart-contract project with no
Django dependency; the dependency points one way only, this adapter ->
permissiondapp.dapp.*, never the reverse.
- class core.permission_providers.permissiondapp.PermissionDappProvider[source]
Bases:
PermissionProviderPermission backend backed by the on-chain Permission dApp and Subtopia.
- subscriptions(address)[source]
Fetch and format the address’s subscriptions for the profile page.
- Parameters:
address (str) – public Algorand address
- Variables:
subscriptions – raw subscription data from chain
- Returns:
render-ready collection, or None
core.permission_providers.updater – Updater module
Module containing the user-permissions update daemon.
Relocated from utils/permissions.py. The loop is provider-agnostic: it
periodically calls the configured permission provider’s refresh(). With no
provider configured the refresh is a no-op, so forks that do not need a
permissions daemon can simply not run the command that drives this.
core.permissions – Application permissions module
Module containing core app mixin classes for subscription permissions.
- class core.permissions.BundleNamesRedirection[source]
Bases:
UserPassesTestMixinBase class redirecting to home when access is denied.
- class core.permissions.CanAccessApiMixin[source]
Bases:
SubscribeRedirectionClass with method for determining if user is allowed to access API.
- class core.permissions.CanAccessAuthorizeMixin[source]
Bases:
ProfileRedirectionClass with method for determining if user is allowed to access API.
- class core.permissions.CanAddBundleNameMixin[source]
Bases:
SubscribeRedirectionClass with method for determining if user can add a bundle name.
- class core.permissions.CanUseBundleNamesMixin[source]
Bases:
BundleNamesRedirectionClass with method for determining if user can use created bundle names.
core.signals – Database signals and triggers module
Module containing core app signals.
- core.signals.create_user_profile(sender, instance, created, **kwargs)[source]
Create profile instance if user is successfully created.
Method is called by signal sent from django infrastructure after sender instance is saved.
- Parameters:
sender (
User) – class responsible for signal sendinginstance (
User) – instance of the sender classcreated (boolean) – value that determines is sender is created or not
- core.signals.post_login(sender, user, request, **kwargs)[source]
Check user’s votes and permission values upon log in.
Method is called by signal sent from django infrastructure after user logs in.
- Parameters:
sender (
User) – class responsible for signal sendinguser (
User) – instance of the user that just logged in
- core.signals.save_user_profile(sender, instance, **kwargs)[source]
Update profile instance after related user is updated.
Method is called by signal sent from django infrastructure after sender instance is updated.
- Parameters:
sender (
User) – class responsible for signal sendinginstance (object of
User) – instance of the sender class
core.urls – Main application URL configuration module
core.views – Main application views module
core.views_connected_addresses – Module for server-rendered (htmx) connected-addresses management
Server-rendered (htmx) connected-addresses management for the site’s core app.
There are three views:
profile_addresses()– the full page (GET); renders the address list inline via theaddress_listpartial inprofile_addresses.html.profile_addresses_action()– the htmx endpoint (POST); performs one operation and returns the refreshed#address_listpartial.profile_link_address()– the “link another wallet” page (GET).
The security model entirely server-side: privilege-expanding operations
(set_primary, enabling login) require a fresh, operation-bound signature from
the current primary, verified by walletauth.management.verify_step_up();
reducing operations (disable login, remove) need only the authenticated session.
The view – never the client – decides whether step-up is required, from the
operation semantics. Targets are resolved strictly within the caller’s own rows,
so there is no ownership oracle.
- core.views_connected_addresses.profile_addresses(request)[source]
Render the connected-addresses management page (full document).
- Parameters:
request – the authenticated request
- Return type:
django.http.HttpResponse
- core.views_connected_addresses.profile_addresses_action(request)[source]
Perform one management operation and return the refreshed list partial.
- Parameters:
request – the authenticated request carrying
operationandtarget_id(plusenabledforset_loginand a step-upnonce/signature for privilege-expanding operations)- Return type:
django.http.HttpResponse
core.tests – Main application unit-tests package
Initialization module for core app unit tests.
manage – Django main management module
Django’s command-line utility for administrative tasks.
nameservice – Name service package
Initialization module for Algorand name services package.
nameservice.ans – ANS module
Module containing functions for Algorand Name Service (ANS).
- nameservice.ans.check_name(name, algod_client)[source]
Return provided address or its ANS owner.
- Parameters:
name (str) – ANS name or Algorand address
algod_client (
AlgodClient) – Algorand node client instance
- Variables:
algo_name – base name with truncated eventual /ans suffix
ans_client – ANS resolver client
name_info – retrieved ANS entry data
- Returns:
str
nameservice.anssdk – ANS SDK module
nameservice.main – Name service main module
Module containing public functions for Algorand name services.
- nameservice.main.check_name(name, algod_client)[source]
Return name service owner for name or itself if name isn’t registered.
- Parameters:
name (str) – ANS name or Algorand address
algod_client (
AlgodClient) – Algorand node client instance
- Variables:
container – temporary container to check if both providers registered name
result – resolved collection of address(es)
- Returns:
str
nameservice.nfd – NFD module
Module containing functions for NF Domains name service.
- nameservice.nfd.check_name(name, algod_client)[source]
Return provided address or addresses connected with NFD.
- Parameters:
name (str) – NFD name or Algorand address
algod_client (
AlgodClient) – Algorand node client instance
- Variables:
algo_name – base name with truncated eventual /nfd suffix
v2_app_id – NFC v2 smart contract application ID
app_state – related NFD application global state
box_addresses – Algorand address(es) connected with NFD v2
addresses – Algorand address(es) connected with provided .algo name
- Returns:
str
- nameservice.nfd.nfd_app_id_from_algo_name(name, algod_client)[source]
Return NFD application identifier connected with provided name.
- Parameters:
name (str) – .algo name we’re looking for
algod_client (
AlgodClient) – Algorand node client instance
- Variables:
box_name – Algorand box name connected with provided algo name
response – Algorand box fetching result
hexed – box value hexadecimal string representation
- Returns:
int
nameservice.xchain – xChain module
Module containing functions for xChain Accounts.
- nameservice.xchain.check_evm_address(evm_address, algod_client)[source]
Return Algorand address for a given EVM address.
- Parameters:
evm_address (str) – EVM address to check
algod_client (
AlgodClient) – Algorand node client instance
- Variables:
compiled – compiled logic signature bytes
lsig – LogicSigAccount instance initialized with compiled bytes
- Returns:
str
nameservice.tests – Name service unit-tests package
Initialization module for nameservice package unit tests.
utils – Utility functions and constants package
Initialization module for helpers functions.
utils.cache – Cache utility module
Module containing functions for retrieving and setting cache values.
utils.charts – Charts utility module
Module containing chart creating functions.
- utils.charts.prepare_base_charts(asas, values, nft_values)[source]
Prepare and return data for ASA and NFT charts.
- Parameters:
asas (dict) – collection of assets immutable data
values (list) – collection of amounts and data related to asset
nft_values (list) – collection of amounts and data related to NFT
- Variables:
asa_colors – collection of asset ids and related CSS color prefixes
nft_colors – collection of NFT collections and related CSS color prefixes
- Returns:
tuple
- utils.charts.prepare_base_charts_from_assets_data(assets_data)[source]
Prepare and return data for ASA and NFT charts.
- Parameters:
assets_data (dict) – processed asset section data ready for rendering
- Variables:
asa_colors – collection of asset ids and related CSS color prefixes
nft_colors – collection of NFT collections and related CSS color prefixes
- Returns:
tuple
- utils.charts.prepare_base_charts_from_serialized_data(serialized_data)[source]
Prepare and return data for ASA and NFT charts from serialized account data.
Counterpart of
prepare_base_charts()that consumes API 2.0 serialized data directly, with no dependence on legacyasas/values/nft_valuesshapes.- Parameters:
serialized_data (dict) – serialized account’s data
- Variables:
asa_colors – collection of asset ids and related CSS color prefixes
nft_colors – collection of NFT collections and related CSS color prefixes
- Returns:
tuple
- utils.charts.prepare_consolidated_charts(serialized_data, asas, values, total, nft_colors)[source]
Prepare and return charts for consolidated view.
- Parameters:
serialized_data (dict) – serialized account’s data
asas (dict) – collection of assets immutable data
values (list) – collection of amounts and data related to asset
total (
Total) – totals collectionnft_colors (dict) – collection of NFT collections and related CSS color prefixes
- Variables:
consolidated_data – all the data needed for consolidated view
consolidated_totals – consolidated view totals
distribution_chart – top assets distribution chart data
ratio_chart – ratio chart data
nftfloor_chart – NFT floor chart data
- Returns:
tuple
- utils.charts.prepare_consolidated_charts_from_assets_data(assets_data)[source]
Prepare and return charts for consolidated view.
- Parameters:
assets_data (dict) – processed asset section data ready for rendering
- Variables:
consolidated_data – all the data needed for consolidated view
consolidated_totals – consolidated view totals
distribution_chart – top assets distribution chart data
ratio_chart – ratio chart data
- Returns:
tuple
- utils.charts.prepare_consolidated_charts_from_serialized_data(serialized_data, nft_colors)[source]
Prepare and return charts for the consolidated view from serialized data.
Counterpart of
prepare_consolidated_charts()that consumes API 2.0 serialized data directly.- Parameters:
serialized_data (dict) – serialized account’s data
nft_colors (dict) – collection of NFT collections and related CSS color prefixes
- Variables:
consolidated_data – all the data needed for the consolidated view
consolidated_totals – consolidated view totals
total – totals instance built from serialized data
distribution_chart – top assets distribution chart data
ratio_chart – ratio chart data
nftfloor_chart – NFT floor chart data
- Returns:
tuple
utils.clients – Clients utility module
Algorand and cache client factories, configured from settings/env.
- utils.clients.algod_instance()[source]
Create and return an Algorand algod client configured from settings.
- Returns:
algosdk.v2client.algod.AlgodClient
- utils.clients.indexer_instance()[source]
Create and return an Algorand indexer client configured from settings.
- Returns:
algosdk.v2client.indexer.IndexerClient
- utils.clients.redis_instance()[source]
Return the frontend’s local (writable) Redis client for bundle data.
- Returns:
Redis
- utils.clients.search_transactions(params, indexer_client=None, delay=0.05, limit=1000)[source]
Run a paginated indexer transaction search on the public indexer.
- Parameters:
params (dict) – indexer search_transactions kwargs (e.g. {“address”: …})
indexer_client (
algosdk.v2client.indexer.IndexerClient) – optional client; created from settings if omitteddelay (float) – seconds to sleep between page requests
limit (int) – maximum number of transactions requested per page
- Variables:
client – indexer client used for the lookup
results – accumulated transaction dicts across pages
next_token – pagination token for the next page, empty when exhausted
page – single page of indexer results
- Returns:
list of transaction dicts
utils.constants – Constants package
Initialization module for constants module.
utils.constants.api – API constants
Module containing API constants.
utils.constants.apiv2 – API v2 constants
Module containing API v2 constants.
utils.constants.charts – Charts constants
Module containing chart constants.
utils.constants.core – Core constants
Module containing core app’s constants.
utils.constants.nameservice – Name service constants
Module containing name service package’s constants.
utils.constants.tax – Tax constants
Module containing tax CSV files creation constants.
utils.constants.users – Users constants
Module containing constants related to user authentication system.
utils.helpers – Helper utility functions
Module containing helper functions.
Asset and asset represent either Algod client’s or Tinyman’s asset data. Asa and asa represent Asa named tuple. amount reporesents amount/quantity in ASA. value reporesents amount in Algo.
- utils.helpers.base64_to_utf(base64_message)[source]
Return provided base64 value converted to UTF string.
- Parameters:
base64_message (str) – base64 encoded value
base64_bytes (bytes) – base64 message as bytes binary
- Returns:
str
- utils.helpers.bundle_from_addresses(addresses)[source]
Canonical bundle hash. DO NOT MODIFY.
Forks and the backend must produce byte-identical hashes, so input is normalized here:
split()collapses any whitespace run and drops empty tokens,setde-duplicates,sortedmakes order deterministic. SHA-1 over UTF-8 of ASCII base32 addresses is identical on every platform.- Parameters:
addresses – Algorand addresses separated by whitespace
- Returns:
40-char uppercase hex digest
- utils.helpers.check_algorand_address(entry, raise_error=False)[source]
Check for entry validity and return provided entry/address
or nameservice addresses if it’s a name.
Return empty string if it’s not a valid Algorand address. Raise ValidationError for an invalid address if provided raise_error is True.
- Parameters:
address (str) – Algorand address or nameservice name
raise_error (Boolean) – whether ValidationError should be raised for invalid address
- Variables:
addresses – evaluated collection of Algorand addresses separated by spaces
_address – current Algorand address to check for validity
valid_address – value indicating if address is a valid entry
- Returns:
str
- utils.helpers.check_bundle_addresses(bundle)[source]
Return addresses from cache client associated with provided bundle.
- Parameters:
bundle (str) – hash value associated with target addresses
- Variables:
cache_client – Redis client instance
- Returns:
str
- utils.helpers.create_bundle(addresses)[source]
Return bundle hash from addresses and update cache if needed.
- Parameters:
addresses (string) – Algorand addresses separated by spaces
- Variables:
bundle – hash made from provided addresses
cache_client – Redis client instance
- Returns:
str
- utils.helpers.create_multiprocess_logger(identifier, prefix='process', level=20)[source]
Create and return logger instance used in multiprocessing environemnt.
- Parameters:
identifier (str) – unique process identifier
prefix (str) – prefix to use for defining logging filename
- Variables:
logger – logger instance
name – current process name
file_handler – instance that writes formatted logging records to disk files
formatter – instance that converts a LogRecord to text
- Returns:
logging.Logger
- utils.helpers.get_env_variable(name, default=None)[source]
Return environment variable with provided name.
Raise ImproperlyConfigured exception if such variable isn’t set.
- Parameters:
name (str) – name of environment variable
- Returns:
str
- utils.helpers.load_transparency_reports()[source]
Scan the static assets directory for ASA Stats transparency reports.
- Variables:
reports_dir – absolute path to the static assets directory
pattern – compiled regex pattern to match transparency report filenames
- Returns:
list
- utils.helpers.message_for_app_code_in_values(values, app_codes, msg)[source]
Return provided message if any code from provided is found in provided values.
- Parameters:
values (
utils.structs.Values) – collection of account’s assets swap valuesapp_codes (list) – collection of provider base app prefixes
msg (str) – message to return if app is in values
- Returns:
str
- utils.helpers.parse_export_limits(raw)[source]
Translate “free:5,Intro:6,Asastatser:7,…” into an int-valued dict.
Blank or malformed entries are skipped; missing tiers fall back to the module defaults in exportpermissions._DEFAULT_LIMITS at read time.
- Parameters:
raw (str) – comma-separated tier configurations
- Variables:
limits – evaluated collection of tier limits mapped to sizes
part – current segment of the raw string being parsed
key – parsed tier name
sep – parsed separator character
value – parsed limit size for the tier
- Returns:
dict
- utils.helpers.pause(seconds=1)[source]
Sleep for provided number of seconds.
- Parameters:
seconds (int) – number of seconds to pause
- utils.helpers.random_slogan()[source]
Return random slogan text from predefined collection.
- Returns:
str
- utils.helpers.read_json(filename)[source]
Return content of JSON file located in provided filename.
- Parameters:
filename (str) – full path to JSON file to read
- Returns:
dict
- utils.helpers.safe_referer(request)[source]
Return a same-origin
Refererforrequest, orNone.Used to bounce the user back to the address page they clicked Swap from (validated, never trusted, to avoid an open redirect).
- Parameters:
request (rest_framework.request.Request | django.http.HttpRequest) – the current request
- Returns:
a safe local URL, or None
- Return type:
str | None
utils.structs – Structures utility module
Module containing data structures.
- class utils.structs.Asa(id, name, unit, total, decimals, url, creator, links)
Bases:
tuple- creator
Alias for field number 6
- decimals
Alias for field number 4
- id
Alias for field number 0
- links
Alias for field number 7
- name
Alias for field number 1
- total
Alias for field number 3
- unit
Alias for field number 2
- url
Alias for field number 5
- class utils.structs.BodyElement(asset, name, type, url, source, amount, value)
Bases:
tuple- amount
Alias for field number 5
- asset
Alias for field number 0
- name
Alias for field number 1
- source
Alias for field number 4
- type
Alias for field number 2
- url
Alias for field number 3
- value
Alias for field number 6
- class utils.structs.Consolidated(balance, staked, liquidity, defi, nftfloor)
Bases:
tuple- balance
Alias for field number 0
- defi
Alias for field number 3
- liquidity
Alias for field number 2
- nftfloor
Alias for field number 4
- staked
Alias for field number 1
- class utils.structs.HeaderElement(icon, label, amount, total)
Bases:
tuple- amount
Alias for field number 2
- icon
Alias for field number 0
- label
Alias for field number 1
- total
Alias for field number 3
- class utils.structs.LedgerProgram(asset, code, dapp)
Bases:
tuple- asset
Alias for field number 0
- code
Alias for field number 1
- dapp
Alias for field number 2
- class utils.structs.LimitOrder(amount_in, asset_out, amount_out, price, escrow)
Bases:
tuple- amount_in
Alias for field number 0
- amount_out
Alias for field number 2
- asset_out
Alias for field number 1
- escrow
Alias for field number 4
- price
Alias for field number 3
- class utils.structs.Nft(id, name, unit, total, collection, urls, path, tpath, listed, last, max, floor, attrs, title, desc, rarity)
Bases:
tuple- attrs
Alias for field number 12
- collection
Alias for field number 4
- desc
Alias for field number 14
- floor
Alias for field number 11
- id
Alias for field number 0
- last
Alias for field number 9
- listed
Alias for field number 8
- max
Alias for field number 10
- name
Alias for field number 1
- path
Alias for field number 6
- rarity
Alias for field number 15
- title
Alias for field number 13
- total
Alias for field number 3
- tpath
Alias for field number 7
- unit
Alias for field number 2
- urls
Alias for field number 5
- class utils.structs.NftFloor(price, gallery, currency, app)
Bases:
tuple- app
Alias for field number 3
- currency
Alias for field number 2
- gallery
Alias for field number 1
- price
Alias for field number 0
- class utils.structs.NftListing(asset, price, quantity, gallery, currency, app)
Bases:
tuple- app
Alias for field number 5
- asset
Alias for field number 0
- currency
Alias for field number 4
- gallery
Alias for field number 3
- price
Alias for field number 1
- quantity
Alias for field number 2
- class utils.structs.NftPurchase(price, group, gallery, time, currency)
Bases:
tuple- currency
Alias for field number 4
- gallery
Alias for field number 2
- group
Alias for field number 1
- price
Alias for field number 0
- time
Alias for field number 3
- class utils.structs.Pool(app, token, liquidity, asset1, balance1, asset2, balance2, fee, code, address, parent)
Bases:
tuple- address
Alias for field number 9
- app
Alias for field number 0
- asset1
Alias for field number 3
- asset2
Alias for field number 5
- balance1
Alias for field number 4
- balance2
Alias for field number 6
- code
Alias for field number 8
- fee
Alias for field number 7
- liquidity
Alias for field number 2
- parent
Alias for field number 10
- token
Alias for field number 1
- class utils.structs.Total(algo, asa, nft, total, totalusdc, priceusdc, pricealgo, noteval)
Bases:
tuple- algo
Alias for field number 0
- asa
Alias for field number 1
- nft
Alias for field number 2
- noteval
Alias for field number 7
- pricealgo
Alias for field number 6
- priceusdc
Alias for field number 5
- total
Alias for field number 3
- totalusdc
Alias for field number 4
utils.userhelpers – User helper utility functions
Module containing helper functions for authenticated users.
- utils.userhelpers.check_authorization_transaction(profile)[source]
Fetch and return provided profile address’ authorization transaction ID.
- Parameters:
profile (class:core.models.Profile) – user profile instance
- Variables:
indexer_client – Algorand Indexer client instance
note – profile’s unique hash representing required note
params – arguments to search transactions Indexer method
results – current set of results
transaction – currently processed transaction
- Returns:
str
- utils.userhelpers.decode_unique_hash(uid, salt='YKmvVHqkEh')[source]
Decode number from unique alphanumeric value.
- Parameters:
uid (str) – unique hash
- Returns:
int
- utils.userhelpers.delete_deactivated()[source]
Delete all deactivated user accounts together with respective profile.
- Variables:
count – current number of deleted users
users – inactive user instances
- Returns:
int
- utils.userhelpers.is_system_reserved_url_path(url_path)[source]
Return True if provided url_path is reserved by the system.
- Parameters:
url_path (str) – URL path to check against the system
- Returns:
Boolean
- utils.userhelpers.slugified_bundle_name(value, allow_unicode=False)[source]
Return a slug of value allowing the dot character, Django-style.
NOTE: this is rewrite of Django’s slugify with added dot (.) as allowed character
Convert to ASCII if ‘allow_unicode’ is False. Convert spaces or repeated dashes to single dashes. Remove characters that aren’t alphanumerics, underscores, or hyphens. Convert to lowercase. Also strip leading and trailing whitespace, dashes, and underscores.
- Parameters:
value (str) – bundle name to slugify
allow_unicode (bool) – keep unicode characters instead of ASCII-folding
- Returns:
str
- utils.userhelpers.truncated_timestamp_and_address(timestamp, address)[source]
Return integer created from provided timestamp.
- Parameters:
timestamp (float) – seconds since epoch
address (str) – public Algorand address
- Variables:
address_repr – representation of public Algorand address converted to int
- Returns:
int
- utils.userhelpers.unique_hash_from_number(number, salt='YKmvVHqkEh')[source]
Get unique alphanumeric value based on supplied number.
- Parameters:
number (int) – number to convert into hashids unique id
- Returns:
str
utils.tests – Utils unit-tests package
Initialization module for helpers unit tests.
walletauth – Wallet authentication package
Wallet-connect address authorization app.
Proves control of an Algorand address by verifying an off-chain signed
0-ALGO self-payment that carries a server-issued nonce, then authorizes the
proven address onto request.user.profile. The signed transaction is never
submitted to the network.
walletauth.account_resolution – Module for resolve a Django account from a wallet address
Resolve a Django account from a proven wallet address.
A verified on-chain address is matched verbatim against the LinkedAddress
registry, so resolution is chain-agnostic: an Algorand wallet stores its base32
address, an EVM/xChain wallet stores its 0x address. The Algorand counterpart
of an EVM address is not computed here – matching is on the stored address,
which keeps login off the algod /compile path. (Canonical uniqueness makes
the stored address effectively unique, so this is unambiguous.)
Only addresses a user opted in for sign-in resolve to an account: the primary is
always login-capable, while secondaries must have login_enabled set. Every
registry row was proven by a signature when it was created, so sign-in never
creates accounts and never trusts an address the client merely names.
- walletauth.account_resolution.ACCOUNT_RESOLVERS = {'algorand': <function _resolve_by_address>, 'evm': <function _resolve_by_address>}
Account resolvers keyed by request chain. Both chains resolve by the stored address; EVM does not need its Algorand counterpart to authenticate.
- exception walletauth.account_resolution.AmbiguousWalletAddress[source]
Bases:
ExceptionRaised when more than one account has the same address login-enabled.
This is a data-integrity condition the canonical unique constraint is meant to prevent. Surfacing it (rather than collapsing to “not linked”) lets the sign-in view tell the user precisely why their wallet was refused.
- walletauth.account_resolution.resolve_account(chain, address)[source]
Resolve the account that may sign in with
addressonchain.- Parameters:
chain (str) – request chain identifier (e.g.
"algorand")address (str) – proven address for that chain
- Returns:
the linked user, or None when unsupported/unlinked
- Return type:
django.contrib.auth.models.User | None
walletauth.addresses – Multi-address accounts module
Address canonicalization and limits for multi-address accounts.
A user account holds one privilege-bearing primary address plus any number of
secondary addresses used only for login (opt-in) and action-gating (e.g. a
Swap button). Secondaries confer no permission, subscription, or governance
weight – those derive solely from the primary (Profile.address), exactly as
before this feature.
To guarantee that a single on-chain account cannot be claimed by two profiles – including via an EVM address and the Algorand xChain (lsig) account it deterministically controls – every linked address is deduplicated on a canonical form rather than its raw string.
- exception walletauth.addresses.CanonicalizationError[source]
Bases:
ExceptionRaised when an address cannot be reduced to its canonical form.
- walletauth.addresses.MAX_SECONDARY_ADDRESSES = 10
Default maximum number of secondary (non-primary) addresses per account. Modest by design: cheap insurance against enumeration/abuse and index bloat. Override with
settings.MAX_SECONDARY_ADDRESSES.
- walletauth.addresses.canonical_for(chain, address)[source]
Return the canonical, dedup form of
addressonchain.Native Algorand addresses are already canonical and returned unchanged. EVM addresses are reduced to their deterministic Algorand xChain (lsig) counterpart, so an EVM address and its lsig collapse to a single identity and cannot be claimed as two.
- Parameters:
chain (str) – chain identifier (
"algorand"or"evm")address (str) – stored/display address
- Variables:
canonical – the lsig counterpart returned by
check_evm_address- Raises:
CanonicalizationError – when an EVM address cannot be reduced (e.g. algod is unreachable), so a non-canonical value is never persisted
- Returns:
canonical address used as the global uniqueness key
- Return type:
str
walletauth.apps – Wallet authentication configuration module
Module containing walletauth app configuration.
walletauth.backends – Authentication backend for wallet sign-in
Authentication backend for wallet sign-in.
The backend trusts a single kwarg, verified_wallet_address, and resolves the
linked account from it. That kwarg is only ever passed by
walletauth.views.WalletLoginVerifyAPIView after the cryptographic
proof has been validated, so the trust boundary is explicit and narrow – the
same pattern social and magic-link logins use. The backend is unreachable via
the normal username/password path because it ignores those credentials.
- class walletauth.backends.WalletAddressBackend[source]
Bases:
BaseBackendResolve a user from an already-verified wallet address.
- authenticate(request, verified_wallet_address=None, chain='algorand', **kwargs)[source]
Return the account linked to a verified address, or
None.- Parameters:
request (django.http.HttpRequest) – the current request (unused; required by the interface)
verified_wallet_address (str | None) – address already proven by the caller
chain (str) – chain the address belongs to
- Returns:
the linked user, or None
- Return type:
django.contrib.auth.models.User | None
walletauth.crypto – Cryptography module
Vendored Ed25519 verification of an Algorand signed transaction.
Ported from the Rewards Suite utils.helpers.verify_signed_transaction. Two
deliberate differences from the reference:
Uses
algosdk.constants.txid_prefix(b"TX") rather than a literal, to make the domain-separation prefix self-documenting. Note this is the transaction prefix, NOT theb"MX"used byalgosdk.util.verify_bytesfor arbitrarysignBytesmessages – using the latter here would reject every real wallet signature.Broadens the caught exceptions so a malformed signature or address yields
Falseinstead of propagating, since this helper is called directly by the verifier rather than from inside a blankettry/exceptin a view.
This function honors authorizing_address (rekeyed accounts). On its own that
is unsafe for an authorization gate: a client can fabricate a rekey claim. The
caller (walletauth.verifiers.AlgorandSignedTxnVerifier) is responsible
for confirming any claimed rekey against on-chain state before trusting it.
- walletauth.crypto.verify_signed_transaction(stxn)[source]
Verify the Ed25519 signature of a signed Algorand transaction.
Verifies against the sender’s key, or the authorizing (rekey) address when one is present on the signed transaction.
- Parameters:
stxn (
algosdk.transaction.SignedTransaction) – signed transaction to verify- Variables:
public_key – address whose key must have produced the signature (the sender, or the authorizing address when the transaction is rekeyed)
verify_key – Ed25519 verify key derived from
public_keyprefixed_message –
b"TX"domain prefix followed by the canonical msgpack encoding of the transaction – the exact bytes that were signed
- Returns:
True if the signature is valid, else False
- Return type:
bool
walletauth.gating – Self-scoped checks for the swap gate
Self-scoped “is this address connected to me?” checks for the swap gate.
The engine shows a Swap button next to a browsed address only when that address is connected to the current user. This is a visibility hint, never an authorization: the swap itself is signed live by the wallet, so a stale link can at worst surface a button whose signature then fails – never a loss.
Matching is on canonical identity. An address connected as an EVM wallet matches
its Algorand lsig counterpart (its stored canonical_address) and vice versa,
so browsing either form resolves to the same connection. No canonicalization
(and so no algod) happens here: the browsed value is compared directly against
each row’s stored address and canonical_address. Lookups are strictly
limited to the requesting user’s own rows – never an oracle for whether an
address belongs to anyone else, and independent of login_enabled (a
connection gates the button whether or not it can also sign in).
- walletauth.gating.is_linked_to_user(user, address)[source]
Return whether
addressis connected touser(self-scoped).- Parameters:
user (django.contrib.auth.models.User) – the requesting user
address (str) – the browsed address
- Returns:
True when the address is one of the user’s connected addresses
- Return type:
bool
- walletauth.gating.linked_addresses_for_user(user, addresses)[source]
Return the subset of
addressesconnected touser(self-scoped).Resolved in a single query against the user’s own rows; the returned values are the originals as supplied (so the caller can map results back).
- Parameters:
user (django.contrib.auth.models.User) – the requesting user (anonymous yields an empty result)
addresses (collections.abc.Iterable[str]) – browsed addresses to test
- Variables:
owned – the user’s stored address and canonical values
- Returns:
the supplied addresses that are connected to
user- Return type:
set[str]
walletauth.gating_views – Swap-gate endpoint API views
walletauth.management – Account address-management operations
Account address-management operations (set-primary, remove, login toggle).
Pure service functions over the LinkedAddress registry, kept free of
HTTP concerns so they are exhaustively unit-testable. The views in
walletauth.management_views enforce authentication, step-up (a fresh
signature from the current primary for privilege/access-expanding operations)
and self-scoping before calling these.
Invariants preserved here: - exactly one primary per account, always login-capable; - permission/subscription/governance follow the primary, re-derived on change; - the primary cannot be removed (a replacement must be promoted first).
- exception walletauth.management.CannotDisablePrimaryLogin[source]
Bases:
ExceptionRaised when login is disabled on the primary address.
- exception walletauth.management.CannotRemovePrimary[source]
Bases:
ExceptionRaised when removal targets the primary address.
- walletauth.management.is_bootstrap_promotion(profile, target)[source]
Whether
targetmay become primary / login-enabled without step-up.Step-up exists to stop a stolen session escalating against an existing primary; it cannot be satisfied before any primary exists. That strands accounts whose legacy
Profile.addresspredates the linked-address registry: linking that same address creates a non-primary row (becauseProfile.addressis already set inlink_address()), yet there is no primary to sign with.Bootstrapping is allowed only when BOTH hold, so a stolen session cannot promote an attacker’s freshly linked wallet:
the account has no current primary, and
targetis the address already authorized on the profile (Profile.address) – an address the account has already proven.
- Parameters:
profile (core.models.Profile) – the owning profile
target (walletauth.models.LinkedAddress) – the row being promoted
- Return type:
bool
- walletauth.management.remove_address(profile, linked)[source]
Remove a secondary address from
profile.- Parameters:
profile (core.models.Profile) – the owning profile (for symmetry/logging)
linked (walletauth.models.LinkedAddress) – the row to remove
- Raises:
CannotRemovePrimary – when
linkedis the primary
- walletauth.management.set_login_enabled(profile, linked, enabled)[source]
Enable or disable sign-in for a linked address.
- Parameters:
profile (core.models.Profile) – the owning profile (for symmetry/logging)
linked (walletauth.models.LinkedAddress) – the row to update
enabled (bool) – desired
login_enabledvalue
- Raises:
CannotDisablePrimaryLogin – when disabling login on the primary
- walletauth.management.set_primary(profile, target)[source]
Promote
target(an existing secondary) to primary; demote the old one.Mirrors the new primary onto
Profile.addressand re-derives permission from it. The previous primary stays linked as a (still login-capable) secondary. A no-op iftargetis already primary.- Parameters:
profile (core.models.Profile) – the owning profile
target (walletauth.models.LinkedAddress) – the row to promote (must belong to
profile)
- Variables:
refreshed – whether permission re-derived in-band
- Returns:
whether the permission refresh succeeded (False -> pending)
- Return type:
bool
- walletauth.management.verify_step_up(*, user, operation, target_id, nonce, payload)[source]
Verify a fresh, operation-bound signature from
user’s current primary.The signed challenge is
prefix + "{nonce}:{operation}:{target_id}", so a signature minted to approve one change cannot be replayed to authorize a different one: altering the operation or the target alters the message the signature must cover, and recovery fails. The nonce is additionally bound to the primary address and single-use (claimed atomically here).Framework-agnostic so both the htmx view and any other caller can use it.
- Parameters:
user – the authenticated user
operation (str) – the step-up operation (“set_primary” or “set_login”)
target_id (int) – id of the caller’s own row the operation acts on
nonce (str) – the raw server-issued nonce token (not the bound form)
payload (collections.abc.Mapping) – proof fields –
signature(EVM) orsignedTransaction(Algorand)
- Returns:
Noneon success, else a human-readable error message- Return type:
str | None
walletauth.management_views – Authenticated step-up challenge API views
walletauth.migrations – Wallet auth application database migrations package
walletauth.models – Wallet authentication ORM module
Module containing walletauth app’s ORM models.
- class walletauth.models.LinkedAddress(*args, **kwargs)[source]
Bases:
ModelA verified wallet address connected to a user’s profile.
Each profile has exactly one primary address – mirrored from
Profile.address, the sole source of permission, subscription and governance – and any number of secondary addresses used only for login (opt-in vialogin_enabled) and action-gating (e.g. showing a Swap button). Secondaries confer no privilege.Rows are globally unique on
canonical_addressso one on-chain account cannot be claimed by two profiles, and a primary is always login-capable (enforced byck_linkedaddress_primary_login).- exception DoesNotExist
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned
Bases:
MultipleObjectsReturned
- address
Stored/display form (EVM lower-cased
0x…or Algorand base32).
- classmethod at_secondary_capacity(profile)[source]
Return whether
profilealready holds the maximum secondaries.- Parameters:
profile (core.models.Profile) – the profile to test
- Returns:
True if no further secondaries may be added
- Return type:
bool
- auth_method
Verification method (
"algorand_wallet"or"evm_xchain").
- authorized
Proof token (nonce) from the verification that linked this address.
- canonical_address
lsig counterpart for EVM, the address itself for native.
- Type:
Canonical dedup key
- chain
Chain identifier (
"algorand"or"evm").
- get_next_by_verified_at(*, field=<django.db.models.fields.DateTimeField: verified_at>, is_next=True, **kwargs)
- get_previous_by_verified_at(*, field=<django.db.models.fields.DateTimeField: verified_at>, is_next=False, **kwargs)
- id
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- is_primary
Whether this is the privilege-bearing primary (mirrors
Profile.address).
- label
Optional user-supplied label.
- login_enabled
Whether this address may be used to log in. Off by default for secondaries; always on for the primary.
- objects = <django.db.models.manager.Manager object>
- profile
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- profile_id
- classmethod secondary_count(profile)[source]
Return the number of secondary (non-primary) addresses on
profile.- Parameters:
profile (core.models.Profile) – the profile to count secondaries for
- Returns:
count of non-primary linked addresses
- Return type:
int
- verified_at
When this address was last verified.
- class walletauth.models.WalletLoginNonce(*args, **kwargs)[source]
Bases:
ModelSingle-use, address-bound challenge for wallet sign-in (no user yet).
Unlike
WalletNonce(authorize), there is no authenticated user when a login challenge is issued, so the nonce is bound to the claimed address and chain. Security does not rely on that binding: the verify step resolves the account from the address the signature actually proves, never from the request body, so a nonce issued for one address cannot be redeemed by a signature proving a different one.- exception DoesNotExist
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned
Bases:
MultipleObjectsReturned
- NONCE_TTL = datetime.timedelta(seconds=300)
Time a nonce remains valid after creation.
- address
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- chain
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- claim()[source]
Atomically transition this nonce from unused to used.
- Variables:
claimed – number of rows the conditional update changed (0 or 1)
- Returns:
True if this call consumed the nonce, else False
- Return type:
bool
- created_at
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- get_next_by_created_at(*, field=<django.db.models.fields.DateTimeField: created_at>, is_next=True, **kwargs)
- get_previous_by_created_at(*, field=<django.db.models.fields.DateTimeField: created_at>, is_next=False, **kwargs)
- id
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- nonce
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- objects = <django.db.models.manager.Manager object>
- classmethod purge_stale()[source]
Delete used or expired login nonces. Intended for a periodic job.
- Variables:
cutoff – timestamp before which unused nonces are considered expired
- Returns:
number of rows deleted
- Return type:
int
- used
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- class walletauth.models.WalletNonce(*args, **kwargs)[source]
Bases:
ModelSingle-use, user-bound challenge for wallet address authorization.
A nonce is issued for an (
user,address) pair and consumed once the matching signed challenge is verified. Binding touserprevents a nonce solicited in one session from being redeemed in another.- exception DoesNotExist
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned
Bases:
MultipleObjectsReturned
- NONCE_TTL = datetime.timedelta(seconds=300)
Time a nonce remains valid after creation.
- address
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- chain
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- claim()[source]
Atomically transition this nonce from unused to used.
Race-safe single-use: only the caller that performs the unused->used transition gets
True; a concurrent request that already consumed the nonce getsFalse.- Variables:
claimed – number of rows the conditional update changed (0 or 1)
- Returns:
True if this call consumed the nonce, else False
- Return type:
bool
- created_at
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- get_next_by_created_at(*, field=<django.db.models.fields.DateTimeField: created_at>, is_next=True, **kwargs)
- get_previous_by_created_at(*, field=<django.db.models.fields.DateTimeField: created_at>, is_next=False, **kwargs)
- id
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- nonce
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- objects = <django.db.models.manager.Manager object>
- classmethod purge_stale()[source]
Delete used or expired nonces. Intended for a periodic job.
- Variables:
cutoff – timestamp before which unused nonces are considered expired
stale – queryset of nonces that are used or past
cutoffdeleted – total number of rows deleted
- Returns:
number of rows deleted
- Return type:
int
- used
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- user
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- user_id
walletauth.signals – Walate auth database signals and triggers module
Keep the linked-address registry consistent with Profile.address.
The walletauth flows (authorize, set-primary, link) reconcile the registry
themselves, but the profile can also be edited elsewhere – e.g. clearing or
changing the address on the profile page. This post_save receiver makes the
registry track Profile.address wherever it changes: it drops any is_primary
row that no longer matches the current address (and all of them when the address
is cleared). It deliberately does not create the primary row – that happens
when the address is proven via the wallet flow – so it never collides with code
that stamps the row explicitly. Crucially, dropping a stale primary also removes
its login_enabled flag, so a removed address can no longer be used to sign in.
Matching is on the raw stored address (which mirrors Profile.address), so
no canonicalization or algod call is needed in the save path.
- walletauth.signals.reconcile_primary_registry(sender, instance, **kwargs)[source]
Drop primary rows that no longer match
instance.address.- Parameters:
sender – the Profile model class
instance (core.models.Profile) – the profile just saved
walletauth.throttling – Module containing throttling for walletauth app’s views
Module containing throttling for walletauth app’s views.
- class walletauth.throttling.WalletAuthRateThrottle[source]
Bases:
_SafeRateMixin,UserRateThrottlePer-user throttle for the wallet nonce/verify (authorize) endpoints.
The rate is read from
REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]["walletauth"](e.g."30/min"). When that scope is not configured the throttle is inert (no limiting) rather than raising, so the endpoints work out of the box and operators opt into a limit by setting the rate.- Variables:
WalletAuthRateThrottle.scope – throttle scope key for the rate lookup
- scope = 'walletauth'
- class walletauth.throttling.WalletLoginRateThrottle[source]
Bases:
_SafeRateMixin,AnonRateThrottlePer-IP throttle for the unauthenticated wallet sign-in endpoints.
Sign-in is anonymous, so the limit is keyed by client IP. Configure
REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]["walletauth-login"](e.g."10/min"); inert until set.- Variables:
WalletLoginRateThrottle.scope – throttle scope key for the rate lookup
- scope = 'walletauth-login'
walletauth.urls – Wallet authentication URL configuration module
walletauth.verifiers – Verification module
Chain-agnostic wallet proof verifiers.
Every supported chain implements the same shape: given the address being
authorized plus the issued nonce/prefix and the raw request payload,
return the proven Algorand address on success or None on failure. For
Algorand the proven address is the signer’s own address; for the deferred EVM
path it will be the xChain-derived Algorand counterpart, so the existing
permission/portfolio model applies unchanged either way.
- walletauth.verifiers.AUTH_METHOD_BY_CHAIN = {'algorand': 'algorand_wallet', 'evm': 'evm_xchain'}
auth_method recorded on the profile, keyed by request chain.
- class walletauth.verifiers.AlgorandSignedTxnVerifier(*, expected_genesis_id='mainnet-v1.0', expected_genesis_hash='wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=', algod_factory=<function algod_instance>)[source]
Bases:
WalletProofVerifierVerify a signed 0-ALGO self-payment carrying the nonce in its note.
Rekeyed accounts are supported: when the signed transaction claims an authorizing address that differs from the sender, the claim is confirmed against on-chain
auth-addrstate via algod before the signature is trusted. A fabricated rekey claim is therefore rejected.- recover(*, nonce, prefix, payload)[source]
Validate the Algorand proof and return the signer’s address.
- Parameters:
nonce (str) – server-issued single-use challenge
prefix (str) – domain-scoped nonce prefix
payload (dict) – raw request data; must carry
signedTransaction
- Variables:
signed_b64 – base64-encoded signed transaction from the payload
raw – msgpack bytes decoded from
signed_b64stxn – reconstructed signed transaction
txn – the inner (unsigned) transaction being inspected
sender – the self-payment sender, returned as the proven address
- Returns:
the proven (sender) address when valid, else None
- Return type:
str | None
- class walletauth.verifiers.EvmXChainVerifier[source]
Bases:
WalletProofVerifierRecover an EVM signer from an EIP-191
personal_signsignature.The signature proves control of the EVM private key over the challenge
prefix+nonce.recover()returns the signer’s EVM address (lowercased so it matches the address the nonce was issued for); the EVM -> Algorand mapping (the xChain logicsig account fromnameservice.xchain.check_evm_address()) is the resolver’s concern, not the verifier’s. The sharedverify()(authorize) builds on this.The logicsig’s own on-chain scheme is EIP-712; that is only relevant when spending from the xChain account. Proving control of the EVM key is what proves control of the derived Algorand account, so a plain message signature over our challenge is sufficient here.
- recover(*, nonce, prefix, payload)[source]
Recover and return the lowercased EVM signer address, or
None.- Parameters:
nonce (str) – server-issued single-use challenge
prefix (str) – domain-scoped nonce prefix
payload (dict) – raw request data; must carry
signature(0x hex)
- Variables:
signature – the EIP-191 signature over
prefix+noncemessage – the exact text the wallet signed
recovered – the EIP-55 address eth-account recovers
- Returns:
lowercased
0xaddress, or None on any failure- Return type:
str | None
- walletauth.verifiers.MAX_EVM_SIGNATURE_LENGTH = 256
An EIP-191 personal_sign signature is 65 bytes (0x + 130 hex = 132 chars). Cap with slack to bound work and reject junk before recovery.
- walletauth.verifiers.MAX_SIGNED_TXN_B64_LENGTH = 2048
Upper bound on the base64 signed-transaction payload. A signed 0-ALGO self-payment carrying the nonce is a few hundred bytes; this generous cap rejects oversized payloads before base64/msgpack decoding (defense in depth; Django’s DATA_UPLOAD_MAX_MEMORY_SIZE already bounds the request body).
- exception walletauth.verifiers.NotSupported[source]
Bases:
ExceptionRaised when a verifier for a recognized chain is not yet enabled.
- class walletauth.verifiers.WalletProofVerifier[source]
Bases:
objectInterface: prove that a signed challenge demonstrates control of an address.
Subclasses implement
recover(), which validates a chain-specific proof and returns the proven Algorand address that produced it (the signer’s own address for Algorand; the xChain-derived counterpart for EVM). The sharedverify()wrapsrecover()for the authorize flow, where the expected address is already known; the login flow callsrecover()directly and resolves the account from whatever address signed.- recover(*, nonce, prefix, payload)[source]
Validate the proof and return the proven address, or
None.- Parameters:
nonce (str) – server-issued single-use challenge
prefix (str) – domain-scoped nonce prefix
payload (dict) – raw request data (chain-specific proof fields)
- Returns:
proven Algorand address or None
- Return type:
str | None
- verify(*, address, nonce, prefix, payload)[source]
Return
addresswhen the proof proves control of it, elseNone.- Parameters:
address (str) – address the user is trying to authorize
nonce (str) – server-issued single-use challenge
prefix (str) – domain-scoped nonce prefix
payload (dict) – raw request data (chain-specific proof fields)
- Variables:
proven – address recovered from the proof, if any
- Returns:
addresswhenrecoverreturns it, else None- Return type:
str | None
walletauth.views – Wallet authentication views module
walletauth.tests – Wallet authentication unit-tests package
widgethost – Widget host package
Initialization module for widgethost package.
widgethost.access – Widget access module
User access checks for widgets, resolved by widget id via the registry.
Lets the host (core models, template filters) ask whether a user may use a widget without importing that widget’s modules — so a widget being absent yields a denied result rather than an import error.
- widgethost.access.can_access_widget(widget_id, profile, size)[source]
Return whether profile may access the widget for size addresses.
Returns False when the widget identified by widget_id is not installed.
- Parameters:
widget_id (str) – unique widget identifier
profile (
core.models.Profile) – the user’s profilesize (int) – number of Algorand addresses
- Variables:
manifest – the widget’s parsed manifest, or None when not installed
- Returns:
Boolean
widgethost.enforcement – Widget enforcement module
Per-request widget access enforcement for the host site.
The reusable gate compares the user’s permission against the widget manifest’s
required_permission band for a resolved address count. Each widget resolves
its own bundle/addresses (via the host’s bundle_and_addresses_from_path) and
calls WidgetAccessMixin.manifest_test_func() with the resolved count, so the
mixin stays agnostic of how a widget reads its URL value. It composes with the
widgets app’s existing BaseUserPassesTestMixin (authentication and profile
presence checks).
- class widgethost.enforcement.WidgetAccessMixin[source]
Bases:
BaseUserPassesTestMixinProvide a manifest-driven permission gate for widget views.
The widget sets
manifest(a class attribute or viaas_view) and callsmanifest_test_func()from its owntest_funcafter resolving the size.- Variables:
WidgetAccessMixin.manifest – the widget’s parsed manifest
- manifest = None
widgethost.manifest – Widget manifest module
Loading, validation, and permission evaluation for widget manifests.
A widget describes itself in a widget.toml file. This module parses and
validates that description and evaluates the host-side required_permission
gate (the forkable, per-user bar) against a resolved address count.
- class widgethost.manifest.Manifest(data)[source]
Bases:
objectParsed and validated description of a single widget.
- Variables:
Manifest.id – unique widget slug
Manifest.name – human-readable widget name
Manifest.version – widget version string
Manifest.origin – provenance, one of inhouse or thirdparty
Manifest.capability – privilege level, one of public or engine-backed
Manifest.revenue_account – payout identifier for thirdparty widgets
Manifest.required_permission – user-permission gate, integer or band list
Manifest.routes – route declarations served by the widget
Manifest.consumers – websocket consumer declarations
Manifest.menu – optional menu entry declaration
Manifest.engine_endpoints – declared privileged engine scopes
Manifest.data – declared user-context keys the host must inject
Manifest.hosts – declared external hosts the widget may call
Manifest.assets – static and template directory declarations
Manifest.category – optional UI grouping, e.g. ‘swap’ (metadata only)
- exception widgethost.manifest.ManifestError[source]
Bases:
ExceptionRaised when a widget manifest is missing or malformed.
- widgethost.manifest.addresses_limit_for_permission(required_permission, profile_permission)[source]
Return the largest address count profile_permission qualifies for.
Returns 0 when the permission clears no band (or for a bare-integer gate), which the historic widget uses to choose between its denial messages.
- Parameters:
required_permission (int or list) – integer or ordered band list from the manifest
profile_permission (int) – the user’s permission integer
- Variables:
allowed – largest qualifying max_addresses, defaulting to zero
band – currently evaluated permission band mapping
- Returns:
int
- widgethost.manifest.can_access(profile_permission, required_permission, size)[source]
Return whether a user with profile_permission may use the widget.
- Parameters:
profile_permission (int) – the user’s permission integer
required_permission (int or list) – integer or ordered band list from the manifest
size (int) – number of resolved Algorand addresses
- Variables:
required – permission integer needed for the given size, or None
- Returns:
Boolean
- widgethost.manifest.load_manifest(path)[source]
Load, validate, and return the widget manifest stored at path.
- Parameters:
path (
pathlib.Path) – full path to a widget.toml file- Variables:
data – parsed widget.toml mapping
- Returns:
- widgethost.manifest.required_permission_for_size(required_permission, size)[source]
Return the permission integer required for size addresses, or None.
None means size exceeds the largest band and access must be denied.
- Parameters:
required_permission (int or list) – integer or ordered band list
size (int) – number of resolved Algorand addresses
- Variables:
band – currently evaluated permission band mapping
- Returns:
int
- widgethost.manifest.validate_manifest(data)[source]
Raise
ManifestErrorwhen the manifest mapping is invalid.- Parameters:
data (dict) – parsed widget.toml mapping
- Variables:
field – currently checked required field name
widgethost.registry – Widget registry module
Discovery of widgets from their manifests.
Each widget keeps its own urls.py / routing.py (regex routes that the
existing widgets/urls.py and widgets/routing.py already auto-include).
This module replaces the hand-maintained INHOUSE_WIDGETS / THIRDPARTY_WIDGETS
lists with manifest discovery: the presence of a widget.toml registers a widget.
- widgethost.registry.discover_manifests()[source]
Discover and load every widget manifest under the widgets package.
- Variables:
manifests – collection of dotted-package and parsed-manifest pairs
manifest_path – full path to a discovered widget.toml file
relative – widget directory path relative to the widgets package
dotted – dotted Python path of the widget package
- Returns:
list
- widgethost.registry.discover_widgets()[source]
Return discovered inhouse and thirdparty widget identifiers.
- Variables:
inhouse – collection of discovered inhouse widget identifiers
thirdparty – collection of discovered thirdparty widget identifiers
manifest – a discovered widget’s parsed manifest
- Returns:
two-tuple
- widgethost.registry.manifest_for(widget_id)[source]
Return the manifest for widget_id, or None when it is not installed.
- Parameters:
widget_id (str) – unique widget identifier
- Returns:
- widgethost.registry.manifests_by_id(refresh=False)[source]
Return discovered manifests keyed by id, building the cache once.
- Parameters:
refresh (bool) – rebuild the cache instead of reusing it
- Variables:
_manifests_by_id – process-wide cache of id to manifest
- Returns:
dict
- widgethost.registry.swap_client_cfg(router_id)[source]
Return a router’s public swap-client config for the browser.
- Parameters:
router_id (str) – the router key, e.g.
"folks"or"haystack"- Returns:
{"network", "referrer", "fee_bps", "api_key"}- Return type:
dict
- widgethost.registry.swap_entry_url(router_id, value)[source]
Return the swap widget shell URL for
router_idandvalue, or “”.Single seam for how router widgets are mounted: each swap widget’s shell URL is named after its widget id (e.g. “folks”). Returns “” when there is no router or the name can’t be reversed, so callers degrade gracefully.
- Parameters:
router_id (str) – chosen swap-router widget id
value (str) – address or bundle hash to swap from
- Returns:
str
- widgethost.registry.swap_holdings_tmpl(router_id)[source]
Return a holdings-URL template (literal
ADDRESSplaceholder) or “”.- Parameters:
router_id (str) – chosen swap-router widget id (presence gate only)
- Returns:
str
- widgethost.registry.swap_routers()[source]
Return discovered swap-router widgets as (id, name) pairs for selection.
A widget opts in by declaring
category = "swap"in its manifest. The user settings page uses this to offer a preferred router; adding a router widget therefore makes it selectable with no settings-page change.- Variables:
routers – collection of (id, name) pairs for swap-category widgets
- Returns:
list
widgethost.tests – Widget host unit-tests package
Initialization module for widgethost unit tests.
widgethost.swap_views – Widget swap-related views
Router-agnostic base views shared by every inhouse swap-router widget.
Each router widget (folks, haystack, …) subclasses these and sets only
template_name + manifest (and, for the shell, client_cfg_context).
The holdings/asset endpoints are generic (account:holdings / assets:lookup); the
only per-router differences are the templates and the shell’s non-secret client
config.
- class widgethost.swap_views.BaseSwapAssetsView(**kwargs)[source]
Bases:
WidgetAccessMixin,TemplateViewhtmx partial: ranked asset metadata for a query via assets:lookup.
- Variables:
manifest – this widget’s parsed manifest
- get_context_data(*args, **kwargs)[source]
Look up assets by name/unit/id for the
qquery parameter.- Returns:
dict
- manifest = None
- class widgethost.swap_views.BaseSwapHoldingsView(**kwargs)[source]
Bases:
WidgetAccessMixin,TemplateViewhtmx partial: fresh holdings for one linked address via account:holdings.
Gated to the user’s own (linked) address. Emits an F1-safe JSON island.
- Variables:
manifest – this widget’s parsed manifest
address – the linked Algorand address whose holdings are fetched
- address = None
- get_context_data(*args, **kwargs)[source]
Fetch and flatten the address’ holdings for the panel.
- Returns:
dict
- manifest = None
- class widgethost.swap_views.BaseSwapShellView(**kwargs)[source]
Bases:
WidgetAccessMixin,TemplateViewRender a router widget’s swap shell for an address or bundle page.
- Variables:
manifest – this widget’s parsed manifest (set by the subclass)
bundle – hash made from public Algorand address(es)
addresses – space separated collection of public Algorand addresses
- addresses = None
- bundle = None
- client_cfg_context()[source]
Per-router non-secret client config for the shell. Override.
- Returns:
dict
- get_context_data(*args, **kwargs)[source]
Expose bundle, addresses, linked subset, router id + client config.
- Returns:
dict
- manifest = None
- widgethost.swap_views.safe_json_for_script(value)[source]
json.dumpsescaped so it cannot break out of a<script>block.Audit finding F1: holdings carry attacker-mintable ASA name/unit, and
json.dumpsdoes not escape</>/&. These are valid JSON escapes thatJSON.parserestores, so there is no behaviour change.- Parameters:
value – any JSON-serialisable object
- Returns:
a JSON string safe to embed in an HTML
<script>element- Return type:
str