From a91431d493390d17e5d2c8162e20d6222d509d80 Mon Sep 17 00:00:00 2001 From: Junichi Sugiura Date: Tue, 20 Aug 2024 14:30:20 +0200 Subject: [PATCH] Skip CreateSession if no policy is provided (#592) * Skip CreateSession if no policy provided * Move policies to ControllerOptions * Remove policy check for log in --- .../components/providers/StarknetProvider.tsx | 59 +++++++++---------- packages/connector/src/index.ts | 6 +- packages/controller/src/index.ts | 48 +++++++++------ packages/controller/src/types.ts | 9 +-- .../keychain/src/components/connect/Login.tsx | 4 +- packages/keychain/src/hooks/connection.tsx | 2 +- packages/keychain/src/pages/index.tsx | 2 +- .../keychain/src/utils/connection/connect.ts | 13 +++- .../keychain/src/utils/connection/types.ts | 2 +- 9 files changed, 83 insertions(+), 62 deletions(-) diff --git a/examples/starknet-react-next/src/components/providers/StarknetProvider.tsx b/examples/starknet-react-next/src/components/providers/StarknetProvider.tsx index ca8268c0e..1c0bb841b 100644 --- a/examples/starknet-react-next/src/components/providers/StarknetProvider.tsx +++ b/examples/starknet-react-next/src/components/providers/StarknetProvider.tsx @@ -25,8 +25,8 @@ const ETH_TOKEN_ADDRESS = // const PAPER_TOKEN_ADDRESS = // "0x0410466536b5ae074f7fea81e5533b8134a9fa08b3dd077dd9db08f64997d113"; -const cartridge = new CartridgeConnector( - [ +const cartridge = new CartridgeConnector({ + policies: [ { target: ETH_TOKEN_ADDRESS, method: "approve", @@ -50,35 +50,34 @@ const cartridge = new CartridgeConnector( method: "allowance", }, ], - { - url: - !process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL || - process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL.split(".")[0] === - "cartridge-starknet-react-next" - ? process.env.XFRAME_URL - : "https://" + - (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL ?? "").replace( - "cartridge-starknet-react-next", - "keychain", - ), - rpc: process.env.NEXT_PUBLIC_RPC_SEPOLIA, - paymaster: { - caller: shortString.encodeShortString("ANY_CALLER"), - }, - // theme: "dope-wars", - // colorMode: "light" - // prefunds: [ - // { - // address: ETH_TOKEN_ADDRESS, - // min: "300000000000000", - // }, - // { - // address: PAPER_TOKEN_ADDRESS, - // min: "100", - // }, - // ], + url: + !process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL || + process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL.split(".")[0] === + "cartridge-starknet-react-next" + ? process.env.XFRAME_URL + : "https://" + + (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL ?? "").replace( + "cartridge-starknet-react-next", + "keychain", + ), + + rpc: process.env.NEXT_PUBLIC_RPC_SEPOLIA, + paymaster: { + caller: shortString.encodeShortString("ANY_CALLER"), }, -); + // theme: "dope-wars", + // colorMode: "light" + // prefunds: [ + // { + // address: ETH_TOKEN_ADDRESS, + // min: "300000000000000", + // }, + // { + // address: PAPER_TOKEN_ADDRESS, + // min: "100", + // }, + // ], +}); function provider(chain: Chain) { switch (chain) { diff --git a/packages/connector/src/index.ts b/packages/connector/src/index.ts index e0693ea89..f9c54984a 100644 --- a/packages/connector/src/index.ts +++ b/packages/connector/src/index.ts @@ -1,14 +1,14 @@ import { Connector } from "@starknet-react/core"; -import Controller, { Policy, ControllerOptions } from "@cartridge/controller"; +import Controller, { ControllerOptions } from "@cartridge/controller"; import { AccountInterface } from "starknet"; class ControllerConnector extends Connector { public controller: Controller; private _account: AccountInterface | undefined; - constructor(policies?: Policy[], options?: ControllerOptions) { + constructor(options?: ControllerOptions) { super(); - this.controller = new Controller(policies, options); + this.controller = new Controller(options); } readonly id = "cartridge"; diff --git a/packages/controller/src/index.ts b/packages/controller/src/index.ts index 9afc97f27..10f808fe7 100644 --- a/packages/controller/src/index.ts +++ b/packages/controller/src/index.ts @@ -30,7 +30,7 @@ import { KEYCHAIN_URL, RPC_SEPOLIA } from "./constants"; class Controller { private url: URL; - private policies: Policy[]; + private policies?: Policy[]; private paymaster?: PaymasterOptions; private connection?: Connection; private modal?: Modal; @@ -38,21 +38,33 @@ class Controller { public rpc: URL; public account?: AccountInterface; - constructor(policies: Policy[] = [], options: ControllerOptions = {}) { - this.url = new URL(options?.url || KEYCHAIN_URL); - this.rpc = new URL(options?.rpc || RPC_SEPOLIA); - this.paymaster = options.paymaster; - this.policies = policies.map((policy) => ({ - ...policy, - target: addAddressPadding(policy.target), - })); + constructor({ + policies, + url, + rpc, + paymaster, + theme, + config, + colorMode, + prefunds, + }: ControllerOptions = {}) { + this.url = new URL(url || KEYCHAIN_URL); + this.rpc = new URL(rpc || RPC_SEPOLIA); + this.paymaster = paymaster; + + if (policies?.length) { + this.policies = policies.map((policy) => ({ + ...policy, + target: addAddressPadding(policy.target), + })); + } - this.setTheme(options?.theme, options?.config?.presets); - if (options?.colorMode) { - this.setColorMode(options.colorMode); + this.setTheme(theme, config?.presets); + if (colorMode) { + this.setColorMode(colorMode); } - if (options?.prefunds?.length) { - this.setPrefunds(options.prefunds); + if (prefunds?.length) { + this.setPrefunds(prefunds); } this.initModal(); @@ -177,10 +189,10 @@ class Controller { this.modal.open(); try { - let response = await this.keychain.connect( - this.policies, - this.rpc.toString(), - ); + let response = await this.keychain.connect({ + rpcUrl: this.rpc.toString(), + policies: this.policies, + }); if (response.code !== ResponseCodes.SUCCESS) { throw new Error(response.message); } diff --git a/packages/controller/src/types.ts b/packages/controller/src/types.ts index af13f5d32..1f9c6dcb1 100644 --- a/packages/controller/src/types.ts +++ b/packages/controller/src/types.ts @@ -61,10 +61,10 @@ export type ProbeReply = { export interface Keychain { probe(rpcUrl?: string): Promise; - connect( - policies: Policy[], - rpcUrl: string, - ): Promise; + connect(args: { + rpcUrl: string; + policies?: Policy[]; + }): Promise; disconnect(): void; reset(): void; @@ -119,6 +119,7 @@ export interface Modal { * Options for configuring the controller */ export type ControllerOptions = { + policies?: Policy[]; /** The URL of keychain */ url?: string; /** The URL of the RPC */ diff --git a/packages/keychain/src/components/connect/Login.tsx b/packages/keychain/src/components/connect/Login.tsx index a47d163e3..cd4272bf2 100644 --- a/packages/keychain/src/components/connect/Login.tsx +++ b/packages/keychain/src/components/connect/Login.tsx @@ -86,8 +86,8 @@ function Form({ await doLogin(usernameField.value, credentialId); break; case LoginMode.Controller: - if (policies.length === 0) { - throw new Error("Policies required for controller "); + if (policies?.length === 0) { + break; } await controller.approve(origin, expiresAt, policies); diff --git a/packages/keychain/src/hooks/connection.tsx b/packages/keychain/src/hooks/connection.tsx index 8aec2ace1..65d022b48 100644 --- a/packages/keychain/src/hooks/connection.tsx +++ b/packages/keychain/src/hooks/connection.tsx @@ -33,7 +33,7 @@ type ConnectionContextValue = { rpcUrl: string; chainId: string; chainName: string; - policies: Policy[]; + policies?: Policy[]; prefunds: Prefund[]; hasPrefundRequest: boolean; error: Error; diff --git a/packages/keychain/src/pages/index.tsx b/packages/keychain/src/pages/index.tsx index e28065414..b5e3e197e 100644 --- a/packages/keychain/src/pages/index.tsx +++ b/packages/keychain/src/pages/index.tsx @@ -40,7 +40,7 @@ function Home() { switch (context.type) { case "connect": { // TODO: show missing policies if mismatch - if (controller.account.sessionJson()) { + if (!context.policies?.length || controller.account.sessionJson()) { context.resolve({ code: ResponseCodes.SUCCESS, address: controller.address, diff --git a/packages/keychain/src/utils/connection/connect.ts b/packages/keychain/src/utils/connection/connect.ts index 0b0afb6b7..c415ffbf4 100644 --- a/packages/keychain/src/utils/connection/connect.ts +++ b/packages/keychain/src/utils/connection/connect.ts @@ -14,10 +14,19 @@ export function connectFactory({ setContext: (context: ConnectionCtx) => void; }) { return (origin: string) => - (policies: Policy[], rpcUrl: string): Promise => { + ({ + rpcUrl, + policies, + }: { + rpcUrl: string; + policies?: Policy[]; + }): Promise => { setOrigin(origin); setRpcUrl(rpcUrl); - setPolicies(policies); + + if (policies?.length) { + setPolicies(policies); + } return new Promise((resolve, reject) => { setContext({ diff --git a/packages/keychain/src/utils/connection/types.ts b/packages/keychain/src/utils/connection/types.ts index 14736619e..4e820133f 100644 --- a/packages/keychain/src/utils/connection/types.ts +++ b/packages/keychain/src/utils/connection/types.ts @@ -26,7 +26,7 @@ export type ConnectionCtx = export type ConnectCtx = { origin: string; type: "connect"; - policies: Policy[]; + policies?: Policy[]; resolve: (res: ConnectReply | ConnectError) => void; reject: (reason?: unknown) => void; };