Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1219: Synchronize with main #11

Merged
merged 7 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/docs/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const [walletAddress] = await pufferClient.requestAddresses();
Mint pufETH to your `walletAddress` or set a target recipient:

```ts
const { transact, estimate } = pufferClient.depositETH(walletAddress);
const { transact, estimate } = pufferClient.vault.depositETH(walletAddress);

// Returns gas estimate of the transaction.
const gasEstimate = await estimate();
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/guides/depositing-eth.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const [walletAddress] = await pufferClient.requestAddresses();
With your address at hand, make the transaction to deposit ETH to mint pufETH.

```ts
const { transact, estimate } = pufferClient.depositETH(walletAddress);
const { transact, estimate } = pufferClient.vault.depositETH(walletAddress);

const weiAmount = new BigInt(1e18);

Expand All @@ -42,7 +42,7 @@ const txHash = await transact(weiAmount);
Alternatively, you can set the pufETH recipient to a different address.

```ts
const { transact, estimate } = pufferClient.depositETH(recipientAddress);
const { transact, estimate } = pufferClient.vault.depositETH(recipientAddress);

const weiAmount = new BigInt(1e18);

Expand Down
2 changes: 1 addition & 1 deletion lib/api/puffer-client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe('PufferClient', () => {
walletClient,
publicClient,
);
const { transact, estimate } = pufferClient.depositETH(mockAddress);
const { transact, estimate } = pufferClient.vault.depositETH(mockAddress);

expect(await transact(BigInt(1))).toBe(mockAddress);
expect(await estimate()).toBe(mockGas);
Expand Down
74 changes: 19 additions & 55 deletions lib/api/puffer-client.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,57 @@
import {
Address,
PublicClient,
WalletClient,
createPublicClient,
createWalletClient,
getContract,
http,
} from 'viem';
import { Chain, VIEM_CHAINS, ViemChain } from '../chains/constants';
import { CHAIN_ADDRESSES } from '../contracts/addresses';
import { ValueOf } from '../utils/types';
import { CHAIN_ABIS } from '../contracts/abis/abis';
import { Chain, VIEM_CHAINS } from '../chains/constants';
import { PufferVaultHandler } from '../contracts/handlers/puffer-vault-handler';

/**
* The core class and the main entry point of the Puffer SDK.
*/
export class PufferClient {
private chainAddresses: ValueOf<typeof CHAIN_ADDRESSES>;
private chainAbis: ValueOf<typeof CHAIN_ABIS>;

private viemChain: ViemChain;
private walletClient: WalletClient;
private publicClient: PublicClient;

// Contract Handlers
public vault: PufferVaultHandler;

/**
* Create the Puffer Client.
*
* @param chain Chain to use for the client.
* @param walletClient The wallet client to use for wallet interactions.
* @param publicClient The public client to use for public interactions.
* @param walletClient The wallet client to use for wallet
* interactions.
* @param publicClient The public client to use for public
* interactions.
*/
constructor(
chain: Chain,
walletClient?: WalletClient,
publicClient?: PublicClient,
) {
this.chainAddresses = CHAIN_ADDRESSES[chain];
this.chainAbis = CHAIN_ABIS[chain];
this.viemChain = VIEM_CHAINS[chain];
const viemChain = VIEM_CHAINS[chain];

this.walletClient =
walletClient ??
createWalletClient({
chain: this.viemChain,
chain: viemChain,
transport: http(),
});
this.publicClient =
publicClient ??
createPublicClient({
chain: this.viemChain,
chain: viemChain,
transport: http(),
});

this.vault = new PufferVaultHandler(
chain,
this.walletClient,
this.publicClient,
);
}

/**
Expand All @@ -60,42 +62,4 @@ export class PufferClient {
public async requestAddresses() {
return await this.walletClient.requestAddresses();
}

/**
* Deposit ETH to the given wallet address. This doesn't make the
* transaction but returns two methods namely `transact` and
* `estimate`.
*
* @param walletAddress Wallet address to get the ETH from.
* @returns `transact: (value: bigint) => Promise<Address>` - Used to
* make the transaction with the given value.
*
* `estimate: () => Promise<bigint>` - Gas estimate of the
* transaction.
*/
public depositETH(walletAddress: Address) {
const contract = getContract({
address: this.chainAddresses.PufferVault as Address,
abi: this.chainAbis.PufferVaultV2,
client: {
wallet: this.walletClient,
// Public client is needed for simulation.
public: this.publicClient,
},
});

const transact = async (value: bigint) =>
await contract.write.depositETH([walletAddress], {
account: walletAddress,
chain: this.viemChain,
value,
});

const estimate = async () =>
await contract.estimateGas.depositETH([walletAddress], {
account: walletAddress,
});

return { transact, estimate };
}
}
2 changes: 1 addition & 1 deletion lib/contracts/addresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const CHAIN_ADDRESSES = {
PufferVault: '0xD9A442856C234a39a81a089C06451EBAa4306a72',
},
[Chain.Holesky]: {
PufferVault: '0x98408eadD0C7cC9AebbFB2AD2787c7473Db7A1fa',
PufferVault: '0x9196830bB4c05504E0A8475A0aD566AceEB6BeC9',
},
[Chain.Anvil]: {
PufferVault: '0xf770bF9384c5aaD8b8a6EFAb5951CF089656A371',
Expand Down
113 changes: 113 additions & 0 deletions lib/contracts/handlers/puffer-vault-handler.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { toHex } from 'viem';
import { mockRpcRequest } from '../../../test/mocks/mock-request';
import {
setupMockWalletClient,
setupMockPublicClient,
} from '../../../test/mocks/setup-mock-clients';
import { Chain } from '../../chains/constants';
import { PufferVaultHandler } from './puffer-vault-handler';

describe('PufferVaultHandler', () => {
it('should deposit ETH', async () => {
const mockAddress = '0xEB77D02f8122B32273444a1b544C147Fb559CB41';
const mockGas = BigInt(1);

const walletRequest = mockRpcRequest({
eth_sendTransaction: mockAddress,
});
const walletClient = setupMockWalletClient(walletRequest);
const publicRequest = mockRpcRequest({ eth_estimateGas: mockGas });
const publicClient = setupMockPublicClient(publicRequest);

const handler = new PufferVaultHandler(
Chain.Anvil,
walletClient,
publicClient,
);
const { transact, estimate } = handler.depositETH(mockAddress);

expect(await transact(BigInt(1))).toBe(mockAddress);
expect(await estimate()).toBe(mockGas);
});

it('should deposit stETH', async () => {
const mockAddress = '0xEB77D02f8122B32273444a1b544C147Fb559CB41';
const mockGas = BigInt(1);
const mockValue = BigInt(1);

const walletRequest = mockRpcRequest({
eth_sendTransaction: mockAddress,
});
const walletClient = setupMockWalletClient(walletRequest);
const publicRequest = mockRpcRequest({ eth_estimateGas: mockGas });
const publicClient = setupMockPublicClient(publicRequest);

const handler = new PufferVaultHandler(
Chain.Anvil,
walletClient,
publicClient,
);
const { transact, estimate } = handler.depositStETH(mockAddress, mockValue);

expect(await transact()).toBe(mockAddress);
expect(await estimate()).toBe(mockGas);
});

it('should check pufETH balance', async () => {
const mockAddress = '0xEB77D02f8122B32273444a1b544C147Fb559CB41';
const mockBalance = BigInt(1);
const mockCallHex = toHex(mockBalance, { size: 32 });

const walletClient = setupMockWalletClient();
const publicRequest = mockRpcRequest({ eth_call: mockCallHex });
const publicClient = setupMockPublicClient(publicRequest);

const handler = new PufferVaultHandler(
Chain.Anvil,
walletClient,
publicClient,
);
const balance = await handler.balanceOf(mockAddress);

expect(balance).toBe(mockBalance);
});

it('should check pufETH rate', async () => {
const mockRate = BigInt(1e18);
const mockCallHex = toHex(mockRate, { size: 32 });

const walletClient = setupMockWalletClient();
const publicRequest = mockRpcRequest({ eth_call: mockCallHex });
const publicClient = setupMockPublicClient(publicRequest);

const handler = new PufferVaultHandler(
Chain.Anvil,
walletClient,
publicClient,
);
const rate = await handler.getPufETHRate();

expect(rate).toBe(mockRate);
});

it('should get allowance', async () => {
const mockAllowance = BigInt(1);
const mockCallHex = toHex(mockAllowance, { size: 32 });

const walletClient = setupMockWalletClient();
const publicRequest = mockRpcRequest({ eth_call: mockCallHex });
const publicClient = setupMockPublicClient(publicRequest);

const handler = new PufferVaultHandler(
Chain.Anvil,
walletClient,
publicClient,
);
const rate = await handler.getAllowance(
'0xEB77D02f8122B32273444a1b544C147Fb559CB41',
'0x92e01fbccae21eed10ab2f278f47905d482df202',
);

expect(rate).toBe(mockAllowance);
});
});
Loading
Loading