Skip to content
Closed
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
120 changes: 70 additions & 50 deletions bun.lock

Large diffs are not rendered by default.

22 changes: 9 additions & 13 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import type { createPlugin } from "@swapkit/plugins";
import type { FullWallet } from "@swapkit/toolboxes";
import type { EVMCreateTransactionParams, EVMTransferParams } from "@swapkit/toolboxes/evm";
import type { createWallet } from "@swapkit/wallets";
import { match } from "ts-pattern";

export type SwapKitParams<P, W> = { config?: SKConfigState; plugins?: P; wallets?: W };

Expand All @@ -34,8 +35,7 @@ export function SwapKit<
}

type PluginName = keyof Plugins;
const connectedWallets = {} as FullWallet;
type ConnectedChains = keyof typeof connectedWallets;
const connectedWallets = {} as Partial<Record<Chain, ChainWallet<Chain>>>;
type ActionType = "transfer" | "approve" | "swap";

type ActionParams<P extends PluginName> = {
Expand Down Expand Up @@ -106,12 +106,10 @@ export function SwapKit<

if (plugin) {
if (type === ApproveMode.CheckOnly && "isAssetValueApproved" in plugin) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might want to use match here to reduce if structures

// @ts-expect-error TODO: add optional approve for plugin
return plugin.isAssetValueApproved({ assetValue }) as ApproveReturnType<T>;
return plugin?.isAssetValueApproved({ assetValue }) as ApproveReturnType<T>;
}
if (type === ApproveMode.Approve && "approveAssetValue" in plugin) {
// @ts-expect-error TODO: add optional approve for plugin
return plugin.approveAssetValue({ assetValue }) as ApproveReturnType<T>;
return plugin?.approveAssetValue({ assetValue }) as ApproveReturnType<T>;
}

throw new SwapKitError({
Expand Down Expand Up @@ -147,12 +145,12 @@ export function SwapKit<
/**
* @Public
*/
function getWallet<T extends ConnectedChains>(chain: T) {
return connectedWallets[chain];
function getWallet<T extends Chain>(chain: T) {
return connectedWallets[chain] as FullWallet[T];
}

function getAllWallets() {
return { ...connectedWallets };
return { ...connectedWallets } as Partial<FullWallet>;
}

function getAddress<T extends Chain>(chain: T) {
Expand Down Expand Up @@ -205,8 +203,7 @@ export function SwapKit<
const plugin = getSwapKitPlugin(pluginName || route.providers[0]);

if ("swap" in plugin) {
// @ts-expect-error TODO: fix this
return plugin.swap({ ...rest, route });
return plugin?.swap?.({ ...rest, route });
}

throw new SwapKitError("core_plugin_swap_not_found");
Expand Down Expand Up @@ -273,9 +270,8 @@ export function SwapKit<
if (!getWallet(chain as Chain)) throw new SwapKitError("core_wallet_connection_not_found");

const baseValue = AssetValue.from({ chain });
const { match } = await import("ts-pattern");

return match(chain as Chain)
return await match(chain as Chain)
.returnType<Promise<AssetValue | undefined> | AssetValue | undefined>()
.with(...EVMChains, (chain) => {
const { address, ...wallet } = getWallet(chain);
Expand Down
50 changes: 45 additions & 5 deletions packages/helpers/src/api/swapkitApi/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
SKConfig,
SwapKitError,
} from "@swapkit/helpers";

import { match, P } from "ts-pattern";
import {
type BalanceResponse,
type BrokerDepositChannelParams,
Expand All @@ -24,6 +24,8 @@ import {
PriceResponseSchema,
type QuoteRequest,
type QuoteResponse,
type QuoteResponseRoute,
QuoteResponseRouteItem,
QuoteResponseSchema,
type TokenListProvidersResponse,
type TokensResponseV2,
Expand Down Expand Up @@ -57,7 +59,12 @@ export async function getTrackerDetails(json: TrackingRequest) {
}

export async function getSwapQuote(json: QuoteRequest) {
const response = await SKRequestClient.post<QuoteResponse>(getApiUrl("/quote"), { json });
const experimentalApiKey = SKConfig.get("envs").experimental_apiKey;

const response = await SKRequestClient.post<QuoteResponse>(getApiUrl("/quote"), {
...(experimentalApiKey ? { dynamicHeader: () => ({ "x-api-key": experimentalApiKey }) } : {}),
json,
});

if (response.error) {
throw new SwapKitError("api_v2_server_error", { message: response.error });
Expand All @@ -77,6 +84,28 @@ export async function getSwapQuote(json: QuoteRequest) {
}
}

export async function getRouteWithTx(json: { routeId: string }) {
const experimentalApiKey = SKConfig.get("envs").experimental_apiKey;

const response = await SKRequestClient.post<QuoteResponseRoute>(getApiUrl("/swap"), {
...(experimentalApiKey ? { dynamicHeader: () => ({ "x-api-key": experimentalApiKey }) } : {}),
json,
});

try {
const parsedResponse = QuoteResponseRouteItem.safeParse(response);

if (!parsedResponse.success) {
throw new SwapKitError("api_v2_invalid_response", parsedResponse.error);
}

return parsedResponse.data;
} catch (error) {
console.error(new SwapKitError("api_v2_invalid_response", error));
return response;
}
}

export async function getChainBalance<T extends Chain>({
chain,
address,
Expand Down Expand Up @@ -185,9 +214,20 @@ export async function getNearDepositChannel(body: NearDepositChannelParams) {
}

function getApiUrl(path?: `/${string}`) {
const { isDev, apiUrl, devApiUrl } = SKConfig.get("envs");

return `${isDev ? devApiUrl : apiUrl}${path}`;
const { isDev, apiUrl, devApiUrl, experimental_apiUrlQuote, experimental_apiUrlSwap } = SKConfig.get("envs");

const defaultUrl = `${isDev ? devApiUrl : apiUrl}${path}`;

return match({ experimental_apiUrlQuote, experimental_apiUrlSwap, path })
.with(
{ experimental_apiUrlQuote: P.string.startsWith("http"), path: "/quote" },
({ experimental_apiUrlQuote, path }) => `${experimental_apiUrlQuote}${path}`,
)
.with(
{ experimental_apiUrlSwap: P.string.startsWith("http"), path: "/swap" },
({ experimental_apiUrlSwap, path }) => `${experimental_apiUrlSwap}${path}`,
)
.otherwise(() => defaultUrl);
}

function evmAssetHasAddress(assetString: string) {
Expand Down
3 changes: 2 additions & 1 deletion packages/helpers/src/api/swapkitApi/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ const QuoteResponseRouteLegItem = object({
sellAsset: string().describe("Asset to sell"),
});

const QuoteResponseRouteItem = object({
export const QuoteResponseRouteItem = object({
buyAsset: string().describe("Asset to buy"),
destinationAddress: string().describe("Destination address"),
estimatedTime: optional(EstimatedTimeSchema),
Expand All @@ -566,6 +566,7 @@ const QuoteResponseRouteItem = object({
memo: optional(string().describe("Memo")),
meta: RouteQuoteMetadataV2Schema,
providers: array(z.enum(ProviderName)),
routeId: string().describe("Route ID"),
sellAmount: string().describe("Sell amount"),
sellAsset: string().describe("Asset to sell"),
sourceAddress: string().describe("Source address"),
Expand Down
3 changes: 3 additions & 0 deletions packages/helpers/src/modules/swapKitConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ const initialState = {
envs: {
apiUrl: "https://api.swapkit.dev",
devApiUrl: "https://dev-api.swapkit.dev",
experimental_apiKey: null as string | null,
experimental_apiUrlQuote: null as string | null,
experimental_apiUrlSwap: null as string | null,
isDev: false,
isStagenet: false,
},
Expand Down
1 change: 1 addition & 0 deletions packages/helpers/src/types/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export type GenericSwapParams<T = unknown> = {
recipient?: string;
feeOptionKey?: FeeOption;
route: T;
useApiTx?: boolean;
};

export type SwapParams<PluginNames = string, R = unknown> = GenericSwapParams<R> & { pluginName?: PluginNames };
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { SwapKitPluginParams } from "./types";

export function createPlugin<
const Name extends string,
T extends (params: SwapKitPluginParams) => Record<string, unknown>,
T extends (params: SwapKitPluginParams) => ReturnType<T>,
K extends { supportedSwapkitProviders?: readonly ProviderName[] },
>({ name, properties, methods }: { name: Name; properties?: K; methods: T }) {
function plugin(pluginParams: SwapKitPluginParams) {
Expand Down
4 changes: 2 additions & 2 deletions packages/sdk/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,14 @@ export const defaultWallets = {
...walletSelectorWallet,
...walletconnectWallet,
...xamanWallet,
};
} as ReturnType<typeof createWallet>;

export function createSwapKit<
Plugins extends ReturnType<typeof createPlugin> = typeof defaultPlugins,
Wallets extends ReturnType<typeof createWallet> = typeof defaultWallets,
>({ config, plugins, wallets }: { config?: SKConfigState; plugins?: Plugins; wallets?: Wallets } = {}) {
const mergedPlugins = { ...defaultPlugins, ...plugins } as typeof defaultPlugins & Plugins;
const mergedWallets = { ...defaultWallets, ...wallets } as typeof defaultWallets & Wallets;
const mergedWallets = { ...defaultWallets, ...wallets } as ReturnType<typeof createWallet> & Wallets;

return SwapKit({ config: config, plugins: mergedPlugins, wallets: mergedWallets });
}
2 changes: 1 addition & 1 deletion packages/toolboxes/src/near/toolbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ import {
} from "./helpers/gasEstimation";
import { createNearContract } from "./helpers/nep141";
import type {
NEP141StorageContract,
NearCreateTransactionParams,
NearFunctionCallParams,
NearToolboxParams,
NearTransferParams,
} from "./types";
import type { NearContractInterface, NearGasEstimateParams } from "./types/contract";
import type { NEP141StorageContract } from "./types/nep141";
import type {
BatchTransaction,
ContractFunctionCallParams,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ export function SwapAssetItem({ asset }: { asset: string | undefined }) {
const assetValue = AssetValue.from({ asset });

return (
<div className="flex items-center gap-3">
<div className="flex min-w-0 items-center gap-3">
<AssetIcon asset={asset} />

<div className="flex flex-col items-start">
<span className="font-medium text-base text-foreground">{assetValue?.ticker}</span>
<div className="flex min-w-0 flex-col items-start">
<span className="max-w-full truncate font-medium text-base text-foreground">{assetValue?.ticker}</span>

<span className="-mt-0.5 text-muted-foreground text-sm">{assetValue?.chain}</span>
</div>
Expand Down
Loading