Skip to content

Commit

Permalink
Skip CreateSession if no policy is provided (#598)
Browse files Browse the repository at this point in the history
* Skip CreateSession if no policy provided

* Move policies to ControllerOptions

* Remove policy check for log in

* Escape nullable policies

* Login to require authentication if no policies

* Reduce txn transfer on example

---------

Co-authored-by: broody <[email protected]>
  • Loading branch information
JunichiSugiura and broody authored Aug 20, 2024
1 parent 0b5c318 commit 2482164
Show file tree
Hide file tree
Showing 12 changed files with 89 additions and 86 deletions.
4 changes: 2 additions & 2 deletions examples/starknet-react-next/src/components/TransferEth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ export const TransferEth = () => {
{
contractAddress: ETH_CONTRACT,
entrypoint: "approve",
calldata: [account?.address, "0x11C37937E08000", "0x0"],
calldata: [account?.address, "0x1C6BF52634000", "0x0"],
},
{
contractAddress: ETH_CONTRACT,
entrypoint: "transfer",
calldata: [account?.address, "0x11C37937E08000", "0x0"],
calldata: [account?.address, "0x1C6BF52634000", "0x0"],
},
])
.then(({ transaction_hash }) => setTxnHash(transaction_hash))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -50,35 +50,33 @@ 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) {
Expand Down
6 changes: 3 additions & 3 deletions packages/connector/src/index.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand Down
48 changes: 30 additions & 18 deletions packages/controller/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,29 +30,41 @@ import { KEYCHAIN_URL, RPC_SEPOLIA } from "./constants";

class Controller {
private url: URL;
private policies: Policy[];
private policies?: Policy[];
private paymaster?: PaymasterOptions;
private connection?: Connection<Keychain>;
private modal?: Modal;
public keychain?: AsyncMethodReturns<Keychain>;
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();
Expand Down Expand Up @@ -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);
}
Expand Down
9 changes: 5 additions & 4 deletions packages/controller/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ export type ProbeReply = {

export interface Keychain {
probe(rpcUrl?: string): Promise<ProbeReply | ConnectError>;
connect(
policies: Policy[],
rpcUrl: string,
): Promise<ConnectReply | ConnectError>;
connect(args: {
rpcUrl: string;
policies?: Policy[];
}): Promise<ConnectReply | ConnectError>;
disconnect(): void;

reset(): void;
Expand Down Expand Up @@ -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 */
Expand Down
2 changes: 1 addition & 1 deletion packages/keychain/src/Policies.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export function Policies({
// The container already set border radius (for top & bottom), but we
// set the bottom radius for the last item here because for certain
// browsers' scrolling behaviour (eg Firefox) just to make it look nicer.
borderBottomRadius={i === policies.length - 1 ? "base" : "none"}
borderBottomRadius={i === policies?.length - 1 ? "base" : "none"}
>
{({ isExpanded }) => (
<>
Expand Down
25 changes: 4 additions & 21 deletions packages/keychain/src/components/connect/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,10 @@ function Form({
credentialId,
});

switch (mode) {
case LoginMode.Webauthn:
await doLogin(usernameField.value, credentialId);
break;
case LoginMode.Controller:
if (policies.length === 0) {
throw new Error("Policies required for controller ");
}

await controller.approve(origin, expiresAt, policies);
break;
if (mode === LoginMode.Controller && policies.length > 0) {
await controller.approve(origin, expiresAt, policies);
} else {
await doLogin(usernameField.value, credentialId);
}

controller.store();
Expand All @@ -100,18 +93,8 @@ function Form({
if (onSuccess) {
onSuccess();
}

log({ type: "webauthn_login", address });
} catch (e) {
setError(e);

log({
type: "webauthn_login_error",
payload: {
error: e?.message,
},
address,
});
}

setIsLoading(false);
Expand Down
4 changes: 2 additions & 2 deletions packages/keychain/src/components/layout/Footer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function Footer({
const isExpandable = useMemo(
() =>
!!origin &&
!!policies.length &&
!!policies?.length &&
variant === "connect" &&
!isSignup &&
!hideTxSummary,
Expand Down Expand Up @@ -100,7 +100,7 @@ export function Footer({
onClick={footer.onToggle}
_hover={{ cursor: "pointer" }}
>
{!hideTxSummary && !!policies.length && (
{!hideTxSummary && !!policies?.length && (
<TransactionSummary
isSlot={isSlot}
createSession={createSession}
Expand Down
2 changes: 1 addition & 1 deletion packages/keychain/src/hooks/connection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type ConnectionContextValue = {
rpcUrl: string;
chainId: string;
chainName: string;
policies: Policy[];
policies?: Policy[];
prefunds: Prefund[];
hasPrefundRequest: boolean;
error: Error;
Expand Down
2 changes: 1 addition & 1 deletion packages/keychain/src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
13 changes: 11 additions & 2 deletions packages/keychain/src/utils/connection/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,19 @@ export function connectFactory({
setContext: (context: ConnectionCtx) => void;
}) {
return (origin: string) =>
(policies: Policy[], rpcUrl: string): Promise<ConnectReply> => {
({
rpcUrl,
policies,
}: {
rpcUrl: string;
policies?: Policy[];
}): Promise<ConnectReply> => {
setOrigin(origin);
setRpcUrl(rpcUrl);
setPolicies(policies);

if (policies?.length) {
setPolicies(policies);
}

return new Promise((resolve, reject) => {
setContext({
Expand Down
2 changes: 1 addition & 1 deletion packages/keychain/src/utils/connection/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down

0 comments on commit 2482164

Please sign in to comment.