Get wallet identity profile
https://triport.io/v1/wallet/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/identity?chains=eth,base,tronOne request, one JSON: verified on-chain names (ENS, Basenames, Unstoppable Domains, SPACE ID), native balance / nonce / contract flag on every mounted EVM network plus Tron, activity summary, known-address labels, and — on request — deployer detection with the list of created tokens.
{address} is an EVM address (0x + 40 hex characters). The profile is
assembled in parallel from every EVM network mounted on the serving PoP; the
Tron address is derived from the same key and queried over Tron JSON-RPC.
Names are read straight from the chain (Universal Resolver for ENS, the
Basenames registry on Base, Unstoppable Domains ProxyReader on Ethereum and
Polygon, the SPACE ID registry on BNB Smart Chain). A name is returned only
when its forward record resolves back to the queried address
(verified: true), so a reverse record pointing at somebody else's name is
never reported as that name. Names that live off-chain (CCIP-read, e.g.
*.cb.id) are listed in unresolved with reason: offchain_lookup.
The response is 200 even when part of the profile is missing: a network
that is not mounted on this PoP or did not answer is reported per chain in
chains.<net>.error, and a name source that failed is listed in
unresolved. Only when every requested network fails does the endpoint
return 503 all_chains_unavailable.
The deployer group is off by default because it scans the address's CREATE
range: Triport derives every contract address the wallet could have created
(keccak(rlp([address, nonce])) for nonce = 0…N-1), checks which of them
hold code, and probes each for ERC-20 metadata (symbol, name, decimals,
totalSupply). Request it with fields=deployer; deployer_max_nonce caps
the scan (default 2000, ceiling 5000, truncated: true when the wallet's
nonce is higher).
This surface is separate from the Solana wallet REST at
/v1/wallet/{base58}/…, which keeps its own contract and is not tier-gated.
Parameters
addressstringrequired0x + 40 hex characters, any letter case. The response echoes it lower-cased.chainsstringoptionaleth,base,polygon,bsc,robinhood,tron. Default: all six. Unknown id → 400 unknown_chain; a known network not mounted on this PoP → chains.<net>.error: "not_mounted".fieldsstringoptionalnames,balances,activity,labels,deployer. Default names,balances,activity,labels.deployer_max_nonceintegeroptional2000, ceiling 5000.fresh0/1optionalwallet_identity token.Response
Response fields
| Field | Type | Description |
|---|---|---|
address | string | Queried address, lower-cased. |
address_tron | string | Tron base58 form of the same key. |
names[] | array | Verified on-chain names. source ∈ ens, basenames, unstoppable, spaceid; chain is where the record was read; primary marks the address's reverse record; verified means the forward record resolves back to the address; normalized means the name is already ENSIP-15 normalized. |
labels[] | array | Triport labels of known addresses (source: "triport", entity, category ∈ cex, bridge, solver, dex, mixer, fund, other). Only verified labels are returned. |
chains.<net> | object | Per-network state: balance_wei (or balance_sun on Tron), balance in coin units, nonce (null on Tron), is_contract, latency_ms. Present with error instead when the network did not answer. |
deployer | object | Only with fields=deployer: is_deployer, scanned_nonces, truncated, contracts[] (chain, address, nonce, is_erc20, symbol, name, decimals, total_supply), tokens_created, errors. |
activity | object | any_tx, chains_active[] (nonce > 0), max_nonce. |
unresolved[] | array | Name sources that could not answer: chain, source, reason ∈ offchain_lookup, upstream_error, not_mounted, timeout, budget, rpc_error, not_available. Always present (possibly empty). |
meta | object | cached, generated_at, pop (eu/us), cost — tokens charged per tier category. |
Errors
| Code | Meaning | When it happens |
|---|---|---|
400 | invalid_address / unknown_chain / invalid_fields / invalid_deployer_max_nonce | Malformed address, unknown network id, unknown field name, or a negative nonce cap. Body: {"error": "<code>", "message": "…", "code": 400}. |
401 | unauthorized / trial_expired / subscription_expired | Missing or invalid credentials, or the trial/subscription has lapsed. |
403 | tier_insufficient | The API key's tier is below business. Response carries current_tier, required_tier, and the X-Required-Tier header. |
429 | rate_limited | wallet_identity sustained RPS exceeded (or the second token for fresh=1 is not available). Response carries Retry-After. |
503 | all_chains_unavailable | Every requested network failed or none is mounted on this PoP. |
All error bodies use the shared envelope (error, message, request_id).
See errors.md for the full envelope and per-code fields.
Examples
JavaScript (fetch)
const address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045";
const res = await fetch(
`https://triport.io/v1/wallet/${address}/identity?fields=names,balances,deployer`,
{ headers: { Authorization: `Bearer ${process.env.TRIPORT_API_KEY}` } }
);
if (!res.ok) {
const err = await res.json();
throw new Error(`${res.status} ${err.error}: ${err.message}`);
}
const profile = await res.json();
const primary = profile.names.find((n) => n.primary && n.verified);
console.log(primary?.name ?? "(no verified name)", profile.deployer?.tokens_created ?? 0);Python (requests)
import os
import requests
address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
res = requests.get(
f"https://triport.io/v1/wallet/{address}/identity",
params={"chains": "eth,base,bsc", "fields": "names,balances,labels"},
headers={"Authorization": f"Bearer {os.environ['TRIPORT_API_KEY']}"},
timeout=30,
)
res.raise_for_status()
profile = res.json()
for chain, state in profile["chains"].items():
print(chain, state.get("balance"), state.get("error", ""))Filtering a list of addresses (shell)
while read -r addr; do
curl -s "https://triport.io/v1/wallet/$addr/identity?fields=names,balances" \
-H "Authorization: Bearer $TRIPORT_API_KEY" \
| jq -r 'select(.names | length > 0) | "\(.address) \(.names[0].name) \(.chains.eth.balance // "-")"'
done < addresses.txtNotes
- Cost accounting: each request charges one
wallet_identitytoken plus, per queried network, one<net>_read_rpctoken per internal upstream call (BSCeth_callis charged asbsc_read_rpc_heavy). The exact breakdown is returned inmeta.cost, so batch runs can be sized against the key's per-network budgets. - Caching: names are cached for 15 minutes, balances and nonces for 60
seconds per PoP;
meta.cached: truemeans no upstream call was made.fresh=1bypasses the cache at double thewallet_identitycost. - Tron: the account model has no nonce, so
chains.tron.nonceisnulland the deployer scan skips Tron; activity comes from the account's last operation time. - Off-chain names: CCIP-read resolvers (ENSIP-10) are not followed in this
version; such names appear in
unresolvedwithreason: offchain_lookuprather than being silently dropped. - Related: the Solana wallet surface is documented under Solana REST; the tier matrix is in Rate limits and tiers.