Alephium's UX

Building for all humans.

The challenge of hiding the tech away to make innovation accessible to all.

Mikaël Vaivre @mika_pote

July 2023

const { data: unknownAssetsBalances } = useQueriesData(
    unknownAssetsIds.map((id) => ({
      ...queries.assets.balances.addressToken(addressHash, id),
      enabled: unknownAssetsIds.length > 0
    }))
  )

  let tokensWithBalanceAndMetadata = flatMap(tokenBalances, (t) => {
    const metadata = find(fungibleTokens, { id: t.id })

    return metadata ? [{ ...t, ...metadata, balance: BigInt(t.balance), lockedBalance: BigInt(t.lockedBalance) }] : []
  })

  tokensWithBalanceAndMetadata = sortBy(tokensWithBalanceAndMetadata, [
    (t) => !t.verified,
    (t) => !t.name,
    (t) => t.name.toLowerCase(),
    'id'
  ])

Alephium's UX

Building for all humans.

The challenge of hiding the tech away to make innovation accessible to all.

Mikaël Vaivre @mika_pote

July 2023

const { data: unknownAssetsBalances } = useQueriesData(
    unknownAssetsIds.map((id) => ({
      ...queries.assets.balances.addressToken(addressHash, id),
      enabled: unknownAssetsIds.length > 0
    }))
  )

  let tokensWithBalanceAndMetadata = flatMap(tokenBalances, (t) => {
    const metadata = find(fungibleTokens, { id: t.id })

    return metadata ? [{ ...t, ...metadata, balance: BigInt(t.balance), lockedBalance: BigInt(t.lockedBalance) }] : []
  })

  tokensWithBalanceAndMetadata = sortBy(tokensWithBalanceAndMetadata, [
    (t) => !t.verified,
    (t) => !t.name,
    (t) => t.name.toLowerCase(),
    'id'
  ])

First principles

const { data: unknownAssetsBalances } = useQueriesData(
    unknownAssetsIds.map((id) => ({
      ...queries.assets.balances.addressToken(addressHash, id),
      enabled: unknownAssetsIds.length > 0
    }))
  )

  let tokensWithBalanceAndMetadata = flatMap(tokenBalances, (t) => {
    const metadata = find(fungibleTokens, { id: t.id })

    return metadata ? [{ ...t, ...metadata, balance: BigInt(t.balance), lockedBalance: BigInt(t.lockedBalance) }] : []
  })

  tokensWithBalanceAndMetadata = sortBy(tokensWithBalanceAndMetadata, [
    (t) => !t.verified,
    (t) => !t.name,
    (t) => t.name.toLowerCase(),
    'id'
  ])

(my)

First principles

const { data: unknownAssetsBalances } = useQueriesData(
    unknownAssetsIds.map((id) => ({
      ...queries.assets.balances.addressToken(addressHash, id),
      enabled: unknownAssetsIds.length > 0
    }))
  )

  let tokensWithBalanceAndMetadata = flatMap(tokenBalances, (t) => {
    const metadata = find(fungibleTokens, { id: t.id })

    return metadata ? [{ ...t, ...metadata, balance: BigInt(t.balance), lockedBalance: BigInt(t.lockedBalance) }] : []
  })

  tokensWithBalanceAndMetadata = sortBy(tokensWithBalanceAndMetadata, [
    (t) => !t.verified,
    (t) => !t.name,
    (t) => t.name.toLowerCase(),
    'id'
  ])

(my)

First principles

const { data: unknownAssetsBalances } = useQueriesData(
    unknownAssetsIds.map((id) => ({
      ...queries.assets.balances.addressToken(addressHash, id),
      enabled: unknownAssetsIds.length > 0
    }))
  )

  let tokensWithBalanceAndMetadata = flatMap(tokenBalances, (t) => {
    const metadata = find(fungibleTokens, { id: t.id })

    return metadata ? [{ ...t, ...metadata, balance: BigInt(t.balance), lockedBalance: BigInt(t.lockedBalance) }] : []
  })

  tokensWithBalanceAndMetadata = sortBy(tokensWithBalanceAndMetadata, [
    (t) => !t.verified,
    (t) => !t.name,
    (t) => t.name.toLowerCase(),
    'id'
  ])

(my)

ITERATE

(a lot)

First principles

const { data: unknownAssetsBalances } = useQueriesData(
    unknownAssetsIds.map((id) => ({
      ...queries.assets.balances.addressToken(addressHash, id),
      enabled: unknownAssetsIds.length > 0
    }))
  )

  let tokensWithBalanceAndMetadata = flatMap(tokenBalances, (t) => {
    const metadata = find(fungibleTokens, { id: t.id })

    return metadata ? [{ ...t, ...metadata, balance: BigInt(t.balance), lockedBalance: BigInt(t.lockedBalance) }] : []
  })

  tokensWithBalanceAndMetadata = sortBy(tokensWithBalanceAndMetadata, [
    (t) => !t.verified,
    (t) => !t.name,
    (t) => t.name.toLowerCase(),
    'id'
  ])

(my)

DON'T BE SCARED TO TRY

(live)

ITERATE

(a lot)

First principles

const { data: unknownAssetsBalances } = useQueriesData(
    unknownAssetsIds.map((id) => ({
      ...queries.assets.balances.addressToken(addressHash, id),
      enabled: unknownAssetsIds.length > 0
    }))
  )

  let tokensWithBalanceAndMetadata = flatMap(tokenBalances, (t) => {
    const metadata = find(fungibleTokens, { id: t.id })

    return metadata ? [{ ...t, ...metadata, balance: BigInt(t.balance), lockedBalance: BigInt(t.lockedBalance) }] : []
  })

  tokensWithBalanceAndMetadata = sortBy(tokensWithBalanceAndMetadata, [
    (t) => !t.verified,
    (t) => !t.name,
    (t) => t.name.toLowerCase(),
    'id'
  ])

(my)

ITERATE

SIMPLE IS BEAUTIFUL

(but simple is hard)

DON'T BE SCARED TO TRY

(live)

(a lot)

First principles

const { data: unknownAssetsBalances } = useQueriesData(
    unknownAssetsIds.map((id) => ({
      ...queries.assets.balances.addressToken(addressHash, id),
      enabled: unknownAssetsIds.length > 0
    }))
  )

  let tokensWithBalanceAndMetadata = flatMap(tokenBalances, (t) => {
    const metadata = find(fungibleTokens, { id: t.id })

    return metadata ? [{ ...t, ...metadata, balance: BigInt(t.balance), lockedBalance: BigInt(t.lockedBalance) }] : []
  })

  tokensWithBalanceAndMetadata = sortBy(tokensWithBalanceAndMetadata, [
    (t) => !t.verified,
    (t) => !t.name,
    (t) => t.name.toLowerCase(),
    'id'
  ])

(my)

ITERATE

SIMPLE IS BEAUTIFUL

(but simple is hard)

DON'T BE SCARED TO TRY

(live)

(a lot)

(especially for engineers)

First principles

const { data: unknownAssetsBalances } = useQueriesData(
    unknownAssetsIds.map((id) => ({
      ...queries.assets.balances.addressToken(addressHash, id),
      enabled: unknownAssetsIds.length > 0
    }))
  )

  let tokensWithBalanceAndMetadata = flatMap(tokenBalances, (t) => {
    const metadata = find(fungibleTokens, { id: t.id })

    return metadata ? [{ ...t, ...metadata, balance: BigInt(t.balance), lockedBalance: BigInt(t.lockedBalance) }] : []
  })

  tokensWithBalanceAndMetadata = sortBy(tokensWithBalanceAndMetadata, [
    (t) => !t.verified,
    (t) => !t.name,
    (t) => t.name.toLowerCase(),
    'id'
  ])

(my)

ITERATE

DON'T BE SCARED TO TRY

DON'T REINVENT THE WHEEL

(but sometimes do)

SIMPLE IS BEAUTIFUL

(but simple is hard)

(live)

(a lot)

(especially for engineers)

First principles

const { data: unknownAssetsBalances } = useQueriesData(
    unknownAssetsIds.map((id) => ({
      ...queries.assets.balances.addressToken(addressHash, id),
      enabled: unknownAssetsIds.length > 0
    }))
  )

  let tokensWithBalanceAndMetadata = flatMap(tokenBalances, (t) => {
    const metadata = find(fungibleTokens, { id: t.id })

    return metadata ? [{ ...t, ...metadata, balance: BigInt(t.balance), lockedBalance: BigInt(t.lockedBalance) }] : []
  })

  tokensWithBalanceAndMetadata = sortBy(tokensWithBalanceAndMetadata, [
    (t) => !t.verified,
    (t) => !t.name,
    (t) => t.name.toLowerCase(),
    'id'
  ])

(my)

DON'T REINVENT THE WHEEL

(but sometimes do)

ITERATE

(a lot)

DON'T BE SCARED TO TRY

(live)

SIMPLE IS BEAUTIFUL

(but simple is hard)

(especially for engineers)

Alephium when I joined in 2019

ITERATE

(a lot)

Principle #1

Good design takes time.

ITERATE

(a lot)

Principle #1

ITERATE

ADAPT

EVOLVE

Alephium

In 2023

Back in 2017 I thought that the industry was getting mature. That the bull run would finally bring blockchain to the masses.

I thought that 2009 to 2017 was enough time to iterate.

IN UI & UX?

ITERATE

We're still young.

I was wrong.

IN UI & UX?

UX needs time to mature.

ITERATE

(often more than tech)

IN UI & UX?

ITERATE

We're still young.

I was wrong.

UX needs time to mature.

Alephium is trying to push the industry forward, leading by example.

Alephium

ITERATE @

We're still young.

I was wrong.

UX needs time to mature.

Alephium is trying to push the industry forward, leading by example.

Alephium

ITERATE @

DON'T REINVENT THE WHEEL

(but sometimes do)

ITERATE

(a lot)

DON'T BE SCARED TO TRY

(live)

SIMPLE IS BEAUTIFUL

(but simple is hard)

(especially for engineers)

First principles

(my)

If it's not good, fail fast and iterate.

You won't know it's good until your users tell you it's good.

DON'T BE SCARED TO TRY

(live)

Principle #2

If it's not good, fail fast and iterate.

You don't know it's good until your users tell you it's good.

DON'T BE SCARED TO TRY

(live)

Principle #2

DON'T REINVENT THE WHEEL

(but sometimes do)

ITERATE

(a lot)

DON'T BE SCARED TO TRY

(live)

SIMPLE IS BEAUTIFUL

(but simple is hard)

(especially for engineers)

First principles

(my)

SIMPLE IS BEAUTIFUL

(but simple is hard)

(especially for engineers)

How do you design an efficient, easy-to-trust and easy to use tool...

...without sprinkling useless noise all over your designs?

...without appearing too gimmicky or too gamified...

...without being cold and boring...

Principle #3

SIMPLE IS BEAUTIFUL

(but simple is hard)

(especially for engineers)

How do you abstract the complexity of the code you know by heart...

...while leveraging the full potential of what you've built.

How do you design an efficient, easy-to-trust and easy to use tool...

...by sprinkling useless noise all over your designs?

...without appearing too gimmicky or too gamified...

...without being cold and boring...

Principle #3

SIMPLE IS BEAUTIFUL

Hide complexity by default

Principle #3

SIMPLE IS BEAUTIFUL

Add fun little details

SIMPLE IS BEAUTIFUL

Focus on current action

SIMPLE IS BEAUTIFUL

Focus on current action

DON'T REINVENT THE WHEEL

(but sometimes do)

ITERATE

(a lot)

DON'T BE SCARED TO TRY

(live)

SIMPLE IS BEAUTIFUL

(but simple is hard)

(especially for engineers)

First principles

(my)

DON'T REINVENT THE WHEEL

(but sometimes do)

- Get inspired by the best.

- Always compare your products with the mainstream (widely adopted) products. Don't build blindly.

- It's not because we're not big that we can't do big things.

And sometimes you're convinced that you can do better than most. If the risk isn't huge, just try. You may just be right! If not... fail and iterate.

Principle #4

DON'T REINVENT THE WHEEL

(but sometimes do)

Extension frustrations

Principle #4

Thank you

Thank you

I'm looking forward to building more great things for you.

Alephium UX

By Mikael Vaivre

Alephium UX

  • 5,192