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

chore: release #530

Merged
merged 3 commits into from
Jun 13, 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
5 changes: 5 additions & 0 deletions .changeset/spicy-pears-attend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@coinbase/onchainkit": patch
---

- **feat**: exported `Swap` components. By @zizzamia #530
6 changes: 3 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

### Patch Changes

- 9fef5e9: - **feat**: added `Swap` component. By @abcrane123 & @kyhyco #522
- **feat**: added `Swap` component. By @abcrane123 & @kyhyco #522 9fef5e9

## 0.20.1

### Patch Changes

- ccb069e: - **feat**: added `buildSwapTransaction`. By @0xAlec & @zizzamia #503 #518
- **fix**: added tailwind utilities to exported styles.css. By @kyhyco #515
- **feat**: added `buildSwapTransaction`. By @0xAlec & @zizzamia #503 #518 ccb069e
- **fix**: added tailwind utilities to exported styles.css. By @kyhyco #515

## 0.20.0

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@coinbase/onchainkit",
"version": "0.20.2",
"version": "0.20.3",
"type": "module",
"repository": "https://github.com/coinbase/onchainkit.git",
"license": "MIT",
Expand Down
55 changes: 54 additions & 1 deletion site/docs/pages/swap/types.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,50 @@ description: Glossary of Types in Swap components & utilities.

# Types [Glossary of Types in Swap components & utilities.]

## `BuildSwapTransaction`

```ts
type BuildSwapTransaction = {
approveTransaction?: SwapTransaction; // The approval transaction
fee: Fee; // The fee for the swap
quote: SwapQuote; // The quote for the swap
transaction: SwapTransaction; // The swap transaction
warning?: QuoteWarning; // The warning associated with the swap
};
```

## `BuildSwapTransactionResponse`

```ts
type BuildSwapTransactionResponse = BuildSwapTransaction | SwapError;
```

## `BuildSwapTransactionParams`

```ts
type BuildSwapTransactionParams = GetSwapQuoteParams & {
fromAddress: Address; // The address of the user
};
```

## `GetSwapQuoteParams`

```ts
export type GetSwapQuoteParams = {
from: Token; // The source token for the swap
to: Token; // The destination token for the swap
amount: string; // The amount to be swapped
amountReference?: string; // The reference amount for the swap
isAmountInDecimals?: boolean; // Whether the amount is in decimals
};
```

## `GetSwapQuoteResponse`

```ts
export type GetSwapQuoteResponse = SwapQuote | SwapError;
```

## `SwapAmountInputReact`

```ts
Expand All @@ -15,10 +59,19 @@ type SwapAmountInputReact = {
};
```

## `SwapError`

```ts
type SwapError = {
code: number; // The error code
error: string; // The error message
};
```

## `SwapReact`

```ts
export type SwapReact = {
type SwapReact = {
account: Account; // Ethereum account
children: ReactNode; // Children components to render
onError?: (error: SwapError) => void; // Callback when swap is unsuccessful
Expand Down
28 changes: 10 additions & 18 deletions src/frame/components/FrameMetadata.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ export function FrameMetadata({
state,
wrapper: Wrapper = Fragment,
}: FrameMetadataReact) {
const button1 = buttons && buttons[0];
const button2 = buttons && buttons[1];
const button3 = buttons && buttons[2];
const button4 = buttons && buttons[3];
const button1 = buttons?.[0];
const button2 = buttons?.[1];
const button3 = buttons?.[2];
const button4 = buttons?.[3];
const postUrlToUse = postUrl || post_url;
const refreshPeriodToUse = refreshPeriod || refresh_period;
const imageSrc = typeof image === 'string' ? image : image.src;
Expand All @@ -47,9 +47,7 @@ export function FrameMetadata({
{!!(button1 && !!button1.action) && (
<meta property="fc:frame:button:1:action" content={button1.action} />
)}
{!!(button1 && button1.target) && (
<meta property="fc:frame:button:1:target" content={button1.target} />
)}
{!!button1?.target && <meta property="fc:frame:button:1:target" content={button1.target} />}
{!!(button1 && button1.action === 'tx' && button1.postUrl) && (
<meta property="fc:frame:button:1:post_url" content={button1.postUrl} />
)}
Expand All @@ -58,9 +56,7 @@ export function FrameMetadata({
{!!(button2 && !!button2.action) && (
<meta property="fc:frame:button:2:action" content={button2.action} />
)}
{!!(button2 && button2.target) && (
<meta property="fc:frame:button:2:target" content={button2.target} />
)}
{!!button2?.target && <meta property="fc:frame:button:2:target" content={button2.target} />}
{!!(button2 && button2.action === 'tx' && button2.postUrl) && (
<meta property="fc:frame:button:2:post_url" content={button2.postUrl} />
)}
Expand All @@ -69,9 +65,7 @@ export function FrameMetadata({
{!!(button3 && !!button3.action) && (
<meta property="fc:frame:button:3:action" content={button3.action} />
)}
{!!(button3 && button3.target) && (
<meta property="fc:frame:button:3:target" content={button3.target} />
)}
{!!button3?.target && <meta property="fc:frame:button:3:target" content={button3.target} />}
{!!(button3 && button3.action === 'tx' && button3.postUrl) && (
<meta property="fc:frame:button:3:post_url" content={button3.postUrl} />
)}
Expand All @@ -80,9 +74,7 @@ export function FrameMetadata({
{!!(button4 && !!button4.action) && (
<meta property="fc:frame:button:4:action" content={button4.action} />
)}
{!!(button4 && button4.target) && (
<meta property="fc:frame:button:4:target" content={button4.target} />
)}
{!!button4?.target && <meta property="fc:frame:button:4:target" content={button4.target} />}
{!!(button4 && button4.action === 'tx' && button4.postUrl) && (
<meta property="fc:frame:button:4:post_url" content={button4.postUrl} />
)}
Expand All @@ -95,8 +87,8 @@ export function FrameMetadata({

{!!isOpenFrame && <meta property="of:version" content="vNext" />}

{!!isOpenFrame && accepts && accepts['xmtp'] && (
<meta property={`of:accepts:xmtp`} content={accepts['xmtp']} />
{!!isOpenFrame && accepts && accepts.xmtp && (
<meta property={'of:accepts:xmtp'} content={accepts.xmtp} />
)}

{!!isOpenFrame && imageSrc && <meta property="of:image" content={imageSrc} />}
Expand Down
11 changes: 5 additions & 6 deletions src/frame/getFrameMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,12 @@ async function getFrameMessage(
isValid: true,
message: response,
};
} else {
// Security best practice, don't return anything if we can't validate the frame.
return {
isValid: false,
message: undefined,
};
}
// Security best practice, don't return anything if we can't validate the frame.
return {
isValid: false,
message: undefined,
};
}

export { getFrameMessage };
2 changes: 1 addition & 1 deletion src/identity/components/Name.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jest.mock('../getSlicedAddress', () => ({
getSlicedAddress: jest.fn(),
}));

const mockSliceAddress = (addr: string) => addr.slice(0, 6) + '...' + addr.slice(-4);
const mockSliceAddress = (addr: string) => `${addr.slice(0, 6)}...${addr.slice(-4)}`;

describe('OnchainAddress', () => {
const testAddress = '0x1234567890abcdef1234567890abcdef12345678';
Expand Down
2 changes: 1 addition & 1 deletion src/identity/components/WithAvatarBadge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function WithAvatarBadgeInner({ children, address }: WithAvatarBadgeInnerReact)
return (
<div className="relative h-8 w-8" data-testid="ockAvatarBadgeContainer">
{children}
{attestations && attestations[0] && (
{attestations?.[0] && (
<div className="absolute -bottom-0.5 -right-0.5 flex h-[15px] w-[15px] items-center justify-center rounded-full bg-transparent">
<div className="flex h-[11px] w-[11px] items-center justify-center">
<Badge />
Expand Down
2 changes: 1 addition & 1 deletion src/identity/components/WithNameBadge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function WithNameBadgeInner({ children, address }: WithNameBadgeInnerReact) {
return (
<div className="flex items-center" data-testid="ockNameBadgeContainer">
{children}
{attestations && attestations[0] && (
{attestations?.[0] && (
<div className="ml-1">
<Badge />
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/swap/components/Swap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export function Swap({ account, children, onError }: SwapReact) {
<div className="flex w-[400px] flex-col rounded-xl bg-white">
<label
className={cn(
'box-border w-full border-b border-solid p-4 text-base',
'box-border w-full border-b border-solid p-4 text-base',
'font-semibold leading-6 text-[#030712]',
)}
>
Expand Down
6 changes: 3 additions & 3 deletions src/swap/components/SwapAmountInput.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import { SwapAmountInput } from './SwapAmountInput';
import { SwapContext } from '../context';
import { Token, TokenChip } from '../../token';
import { SwapContextType } from '../types';
import { Account, Address } from 'viem';
import { type Token, TokenChip } from '../../token';
import type { SwapContextType } from '../types';
import type { Account, Address } from 'viem';

jest.mock('../../token', () => ({
TokenChip: jest.fn(() => <div>TokenChip</div>),
Expand Down
2 changes: 1 addition & 1 deletion src/swap/components/SwapAmountInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export function SwapAmountInput({ label, token, type }: SwapAmountInputReact) {
<div
className={cn(
'box-border flex w-full flex-col items-start',
'gap-[11px] border-b border-solid bg-[#FFF] p-4',
'gap-[11px] border-b border-solid bg-[#FFF] p-4',
)}
data-testid="ockSwapAmountInput_Container"
>
Expand Down
2 changes: 1 addition & 1 deletion src/swap/context.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createContext } from 'react';
import { SwapContextType } from './types';
import type { SwapContextType } from './types';

export const SwapContext = createContext<SwapContextType>({} as SwapContextType);
4 changes: 2 additions & 2 deletions src/swap/core/getSwapQuote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { sendRequest } from '../../queries/request';
import { getAPIParamsForToken } from './getAPIParamsForToken';
import type {
GetSwapQuoteResponse,
Quote,
SwapQuote,
SwapError,
GetSwapQuoteParams,
SwapAPIParams,
Expand All @@ -21,7 +21,7 @@ export async function getSwapQuote(params: GetSwapQuoteParams): Promise<GetSwapQ
const apiParams = getAPIParamsForToken({ ...defaultParams, ...params });

try {
const res = await sendRequest<SwapAPIParams, Quote>(CDP_GET_SWAP_QUOTE, [apiParams]);
const res = await sendRequest<SwapAPIParams, SwapQuote>(CDP_GET_SWAP_QUOTE, [apiParams]);
if (res.error) {
return {
code: res.error.code,
Expand Down
8 changes: 8 additions & 0 deletions src/swap/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
// 🌲☀️🌲
export { Swap } from './components/Swap';
export { SwapAmountInput } from './components/SwapAmountInput';
export { SwapButton } from './components/SwapButton';
export { buildSwapTransaction } from './core/buildSwapTransaction';
export { getSwapQuote } from './core/getSwapQuote';
export type {
BuildSwapTransaction,
BuildSwapTransactionParams,
BuildSwapTransactionResponse,
GetSwapQuoteParams,
GetSwapQuoteResponse,
SwapReact,
SwapAmountInputReact,
SwapButtonReact,
SwapError,
SwapQuote,
SwapTransaction,
} from './types';
44 changes: 28 additions & 16 deletions src/swap/types.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import type { Account, Address, Hex } from 'viem';
import type { Token } from '../token/types';
import { ReactNode } from 'react';
import type { ReactNode } from 'react';

export type AddressOrETH = Address | 'ETH';

/**
* Note: exported as public Type
*/
export type BuildSwapTransaction = {
approveTransaction?: SwapTransaction; // The approval transaction
fee: Fee; // The fee for the swap
quote: Quote; // The quote for the swap
quote: SwapQuote; // The quote for the swap
transaction: SwapTransaction; // The swap transaction
warning?: QuoteWarning; // The warning associated with the swap
};
Expand Down Expand Up @@ -57,19 +60,7 @@ export type GetSwapQuoteParams = {
/**
* Note: exported as public Type
*/
export type GetSwapQuoteResponse = Quote | SwapError;

export type Quote = {
amountReference: string; // The reference amount for the quote
from: Token; // The source token for the swap
fromAmount: string; // The amount of the source token
hasHighPriceImpact: boolean; // Whether the price impact is high
priceImpact: string; // The price impact of the swap
slippage: string; // The slippage of the swap
to: Token; // The destination token for the swap
toAmount: string; // The amount of the destination token
warning?: QuoteWarning; // The warning associated with the quote
};
export type GetSwapQuoteResponse = SwapQuote | SwapError;

export type QuoteWarning = {
description?: string; // The description of the warning
Expand Down Expand Up @@ -101,10 +92,13 @@ export type SwapAPIResponse = {
approveTx?: RawTransactionData; // The approval transaction
chainId: string; // The chain ID
fee: Fee; // The fee for the trade
quote: Quote; // The quote for the trade
quote: SwapQuote; // The quote for the trade
tx: RawTransactionData; // The trade transaction
};

/**
* Note: exported as public Type
*/
export type SwapButtonReact = {
onError?: (error: SwapError) => void;
onSubmit?: (swapTransaction: BuildSwapTransaction) => void;
Expand All @@ -122,13 +116,31 @@ export type SwapContextType = {
toToken?: Token;
};

/**
* Note: exported as public Type
*/
export type SwapQuote = {
amountReference: string; // The reference amount for the quote
from: Token; // The source token for the swap
fromAmount: string; // The amount of the source token
hasHighPriceImpact: boolean; // Whether the price impact is high
priceImpact: string; // The price impact of the swap
slippage: string; // The slippage of the swap
to: Token; // The destination token for the swap
toAmount: string; // The amount of the destination token
warning?: QuoteWarning; // The warning associated with the quote
};

export type SwapParams = {
amount: string;
fromAddress: Address;
from: Token;
to: Token;
};

/**
* Note: exported as public Type
*/
export type SwapReact = {
account: Account;
children: ReactNode;
Expand Down
2 changes: 1 addition & 1 deletion src/utils/neynar/frame/neynarFrameValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export async function neynarFrameValidation(
castReactionContext = true,
followContext = true,
): Promise<FrameValidationData | undefined> {
const url = `https://api.neynar.com/v2/farcaster/frame/validate`;
const url = 'https://api.neynar.com/v2/farcaster/frame/validate';

const responseBody = await postDataToNeynar(url, apiKey, {
message_bytes_in_hex: messageBytes,
Expand Down
2 changes: 1 addition & 1 deletion src/utils/neynar/user/getCustodyAddressForFidNeynar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export async function getCustodyAddressForFidNeynar(
const url = `https://api.neynar.com/v1/farcaster/custody-address?fid=${fid}`;
const responseBody = await getDataFromNeynar(url, apiKey);
if (!responseBody || !responseBody.result || !responseBody.result.custodyAddress) {
throw new Error('No custody address found for FID ' + fid);
throw new Error(`No custody address found for FID ${fid}`);
}
return responseBody.result.custodyAddress;
}
Loading
Loading