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: Exception

Raised when the ASA Stats backend returns a non-success response.

api.client.download_export(bundle)[source]

Return the export archive bytes (streamed) for bundle.

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 manifest engine_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_price()[source]

Return {“price”: <ALGO price in USDC>}.

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.client.reset_export(bundle)[source]

Delete the backend export archive and reset its status for bundle.

api.client.start_export(value, addresses)[source]

Trigger backend CSV-export processing. addresses is authoritative.

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.

value is 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’s bundle_from_addresses cross-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.

class api.permissions.CanAccessApiPermission[source]

Bases: BasePermission

Permission check if user has acceess to API.

has_permission(request, view)[source]

FIXME: implement commented out routine after a month passes in production.

Also change from JWTStatelessUserAuthentication to JWTAuthentication afterwards.

api.serializers – API serializers module

Module containing api app’s serializers.

class api.serializers.AccountInfoSerializer(*args, **kwargs)[source]

Bases: Serializer

Serialize 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: Serializer

Serialize 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: Serializer

Serialize 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: Serializer

Serialize 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: Serializer

Serialize 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: Serializer

Serialize 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: Serializer

Serialize collection of addresses and .algo names.

Variables:

BundleRetrieveSerializer.addresses – collection of public Algorand addresses

class api.serializers.BundleHashSerializer(*args, **kwargs)[source]

Bases: Serializer

Serialize bundle hash.

Variables:

BundleRetrieveSerializer.bundle – unique hash for public Algorand addresses

class api.serializers.DistributionLinkSerializer(*args, **kwargs)[source]

Bases: Serializer

Serialize 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: Serializer

Serialize 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: Serializer

Serialize 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: Serializer

Serialize 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: Serializer

Serialize 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: Serializer

Serialize .algo name.

Variables:

NfdNameSerializer.nfd_name – NFD .algo name

class api.serializers.NftCollectionSerializer(*args, **kwargs)[source]

Bases: Serializer

Serialize 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: Serializer

Serialize NFT currency object.

Variables:
  • NftCurrencySerializer.amount – currency’s amount

  • NftCurrencySerializer.asset – asset’s serializer

class api.serializers.NftItemSerializer(*args, **kwargs)[source]

Bases: Serializer

Serialize 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: Serializer

Serialize 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: Serializer

Serialize 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.NftSaleTypeQuerySerializer(*args, **kwargs)[source]

Bases: Serializer

class api.serializers.NftSerializer(*args, **kwargs)[source]

Bases: Serializer

Serialize 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: Serializer

Serialize NFT trait object.

Variables:
  • NftTraitSerializer.name – NFT trait name

  • NftTraitSerializer.value – NFT trait value

class api.serializers.NftUrlSerializer(*args, **kwargs)[source]

Bases: Serializer

Serialize NFT URL object.

Variables:
  • NftUrlSerializer.typ – NFT URL type

  • NftUrlSerializer.url – URL value

class api.serializers.NotevalItemSerializer(*args, **kwargs)[source]

Bases: Serializer

Serialize 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: Serializer

Serialize 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: Serializer

Serialize 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: Serializer

Serialize 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

Bases: tuple

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

Alias for field number 2

value

Alias for field number 0

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

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

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

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

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

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: AuthBase

Requests 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: StaticViewSitemap

Static 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

items()[source]

Sets static pages names to include in sitemap file.

Returns:

list of page names

priority = 1.0
protocol = 'http'
class config.sitemaps.StaticViewSitemap[source]

Bases: Sitemap

Static 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.

class core.apps.CoreConfig(app_name, app_module)[source]

Bases: AppConfig

Main class for core application.

Variables:

CoreConfig.name – app name

default_auto_field = 'django.db.models.BigAutoField'
name = 'core'
ready()[source]

Run this import when Django starts.

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.context_processors.global_constants(request)[source]

Return collection of project’s constants.

Parameters:

request (django.http.HttpRequest) – HTTP request object

Returns:

dict

core.context_processors.walletconnect(request)[source]

Expose the WalletConnect project id to template context.

Parameters:

request (django.http.HttpRequest) – current request (unused; signature required by Django)

Returns:

mapping with the WalletConnect project id

Return type:

dict

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_value may export a bundle of size.

Free (no-tier) users may export up to the free limit; paid tiers extend it. permission_value is None for 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: Form

Form 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: ModelForm

Base 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: Form

Subclass 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.

signup(request, user)[source]

Dummy overridden Form.signup method as required by django-allauth.

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: Form

Form 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: Form

Form 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: Form

Form 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: BaseBundleNameForm

Form 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: ModelForm

Form 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.

class Meta[source]

Bases: object

fields = ('preferred_explorer',)
model

alias of Profile

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: ProfileInlineForm

Formset for editing profile’s data. It is instantiated together with UpdateUserForm form 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
model

alias of Profile

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: BaseInlineFormSet

Form class for editing user profile’s data.

Variables:

permission – user’s permission on website

class Meta[source]

Bases: object

fields = ['address']
model

alias of Profile

address = <django.forms.fields.CharField object>
clean()[source]

Validate if address field contains a valid public Algorand address.

Returns:

list

class core.forms.ProfileRouterForm(*args, **kwargs)[source]

Bases: ModelForm

Form 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.

class Meta[source]

Bases: object

fields = ('preferred_router',)
model

alias of Profile

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: ModelForm

Model 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: MinifyHtmlMiddleware

Custom 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}
class core.middleware.CustomUserHeaderMiddleware(get_response)[source]

Bases: object

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: Model

User’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:

BundleName

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_absolute_url()[source]

Return url of the edit bundle name page.

Returns:

str

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.parent is a ForwardManyToOneDescriptor instance.

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.

save(**kwargs)[source]

Call super save method after name and bundle fields are created if needed.

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: Model

App’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.

address_authorization_note()[source]

Return unique user’s hash.

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 0x EVM 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

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.children is a ReverseManyToOneDescriptor instance.

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

bundlenames()[source]

Return all profile’s bundle names.

Returns:

QuerySet

can_access_api()[source]

Return True if user is allowed to access API.

Returns:

Boolean

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_absolute_url()[source]

Return url of the profile home page.

Returns:

url

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.children is a ReverseManyToOneDescriptor instance.

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:

Profile

save(**kwargs)[source]

Reset authorized and permission fields if authorized address is changed.

show_sort_and_filter()[source]

Return True if sorting and filtering panel should be presented to user.

Returns:

Boolean

tier_name()[source]

Return subscription tier name from instance’s permission value.

Returns:

str

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.place is a ForwardOneToOneDescriptor instance.

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: object

Default no-op permission backend.

Deployers subclass this and point settings.PERMISSION_PROVIDER at 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.

refresh()[source]

Run the periodic permission-backend update. No-op by default.

Returns:

None

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

Return display markup for a subscription tier name.

Parameters:

tier_name (str) – subscription tier name

Returns:

str

votes_and_permission(address)[source]

Return the votes and permission pair for an address.

Parameters:

address (str) – public Algorand address

Returns:

two-tuple of ints, or None to leave the profile unchanged

core.permission_provider.get_permission_provider()[source]

Return the configured permission provider instance, built once.

Resolves settings.PERMISSION_PROVIDER lazily 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:

PermissionProvider

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: PermissionProvider

Permission backend backed by the on-chain Permission dApp and Subtopia.

refresh()[source]

Update the mainnet Permission dApp boxes from chain.

Returns:

None

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

Return Subtopia tier link markup for a tier name.

Parameters:

tier_name (str) – subscription tier name

Returns:

str

votes_and_permission(address)[source]

Fetch votes and permission for an address from the Permission dApp.

Parameters:

address (str) – public Algorand address

Variables:
  • box_name – base64 encoded box name

  • values – deserialized box values

Returns:

two-tuple

core.permission_providers.permissiondapp.formatted_subscription_timestamps(subscriptions)[source]

Return provided subscriptions with values in a form of days left.

Parameters:

subscriptions (dict) – collection of tier names and expiration epochs

Returns:

dict

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.permission_providers.updater.run_permissions_update()[source]

Run infinite loop and update user permissions.

core.permissions – Application permissions module

Module containing core app mixin classes for subscription permissions.

class core.permissions.BundleNamesRedirection[source]

Bases: UserPassesTestMixin

Base class redirecting to home when access is denied.

handle_no_permission()[source]

Calls super method and redirect to subscribe page on exception.

class core.permissions.CanAccessApiMixin[source]

Bases: SubscribeRedirection

Class with method for determining if user is allowed to access API.

test_func()[source]

Return True if user is allowed to create another bundle name.

Returns:

Boolean

class core.permissions.CanAccessAuthorizeMixin[source]

Bases: ProfileRedirection

Class with method for determining if user is allowed to access API.

test_func()[source]

Return True if user is allowed to create another bundle name.

Returns:

Boolean

class core.permissions.CanAddBundleNameMixin[source]

Bases: SubscribeRedirection

Class with method for determining if user can add a bundle name.

test_func()[source]

Return True if user is allowed to create another bundle name.

Returns:

Boolean

class core.permissions.CanUseBundleNamesMixin[source]

Bases: BundleNamesRedirection

Class with method for determining if user can use created bundle names.

test_func()[source]

Return True if user is allowed to use created bundle names.

Returns:

Boolean

class core.permissions.ProfileRedirection[source]

Bases: UserPassesTestMixin

Base class redirecting to profile page when access is denied.

handle_no_permission()[source]

Calls super method and redirect to profile page on exception.

class core.permissions.SubscribeRedirection[source]

Bases: UserPassesTestMixin

Base class redirecting to subscribe when access is denied.

handle_no_permission()[source]

Calls super method and redirect to subscribe page on exception.

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 sending

  • instance (User) – instance of the sender class

  • created (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 sending

  • user (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 sending

  • instance (object of User) – instance of the sender class

core.templatetags – Template tags package

core.templatetags.core_extras – Core extra template tags

Module containing Django templates filters and tags for the website.

core.templatetags.core_extras.abs_value(value)[source]

Return the absolute value of value, or 0 if unparseable.

Used by snippets/asas/program.html to display the magnitude of negative amounts (e.g. borrowed asset amount) inside parens without a stray minus sign — the parens + myred-text styling already convey the negative semantics.

For int input returns an int (so it composes cleanly with amount_repr which expects int(amount) / 10**decimals); for non-int input returns a float.

Parameters:

value – numeric value as int, float, Decimal, or string

Returns:

type matching the input where possible

core.templatetags.core_extras.amount_repr(amount, decimals)[source]

Return amount divided with ten on provided decimals.

Parameters:
  • amount (int) – asset amount

  • decimals (int) – number of decimal places

Returns:

string

core.templatetags.core_extras.asa_icon(asaitem)[source]

Return the absolute CDN path to the icon for an asaitem.

For non-USDC assets, look for a provider override match in three places (in order): explicit provider name on any program, the asset’s display name, and linked URLs on programs. The redundancy matches how the serialized payload describes Lofty/ANote assets — some entries carry the provider explicitly, some only the linked URL, some only the asset name prefix. Falls back to the standard per-asset thumbnail path.

Parameters:

asaitem (dict) – serialized asaitem

Returns:

str

core.templatetags.core_extras.bundle_hash(collection)[source]

Return bundle hash from provided addresses collection.

Parameters:

collection (list) – collection of public Algorand addresses

Returns:

str

core.templatetags.core_extras.dict_get(mapping, key)[source]

Return value from dict-like mapping for given key.

Replaces the legacy dict_value filter. Used for color-slot lookups keyed by asset id, where Django’s dotted access doesn’t reach (numeric keys aren’t valid attribute names).

Parameters:
  • mapping (dict) – dict to look up in

  • key – lookup key

Returns:

value at key, or empty string if missing

core.templatetags.core_extras.dist_height(distchart, max_size=475, min_size=80)[source]

Return distribution chart canvas height based on provided object size.

Parameters:
  • distchart (dict) – distribution chart data

  • max_size (int) – maximum canvas size

  • min_size (int) – minimum canvas size

Returns:

int

core.templatetags.core_extras.dist_price(d, decimals)[source]

Per-distribution-entry implied ALGO price.

Used by snippets/asas/program.html to render a price line for each row inside a program’s distribution breakdown. Prior to this fix the template reused the parent asaitem’s top-level price for every row in the loop, so all distribution rows displayed the same (wrong) price. This tag computes the price from the specific distribution entry’s own value (ALGO) and amount (raw asset units), scoped per-iteration.

Parameters:
  • d – single distribution dict from prog.distribution; must contain value (ALGO amount, numeric or numeric string) and amount (raw integer asset units, matching the same encoding as prog.amount elsewhere in this template)

  • decimals – asset.decimals, used to convert the raw integer amount into asset-unit terms

Returns:

float price (ALGO per 1 asset unit), or None if the entry is missing data, malformed, or amount is zero

core.templatetags.core_extras.explorer_base(context, explorer='')[source]

Return the viewer’s explorer base URL (provider home).

Used for the native-ALGO / bundle cases that link to the explorer root instead of a specific entity.

Parameters:
  • context (dict) – the template context

  • explorer (str) – optional explicit explorer key override

Returns:

str

core.templatetags.core_extras.explorer_name(context, explorer='')[source]

Return the viewer’s explorer display name (e.g. "Allo").

Parameters:
  • context (dict) – the template context

  • explorer (str) – optional explicit explorer key override

Returns:

str

core.templatetags.core_extras.explorer_tx_path(context, explorer='')[source]

Return the viewer’s explorer transaction path segment (e.g. "tx/").

Handed to the swap controller via a data attribute so the success link follows the viewer’s chosen explorer.

Parameters:
  • context (dict) – the template context

  • explorer (str) – optional explicit explorer key override

Returns:

str

core.templatetags.core_extras.explorer_url(context, entity, value, explorer='')[source]

Return the viewer’s explorer URL for entity and value.

Replaces the hard-coded https://allo.info/... anchors. entity is one of "address", "asset", "transaction".

Parameters:
  • context (dict) – the template context (carries the viewer)

  • entity (str) – blockchain entity kind

  • value – address, asset id, or transaction id

  • explorer (str) – optional explicit explorer key override

Returns:

str

core.templatetags.core_extras.export_access(profile, size)[source]

Gate B: may this browsing user export a bundle of size?

core.templatetags.core_extras.export_capability(deployment_permission, size)[source]

Gate A: is this deployment entitled to export a bundle of size?

core.templatetags.core_extras.get_styling(elem, key)[source]

Return style for the argument.

Parameters:
  • elem (dictionary) – field element

  • key (string) – key to look for

Returns:

type/style for provided key

core.templatetags.core_extras.has_styling(elem)[source]

Return True if there’s styling for element.

Parameters:

elem (dict) – field element

Returns:

Boolean

core.templatetags.core_extras.historic_access(profile, size)[source]

Return True if provided profile can access historic widget for size.

Parameters:
  • profile (class:core.models.Profile) – user profile instance

  • size (int) – number of Algorand addresses

Returns:

Boolean

core.templatetags.core_extras.historic_data(collection)[source]

Return historic widget URL suffix and bundle length from provided arguments.

Parameters:

collection (list) – collection of Algorand addresses

Returns:

two-tuple

core.templatetags.core_extras.integer_comma(value)[source]

Return provided integer value to string with thousand separators.

Parameters:

value (int) – value to format

Returns:

string

core.templatetags.core_extras.invert_price(price)[source]

Return 1/price (or 0 when price is missing/zero).

Used by the per-distribution price line in snippets/asas/program.html (Phase 5c-fixes / W3). price is the parent asaitem’s price field — ALGO per 1 unit of asset. Inverting it gives asset units per 1 ALGO, which is the form the website renders (e.g. 0.10966392 USDC/ALGO).

Parameters:

price – Decimal/string/float price value

Returns:

1/price as a float, or 0.0 if price is falsy or non-numeric

core.templatetags.core_extras.is_distribution(name)[source]

Return True if provided name represents a distributed pool.

Parameters:

name (str) – pool name

Returns:

Boolean

core.templatetags.core_extras.is_negative(value)[source]

Return True if value parses as a strictly negative number.

Used by snippets/asas/program.html to detect borrow / debt / loss programs whose prog.value and prog.amount come back negative from the V2 serializer. The template wraps such values in parens and applies the myred-text CSS class.

Parameters:

value – numeric value as int, float, Decimal, or string

Returns:

True if value < 0, False otherwise (including unparseable)

core.templatetags.core_extras.list_item(collection, index)[source]

Return value from list at provided index.

Parameters:
  • collection (list) – collection of items

  • index (int) – index in list to fetch value for

Returns:

int/str

core.templatetags.core_extras.program_url_title(program)[source]

Return the anchor title text for a per-program link.

Centralises the legacy "Go to <provider> application" boilerplate that the old templates inlined into every per-key branch.

Parameters:

program (dict) – serialized program object (asaitem.programs[i].program)

Returns:

str

core.templatetags.core_extras.provider_icon(name)[source]

Return the absolute CDN path to a provider’s small icon.

The existing convention is /icons/providers/<name>.png where <name> is the lowercased provider name with whitespace stripped. This matches the legacy coinmarketcap.png / livecoinwatch.png naming derived by hand in the old templates.

Parameters:

name (str) – provider display name from the serialized payload

Returns:

str

core.templatetags.core_extras.short_address(address)[source]

Return short representation of provided address.

Parameters:

address (str) – Algorand address

Returns:

str

core.templatetags.core_extras.short_addresses(addresses)[source]

Return short representation of provided addresses.

Parameters:

addresses (str) – Algorand addresses separated by space

Returns:

str

core.templatetags.core_extras.split_by_space(addresses)[source]

Return collection of addresses from space-separated addresses.

Parameters:

addresses (str) – Algorand addresses separated by space

Returns:

list

core.templatetags.core_extras.strid(prefix, number)[source]

Return string created from provided string prefix and integer.

Parameters:
  • prefix (str) – prefix of the future string

  • number (int) – integer part of the future string

Returns:

string

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:

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 operation and target_id (plus enabled for set_login and a step-up nonce/signature for privilege-expanding operations)

Return type:

django.http.HttpResponse

Render the ‘link another wallet’ page (reuses the authorize wallet UI).

Parameters:

request – the authenticated request

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.

manage.main()[source]

Run 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.cache.cached_bundle(bundle, cache_client)[source]

Return addresses associated with provided bundle from cache.

Parameters:
  • bundle (str) – hash value associated with target addresses

  • cache_client (Redis) – Redis client instance

Variables:

value – cached value

Returns:

str

utils.cache.cupdate_bundle(bundle, addresses, cache_client)[source]

Update cache with bundle named tuple.

Parameters:
  • bundle (str) – hash made from provided addresses

  • addresses (string) – Algorand addresses separated by spaces

  • cache_client (Redis) – Redis client instance

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 legacy asas / values / nft_values shapes.

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 collection

  • nft_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 omitted

  • delay (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.

class utils.constants.users.BundleLimit(count, size)

Bases: tuple

count

Alias for field number 0

size

Alias for field number 1

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, set de-duplicates, sorted makes 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 values

  • app_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 Referer for request, or None.

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.helpers.weighted_randomized_banner(banners=[])[source]

Select a single banner from a list based on their assigned weights.

Parameters:

banners (list) – collection of banners data

Variables:

weights – collection of existing banner weights

Returns:

dict

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

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.userhelpers.user_display(user)[source]

Return human readable representation of provided user instance.

Parameters:

user (class:django.contrib.auth.models.User) – user instance

Returns:

str

utils.userhelpers.validate_address_or_algo_name_url_path(url_path)[source]

Raise ValidationError if provided url_path is Algorand address or .algo name.

Parameters:

url_path (str) – URL path to check

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: Exception

Raised 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 address on chain.

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: Exception

Raised 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 address on chain.

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.addresses.max_secondary_addresses()[source]

Return the configured cap on secondary addresses per account.

Returns:

the cap, from settings.MAX_SECONDARY_ADDRESSES or the default

Return type:

int

walletauth.apps – Wallet authentication configuration module

Module containing walletauth app configuration.

class walletauth.apps.WalletauthConfig(app_name, app_module)[source]

Bases: AppConfig

Application configuration for the walletauth app.

Variables:

WalletauthConfig.name – app name

default_auto_field = 'django.db.models.BigAutoField'
name = 'walletauth'
ready()[source]

Connect the primary-registry reconciliation to Profile saves.

verbose_name = 'Wallet authorization'

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: BaseBackend

Resolve 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

get_user(user_id)[source]

Return the user for user_id as required by the backend interface.

Parameters:

user_id (int) – primary key of the user

Returns:

the 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:

  1. 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 the b"MX" used by algosdk.util.verify_bytes for arbitrary signBytes messages – using the latter here would reject every real wallet signature.

  2. Broadens the caught exceptions so a malformed signature or address yields False instead of propagating, since this helper is called directly by the verifier rather than from inside a blanket try/except in 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_key

  • prefixed_messageb"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 address is connected to user (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 addresses connected to user (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: Exception

Raised when login is disabled on the primary address.

exception walletauth.management.CannotRemovePrimary[source]

Bases: Exception

Raised when removal targets the primary address.

walletauth.management.is_bootstrap_promotion(profile, target)[source]

Whether target may 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.address predates the linked-address registry: linking that same address creates a non-primary row (because Profile.address is already set in link_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

  • target is the address already authorized on the profile (Profile.address) – an address the account has already proven.

Parameters:
Return type:

bool

walletauth.management.remove_address(profile, linked)[source]

Remove a secondary address from profile.

Parameters:
Raises:

CannotRemovePrimary – when linked is the primary

walletauth.management.set_login_enabled(profile, linked, enabled)[source]

Enable or disable sign-in for a linked address.

Parameters:
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.address and re-derives permission from it. The previous primary stays linked as a (still login-capable) secondary. A no-op if target is already primary.

Parameters:
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) or signedTransaction (Algorand)

Returns:

None on 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: Model

A 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 via login_enabled) and action-gating (e.g. showing a Swap button). Secondaries confer no privilege.

Rows are globally unique on canonical_address so one on-chain account cannot be claimed by two profiles, and a primary is always login-capable (enforced by ck_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 profile already 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.parent is a ForwardManyToOneDescriptor instance.

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: Model

Single-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.

is_expired()[source]

Return True once the nonce is older than NONCE_TTL.

Returns:

Boolean

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: Model

Single-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 to user prevents 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 gets False.

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.

is_expired()[source]

Return True once the nonce is older than NONCE_TTL.

Returns:

Boolean

mark_used()[source]

Mark this nonce as consumed so it cannot be replayed.

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 cutoff

  • deleted – 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.parent is a ForwardManyToOneDescriptor instance.

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:

walletauth.templatetags – Wallet auth template tags package

walletauth.templatetags.walletauth_extras – Wallet auth extra template tags

Template tags for embedding the wallet connector on any page.

Exposing the supported-wallet list as a tag lets the sign-in partial be dropped into the allauth login template (or anywhere) without a custom view or context processor: {% supported_wallets as wallets %} then iterate.

walletauth.templatetags.walletauth_extras.supported_wallets()[source]

Return the supported-wallet descriptors for card rendering.

Returns:

list of {"id", "name"} wallet descriptors

Return type:

list

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, UserRateThrottle

Per-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, AnonRateThrottle

Per-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: WalletProofVerifier

Verify 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-addr state 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_b64

  • stxn – 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: WalletProofVerifier

Recover an EVM signer from an EIP-191 personal_sign signature.

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 from nameservice.xchain.check_evm_address()) is the resolver’s concern, not the verifier’s. The shared verify() (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+nonce

  • message – the exact text the wallet signed

  • recovered – the EIP-55 address eth-account recovers

Returns:

lowercased 0x address, 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: Exception

Raised when a verifier for a recognized chain is not yet enabled.

class walletauth.verifiers.WalletProofVerifier[source]

Bases: object

Interface: 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 shared verify() wraps recover() for the authorize flow, where the expected address is already known; the login flow calls recover() 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 address when the proof proves control of it, else None.

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:

address when recover returns 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 profile

  • size (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: BaseUserPassesTestMixin

Provide a manifest-driven permission gate for widget views.

The widget sets manifest (a class attribute or via as_view) and calls manifest_test_func() from its own test_func after resolving the size.

Variables:

WidgetAccessMixin.manifest – the widget’s parsed manifest

manifest = None
manifest_test_func(size)[source]

Return whether the user clears the manifest gate for size addresses.

Parameters:

size (int) – number of resolved Algorand addresses

Returns:

Boolean

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: object

Parsed 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: Exception

Raised 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:

Manifest

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 ManifestError when 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.manifest.Manifest

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_id and value, 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 ADDRESS placeholder) 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, TemplateView

htmx 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 q query parameter.

Returns:

dict

manifest = None
test_func()[source]

Gate on an authenticated profile (asset metadata is public).

Returns:

Boolean

class widgethost.swap_views.BaseSwapHoldingsView(**kwargs)[source]

Bases: WidgetAccessMixin, TemplateView

htmx 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
test_func()[source]

Resolve the address and gate on permission plus user-linkage.

Returns:

Boolean

class widgethost.swap_views.BaseSwapShellView(**kwargs)[source]

Bases: WidgetAccessMixin, TemplateView

Render 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
test_func()[source]

Resolve bundle/addresses from the URL and apply the permission gate.

Returns:

Boolean

widgethost.swap_views.safe_json_for_script(value)[source]

json.dumps escaped so it cannot break out of a <script> block.

Audit finding F1: holdings carry attacker-mintable ASA name/unit, and json.dumps does not escape </>/&. These are valid JSON escapes that JSON.parse restores, 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