Interfaces

Get familiar with ZKsync SSO interfaces

While the internal functionality can be quite complex, the external interfaces for developers are very simple. This provides some technical information on how these components can be used.

Auth Server

The entrypoint to the SDK is via the zksyncSsoConnector to connect to the Auth Server. This takes the session config, basic app information (name, icon), and Auth Server URL. The fully expanded type looks like:

/**
  * @member metadata - Defaults to page title and website favicon
  * @member session - Session configuration preferences
  * @member authServerUrl - URL of the Auth Server
  */
type ZksyncSsoConnectorOptions = {
  metadata?: {
    name: string,
    icon?: string,
  },
  session?: SessionPreferences,
  authServerUrl?: string;
};

This returns a WAGMI connector that can be used to perform wallet-like actions with the available account. All of the functionality is then exposed via WAGMI, making the ZKsync SSO account nearly indistinguishable from any other standard wallet provider!

Sessions

Sessions allow only those transactions that are explicitly allowed by the session configuration.

/**
  * @member expiresAt - Expiry time for the session (e.g. "8 hours"). Defaults are set by the Auth Server (currently 1 day).
  * @member feeLimit - Maximum amount of ETH that can be spent on gas fees
  * @member transfers - ETH transfer transaction policies
  * @member contractCalls - Contract call transaction policies
  */
type SessionPreferences = {
  expiresAt?: string | bigint | Date;
  feeLimit?: Limit,
  transfers?: TransferPolicy[];
  contractCalls?: CallPolicy[];
}

Limits

Limit Types

  • Unlimited: No limit is enforced
  • Lifetime: Limit is enforced over the lifetime of the session
  • Allowance: Limit is enforced over a specific period of time and is reset every period seconds (based on the block.timestamp)
Allowance limits are currently WORK-IN-PROGRESS. Transaction validation will fail if it relies on this limit type.
type LimitType =
  "Unlimited" |
  "Lifetime" |
  "Allowance";

Limit Use Cases

Limits are used in two places:

  • Value Policies: Limits the amount of ETH that can be transferred
  • Function Argument Constraints: Limits the amount that can be passed to a contract function (argument is parsed as uint256)
/**
 * @member limitType - Type of limit to enforce
 * @member limit - The limit is exceeded if the tracked value is greater than set value over the provided period (if applicable)
 * @member period - Resets limit every `period` seconds. The block.timestamp divisor for the limit to be enforced (eg: "60 minutes", "24 hours")
 */
type Limit =
  bigint | // Resolves to "lifetime" limit
  { limit: bigint; period?: string | bigint } | // If period is set resolves to "allowance" limit, otherwise "lifetime"
  { limitType: "lifetime"; limit: bigint } |
  { limitType: "unlimited" } |
  { limitType: "allowance"; limit: bigint; period: string | bigint };

Transfer Policy

Allowed ETH transfers (non-contract calls).

/**
 * @member to - Allowed recipient address
 * @member maxValuePerUse - Per transaction ETH limit
 * @member valueLimit - Cumulative ETH limit
 */
type TransferPolicy = {
  to: Address;
  maxValuePerUse?: bigint;
  valueLimit?: Limit;
};

Contract Call Policy

Allowed contract calls.

/**
 * @member address - Contract address
 * @member abi - Contract ABI
 * @member functionName - Function name to call
 * @member maxValuePerUse - Per transaction limit for the ETH value included in the transaction
 * @member valueLimit - Cumulative limit for the ETH value of the transaction
 * @member constraints - List of constraints to apply to the function arguments; unconstrained if not set
 */
type CallPolicy = {
  address: Address;
  abi: Abi;
  functionName: string;
  maxValuePerUse?: bigint;
  valueLimit?: PartialLimit;
  constraints?: Constraint[];
};

Constraints

If constraints are not set, the function allows any argument values.

Constraints enforce limits on the arguments of a contract call. They can be stacked and are checked in order. Any constraint failure will cause the transaction validation to fail.

/**
 * @member index - Index of the argument to check
 * @member value - Value of the argument to compare against
 * @member condition - The kind of check to perform (None, =, >, <, >=, <=, !=)
 * @member limit - Limit to enforce on the parsed value
 */
type Constraint = {
  index: number;
  value?: unknown;
  condition?: ConstraintCondition;
  limit?: Limit;
};
type ConstraintCondition =
  "Unconstrained" | // No constraint
  "Equal" |         // =
  "Greater" |       // >
  "Less" |          // <
  "GreaterEqual" |  // >=
  "LessEqual" |     // <=
  "NotEqual";       // !=

Made with ❤️ by the ZKsync Community