Skip to content

Commit

Permalink
feat: add feature to check if hex is an account (#3307)
Browse files Browse the repository at this point in the history
  • Loading branch information
maschad authored Oct 10, 2024
1 parent d1b4505 commit d968532
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .changeset/shiny-badgers-stare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@fuel-ts/account": patch
"fuels": patch
---

feat: add feature to check if hex is an account
16 changes: 16 additions & 0 deletions packages/account/src/providers/operations.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,22 @@ query getMessageByNonce($nonce: Nonce!) {
}
}

query isUserAccount(
$blobId: BlobId!
$contractId: ContractId!
$transactionId: TransactionId!
) {
blob(id: $blobId) {
id
}
contract(id: $contractId) {
id
}
transaction(id: $transactionId) {
id
}
}

subscription submitAndAwait($encodedTransaction: HexString!) {
submitAndAwait(tx: $encodedTransaction) {
...transactionStatusSubscriptionFragment
Expand Down
39 changes: 39 additions & 0 deletions packages/account/src/providers/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1950,6 +1950,45 @@ Supported fuel-core version: ${supportedVersion}.`
return bn(latestBlockHeight);
}

/**
* Check if the given ID is an account.
*
* @param id - The ID to check.
* @returns A promise that resolves to the result of the check.
*/
async isUserAccount(id: string): Promise<boolean> {
const { contract, blob, transaction } = await this.operations.isUserAccount({
blobId: id,
contractId: id,
transactionId: id,
});

if (contract || blob || transaction) {
return false;
}
return true;
}

async getAddressType(id: string): Promise<'Account' | 'Contract' | 'Transaction' | 'Blob'> {
const { contract, blob, transaction } = await this.operations.isUserAccount({
blobId: id,
contractId: id,
transactionId: id,
});

if (contract) {
return 'Contract';
}
if (blob) {
return 'Blob';
}
if (transaction) {
return 'Transaction';
}

return 'Account';
}

/**
* Get the transaction response for the given transaction ID.
*
Expand Down
80 changes: 80 additions & 0 deletions packages/fuel-gauge/src/check-user-account.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { ContractFactory } from 'fuels';
import { launchTestNode } from 'fuels/test-utils';

import { AdvancedLoggingFactory } from '../test/typegen/contracts/AdvancedLoggingFactory';
import { ScriptDummy } from '../test/typegen/scripts';

/**
* @group browser
* @group node
*/
describe('User account tests', () => {
it('should return false for a blob ID', async () => {
using launch = await launchTestNode();

const {
provider,
wallets: [wallet],
} = launch;

const factory = new ContractFactory(ScriptDummy.bytecode, ScriptDummy.abi, wallet);
const { waitForResult, blobId } = await factory.deployAsBlobTxForScript();

await waitForResult();

expect(await provider.isUserAccount(blobId)).toBe(false);
});

it('should return false for a contract ID', async () => {
using launch = await launchTestNode();

const {
provider,
wallets: [wallet],
} = launch;

const factory = new AdvancedLoggingFactory(wallet);
const { waitForResult } = await factory.deploy();

const { contract } = await waitForResult();

expect(await provider.isUserAccount(contract.id.toB256())).toBe(false);
});

it('should return true for a wallet address', async () => {
using launch = await launchTestNode();

const {
provider,
wallets: [wallet],
} = launch;

expect(await provider.isUserAccount(wallet.address.toB256())).toBe(true);
});

it('should return false for a transaction ID', async () => {
using launch = await launchTestNode();

const {
provider,
wallets: [wallet],
} = launch;

const tx = await wallet.transfer(wallet.address, 100, provider.getBaseAssetId());

await tx.wait();

expect(await provider.isUserAccount(tx.id)).toBe(false);
});

it('should return the correct address type', async () => {
using launch = await launchTestNode();

const {
provider,
wallets: [wallet],
} = launch;

expect(await provider.getAddressType(wallet.address.toB256())).toBe('Account');
});
});

0 comments on commit d968532

Please # to comment.