Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

Commit

Permalink
Add assertAccountsExist function to @solana/accounts (#1995)
Browse files Browse the repository at this point in the history
* Add assertAccountsExist function to @solana/accounts

* Add assertAccountsExist to the accounts README
  • Loading branch information
mcintyre94 authored Jan 2, 2024
1 parent a1fafee commit ef2569b
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 1 deletion.
15 changes: 15 additions & 0 deletions packages/accounts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,21 @@ assertAccountExists(myAccount);
myAccount satisfies EncodedAccount<'1234..5678'>;
```

### `assertAccountsExist()`

Given an array of `MaybeAccount`s, this function asserts that all the accounts
exist and allows them to be used as an array of `Account`s going forward.

```ts
const myAccounts: MaybeEncodedAccount<Address>[];
assertAccountsExist(myAccounts);

// Now we can use them as an array of accounts
for (const a of myAccounts) {
a satisfies EncodedAccount<Address>;
}
```

### `parseBase64RpcAccount()`

This function parses a base64-encoded account provided by the RPC client into an `EncodedAccount` type or a `MaybeEncodedAccount` type if the raw data can be set to `null`.
Expand Down
34 changes: 33 additions & 1 deletion packages/accounts/src/__tests__/maybe-account-test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'test-matchers/toBeFrozenObject';

import { assertAccountExists, MaybeEncodedAccount } from '../maybe-account';
import { assertAccountExists, assertAccountsExist, MaybeEncodedAccount } from '../maybe-account';

describe('assertAccountExists', () => {
it('fails if the provided MaybeAccount does not exist', () => {
Expand All @@ -14,3 +14,35 @@ describe('assertAccountExists', () => {
expect(fn).toThrow(`Expected account [1111] to exist`);
});
});

describe('assertAccountsExist', () => {
it('fails if any of the provided MaybeAccounts do not exist', () => {
// Given two non-existing accounts and an existing account.
const maybeAccounts = [
<MaybeEncodedAccount>{ address: '1111', exists: false },
<MaybeEncodedAccount>{ address: '2222', exists: false },
<MaybeEncodedAccount>{ address: '3333', exists: true }
];

// When we assert that all the accounts exist.
const fn = () => assertAccountsExist(maybeAccounts);

// Then we expect an error to be thrown with the non-existent accounts
expect(fn).toThrow('Expected accounts [1111, 2222] to exist');
})

it('does not fail if all accounts exist', () => {
// Given three accounts that all exist
const maybeAccounts = [
<MaybeEncodedAccount>{ address: '1111', exists: true },
<MaybeEncodedAccount>{ address: '2222', exists: true },
<MaybeEncodedAccount>{ address: '3333', exists: true }
];

// When we assert that all the accounts exist.
const fn = () => assertAccountsExist(maybeAccounts);

// Then we expect an error not to be thrown
expect(fn).not.toThrow();
})
})
24 changes: 24 additions & 0 deletions packages/accounts/src/__typetests__/maybe-account-typetest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Address } from "@solana/addresses";

import { Account } from "../account";
import { assertAccountExists, assertAccountsExist,MaybeAccount } from "../maybe-account";

type MockData = { foo: 42 };

{
// It narrows a MaybeAccount to an Account
const account = {} as unknown as MaybeAccount<MockData, '1111'>;
assertAccountExists(account);
account satisfies Account<MockData, '1111'>;
}

{
// It narrows an array of MaybeAccounts to an array of Accounts
const accounts = [
{} as unknown as MaybeAccount<MockData, '1111'>,
{} as unknown as MaybeAccount<MockData, '2222'>,
{} as unknown as MaybeAccount<MockData, '3333'>,
];
assertAccountsExist(accounts);
accounts satisfies Account<MockData, Address>[];
}
12 changes: 12 additions & 0 deletions packages/accounts/src/maybe-account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,15 @@ export function assertAccountExists<TData extends object | Uint8Array, TAddress
throw new Error(`Expected account [${account.address}] to exist.`);
}
}

/** Asserts that all accounts that may or may not exist, actually all exist. */
export function assertAccountsExist<TData extends object | Uint8Array, TAddress extends string = string>(
accounts: MaybeAccount<TData, TAddress>[]
): asserts accounts is (Account<TData, TAddress> & { exists: true })[] {
const missingAccounts = accounts.filter(a => !a.exists);
if(missingAccounts.length > 0) {
const missingAddresses = missingAccounts.map(a => a.address);
// TODO: Coded error.
throw new Error(`Expected accounts [${missingAddresses.join(', ')}] to exist.`);
}
}

0 comments on commit ef2569b

Please sign in to comment.