# You
Documentation: next (source: develop).

Install the preview: `pnpm add @aephia/atlas-kit@next`. These docs follow develop and may include changes not yet published to npm.

> Wallets, profiles, and characters — and why you cannot get from one to the next by calculation.

Markdown source of https://develop.atlas-kit-docs.pages.dev/guides/identity/ — see https://develop.atlas-kit-docs.pages.dev/ai/ for the full machine-readable surface.

Almost every read starts by working out **who** you are asking about. That chain
has three links, and one of them is harder than it looks.

```text
Wallet ──▶ Profile ──▶ Character
```

A **wallet** is a Solana account someone controls. A profile
is their on-chain identity across Star Atlas. A character
is that profile's presence inside SAGE specifically — the
thing that owns fleets and accrues progress.

## Getting a character

If you already have a profile address, one call gets you the character:

```ts
const character = await sage.characters.forProfile(profileAddress);
```

That is the normal starting point, and most guides here begin from it.

> **Runnable example — Walk the identity chain.** From a profile to its character, then to everything that character owns. Run it in the browser at https://develop.atlas-kit-docs.pages.dev/guides/identity/.

## The part that surprises people

**You cannot calculate a profile address from a wallet address.**

Many Solana accounts have a derivable address computed from
known inputs, so you can work them out offline. Profiles do not: a profile is created
by its owner, and its address is assigned at creation. Nothing about the wallet
predicts it.

:::game[A wallet is not a player Profile]
Your wallet is the key you use to approve actions. Your Player Profile is your
identity inside Star Atlas, and you create it separately. A Profile can be
linked to more than one wallet, so a wallet address alone does not tell the
game which Profile you mean. An app therefore needs the Profile address or a
service that already knows which wallets belong to which Profile.
:::

So going wallet → profile is a _search_, not a calculation, and the SDK makes
you choose how to search rather than guessing:

```ts
const sage = createSageClient({
  cluster: 'zink-ptr',
  rpc,
  discovery: { walletProfiles },
});

const wallet = sage.wallets.get(walletAddress);
const profiles = await wallet.profiles.all({ strategy: 'provider' });
```

`walletProfiles` is a provider you supply — a lookup table you maintain, an
indexer, or anything else that can answer "which profiles belong to this
wallet". Without one, the `provider` strategy has no way to answer and says so.

If you already know the addresses, skip the provider entirely and pass them:

```ts
const profiles = await wallet.profiles.all({
  strategy: 'known-addresses',
  addresses: [profileAddress],
});
```

:::caution[This is the most common place to get stuck]
If you are building something where users arrive with a wallet address and
nothing else, solve this first. It shapes everything downstream, and it has no
free answer — you need either a known mapping or an indexer.

If you control the profile addresses you care about, skip the whole problem and
start from `sage.characters.forProfile()`.
:::

## What a character gives you

The character is the hub. Almost every gameplay read hangs off it:

```ts
const fleets = await character.fleets.all();
const stakes = await character.claimStakes.all();
const bases = await character.starbases.all();
```

Each of those is a separate network read, which is why each is a method rather
than a property. See [how Atlas Kit reads the
game](/start-here/how-it-thinks/) for why that distinction is consistent across
the whole API.

## Gotchas

**A profile with no character is possible.** Someone can hold a Star Atlas
profile without having entered SAGE. `forProfile` will tell you rather than
inventing an empty character.

**A wallet can hold more than one profile.** `wallet.profiles.all()` returns an
array for that reason. Do not assume the first is the one you want.

**Council Rank is its own read.** Levels are judged against the game's XP
thresholds rather than stored, so they come from their own joined read —
[Council Rank](/guides/council-rank/) covers the rank, research, and perks.

## Reference

- [`identity`](/reference/identity/) — every export in this entry
- [`fleets`](/guides/fleets/) — the usual next step
