Skip to content
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
31 changes: 31 additions & 0 deletions packages/sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,37 @@ await client.executeSwapQuote({
});
```

## Authentication

Some Across API features require authentication via an API key. You can provide the
key at the client level or per-request.

### Client-level API key

```ts
const client = createAcrossClient({
integratorId: "0xdead",
chains: [mainnet, optimism, arbitrum],
apiKey: "your-api-key",
});

// All authenticated requests will use this key automatically
const quote = await client.getSwapQuote({ route, amount });
```

### Per-request API key

```ts
// Override or provide the key for a single request
const quote = await client.getSwapQuote({
route,
amount,
apiKey: "per-request-key",
});
```

The key is sent as a `Bearer` token in the `Authorization` header.

## Deposit details

TODO
Expand Down
10 changes: 9 additions & 1 deletion packages/sdk/src/actions/getSwapQuote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ export type GetSwapQuoteParams = Omit<
* [Optional] The Across API URL to use. Defaults to the mainnet API URL.
*/
apiUrl?: string;
/**
* [Optional] An API key for accessing authenticated features. Will be sent
* as a Bearer token in the Authorization header.
*/
apiKey?: string;
};

/**
Expand All @@ -57,7 +62,7 @@ export type GetSwapQuoteParams = Omit<
export async function getSwapQuote(
params: GetSwapQuoteParams,
): Promise<SwapApprovalApiResponse> {
const { logger, apiUrl = MAINNET_API_URL, ...otherParams } = params;
const { logger, apiUrl = MAINNET_API_URL, apiKey, ...otherParams } = params;

logger?.debug("Getting swap quote with params:", otherParams);

Expand All @@ -83,12 +88,15 @@ export async function getSwapQuote(
value: action.value?.toString() ?? "0",
})),
},
apiKey,
);
} else {
data = await fetchAcrossApi<SwapApprovalApiResponse>(
url,
queryParams,
logger,
undefined,
apiKey,
);
}

Expand Down
10 changes: 9 additions & 1 deletion packages/sdk/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@ export type AcrossClientOptions = {
* Defaults to `3_000` milliseconds.
*/
pollingInterval?: number;
/**
* An API key for accessing authenticated Across API features. Will be sent as
* a Bearer token in the Authorization header.
*/
apiKey?: string;
/**
* Tenderly related options. Can be used for additional debugging support on Tenderly.
* @see https://tenderly.co/transaction-simulator
Expand Down Expand Up @@ -164,6 +169,7 @@ export class AcrossClient {
private walletClient?: ConfiguredWalletClient;
private apiUrl: string;
private indexerUrl: string;
private apiKey?: string;

logger: LoggerT;

Expand Down Expand Up @@ -197,6 +203,7 @@ export class AcrossClient {
this.indexerUrl =
args?.useTestnet === true ? TESTNET_INDEXER_API : MAINNET_INDEXER_API;
this.apiUrl = args?.useTestnet === true ? TESTNET_API_URL : MAINNET_API_URL;
this.apiKey = args.apiKey;
this.logger =
args?.logger ??
new DefaultLogger(args?.logLevel ?? CLIENT_DEFAULTS.logLevel);
Expand Down Expand Up @@ -655,7 +662,7 @@ export class AcrossClient {
* @returns See {@link SwapApprovalApiResponse}.
*/
async getSwapQuote(
params: MakeOptional<GetSwapQuoteParams, "logger" | "apiUrl">,
params: MakeOptional<GetSwapQuoteParams, "logger" | "apiUrl" | "apiKey">,
): Promise<SwapApprovalApiResponse> {
try {
const quote = await getSwapQuote({
Expand All @@ -664,6 +671,7 @@ export class AcrossClient {
integratorId: params?.integratorId ?? this.integratorId,
logger: params?.logger ?? this.logger,
apiUrl: params?.apiUrl ?? this.apiUrl,
apiKey: params?.apiKey ?? this.apiKey,
});
return quote;
} catch (e) {
Expand Down
16 changes: 10 additions & 6 deletions packages/sdk/src/utils/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,21 @@ function makeFetcher(
params: Record<string, ParamBaseValue | Array<ParamBaseValue>>,
logger?: LoggerT,
body?: Record<string, unknown>,
apiKey?: string,
): Promise<ResBody> => {
const searchParams = buildSearchParams(params);
const url = `${apiUrl}?${searchParams}`;

logger?.debug(`Fetching ${name}...`, url);

const headers: Record<string, string> = {};
if (method === "POST") {
headers["Content-Type"] = "application/json";
}
if (apiKey) {
headers["Authorization"] = `Bearer ${apiKey}`;
}

const res = await fetch(url, {
method,
body:
Expand All @@ -78,12 +87,7 @@ function makeFetcher(
typeof value === "bigint" ? value.toString() : value,
)
: undefined,
headers:
method === "POST"
? {
"Content-Type": "application/json",
}
: undefined,
headers: Object.keys(headers).length > 0 ? headers : undefined,
});

// Try to parse the response as JSON. If it fails, parse it as text.
Expand Down
2 changes: 0 additions & 2 deletions packages/sdk/test/common/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
linea,
lisk,
scroll,
redstone,
zora,
sepolia,
} from "viem/chains";
Expand All @@ -24,7 +23,6 @@ export const MAINNET_SUPPORTED_CHAINS = [
linea,
lisk,
scroll,
redstone,
zora,
] as const;

Expand Down
Loading