Skip to content

Commit

Permalink
docs: improve documentation on address format conversions (#1508)
Browse files Browse the repository at this point in the history
* docs: improve documentation around address convesion

* chore: linting

* chore: changeset

* feat: remove addrtess class function

* docs: spelling

* chore: force rebuild

* chore: spelling/grammar

Co-authored-by: Anderson Arboleya <[email protected]>

* chore: spelling/grammar

Co-authored-by: Anderson Arboleya <[email protected]>

* chore: spelling/grammar

Co-authored-by: Anderson Arboleya <[email protected]>

* chore: spelling/grammar

Co-authored-by: Anderson Arboleya <[email protected]>

* chore: spelling/grammar

Co-authored-by: Anderson Arboleya <[email protected]>

---------

Co-authored-by: Anderson Arboleya <[email protected]>
Co-authored-by: Dhaiwat <[email protected]>
  • Loading branch information
3 people authored Dec 13, 2023
1 parent e6064bf commit 166a48b
Show file tree
Hide file tree
Showing 10 changed files with 187 additions and 75 deletions.
5 changes: 5 additions & 0 deletions .changeset/stale-flowers-cheer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fuel-ts/address": patch
---

Add further utility to Address and improve docs around conversions
7 changes: 6 additions & 1 deletion apps/docs-snippets/src/guide/types/bech32.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ describe(__filename, () => {

// #context console.log(address.bech32Address);

// #context > fuel1d5cfwekq78r0zq73g7eg0747etkaxxltrqx5tncm7lvg89awe3hswhqjhs
// fuel1d5cfwekq78r0zq73g7eg0747etkaxxltrqx5tncm7lvg89awe3hswhqjhs
// #endregion bech32-2

// #region addresses-1
const bech32 = 'fuel1d5cfwekq78r0zq73g7eg0747etkaxxltrqx5tncm7lvg89awe3hswhqjhs';
// #endregion addresses-1
expect(address.toAddress()).toMatch(/^fuel1/);
expect(bech32).toEqual('fuel1d5cfwekq78r0zq73g7eg0747etkaxxltrqx5tncm7lvg89awe3hswhqjhs');
});
});
6 changes: 6 additions & 0 deletions apps/docs-snippets/src/guide/types/bits256.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,15 @@ describe(__filename, () => {

// randomB256 is a hexlified string representing a 256-bit value
const randomB256: string = getRandomB256();
// 0xbebd3baab326f895289ecbd4210cf886ce41952316441ae4cac35f00f0e882a6
// #endregion bits256-1

// #region addresses-2
const bits256 = '0xbebd3baab326f895289ecbd4210cf886ce41952316441ae4cac35f00f0e882a6';
// #endregion addresses-2

expect(typeof randomB256 === 'string').toBeTruthy();
expect(bits256).toBe('0xbebd3baab326f895289ecbd4210cf886ce41952316441ae4cac35f00f0e882a6');
});

it('should successfully convert between hexed b256 and Uint8Array', () => {
Expand Down
2 changes: 1 addition & 1 deletion apps/docs-snippets/src/guide/types/bits512.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ describe(__filename, () => {

// #context console.log(walllet.publicKey);

// #context > 0x97e3a666e4cd34b6b3cf778ef5ec617de4439b68f7a629245442a1fece7713094a1cb0aa7ad0ac253ca1ea47d4618f9090b2a881e829e091fb2c426763e94cca
// 0x97e3a666e4cd34b6b3cf778ef5ec617de4439b68f7a629245442a1fece7713094a1cb0aa7ad0ac253ca1ea47d4618f9090b2a881e829e091fb2c426763e94cca
// #endregion bits512-2
// #region bits512-4
const b512 = wallet.publicKey;
Expand Down
125 changes: 86 additions & 39 deletions apps/docs-snippets/src/guide/types/conversion.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import type { Bytes, WalletLocked } from 'fuels';
import type { WalletLocked, AssetId } from 'fuels';
import {
Wallet,
FUEL_NETWORK_URL,
Provider,
Contract,
Address,
ZeroBytes32,
arrayify,
hexlify,
randomBytes,
isBech32,
toBech32,
toB256,
isB256,
} from 'fuels';

import { DocSnippetProjectsEnum, getDocsSnippetsForcProject } from '../../../test/fixtures/forc-projects';
import {
DocSnippetProjectsEnum,
getDocsSnippetsForcProject,
} from '../../../test/fixtures/forc-projects';

describe(__filename, () => {
const { abiContents: abi } = getDocsSnippetsForcProject(DocSnippetProjectsEnum.ECHO_VALUES);
Expand All @@ -21,63 +24,107 @@ describe(__filename, () => {
provider = await Provider.create(FUEL_NETWORK_URL);
});

it('should successfully convert between b256 and bytes32', () => {
// #region conversion-1
const random256BitsArr: Bytes = randomBytes(32);
it('converts between bech32 and b256 using address', () => {
// #region conversion-5
// #context import { Address } from 'fuels';

const bech32 = 'fuel1d5cfwekq78r0zq73g7eg0747etkaxxltrqx5tncm7lvg89awe3hswhqjhs';
const addressInstance = Address.fromDynamicInput(bech32);
const b256 = addressInstance.toB256();
// 0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f
// #endregion conversion-5

expect(b256).toBe('0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f');
});

it('converts between bech32 and b256 using utilities', () => {
let b256;

// #region conversion-6
// #context import { toB256, isBech32 } from 'fuels';

const bech32 = 'fuel1d5cfwekq78r0zq73g7eg0747etkaxxltrqx5tncm7lvg89awe3hswhqjhs';

if (isBech32(bech32)) {
b256 = toB256(bech32);
// 0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f
}
// #endregion conversion-6

expect(b256).toBe('0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f');
});

it('converts between b256 and bech32 using address', () => {
// #region conversion-7
// #context import { Address } from 'fuels';

const b256 = '0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f';
const addressInstance = Address.fromDynamicInput(b256);
const bech32 = addressInstance.bech32Address;
// fuel1d5cfwekq78r0zq73g7eg0747etkaxxltrqx5tncm7lvg89awe3hswhqjhs

// #endregion conversion-7

expect(bech32).toBe('fuel1d5cfwekq78r0zq73g7eg0747etkaxxltrqx5tncm7lvg89awe3hswhqjhs');
});

it('converts between b256 and bech32 using utilities', () => {
let bech32;

const hexed256BitsStr: string = hexlify(random256BitsArr);
// #region conversion-8
// #context import { toB256, isBech32 } from 'fuels';

const address = Address.fromB256(hexed256BitsStr);
const b256 = '0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f';

const arrayB256: Uint8Array = arrayify(random256BitsArr);
if (isB256(b256)) {
bech32 = toBech32(b256);
// fuel1d5cfwekq78r0zq73g7eg0747etkaxxltrqx5tncm7lvg89awe3hswhqjhs
}
// #endregion conversion-8

expect(address.toBytes()).toEqual(arrayB256);
expect(address.toB256()).toEqual(hexed256BitsStr);
expect(arrayify(address.toB256())).toEqual(arrayB256);
// #endregion conversion-1
expect(bech32).toBe('fuel1d5cfwekq78r0zq73g7eg0747etkaxxltrqx5tncm7lvg89awe3hswhqjhs');
});

it('should successfully validate contract id equality', () => {
// #region conversion-2
// #context import { FUEL_NETWORK_URL } from 'fuels';
// #context import { Address, Contract} from 'fuels';

const address = Address.fromB256(
'0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f'
);

const address = Address.fromRandom();
const contract = new Contract(address, abi, provider);

const contractLike = new Contract(address, abi, provider);
const bech32 = contract.id.toAddress();
// fuel1d5cfwekq78r0zq73g7eg0747etkaxxltrqx5tncm7lvg89awe3hswhqjhs

expect(address.equals(<Address>contractLike.id)).toBeTruthy();
// #endregion conversion-2
expect(bech32).toBe('fuel1d5cfwekq78r0zq73g7eg0747etkaxxltrqx5tncm7lvg89awe3hswhqjhs');
});

it('should successfully validate a wallet address equality', () => {
// #region conversion-3
const address = Address.fromRandom();
// #context import { Wallet, Address } from 'fuels';

const address = Address.fromB256(
'0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f'
);
const wallet: WalletLocked = Wallet.fromAddress(address, provider);

// we use the cast here to cast from `AbstractAddress` to `Address`
expect(address.equals(<Address>wallet.address)).toBeTruthy();

expect(wallet.address.toBytes()).toEqual(arrayify(wallet.address.toB256()));
const walletAddress = wallet.address.toAddress();
// #endregion conversion-3

expect(walletAddress).toBe('fuel1d5cfwekq78r0zq73g7eg0747etkaxxltrqx5tncm7lvg89awe3hswhqjhs');
});

it('should successfully create new address from asset id', () => {
// #region conversion-4
// #context import { ZeroBytes32 } from 'fuels';

const assetId: string = ZeroBytes32;
// #context import { Address, AssetId } from 'fuels';

const address1 = Address.fromString(assetId);
const address2 = Address.fromB256(assetId);
const address3 = Address.fromDynamicInput(assetId);

expect(address1.toB256()).toEqual(assetId);
expect(address2.toB256()).toEqual(assetId);
expect(address3.toB256()).toEqual(assetId);

// consistent bytes conversion
expect(arrayify(assetId)).toEqual(arrayify(address1.toB256()));
const b256 = '0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f';
const address = Address.fromB256(b256);
const assetId: AssetId = address.toAssetId();
// #endregion conversion-4

expect(assetId.value);
});
});
13 changes: 12 additions & 1 deletion apps/docs-snippets/src/guide/types/evm-address.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { B256AddressEvm, Contract, EvmAddress } from 'fuels';
import type { Contract, EvmAddress, B256AddressEvm } from 'fuels';
import { Address } from 'fuels';

import { DocSnippetProjectsEnum } from '../../../test/fixtures/forc-projects';
Expand All @@ -22,7 +22,18 @@ describe('EvMAddress', () => {
};
// #endregion evm-address-1

// #region addresses-3
// #context import type { EvmAddress } from 'fuels';

const address: EvmAddress = {
value: '0x000000000000000000000000210cf886ce41952316441ae4cac35f00f0e882a6',
};
// #endregion addresses-3

expect(evmAddress.value).toBe(Bits256);
expect(address.value).toBe(
'0x000000000000000000000000210cf886ce41952316441ae4cac35f00f0e882a6'
);
});

it('should create an Evm Address from a B256Address', async () => {
Expand Down
15 changes: 11 additions & 4 deletions apps/docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,6 @@ export default defineConfig({
text: 'Vectors',
link: '/guide/types/vectors',
},
{
text: 'Conversion',
link: '/guide/types/conversion',
},
],
},
{
Expand Down Expand Up @@ -316,6 +312,17 @@ export default defineConfig({
},
],
},
{
text: 'Addresses',
link: '/guide/addresses',
collapsed: true,
items: [
{
text: 'Conversion',
link: 'guide/addresses/conversion',
},
],
},
{
text: 'Cookbook',
link: '/guide/cookbook/',
Expand Down
41 changes: 41 additions & 0 deletions apps/docs/src/guide/addresses/conversion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Converting Between Address Formats and Native Types

This guide demonstrates how to convert between address formats and Sway Standard Types using helper functions. Native types are wrappers for bytes, and you can perform conversions between them by leveraging these functions and classes.

## From `Bech32` to `b256`

By instantiating an `Address`, we can validate a `Bech32` address and easily convert it to a `b256`:

<<< @/../../docs-snippets/src/guide/types/conversion.test.ts#conversion-5{ts:line-numbers}

Or, if you'd prefer to use utility functions directly for validation and conversion, you can use `isBech32` and `toB256`:

<<< @/../../docs-snippets/src/guide/types/conversion.test.ts#conversion-6{ts:line-numbers}

## From `b256` to `Bech32`

In a similar fashion, we have both class functions on the `Address` and utilities available for `b256` validation and conversion:

<<< @/../../docs-snippets/src/guide/types/conversion.test.ts#conversion-7{ts:line-numbers}

And by using the `isB256` and `toBech32` utilities:

<<< @/../../docs-snippets/src/guide/types/conversion.test.ts#conversion-8{ts:line-numbers}

## Converting a Contract ID

The Contract `id` property has the [`AbstractAddress`](../types/address#abstractaddress-class) type. Therefore, it can be converted using the `Address` class functions such as `toAddress` and `toB256`:

<<< @/../../docs-snippets/src/guide/types/conversion.test.ts#conversion-2{ts:line-numbers}

## Converting a Wallet Address

Similarly, the Wallet `address` property is also of type [`AbstractAddress`](../types/address#abstractaddress-class) and can therefore use the same `Address` class functions for conversion:

<<< @/../../docs-snippets/src/guide/types/conversion.test.ts#conversion-3{ts:line-numbers}

## Converting an Asset ID

[Asset IDs](../types/asset-id.md) are a wrapped [b256](../types/bits256.md) value. The following example shows how to create an `Address` from a `b256` type:

<<< @/../../docs-snippets/src/guide/types/conversion.test.ts#conversion-4{ts:line-numbers}
19 changes: 19 additions & 0 deletions apps/docs/src/guide/addresses/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Addresses

Addresses and varying address formats are commonplace when interacting with decentralized applications. Furthermore, different networks may enforce different address formats.

The Fuel Network uses the [`Bech32`](../types/bech32.md) address format for its interactions, an example of which can be seen below:

<<< @/../../docs-snippets/src/guide/types/bech32.test.ts#addresses-1{ts:line-numbers}

However, a hexlified [Bits256](../types/bits256.md) (hex) is another common address format; an example can be seen below:

<<< @/../../docs-snippets/src/guide/types/bits256.test.ts#addresses-2{ts:line-numbers}

At times, these can even be wrapped in a [Struct](../types/structs.md). Such as an [Asset ID](../types/asset-id.md) or a [EVM Address](../types/evm-address.md):

<<< @/../../docs-snippets/src/guide/types/evm-address.test.ts#addresses-3{ts:line-numbers}

The TS-SDK makes converting between these addresses simple using the [Address](../types/address.md) helper, which provides various utilities for conversion.

The following [conversion guide](./conversion.md) will show how to utilize this class to convert between address formats, as well as Sway Standard Types.
29 changes: 0 additions & 29 deletions apps/docs/src/guide/types/conversion.md

This file was deleted.

0 comments on commit 166a48b

Please sign in to comment.