hedera-mirror-node icon indicating copy to clipboard operation
hedera-mirror-node copied to clipboard

max_automatic_token_associations , ¿How do we know the ones left?

Open AdrianKBL opened this issue 2 years ago • 9 comments

Description

Good morning,

Yesterday due to a big event in real life made by Karate Kombat, they decided to use our Launchpad (Kabila). They had a normal use case for Web2 companies, where they want to onboard people from Web2 into Web3, without those people knowing.

To be able to accomplish this, each new Account created by Kabila Wallet, was created with 3 max_automatic_token_associations , our surprise arrives when we start testing and after one these accounts receive an NFT or FT, the number don't decrease and either we have another field where tell us the remaining_token_associations, so basically, we can't know, which makes a really bad user experience for users that had 3 but wasted all of them, since we can't tell them what to do (Force them to associate the Token Id before).

Could we have a new field on the mirror node to be able to fix this issue, I think it's very important and more for us since we will be working with companies in Web2 onboarding them into Hedera soon.

Regards

Steps to reproduce

const newAccount = await new AccountCreateTransaction()
  .setKey(publicKey)
  .setMaxAutomaticTokenAssociations(3)
  .execute(client);
const getReceipt = await newAccount.getReceipt(client);
const newAccountId = getReceipt.accountId.toString();

Send one NFT or FT to that account without associating first and check mirror node:

const response = await fetch(`https://mainnet.mirrornode.hedera.com/api/v1/accounts?account.id=${accountId}`);
const data = await response.json();
const maxAssociations = data?.accounts[0]?.max_automatic_token_associations;

Additional context

No response

Hedera network

mainnet

Version

2.36.0

Operating system

macOS

AdrianKBL avatar Dec 16 '23 08:12 AdrianKBL

The short answer is neither consensus nodes or mirror nodes seem to expose the remaining auto associations. HAPI CryptoGetInfoQuery returns max_automatic_token_associations but it is just the max amount the user initially specified. MAPI /api/v1/accounts max_automatic_token_associations also returns the max amount, as you noted. Since the remaining automatic token associations can go down or up, this max amount is still useful to return and changing it could break users logic. We'd need to have a new field to return the remaining associations which would require a Hedera Improvement Proposal (HIP).

Consensus nodes already track the remaining associations internally so exposing it would be relatively straightforward. Mirror nodes do not currently track the remaining associations so the effort to add it is increased. There is a repeated TokenAssociation automatic_token_associations in the TransactionRecord that mirror node can use to decrement the remaining associations appropriately. The problem comes during dissociate and how to increment it in a performant matter. We'd have to join on token_account and increment the account's remaining where automatic_association=true, but this would be slow on a sharded database.

So unfortunately we don't have a workaround for you and to go through the HIP process and implement it would take some time. But at least we can start that process.

steven-sheehy avatar Dec 18 '23 18:12 steven-sheehy

Sounds good @steven-sheehy , who is gonna take care about defining the HIP and starting the first steps?

AdrianKBL avatar Dec 19 '23 22:12 AdrianKBL

please add LG to the requestor's list @steven-sheehy. Is there anything that we, the DA team, can assist with here? Has there been any updates?

FYI @pathornteng

Ashe-Oro avatar Feb 20 '24 15:02 Ashe-Oro

@steven-sheehy : @AdrianKBL is mentioning that your team implemented this, confirmed it with their team in another thread, and that this issue is meant to be closed. Can you please provide @AdrianKBL clarification on this issue?

the next steps for the mirror node team to support this in the future is for someone in the community to champion the HIP

Adrián Marín 10:54 AM Thats already implemented

Simi Hunjan :spiral_calendar_pad: 10:55 AM in the mirror node? the issue is still open

Adrián Marín 10:55 AM Yeah they didn’t closed 10:55 But they answered in another thread New 10:56 If it wasn’t implemented how are we retrieving the data from public mirror node? 10:56 Also noted that is not only happening in the public mirror node, also in private providers as Hgraph which we calculate it following what the mirror node team told us a few months ago

SimiHunjan avatar Jun 17 '24 18:06 SimiHunjan

It is not implemented. The only way it could be implemented without a new field being added and a HIP is to change the current field to return the remaining amount. But I mentioned previously we would not do that as it could break some customers.

steven-sheehy avatar Jun 17 '24 18:06 steven-sheehy

Hello @steven-sheehy , so Tyler from Hgraph followed your instructions from his Private Mirror Node Provider (Hgraph)

There is a repeated TokenAssociation automatic_token_associations in the TransactionRecord that mirror node can use to decrement the remaining associations appropriately. The problem comes during dissociate and how to increment it in a performant matter. We'd have to join on token_account and increment the account's remaining where automatic_association=true, but this would be slow on a sharded database.

I believe they're doing what you suggested here and they're returning to me the remaining automatic autoassociations via GraphQL

subscription AccountTokenBalances {
    entity_by_pk(id: ${accountId}) {
      balance
      max_automatic_token_associations
      token_account_aggregate(where: {automatic_association: {_eq: true}}) {
      aggregate {
        count(columns: automatic_association)
      }
    }
    token_account(
      where: {token: {type: {_eq: "FUNGIBLE_COMMON"}}}) {
        balance
        associated
      }
    }
  }
const accountTokenAssociations = data?.entity_by_pk?.max_automatic_token_associations ?? 0;
const tokenAssociationsWasted = data?.entity_by_pk?.token_account_aggregate?.aggregate?.count ?? 0;
const remainingTokenAssociations = accountTokenAssociations - tokenAssociationsWasted;

And the result match with what the queries from the Public Mirror Node returns (Even if the field Itself is not being returned, we can look for it with the next query) and It returns 2 left.

const accountId = "1704837";
const baseUrl = "https://mainnet-public.mirrornode.hedera.com/";
const tokensUrl = `${baseUrl}/api/v1/accounts/${accountId}/tokens?limit=100&order=desc`;
const accountUrl = `${baseUrl}/api/v1/accounts/${accountId}`;

async function fetchTokens(url) {
  let tokenAccount = [];
  let nextUrl = url;

  while (nextUrl) {
    const response = await fetch(nextUrl);
    const data = await response.json();
    tokenAccount = tokenAccount.concat(data.tokens);
    nextUrl = data.links.next ? baseUrl + data.links.next : null;
  }

  return tokenAccount;
}

async function getAccountInfo(url) {
  const response = await fetch(url);
  const data = await response.json();
  return data;
}

async function main() {
  // Fetch tokens
  const tokens = await fetchTokens(tokensUrl);

  // Count tokens with automatic_association == true
  const automaticAssociationCount = tokens.filter(token => token.automatic_association).length;

  console.log(`Number of tokens with automatic association: ${automaticAssociationCount}`);

  // Fetch account information
  const accountInfo = await getAccountInfo(accountUrl);

  console.log(`Max automatic token associations: ${accountInfo.max_automatic_token_associations}`);
}

main();

Output:

Number of tokens with automatic association: 7 Max automatic token associations: 9 Remaining automatic token associations: 9 - 7 --> 2

Are we missing anything?

AdrianKBL avatar Jun 17 '24 20:06 AdrianKBL

Any news @steven-sheehy ? We keep getting reports... Also as far as I saw, HashPack has integrated it, so as soon as other DApps start using it, they will start having the problems that I'm commenting here. image

AdrianKBL avatar Jun 20 '24 06:06 AdrianKBL

Hello @steven-sheehy , could we get an answer please?

AdrianKBL avatar Jul 31 '24 07:07 AdrianKBL

Not sure what you're asking me. I can't debug some code that calls someone else's GraphQL API. Nor do I recommend implementing remaining associations client side without support for calculating it on write. There are nuanced corner cases that would need to be carefully handled.

As far as official mirror node support, we would prefer to wait for HIP-904 Friction-less airdrops to be released in consensus node v0.54. With airdrops, the need to allocate and calculate association slots goes away and is a much nicer solution that we want to push people towards using.

steven-sheehy avatar Aug 01 '24 23:08 steven-sheehy