bguiz
bguiz

Reputation: 28587

How to query the (ordered) account IDs for a set of lazy-created accounts created by a `TransferTransaction` to EVM addresses on Hedera?

I've done the following steps 1 through 3, and figuring out how to complete step 4.

(1) Generate several several EVM addresses (evmAddress*) locally, and those EVM addresses do not have accounts on the Hedera network yet.

(2) Create a TransferTransaction which transfers from an existing account (operatorId) to the EVM addresses, like so:

const tinyBarsPerHbar = 100_000_000;
const multiTransferTx = new TransferTransaction()
        .addHbarTransfer(operatorId, -30 * tinyBarsPerHbar)
        .addHbarTransfer(evmAddress1, 10 * tinyBarsPerHbar)
        .addHbarTransfer(evmAddress2, 10 * tinyBarsPerHbar)
        .addHbarTransfer(evmAddress3, 10 * tinyBarsPerHbar)
        .freezeWith(client)
        .sign(operatorKey);
const transferTxResponse = await multiTransferTx.execute(client);

(3) When multiTransferTx completes, the EVM addresses now have accounts on the Hedera network lazily created, and associated with them

(4) Now need to find out what account ID each EVM address maps to, i.e. produce something like this:

{
  evmAddress1: accountId1,
  evmAddress2: accountId2,
  evmAddress3: accountId3,
}

How can step 4 be accomplished?


Note:

I have self-answered below, with a caveat that unfortunately makes it a not-good-enough solution. Would like to receive another answer that isn't subject to this caveat where the order/ mapping is guaranteed.

Upvotes: 1

Views: 62

Answers (2)

Ed Marquez
Ed Marquez

Reputation: 518

You can query the account id of the accounts created by following these step:

  1. Get the tx record:

    const transferToAliasRec = await transferToAliasSubmit.getRecord(client);

  2. Perform a record query with .setIncludeChildren() set to true:

    const txRec = await new TransactionRecordQuery().setTransactionId(transferToAliasRec.transactionId).setIncludeChildren(true).execute(client);

  3. Iterate through the children with i to get the account id from the receipt from each child tx:

    `console.log(`- New account ID: ${txRec.children[i].receipt.accountId.toString()} \n`);
    
  4. [Optional] Double check on HashScan

Upvotes: 1

bguiz
bguiz

Reputation: 28587

Step 4 can be accomplished, with a caveat, described below, using the following code

    // obtain `transferTxId` from `multiTransferTx`

    // convert transaction ID to a Mirror Node API URL
    const [idPart1, idPart2] = transferTxId.split('@');
    const transferTxIdMnFormat = `${idPart1}-${idPart2.replace('.', '-')}`;
    const transferTxMnResponse = await fetch(`https://testnet.mirrornode.hedera.com/api/v1/transactions/${transferTxIdMnFormat}?nonce=0`);
    const transferTxMnResult = await transferTxMnResponse.json();

    // parse 
    const transfers = transferTxMnResult.transactions[0].transfers;

This produces an output similar to this:

[
  { account: '0.0.5', amount: 4547, is_approval: false },
  { account: '0.0.98', amount: 96793, is_approval: false },
  { account: '0.0.800', amount: 10754, is_approval: false },
  { account: '0.0.1521', amount: -2000112094, is_approval: false },
  { account: '0.0.1529253', amount: 1000000000, is_approval: false },
  { account: '0.0.1529255', amount: 1000000000, is_approval: false },
  { account: '0.0.1530238', amount: 1000000000, is_approval: false }
]

Subsequently, filtering this list by amount === 1000000000, yields the account IDs that I want.


The caveat:

The above approach works, however, it does not state which account IDs map to which EVM addresses. We can make the assumption that the order in which these account IDs appear is the same as the order in which addHbarTransfer is called when creating the multiTransferTx. And manual testing seems to bear this out - the order does indeed match. However, this is not documented behaviour, and thus is not guaranteed. We don't even know if the order is deterministic.

Upvotes: 0

Related Questions