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
5 changes: 5 additions & 0 deletions .changeset/old-wolves-bake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@across-protocol/app-sdk": minor
---

fix: validate solana addresses for actions
7 changes: 3 additions & 4 deletions packages/sdk/src/actions/getSwapQuote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import {
SwapApprovalApiResponse,
swapApprovalResponseSchema,
} from "../api/swap-approval.js";
import { Amount, Action } from "../types/index.js";
import { Address } from "viem";
import { Amount, Action, AnyChainAddress } from "../types/index.js";

/**
* Params for {@link getSwapQuote}.
Expand All @@ -25,9 +24,9 @@ export type GetSwapQuoteParams = Omit<
amount: Amount;
route: {
originChainId: number;
inputToken: Address;
inputToken: AnyChainAddress;
destinationChainId: number;
outputToken: Address;
outputToken: AnyChainAddress;
};
skipOriginTxEstimation?: boolean;
slippage?: number;
Expand Down
48 changes: 24 additions & 24 deletions packages/sdk/src/api/swap-approval.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import z from "zod";
import {
ethereumAddress,
anyChainAddress,
bigNumberString,
positiveInteger,
positiveIntString,
Expand All @@ -19,21 +19,21 @@ export enum FeeDetailsType {
export const baseSwapQueryParamsSchema = z.object({
amount: positiveIntString,
tradeType: z.enum(["minOutput", "exactOutput", "exactInput"]).optional(),
inputToken: ethereumAddress,
outputToken: ethereumAddress,
inputToken: anyChainAddress,
outputToken: anyChainAddress,
originChainId: positiveIntString,
destinationChainId: positiveIntString,
depositor: ethereumAddress,
recipient: ethereumAddress.optional(),
depositor: anyChainAddress,
recipient: anyChainAddress.optional(),
integratorId: z.string().optional(),
refundAddress: ethereumAddress.optional(),
refundAddress: anyChainAddress.optional(),
refundOnOrigin: booleanString.optional(),
slippage: positiveFloatString(0.5).optional(), // max. 50% slippage
skipOriginTxEstimation: booleanString.optional(),
excludeSources: stringOrStringArray.optional(),
includeSources: stringOrStringArray.optional(),
appFee: positiveFloatString(1).optional(),
appFeeRecipient: ethereumAddress.optional(),
appFeeRecipient: anyChainAddress.optional(),
strictTradeType: booleanString.optional(),
});

Expand All @@ -43,7 +43,7 @@ const feeComponentSchema = z.object({
amountUsd: z.string(),
pct: z.string(),
token: z.object({
address: ethereumAddress,
address: anyChainAddress,
symbol: z.string(),
decimals: positiveInteger,
chainId: positiveInteger,
Expand All @@ -55,7 +55,7 @@ const bridgeFeeDetailComponentSchema = z.object({
pct: z.string(),
token: z
.object({
address: ethereumAddress,
address: anyChainAddress,
symbol: z.string(),
decimals: positiveInteger,
chainId: positiveInteger,
Expand All @@ -69,7 +69,7 @@ const gasFeeSchema = z.object({
amount: bigNumberString,
amountUsd: z.string(),
token: z.object({
address: ethereumAddress,
address: anyChainAddress,
symbol: z.string(),
decimals: positiveInteger,
chainId: positiveInteger,
Expand All @@ -78,13 +78,13 @@ const gasFeeSchema = z.object({

const swapStepSchema = z.object({
tokenIn: z.object({
address: ethereumAddress,
address: anyChainAddress,
symbol: z.string(),
decimals: positiveInteger,
chainId: positiveInteger,
}),
tokenOut: z.object({
address: ethereumAddress,
address: anyChainAddress,
symbol: z.string(),
decimals: positiveInteger,
chainId: positiveInteger,
Expand All @@ -103,14 +103,14 @@ const bridgeStepSchema = z.object({
inputAmount: bigNumberString,
outputAmount: bigNumberString,
tokenIn: z.object({
address: ethereumAddress,
address: anyChainAddress,
symbol: z.string(),
decimals: positiveInteger,
chainId: positiveInteger,
name: z.string().optional(),
}),
tokenOut: z.object({
address: ethereumAddress,
address: anyChainAddress,
symbol: z.string(),
decimals: positiveInteger,
chainId: positiveInteger,
Expand All @@ -120,7 +120,7 @@ const bridgeStepSchema = z.object({
amount: bigNumberString,
pct: z.string(),
token: z.object({
address: ethereumAddress,
address: anyChainAddress,
symbol: z.string(),
decimals: positiveInteger,
chainId: positiveInteger,
Expand All @@ -139,22 +139,22 @@ const bridgeStepSchema = z.object({
});

const allowanceCheckSchema = z.object({
token: ethereumAddress,
spender: ethereumAddress,
token: anyChainAddress,
spender: anyChainAddress,
actual: bigNumberString,
expected: bigNumberString,
});

const balanceCheckSchema = z.object({
token: ethereumAddress,
token: anyChainAddress,
actual: bigNumberString,
expected: bigNumberString,
});

const swapTxSchema = z.object({
simulationSuccess: z.boolean(),
chainId: positiveInteger,
to: ethereumAddress,
to: anyChainAddress,
data: z.string(),
value: bigNumberString.optional(),
gas: bigNumberString.optional(),
Expand All @@ -167,7 +167,7 @@ const eip712Schema = z.object({
name: z.string(),
version: z.string(),
chainId: positiveInteger,
verifyingContract: ethereumAddress,
verifyingContract: anyChainAddress,
}),
types: z.record(
z.array(
Expand Down Expand Up @@ -197,7 +197,7 @@ export const swapApprovalResponseSchema = z.object({
.array(
z.object({
chainId: positiveInteger,
to: ethereumAddress,
to: anyChainAddress,
data: z.string(),
}),
)
Expand All @@ -208,21 +208,21 @@ export const swapApprovalResponseSchema = z.object({
destinationSwap: swapStepSchema.optional(),
}),
inputToken: z.object({
address: ethereumAddress,
address: anyChainAddress,
symbol: z.string(),
decimals: positiveInteger,
chainId: positiveInteger,
name: z.string().optional(),
}),
outputToken: z.object({
address: ethereumAddress,
address: anyChainAddress,
symbol: z.string(),
decimals: positiveInteger,
chainId: positiveInteger,
name: z.string().optional(),
}),
refundToken: z.object({
address: ethereumAddress,
address: anyChainAddress,
symbol: z.string(),
decimals: positiveInteger,
chainId: positiveInteger,
Expand Down
10 changes: 10 additions & 0 deletions packages/sdk/src/api/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ export const ethereumAddress = z.string().regex(/^0x[a-fA-F0-9]{40}$/, {
message: "Invalid Ethereum address format",
});

// Solana base58 address (32-44 chars)
export const solanaAddress = z
.string()
.regex(/^[1-9A-HJ-NP-Za-km-z]{32,44}$/, {
message: "Invalid Solana address format",
});

// EVM or Solana address
export const anyChainAddress = z.union([ethereumAddress, solanaAddress]);

export const bigNumberString = z.string().regex(/^-?\d+$/, {
message: "Invalid BigNumber string format",
});
Expand Down
3 changes: 3 additions & 0 deletions packages/sdk/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@
import { AcrossChain } from "../utils/getSupportedChains.js";
import { spokePoolAbiV3, spokePoolAbiV3_5 } from "../abis/SpokePool/index.js";
import { NoNullValuesOfObject } from "../utils/index.js";
import { parseFillLogs } from "@/actions/waitForFillTx.js";

Check warning on line 16 in packages/sdk/src/types/index.ts

View workflow job for this annotation

GitHub Actions / build-lint-test

'@/actions/waitForFillTx.js' import is restricted from being used by a pattern. Use relative imports instead of path aliases in library code to avoid compilation issues

export type Status = keyof typeof STATUS;

export type Amount = string | bigint;

/** EVM (viem Address) or Solana address. */
export type AnyChainAddress = Address | string;

export type ConfiguredWalletClient = WalletClient<Transport, Chain, Account>;
export type ConfiguredPublicClient = PublicClient<Transport, Chain>;

Expand Down
Loading