Skip to content

Commit

Permalink
Add CGW AddressBooks creation and retrieval tests (#43)
Browse files Browse the repository at this point in the history
* Init AddressBooks tests

* CGW / Add tests for Create AddressBookItems

* Add AddressBookItem creation test
  • Loading branch information
hectorgomezv authored Nov 21, 2024
1 parent 1818e51 commit 776a297
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/__tests__/cgw/accounts.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ describe('CGW Auth tests', () => {
const account = await cgw.getAccount(accessToken, created.address);
expect(account.address).toBe(created.address);
expect(account.id).toBe(created.id);
expect(account.name).toBe(created.name);
} finally {
await cgw.deleteAccount(accessToken, address);
}
Expand Down Expand Up @@ -119,6 +120,7 @@ describe('CGW Auth tests', () => {
const account = await cgw.getAccount(accessToken, created.address);
expect(account.address).toBe(created.address);
expect(account.id).toBe(created.id);
expect(account.name).toBe(created.name);
const dataTypes = await cgw.getDataTypes();
const upsertAccountDataSettingsDto = {
accountDataSettings: dataTypes
Expand Down
174 changes: 174 additions & 0 deletions src/__tests__/cgw/address-books.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import { configuration } from '@/config/configuration';
import { CGWAccount, ClientGatewayClient } from '@/datasources/cgw/cgw-client';
import { faker } from '@faker-js/faker';
import { ethers, getAddress, Wallet } from 'ethers';

let signer: Wallet;
let accessToken: string;

const { privateKeys, walletAddresses } = configuration;

const getAccessToken = async (cgw: ClientGatewayClient) => {
const { nonce } = await cgw.getNonce();
const message = cgw.createSiweMessage(walletAddresses[0], nonce);

const accessToken = await cgw.login({
message,
signature: await signer.signMessage(message),
});

if (accessToken === undefined) {
throw new Error('Access token is undefined');
}

return accessToken;
};

describe('CGW Address Books tests', () => {
const cgw: ClientGatewayClient = new ClientGatewayClient();

beforeAll(async () => {
const { chain, rpc } = configuration;
const provider = new ethers.AlchemyProvider(chain.name, rpc.apiKey);
signer = new ethers.Wallet(privateKeys[0], provider);
accessToken = await getAccessToken(cgw);
});

let createdAccount: CGWAccount;

describe('Address Books endpoints', () => {
it('should create an Account, and fail to get its Address Book', async () => {
const address = walletAddresses[0];
const name = 'TestAccount';
const chainId = configuration.chain.chainId;
const createAccountDto = { address, name };
try {
createdAccount = await cgw.createAccount(accessToken, createAccountDto);
expect(createdAccount).toBeDefined();
expect(createdAccount.address).toBe(address);
const account = await cgw.getAccount(
accessToken,
createdAccount.address,
);
expect(account.address).toBe(createdAccount.address);
expect(account.id).toBe(createdAccount.id);
expect(account.name).toBe(createdAccount.name);

// Enable setting for all data types
const dataTypes = await cgw.getDataTypes();
const upsertAccountDataSettingsDto = {
accountDataSettings: dataTypes
.filter((dt) => dt.isActive)
.map((dt) => ({
dataTypeId: dt.id,
enabled: true,
})),
};

await cgw.upsertAccountDataSettings(
accessToken,
address,
upsertAccountDataSettingsDto,
);

await cgw.getAddressBook(accessToken, address, chainId);
} catch (error) {
expect(error.response.data).toBe('Address Book not found');
expect(error.response.status).toBe(404);
} finally {
await cgw.deleteAccount(accessToken, address);
}
});

it('should create an Account, create an AddressBookItem and retrieve the AddressBook', async () => {
const address = walletAddresses[0];
const name = 'TestAccount';
const chainId = configuration.chain.chainId;
const createAccountDto = { address, name };
try {
createdAccount = await cgw.createAccount(accessToken, createAccountDto);
expect(createdAccount).toBeDefined();
expect(createdAccount.address).toBe(address);
const account = await cgw.getAccount(
accessToken,
createdAccount.address,
);
expect(account.address).toBe(createdAccount.address);
expect(account.id).toBe(createdAccount.id);
expect(account.name).toBe(createdAccount.name);

// Enable setting for all data types
const dataTypes = await cgw.getDataTypes();
const upsertAccountDataSettingsDto = {
accountDataSettings: dataTypes
.filter((dt) => dt.isActive)
.map((dt) => ({
dataTypeId: dt.id,
enabled: true,
})),
};

await cgw.upsertAccountDataSettings(
accessToken,
address,
upsertAccountDataSettingsDto,
);

const createAddressBookItemDto = {
name: 'TestAddressBookItem',
address: faker.finance.ethereumAddress(),
};
const secondCreateAddressBookItemDto = {
name: 'SecondTestAddressBookItem',
address: faker.finance.ethereumAddress(),
};
const item = await cgw.createAddressBookItem(
accessToken,
address,
chainId,
createAddressBookItemDto,
);
const secondItem = await cgw.createAddressBookItem(
accessToken,
address,
chainId,
secondCreateAddressBookItemDto,
);
expect(item).toStrictEqual({
id: expect.any(String),
name: createAddressBookItemDto.name,
address: getAddress(createAddressBookItemDto.address), // should be checksummed by the CGW
});
expect(secondItem).toStrictEqual({
id: expect.any(String),
name: secondCreateAddressBookItemDto.name,
address: getAddress(secondCreateAddressBookItemDto.address), // should be checksummed by the CGW
});
const addressBook = await cgw.getAddressBook(
accessToken,
address,
chainId,
);
expect(addressBook).toStrictEqual({
id: expect.any(String),
accountId: account.id,
chainId,
data: [
{
id: '1',
name: 'TestAddressBookItem',
address: getAddress(createAddressBookItemDto.address), // should be checksummed by the CGW
},
{
id: '2',
name: 'SecondTestAddressBookItem',
address: getAddress(secondCreateAddressBookItemDto.address), // should be checksummed by the CGW
},
],
});
} finally {
await cgw.deleteAccount(accessToken, address);
}
});
});
});
1 change: 1 addition & 0 deletions src/__tests__/cgw/counterfactual-safes.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ describe('CGW Counterfactual Safes tests', () => {
);
expect(account.address).toBe(createdAccount.address);
expect(account.id).toBe(createdAccount.id);
expect(account.name).toBe(createdAccount.name);

// Enable setting for all data types
const dataTypes = await cgw.getDataTypes();
Expand Down
44 changes: 44 additions & 0 deletions src/datasources/cgw/cgw-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export interface CGWAccount {
id: string;
groupId: string | null;
address: string;
name: string;
}

export interface CGWDataType {
Expand All @@ -107,6 +108,16 @@ export interface CGWUpsertAccountDataSettingsDto {
accountDataSettings: CGWAccountDataSetting[];
}

export interface CGWAddressBook {
accountId: string;
chainId: string;
data: Array<{
id: string;
name: string;
address: string;
}>;
}

export interface CGWCounterfactualSafe {
chainId: string;
creator: string;
Expand All @@ -118,6 +129,11 @@ export interface CGWCounterfactualSafe {
threshold: number;
}

export interface CGWCreateAddressBookItemDto {
name: string;
address: string;
}

export interface CGWCreateCounterfactualSafeDTO {
chainId: string;
fallbackHandler: string;
Expand Down Expand Up @@ -257,6 +273,34 @@ export class ClientGatewayClient {
}
}

// Address Books endpoints

async getAddressBook(
accessToken: string,
address: string,
chainId: string,
): Promise<CGWAddressBook> {
const { data } = await httpClient.get(
`${this.baseUri}/v1/accounts/${address}/address-books/${chainId}`,
{ headers: { Cookie: accessToken } },
);
return data;
}

async createAddressBookItem(
accessToken: string,
address: string,
chainId: string,
createAddressBookItemDto: CGWCreateAddressBookItemDto,
): Promise<CGWAddressBook> {
const { data } = await httpClient.post(
`${this.baseUri}/v1/accounts/${address}/address-books/${chainId}`,
createAddressBookItemDto,
{ headers: { Cookie: accessToken } },
);
return data;
}

// Counterfactual Safes endpoints

async createCounterfactualSafe(
Expand Down

0 comments on commit 776a297

Please sign in to comment.