TriportRPC

Get wallet identity profile

GEThttps://triport.io/v1/wallet/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/identity?chains=eth,base,tron

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

Cross-chain — Ethereum, Base, Polygon, BNB Smart Chain, Robinhood Chain, Tron— (tier-gated, see below)Business — 30 rps (wallet_identity, burst ×2); Enterprise — 150 rps

{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

addressstringrequired
Path segment. EVM address, 0x + 40 hex characters, any letter case. The response echoes it lower-cased.
chainsstringoptional
Comma-separated subset of eth,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".
fieldsstringoptional
Comma-separated projection of names,balances,activity,labels,deployer. Default names,balances,activity,labels.
deployer_max_nonceintegeroptional
Nonce range scanned for created contracts. Default 2000, ceiling 5000.
fresh0/1optional
Bypass the profile cache (names 15 min, balances 60 s). Costs a second wallet_identity token.

Response

Response fields

FieldTypeDescription
addressstringQueried address, lower-cased.
address_tronstringTron base58 form of the same key.
names[]arrayVerified on-chain names. sourceens, 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[]arrayTriport labels of known addresses (source: "triport", entity, categorycex, bridge, solver, dex, mixer, fund, other). Only verified labels are returned.
chains.<net>objectPer-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.
deployerobjectOnly with fields=deployer: is_deployer, scanned_nonces, truncated, contracts[] (chain, address, nonce, is_erc20, symbol, name, decimals, total_supply), tokens_created, errors.
activityobjectany_tx, chains_active[] (nonce > 0), max_nonce.
unresolved[]arrayName sources that could not answer: chain, source, reasonoffchain_lookup, upstream_error, not_mounted, timeout, budget, rpc_error, not_available. Always present (possibly empty).
metaobjectcached, generated_at, pop (eu/us), cost — tokens charged per tier category.

Errors

CodeMeaningWhen it happens
400invalid_address / unknown_chain / invalid_fields / invalid_deployer_max_nonceMalformed address, unknown network id, unknown field name, or a negative nonce cap. Body: {"error": "<code>", "message": "…", "code": 400}.
401unauthorized / trial_expired / subscription_expiredMissing or invalid credentials, or the trial/subscription has lapsed.
403tier_insufficientThe API key's tier is below business. Response carries current_tier, required_tier, and the X-Required-Tier header.
429rate_limitedwallet_identity sustained RPS exceeded (or the second token for fresh=1 is not available). Response carries Retry-After.
503all_chains_unavailableEvery 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.txt

Notes

  • Cost accounting: each request charges one wallet_identity token plus, per queried network, one <net>_read_rpc token per internal upstream call (BSC eth_call is charged as bsc_read_rpc_heavy). The exact breakdown is returned in meta.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: true means no upstream call was made. fresh=1 bypasses the cache at double the wallet_identity cost.
  • Tron: the account model has no nonce, so chains.tron.nonce is null and 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 unresolved with reason: offchain_lookup rather than being silently dropped.
  • Related: the Solana wallet surface is documented under Solana REST; the tier matrix is in Rate limits and tiers.