@cartridge/controller 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/telegram/provider.ts","../../src/constants.ts","../../src/session/account.ts","../../src/utils.ts","../../src/provider.ts","../../src/icon.ts"],"sourcesContent":["import {\n cloudStorage,\n miniApp,\n openLink,\n retrieveLaunchParams,\n} from \"@telegram-apps/sdk\";\nimport { ec, stark, WalletAccount } from \"starknet\";\n\nimport { KEYCHAIN_URL } from \"src/constants\";\nimport { Policy } from \"src/types\";\nimport SessionAccount from \"src/session/account\";\nimport BaseProvider from \"src/provider\";\n\ninterface SessionRegistration {\n username: string;\n address: string;\n ownerGuid: string;\n transactionHash?: string;\n expiresAt: string;\n}\n\nexport default class TelegramProvider extends BaseProvider {\n private _tmaUrl: string;\n protected _chainId: string;\n protected _username?: string;\n protected _policies: Policy[];\n\n constructor({\n rpc,\n chainId,\n policies,\n tmaUrl,\n }: {\n rpc: string;\n chainId: string;\n policies: Policy[];\n tmaUrl: string;\n }) {\n super({\n rpc,\n });\n\n this._tmaUrl = tmaUrl;\n this._chainId = chainId;\n this._policies = policies;\n\n if (typeof window !== \"undefined\") {\n (window as any).starknet_controller = this;\n }\n }\n\n async probe(): Promise<WalletAccount | undefined> {\n await this.tryRetrieveFromQueryOrStorage();\n return;\n }\n\n async connect(): Promise<WalletAccount | undefined> {\n await this.tryRetrieveFromQueryOrStorage();\n if (this.account) {\n return;\n }\n\n // Generate a random local key pair\n const pk = stark.randomAddress();\n const publicKey = ec.starkCurve.getStarkKey(pk);\n\n cloudStorage.setItem(\n \"sessionSigner\",\n JSON.stringify({\n privKey: pk,\n pubKey: publicKey,\n }),\n );\n\n const url = `${KEYCHAIN_URL}/session?public_key=${publicKey}&redirect_uri=${\n this._tmaUrl\n }&redirect_query_name=startapp&policies=${JSON.stringify(\n this._policies,\n )}&rpc_url=${this.rpc}`;\n\n localStorage.setItem(\"lastUsedConnector\", this.id);\n openLink(url);\n miniApp.close();\n\n return;\n }\n\n disconnect(): Promise<void> {\n cloudStorage.deleteItem(\"sessionSigner\");\n cloudStorage.deleteItem(\"session\");\n this.account = undefined;\n this._username = undefined;\n return Promise.resolve();\n }\n\n async tryRetrieveFromQueryOrStorage() {\n const signer = JSON.parse((await cloudStorage.getItem(\"sessionSigner\"))!);\n let sessionRegistration: SessionRegistration | null = null;\n\n const launchParams = retrieveLaunchParams();\n const session = launchParams.startParam;\n if (session) {\n sessionRegistration = JSON.parse(atob(session));\n cloudStorage.setItem(\"session\", JSON.stringify(sessionRegistration));\n }\n\n if (!sessionRegistration) {\n const session = await cloudStorage.getItem(\"session\");\n if (session) {\n sessionRegistration = JSON.parse(session);\n }\n }\n\n if (!sessionRegistration) {\n return;\n }\n\n this._username = sessionRegistration.username;\n this.account = new SessionAccount(this, {\n rpcUrl: this.rpc.toString(),\n privateKey: signer.privKey,\n address: sessionRegistration.address,\n ownerGuid: sessionRegistration.ownerGuid,\n chainId: this._chainId,\n expiresAt: parseInt(sessionRegistration.expiresAt),\n policies: this._policies,\n });\n\n return this.account;\n }\n}\n","export const KEYCHAIN_URL = \"https://x.cartridge.gg\";\nexport const PROFILE_URL = \"https://profile.cartridge.gg\";\n","import { Policy } from \"@cartridge/account-wasm\";\nimport { CartridgeSessionAccount } from \"@cartridge/account-wasm/session\";\nimport { Call, InvokeFunctionResponse, WalletAccount } from \"starknet\";\n\nimport { normalizeCalls } from \"../utils\";\nimport BaseProvider from \"../provider\";\n\nexport * from \"../errors\";\nexport * from \"../types\";\nexport { defaultPresets } from \"../presets\";\n\nexport default class SessionAccount extends WalletAccount {\n public controller: CartridgeSessionAccount;\n\n constructor(\n provider: BaseProvider,\n {\n rpcUrl,\n privateKey,\n address,\n ownerGuid,\n chainId,\n expiresAt,\n policies,\n }: {\n rpcUrl: string;\n privateKey: string;\n address: string;\n ownerGuid: string;\n chainId: string;\n expiresAt: number;\n policies: Policy[];\n },\n ) {\n super({ nodeUrl: rpcUrl }, provider);\n\n this.controller = CartridgeSessionAccount.new_as_registered(\n rpcUrl,\n privateKey,\n address,\n ownerGuid,\n chainId,\n {\n expiresAt,\n policies,\n },\n );\n }\n\n /**\n * Invoke execute function in account contract\n *\n * @param calls the invocation object or an array of them, containing:\n * - contractAddress - the address of the contract\n * - entrypoint - the entrypoint of the contract\n * - calldata - (defaults to []) the calldata\n * - signature - (defaults to []) the signature\n * @param abis (optional) the abi of the contract for better displaying\n *\n * @returns response from addTransaction\n */\n async execute(calls: Call | Call[]): Promise<InvokeFunctionResponse> {\n return this.controller.execute(normalizeCalls(calls));\n }\n}\n","import { addAddressPadding, Call, CallData } from \"starknet\";\n\nexport function normalizeCalls(calls: Call | Call[]) {\n return (Array.isArray(calls) ? calls : [calls]).map((call) => {\n return {\n entrypoint: call.entrypoint,\n contractAddress: addAddressPadding(call.contractAddress),\n calldata: CallData.toHex(call.calldata),\n };\n });\n}\n","import { WalletAccount } from \"starknet\";\nimport {\n AddInvokeTransactionParameters,\n Errors,\n Permission,\n RequestFn,\n StarknetWindowObject,\n TypedData,\n WalletEventHandlers,\n WalletEventListener,\n WalletEvents,\n} from \"@starknet-io/types-js\";\n\nimport { icon } from \"./icon\";\nimport { ProviderOptions } from \"./types\";\n\nexport default abstract class BaseProvider implements StarknetWindowObject {\n public id = \"controller\";\n public name = \"Controller\";\n public version = \"0.4.0\";\n public icon = icon;\n\n public rpc: URL;\n public account?: WalletAccount;\n public subscriptions: WalletEvents[] = [];\n\n constructor(options: ProviderOptions) {\n const { rpc } = options;\n\n this.rpc = new URL(rpc);\n }\n\n request: RequestFn = async (call) => {\n switch (call.type) {\n case \"wallet_getPermissions\":\n await this.probe();\n\n if (this.account) {\n return [Permission.ACCOUNTS];\n }\n\n return [];\n\n case \"wallet_requestAccounts\": {\n if (this.account) {\n return [this.account.address];\n }\n\n this.account = await this.probe();\n if (!this.account) {\n this.account = await this.connect();\n }\n\n if (this.account) {\n return [this.account.address];\n }\n\n return [];\n }\n\n case \"wallet_watchAsset\":\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"wallet_watchAsset not implemented\",\n } as Errors.UNEXPECTED_ERROR;\n\n case \"wallet_addStarknetChain\":\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"wallet_addStarknetChain not implemented\",\n } as Errors.UNEXPECTED_ERROR;\n\n case \"wallet_switchStarknetChain\":\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"wallet_switchStarknetChain not implemented\",\n } as Errors.UNEXPECTED_ERROR;\n\n case \"wallet_requestChainId\":\n if (!this.account) {\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"wallet_deploymentData not implemented\",\n } as Errors.UNEXPECTED_ERROR;\n }\n\n return await this.account.getChainId();\n\n case \"wallet_deploymentData\":\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"wallet_deploymentData not implemented\",\n } as Errors.UNEXPECTED_ERROR;\n\n case \"wallet_addInvokeTransaction\":\n if (!this.account) {\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"wallet_deploymentData not implemented\",\n } as Errors.UNEXPECTED_ERROR;\n }\n\n let params = call.params as AddInvokeTransactionParameters;\n return await this.account.execute(\n params.calls.map((call) => ({\n contractAddress: call.contract_address,\n entrypoint: call.entry_point,\n calldata: call.calldata,\n })),\n );\n\n case \"wallet_addDeclareTransaction\":\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"wallet_addDeclareTransaction not implemented\",\n } as Errors.UNEXPECTED_ERROR;\n\n case \"wallet_signTypedData\": {\n if (!this.account) {\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"Account not initialized\",\n } as Errors.UNEXPECTED_ERROR;\n }\n\n return await this.account.signMessage(call.params as TypedData);\n }\n\n case \"wallet_supportedSpecs\":\n return [];\n case \"wallet_supportedWalletApi\":\n return [];\n default:\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: `Unknown RPC call type: ${call.type}`,\n } as Errors.UNEXPECTED_ERROR;\n }\n };\n\n on: WalletEventListener = <E extends keyof WalletEventHandlers>(\n event: E,\n handler: WalletEventHandlers[E],\n ): void => {\n if (event !== \"accountsChanged\" && event !== \"networkChanged\") {\n throw new Error(`Unknown event: ${event}`);\n }\n this.subscriptions.push({ type: event, handler } as WalletEvents);\n };\n\n off: WalletEventListener = <E extends keyof WalletEventHandlers>(\n event: E,\n handler: WalletEventHandlers[E],\n ): void => {\n if (event !== \"accountsChanged\" && event !== \"networkChanged\") {\n throw new Error(`Unknown event: ${event}`);\n }\n const idx = this.subscriptions.findIndex(\n (sub) => sub.type === event && sub.handler === handler,\n );\n if (idx >= 0) {\n this.subscriptions.splice(idx, 1);\n }\n };\n\n abstract probe(): Promise<WalletAccount | undefined>;\n abstract connect(): Promise<WalletAccount | undefined>;\n}\n","export const icon =\n \"data:image/png;base64,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\";\n"],"mappings":"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","names":["call","session"]}
1
+ {"version":3,"sources":["../../src/telegram/provider.ts","../../src/constants.ts","../../src/session/account.ts","../../src/utils.ts","../../src/provider.ts","../../src/icon.ts"],"sourcesContent":["import {\n cloudStorage,\n miniApp,\n openLink,\n retrieveLaunchParams,\n} from \"@telegram-apps/sdk\";\nimport { ec, stark, WalletAccount } from \"starknet\";\n\nimport { KEYCHAIN_URL } from \"src/constants\";\nimport { Policy } from \"src/types\";\nimport SessionAccount from \"src/session/account\";\nimport BaseProvider from \"src/provider\";\nimport { toWasmPolicies } from \"src/utils\";\n\ninterface SessionRegistration {\n username: string;\n address: string;\n ownerGuid: string;\n transactionHash?: string;\n expiresAt: string;\n}\n\nexport default class TelegramProvider extends BaseProvider {\n private _tmaUrl: string;\n protected _chainId: string;\n protected _username?: string;\n protected _policies: Policy[];\n\n constructor({\n rpc,\n chainId,\n policies,\n tmaUrl,\n }: {\n rpc: string;\n chainId: string;\n policies: Policy[];\n tmaUrl: string;\n }) {\n super({\n rpc,\n });\n\n this._tmaUrl = tmaUrl;\n this._chainId = chainId;\n this._policies = policies;\n\n if (typeof window !== \"undefined\") {\n (window as any).starknet_controller = this;\n }\n }\n\n async probe(): Promise<WalletAccount | undefined> {\n await this.tryRetrieveFromQueryOrStorage();\n return;\n }\n\n async connect(): Promise<WalletAccount | undefined> {\n await this.tryRetrieveFromQueryOrStorage();\n if (this.account) {\n return;\n }\n\n // Generate a random local key pair\n const pk = stark.randomAddress();\n const publicKey = ec.starkCurve.getStarkKey(pk);\n\n cloudStorage.setItem(\n \"sessionSigner\",\n JSON.stringify({\n privKey: pk,\n pubKey: publicKey,\n }),\n );\n\n const url = `${KEYCHAIN_URL}/session?public_key=${publicKey}&redirect_uri=${\n this._tmaUrl\n }&redirect_query_name=startapp&policies=${JSON.stringify(\n this._policies,\n )}&rpc_url=${this.rpc}`;\n\n localStorage.setItem(\"lastUsedConnector\", this.id);\n openLink(url);\n miniApp.close();\n\n return;\n }\n\n disconnect(): Promise<void> {\n cloudStorage.deleteItem(\"sessionSigner\");\n cloudStorage.deleteItem(\"session\");\n this.account = undefined;\n this._username = undefined;\n return Promise.resolve();\n }\n\n async tryRetrieveFromQueryOrStorage() {\n const signer = JSON.parse((await cloudStorage.getItem(\"sessionSigner\"))!);\n let sessionRegistration: SessionRegistration | null = null;\n\n const launchParams = retrieveLaunchParams();\n const session = launchParams.startParam;\n if (session) {\n sessionRegistration = JSON.parse(atob(session));\n cloudStorage.setItem(\"session\", JSON.stringify(sessionRegistration));\n }\n\n if (!sessionRegistration) {\n const session = await cloudStorage.getItem(\"session\");\n if (session) {\n sessionRegistration = JSON.parse(session);\n }\n }\n\n if (!sessionRegistration) {\n return;\n }\n\n this._username = sessionRegistration.username;\n this.account = new SessionAccount(this, {\n rpcUrl: this.rpc.toString(),\n privateKey: signer.privKey,\n address: sessionRegistration.address,\n ownerGuid: sessionRegistration.ownerGuid,\n chainId: this._chainId,\n expiresAt: parseInt(sessionRegistration.expiresAt),\n policies: toWasmPolicies(this._policies),\n });\n\n return this.account;\n }\n}\n","export const KEYCHAIN_URL = \"https://x.cartridge.gg\";\nexport const PROFILE_URL = \"https://profile.cartridge.gg\";\n","import { Policy } from \"@cartridge/account-wasm\";\nimport { CartridgeSessionAccount } from \"@cartridge/account-wasm/session\";\nimport { Call, InvokeFunctionResponse, WalletAccount } from \"starknet\";\n\nimport { normalizeCalls } from \"../utils\";\nimport BaseProvider from \"../provider\";\n\nexport * from \"../errors\";\nexport * from \"../types\";\nexport { defaultPresets } from \"../presets\";\n\nexport default class SessionAccount extends WalletAccount {\n public controller: CartridgeSessionAccount;\n\n constructor(\n provider: BaseProvider,\n {\n rpcUrl,\n privateKey,\n address,\n ownerGuid,\n chainId,\n expiresAt,\n policies,\n }: {\n rpcUrl: string;\n privateKey: string;\n address: string;\n ownerGuid: string;\n chainId: string;\n expiresAt: number;\n policies: Policy[];\n },\n ) {\n super({ nodeUrl: rpcUrl }, provider);\n\n this.controller = CartridgeSessionAccount.new_as_registered(\n rpcUrl,\n privateKey,\n address,\n ownerGuid,\n chainId,\n {\n expiresAt,\n policies,\n },\n );\n }\n\n /**\n * Invoke execute function in account contract\n *\n * @param calls the invocation object or an array of them, containing:\n * - contractAddress - the address of the contract\n * - entrypoint - the entrypoint of the contract\n * - calldata - (defaults to []) the calldata\n * - signature - (defaults to []) the signature\n * @param abis (optional) the abi of the contract for better displaying\n *\n * @returns response from addTransaction\n */\n async execute(calls: Call | Call[]): Promise<InvokeFunctionResponse> {\n return this.controller.execute(normalizeCalls(calls));\n }\n}\n","import {\n addAddressPadding,\n Call,\n CallData,\n hash,\n typedData,\n TypedDataRevision,\n} from \"starknet\";\nimport { Policy } from \"./types\";\nimport wasm from \"@cartridge/account-wasm/controller\";\n\nexport function normalizeCalls(calls: Call | Call[]) {\n return (Array.isArray(calls) ? calls : [calls]).map((call) => {\n return {\n entrypoint: call.entrypoint,\n contractAddress: addAddressPadding(call.contractAddress),\n calldata: CallData.toHex(call.calldata),\n };\n });\n}\n\nexport function toWasmPolicies(policies: Policy[]): wasm.Policy[] {\n return policies.map((richPolicy) => {\n if (\"target\" in richPolicy) {\n return {\n target: richPolicy.target,\n method: richPolicy.method,\n };\n } else {\n const domainHash = typedData.getStructHash(\n richPolicy.types,\n \"StarknetDomain\",\n richPolicy.domain,\n TypedDataRevision.ACTIVE,\n );\n const typeHash = typedData.getTypeHash(\n richPolicy.types,\n richPolicy.primaryType,\n TypedDataRevision.ACTIVE,\n );\n\n return {\n scope_hash: hash.computePoseidonHash(domainHash, typeHash),\n };\n }\n });\n}\n","import { WalletAccount } from \"starknet\";\nimport {\n AddInvokeTransactionParameters,\n Errors,\n Permission,\n RequestFn,\n StarknetWindowObject,\n TypedData,\n WalletEventHandlers,\n WalletEventListener,\n WalletEvents,\n} from \"@starknet-io/types-js\";\n\nimport { icon } from \"./icon\";\nimport { ProviderOptions } from \"./types\";\n\nexport default abstract class BaseProvider implements StarknetWindowObject {\n public id = \"controller\";\n public name = \"Controller\";\n public version = \"0.4.0\";\n public icon = icon;\n\n public rpc: URL;\n public account?: WalletAccount;\n public subscriptions: WalletEvents[] = [];\n\n constructor(options: ProviderOptions) {\n const { rpc } = options;\n\n this.rpc = new URL(rpc);\n }\n\n request: RequestFn = async (call) => {\n switch (call.type) {\n case \"wallet_getPermissions\":\n await this.probe();\n\n if (this.account) {\n return [Permission.ACCOUNTS];\n }\n\n return [];\n\n case \"wallet_requestAccounts\": {\n if (this.account) {\n return [this.account.address];\n }\n\n this.account = await this.probe();\n if (!this.account) {\n this.account = await this.connect();\n }\n\n if (this.account) {\n return [this.account.address];\n }\n\n return [];\n }\n\n case \"wallet_watchAsset\":\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"wallet_watchAsset not implemented\",\n } as Errors.UNEXPECTED_ERROR;\n\n case \"wallet_addStarknetChain\":\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"wallet_addStarknetChain not implemented\",\n } as Errors.UNEXPECTED_ERROR;\n\n case \"wallet_switchStarknetChain\":\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"wallet_switchStarknetChain not implemented\",\n } as Errors.UNEXPECTED_ERROR;\n\n case \"wallet_requestChainId\":\n if (!this.account) {\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"wallet_deploymentData not implemented\",\n } as Errors.UNEXPECTED_ERROR;\n }\n\n return await this.account.getChainId();\n\n case \"wallet_deploymentData\":\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"wallet_deploymentData not implemented\",\n } as Errors.UNEXPECTED_ERROR;\n\n case \"wallet_addInvokeTransaction\":\n if (!this.account) {\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"wallet_deploymentData not implemented\",\n } as Errors.UNEXPECTED_ERROR;\n }\n\n let params = call.params as AddInvokeTransactionParameters;\n return await this.account.execute(\n params.calls.map((call) => ({\n contractAddress: call.contract_address,\n entrypoint: call.entry_point,\n calldata: call.calldata,\n })),\n );\n\n case \"wallet_addDeclareTransaction\":\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"wallet_addDeclareTransaction not implemented\",\n } as Errors.UNEXPECTED_ERROR;\n\n case \"wallet_signTypedData\": {\n if (!this.account) {\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"Account not initialized\",\n } as Errors.UNEXPECTED_ERROR;\n }\n\n return await this.account.signMessage(call.params as TypedData);\n }\n\n case \"wallet_supportedSpecs\":\n return [];\n case \"wallet_supportedWalletApi\":\n return [];\n default:\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: `Unknown RPC call type: ${call.type}`,\n } as Errors.UNEXPECTED_ERROR;\n }\n };\n\n on: WalletEventListener = <E extends keyof WalletEventHandlers>(\n event: E,\n handler: WalletEventHandlers[E],\n ): void => {\n if (event !== \"accountsChanged\" && event !== \"networkChanged\") {\n throw new Error(`Unknown event: ${event}`);\n }\n this.subscriptions.push({ type: event, handler } as WalletEvents);\n };\n\n off: WalletEventListener = <E extends keyof WalletEventHandlers>(\n event: E,\n handler: WalletEventHandlers[E],\n ): void => {\n if (event !== \"accountsChanged\" && event !== \"networkChanged\") {\n throw new Error(`Unknown event: ${event}`);\n }\n const idx = this.subscriptions.findIndex(\n (sub) => sub.type === event && sub.handler === handler,\n );\n if (idx >= 0) {\n this.subscriptions.splice(idx, 1);\n }\n };\n\n abstract probe(): Promise<WalletAccount | undefined>;\n abstract connect(): Promise<WalletAccount | undefined>;\n}\n","export const icon =\n \"data:image/png;base64,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\";\n"],"mappings":"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","names":["call","session"]}
@@ -1,7 +1,6 @@
1
1
  import { constants, BigNumberish, Call, Abi, InvocationsDetails } from 'starknet';
2
- import { AddInvokeTransactionResult, TypedData, Signature } from '@starknet-io/types-js';
2
+ import { StarknetType, StarknetDomain, AddInvokeTransactionResult, TypedData, Signature } from '@starknet-io/types-js';
3
3
  import { AsyncMethodReturns } from '@cartridge/penpal';
4
- import wasm from '@cartridge/account-wasm/controller';
5
4
 
6
5
  type IFrameOptions$1<CallSender> = Omit<ConstructorParameters<typeof IFrame>[0], "id" | "url" | "onConnect"> & {
7
6
  url?: string;
@@ -51,9 +50,17 @@ type Session = {
51
50
  privateKey: string;
52
51
  };
53
52
  };
54
- type Policy = wasm.Policy & {
53
+ type Policy = CallPolicy | TypedDataPolicy;
54
+ type CallPolicy = {
55
+ target: string;
56
+ method: string;
55
57
  description?: string;
56
58
  };
59
+ type TypedDataPolicy = {
60
+ types: Record<string, StarknetType[]>;
61
+ primaryType: string;
62
+ domain: StarknetDomain;
63
+ };
57
64
  declare enum ResponseCodes {
58
65
  SUCCESS = "SUCCESS",
59
66
  NOT_CONNECTED = "NOT_CONNECTED",
@@ -159,7 +166,7 @@ type ProfileOptions = IFrameOptions & {
159
166
  /** The tokens to be listed on Inventory modal */
160
167
  tokens?: Tokens;
161
168
  };
162
- type ProfileContextTypeVariant = "inventory" | "trophies" | "achievements";
169
+ type ProfileContextTypeVariant = "inventory" | "trophies" | "achievements" | "activity";
163
170
  type ColorMode = "light" | "dark";
164
171
  type ControllerTheme = {
165
172
  id: string;
@@ -189,4 +196,4 @@ type Tokens = {
189
196
  erc20?: string[];
190
197
  };
191
198
 
192
- export { type ConnectError as C, type DeployReply as D, type ExecuteReply as E, type IFrames as I, type Keychain as K, type Modal as M, type Policy as P, ResponseCodes as R, type Session as S, type ThemeValue as T, type ControllerError as a, type ConnectReply as b, type ProbeReply as c, type ControllerAccounts as d, type Profile as e, type ControllerOptions as f, type IFrameOptions as g, type ProviderOptions as h, type KeychainOptions as i, type ProfileOptions as j, type ProfileContextTypeVariant as k, type ColorMode as l, type ControllerTheme as m, type ControllerThemePresets as n, type ControllerThemePreset as o, type ControllerColors as p, type ControllerColor as q, type Prefund as r, type Tokens as s, type IFrameOptions$1 as t, IFrame as u, KeychainIFrame as v, type ProfileIFrameOptions as w, ProfileIFrame as x };
199
+ export { type CallPolicy as C, type DeployReply as D, type ExecuteReply as E, type IFrames as I, type Keychain as K, type Modal as M, type Policy as P, ResponseCodes as R, type Session as S, type TypedDataPolicy as T, type ConnectError as a, type ControllerError as b, type ConnectReply as c, type ProbeReply as d, type ControllerAccounts as e, type Profile as f, type ControllerOptions as g, type IFrameOptions as h, type ProviderOptions as i, type KeychainOptions as j, type ProfileOptions as k, type ProfileContextTypeVariant as l, type ColorMode as m, type ControllerTheme as n, type ControllerThemePresets as o, type ControllerThemePreset as p, type ControllerColors as q, type ControllerColor as r, type ThemeValue as s, type Prefund as t, type Tokens as u, type IFrameOptions$1 as v, IFrame as w, KeychainIFrame as x, type ProfileIFrameOptions as y, ProfileIFrame as z };
package/dist/types.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import 'starknet';
2
2
  import '@starknet-io/types-js';
3
- export { l as ColorMode, C as ConnectError, b as ConnectReply, d as ControllerAccounts, q as ControllerColor, p as ControllerColors, a as ControllerError, f as ControllerOptions, m as ControllerTheme, o as ControllerThemePreset, n as ControllerThemePresets, D as DeployReply, E as ExecuteReply, g as IFrameOptions, I as IFrames, K as Keychain, i as KeychainOptions, M as Modal, P as Policy, r as Prefund, c as ProbeReply, e as Profile, k as ProfileContextTypeVariant, j as ProfileOptions, h as ProviderOptions, R as ResponseCodes, S as Session, T as ThemeValue, s as Tokens } from './types-BkXOAuzX.js';
4
- import '@cartridge/account-wasm/controller';
3
+ export { C as CallPolicy, m as ColorMode, a as ConnectError, c as ConnectReply, e as ControllerAccounts, r as ControllerColor, q as ControllerColors, b as ControllerError, g as ControllerOptions, n as ControllerTheme, p as ControllerThemePreset, o as ControllerThemePresets, D as DeployReply, E as ExecuteReply, h as IFrameOptions, I as IFrames, K as Keychain, j as KeychainOptions, M as Modal, P as Policy, t as Prefund, d as ProbeReply, f as Profile, l as ProfileContextTypeVariant, k as ProfileOptions, i as ProviderOptions, R as ResponseCodes, S as Session, s as ThemeValue, u as Tokens, T as TypedDataPolicy } from './types-ikHqoYmG.js';
5
4
  import '@cartridge/penpal';
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import {\n constants,\n BigNumberish,\n Call,\n Abi,\n InvocationsDetails,\n} from \"starknet\";\nimport {\n AddInvokeTransactionResult,\n Signature,\n TypedData,\n} from \"@starknet-io/types-js\";\nimport { KeychainIFrame, ProfileIFrame } from \"./iframe\";\nimport wasm from \"@cartridge/account-wasm/controller\";\n\nexport type Session = {\n chainId: constants.StarknetChainId;\n policies: Policy[];\n maxFee: BigNumberish;\n expiresAt: bigint;\n credentials: {\n authorization: string[];\n privateKey: string;\n };\n};\n\nexport type Policy = wasm.Policy & {\n description?: string;\n};\n\nexport enum ResponseCodes {\n SUCCESS = \"SUCCESS\",\n NOT_CONNECTED = \"NOT_CONNECTED\",\n ERROR = \"ERROR\",\n CANCELED = \"CANCELED\",\n USER_INTERACTION_REQUIRED = \"USER_INTERACTION_REQUIRED\",\n}\n\nexport type ConnectError = {\n code: ResponseCodes;\n message: string;\n error?: ControllerError;\n};\n\nexport type ControllerError = {\n code: Number;\n message: string;\n data?: any;\n};\n\nexport type ConnectReply = {\n code: ResponseCodes.SUCCESS;\n address: string;\n policies: Policy[];\n};\n\nexport type ExecuteReply =\n | (AddInvokeTransactionResult & {\n code: ResponseCodes.SUCCESS;\n })\n | {\n code: ResponseCodes.USER_INTERACTION_REQUIRED;\n };\n\nexport type ProbeReply = {\n code: ResponseCodes.SUCCESS;\n address: string;\n};\n\nexport type DeployReply = {\n code: ResponseCodes.SUCCESS;\n transaction_hash: string;\n};\n\nexport type IFrames = {\n keychain: KeychainIFrame;\n profile?: ProfileIFrame;\n};\n\ntype ContractAddress = string;\ntype CartridgeID = string;\nexport type ControllerAccounts = Record<ContractAddress, CartridgeID>;\n\nexport interface Keychain {\n probe(rpcUrl: string): Promise<ProbeReply | ConnectError>;\n connect(\n policies: Policy[],\n rpcUrl: string,\n ): Promise<ConnectReply | ConnectError>;\n disconnect(): void;\n\n reset(): void;\n revoke(origin: string): void;\n\n deploy(): Promise<DeployReply | ConnectError>;\n execute(\n calls: Call | Call[],\n abis?: Abi[],\n transactionsDetail?: InvocationsDetails,\n sync?: boolean,\n paymaster?: any,\n error?: ControllerError,\n ): Promise<ExecuteReply | ConnectError>;\n signMessage(\n typedData: TypedData,\n account: string,\n async?: boolean,\n ): Promise<Signature | ConnectError>;\n logout(): Promise<void>;\n openSettings(): Promise<void | ConnectError>;\n session(): Promise<Session>;\n sessions(): Promise<{\n [key: string]: Session;\n }>;\n delegateAccount(): string;\n username(): string;\n fetchControllers(contractAddresses: string[]): Promise<ControllerAccounts>;\n openPurchaseCredits(): void;\n openExecute(): void;\n}\nexport interface Profile {\n navigate(path: string): void;\n}\n\nexport interface Modal {\n open: () => void;\n close: () => void;\n}\n\n/**\n * Options for configuring the controller\n */\nexport type ControllerOptions = ProviderOptions &\n KeychainOptions &\n ProfileOptions;\n\nexport type IFrameOptions = {\n /** The ID of the starter pack to use */\n starterPackId?: string;\n /** The theme to use */\n theme?: string;\n /** The color mode to use */\n colorMode?: ColorMode;\n};\n\nexport type ProviderOptions = {\n /** The URL of the RPC */\n rpc: string;\n};\n\nexport type KeychainOptions = IFrameOptions & {\n policies?: Policy[];\n /** The URL of keychain */\n url?: string;\n /** The origin of keychain */\n origin?: string;\n /** Propagate transaction errors back to caller instead of showing modal */\n propagateSessionErrors?: boolean;\n};\n\nexport type ProfileOptions = IFrameOptions & {\n /** The URL of profile. Mainly for internal development purpose */\n profileUrl?: string;\n /** The project name of Slot instance. */\n slot?: string;\n /** The namespace to use to fetch trophies data from indexer. Will be mandatory once profile page is in production */\n namespace?: string;\n /** The tokens to be listed on Inventory modal */\n tokens?: Tokens;\n};\n\nexport type ProfileContextTypeVariant =\n | \"inventory\"\n | \"trophies\"\n | \"achievements\";\n\nexport type ColorMode = \"light\" | \"dark\";\n\nexport type ControllerTheme = {\n id: string;\n name: string;\n icon: string;\n cover: ThemeValue<string>;\n colorMode: ColorMode;\n};\n\nexport type ControllerThemePresets = Record<string, ControllerThemePreset>;\n\nexport type ControllerThemePreset = Omit<ControllerTheme, \"colorMode\"> & {\n colors?: ControllerColors;\n};\n\nexport type ControllerColors = {\n primary?: ControllerColor;\n primaryForeground?: ControllerColor;\n};\n\nexport type ControllerColor = ThemeValue<string>;\n\nexport type ThemeValue<T> = T | { dark: T; light: T };\n\nexport type Prefund = { address: string; min: string };\n\nexport type Tokens = {\n erc20?: string[];\n};\n"],"mappings":";AA8BO,IAAK,gBAAL,kBAAKA,mBAAL;AACL,EAAAA,eAAA,aAAU;AACV,EAAAA,eAAA,mBAAgB;AAChB,EAAAA,eAAA,WAAQ;AACR,EAAAA,eAAA,cAAW;AACX,EAAAA,eAAA,+BAA4B;AALlB,SAAAA;AAAA,GAAA;","names":["ResponseCodes"]}
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import {\n constants,\n BigNumberish,\n Call,\n Abi,\n InvocationsDetails,\n} from \"starknet\";\nimport {\n AddInvokeTransactionResult,\n Signature,\n StarknetDomain,\n StarknetType,\n TypedData,\n} from \"@starknet-io/types-js\";\nimport { KeychainIFrame, ProfileIFrame } from \"./iframe\";\n\nexport type Session = {\n chainId: constants.StarknetChainId;\n policies: Policy[];\n maxFee: BigNumberish;\n expiresAt: bigint;\n credentials: {\n authorization: string[];\n privateKey: string;\n };\n};\n\nexport type Policy = CallPolicy | TypedDataPolicy;\n\nexport type CallPolicy = {\n target: string;\n method: string;\n description?: string;\n};\n\nexport type TypedDataPolicy = {\n types: Record<string, StarknetType[]>;\n primaryType: string;\n domain: StarknetDomain;\n};\n\nexport enum ResponseCodes {\n SUCCESS = \"SUCCESS\",\n NOT_CONNECTED = \"NOT_CONNECTED\",\n ERROR = \"ERROR\",\n CANCELED = \"CANCELED\",\n USER_INTERACTION_REQUIRED = \"USER_INTERACTION_REQUIRED\",\n}\n\nexport type ConnectError = {\n code: ResponseCodes;\n message: string;\n error?: ControllerError;\n};\n\nexport type ControllerError = {\n code: Number;\n message: string;\n data?: any;\n};\n\nexport type ConnectReply = {\n code: ResponseCodes.SUCCESS;\n address: string;\n policies: Policy[];\n};\n\nexport type ExecuteReply =\n | (AddInvokeTransactionResult & {\n code: ResponseCodes.SUCCESS;\n })\n | {\n code: ResponseCodes.USER_INTERACTION_REQUIRED;\n };\n\nexport type ProbeReply = {\n code: ResponseCodes.SUCCESS;\n address: string;\n};\n\nexport type DeployReply = {\n code: ResponseCodes.SUCCESS;\n transaction_hash: string;\n};\n\nexport type IFrames = {\n keychain: KeychainIFrame;\n profile?: ProfileIFrame;\n};\n\ntype ContractAddress = string;\ntype CartridgeID = string;\nexport type ControllerAccounts = Record<ContractAddress, CartridgeID>;\n\nexport interface Keychain {\n probe(rpcUrl: string): Promise<ProbeReply | ConnectError>;\n connect(\n policies: Policy[],\n rpcUrl: string,\n ): Promise<ConnectReply | ConnectError>;\n disconnect(): void;\n\n reset(): void;\n revoke(origin: string): void;\n\n deploy(): Promise<DeployReply | ConnectError>;\n execute(\n calls: Call | Call[],\n abis?: Abi[],\n transactionsDetail?: InvocationsDetails,\n sync?: boolean,\n paymaster?: any,\n error?: ControllerError,\n ): Promise<ExecuteReply | ConnectError>;\n signMessage(\n typedData: TypedData,\n account: string,\n async?: boolean,\n ): Promise<Signature | ConnectError>;\n logout(): Promise<void>;\n openSettings(): Promise<void | ConnectError>;\n session(): Promise<Session>;\n sessions(): Promise<{\n [key: string]: Session;\n }>;\n delegateAccount(): string;\n username(): string;\n fetchControllers(contractAddresses: string[]): Promise<ControllerAccounts>;\n openPurchaseCredits(): void;\n openExecute(): void;\n}\nexport interface Profile {\n navigate(path: string): void;\n}\n\nexport interface Modal {\n open: () => void;\n close: () => void;\n}\n\n/**\n * Options for configuring the controller\n */\nexport type ControllerOptions = ProviderOptions &\n KeychainOptions &\n ProfileOptions;\n\nexport type IFrameOptions = {\n /** The ID of the starter pack to use */\n starterPackId?: string;\n /** The theme to use */\n theme?: string;\n /** The color mode to use */\n colorMode?: ColorMode;\n};\n\nexport type ProviderOptions = {\n /** The URL of the RPC */\n rpc: string;\n};\n\nexport type KeychainOptions = IFrameOptions & {\n policies?: Policy[];\n /** The URL of keychain */\n url?: string;\n /** The origin of keychain */\n origin?: string;\n /** Propagate transaction errors back to caller instead of showing modal */\n propagateSessionErrors?: boolean;\n};\n\nexport type ProfileOptions = IFrameOptions & {\n /** The URL of profile. Mainly for internal development purpose */\n profileUrl?: string;\n /** The project name of Slot instance. */\n slot?: string;\n /** The namespace to use to fetch trophies data from indexer. Will be mandatory once profile page is in production */\n namespace?: string;\n /** The tokens to be listed on Inventory modal */\n tokens?: Tokens;\n};\n\nexport type ProfileContextTypeVariant =\n | \"inventory\"\n | \"trophies\"\n | \"achievements\"\n | \"activity\";\n\nexport type ColorMode = \"light\" | \"dark\";\n\nexport type ControllerTheme = {\n id: string;\n name: string;\n icon: string;\n cover: ThemeValue<string>;\n colorMode: ColorMode;\n};\n\nexport type ControllerThemePresets = Record<string, ControllerThemePreset>;\n\nexport type ControllerThemePreset = Omit<ControllerTheme, \"colorMode\"> & {\n colors?: ControllerColors;\n};\n\nexport type ControllerColors = {\n primary?: ControllerColor;\n primaryForeground?: ControllerColor;\n};\n\nexport type ControllerColor = ThemeValue<string>;\n\nexport type ThemeValue<T> = T | { dark: T; light: T };\n\nexport type Prefund = { address: string; min: string };\n\nexport type Tokens = {\n erc20?: string[];\n};\n"],"mappings":";AAyCO,IAAK,gBAAL,kBAAKA,mBAAL;AACL,EAAAA,eAAA,aAAU;AACV,EAAAA,eAAA,mBAAgB;AAChB,EAAAA,eAAA,WAAQ;AACR,EAAAA,eAAA,cAAW;AACX,EAAAA,eAAA,+BAA4B;AALlB,SAAAA;AAAA,GAAA;","names":["ResponseCodes"]}
package/dist/utils.d.ts CHANGED
@@ -1,10 +1,15 @@
1
1
  import * as starknet from 'starknet';
2
2
  import { Call } from 'starknet';
3
+ import { P as Policy } from './types-ikHqoYmG.js';
4
+ import wasm from '@cartridge/account-wasm/controller';
5
+ import '@starknet-io/types-js';
6
+ import '@cartridge/penpal';
3
7
 
4
8
  declare function normalizeCalls(calls: Call | Call[]): {
5
9
  entrypoint: string;
6
10
  contractAddress: string;
7
11
  calldata: starknet.HexCalldata;
8
12
  }[];
13
+ declare function toWasmPolicies(policies: Policy[]): wasm.Policy[];
9
14
 
10
- export { normalizeCalls };
15
+ export { normalizeCalls, toWasmPolicies };
package/dist/utils.js CHANGED
@@ -1,5 +1,11 @@
1
1
  // src/utils.ts
2
- import { addAddressPadding, CallData } from "starknet";
2
+ import {
3
+ addAddressPadding,
4
+ CallData,
5
+ hash,
6
+ typedData,
7
+ TypedDataRevision
8
+ } from "starknet";
3
9
  function normalizeCalls(calls) {
4
10
  return (Array.isArray(calls) ? calls : [calls]).map((call) => {
5
11
  return {
@@ -9,7 +15,33 @@ function normalizeCalls(calls) {
9
15
  };
10
16
  });
11
17
  }
18
+ function toWasmPolicies(policies) {
19
+ return policies.map((richPolicy) => {
20
+ if ("target" in richPolicy) {
21
+ return {
22
+ target: richPolicy.target,
23
+ method: richPolicy.method
24
+ };
25
+ } else {
26
+ const domainHash = typedData.getStructHash(
27
+ richPolicy.types,
28
+ "StarknetDomain",
29
+ richPolicy.domain,
30
+ TypedDataRevision.ACTIVE
31
+ );
32
+ const typeHash = typedData.getTypeHash(
33
+ richPolicy.types,
34
+ richPolicy.primaryType,
35
+ TypedDataRevision.ACTIVE
36
+ );
37
+ return {
38
+ scope_hash: hash.computePoseidonHash(domainHash, typeHash)
39
+ };
40
+ }
41
+ });
42
+ }
12
43
  export {
13
- normalizeCalls
44
+ normalizeCalls,
45
+ toWasmPolicies
14
46
  };
15
47
  //# sourceMappingURL=utils.js.map
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.ts"],"sourcesContent":["import { addAddressPadding, Call, CallData } from \"starknet\";\n\nexport function normalizeCalls(calls: Call | Call[]) {\n return (Array.isArray(calls) ? calls : [calls]).map((call) => {\n return {\n entrypoint: call.entrypoint,\n contractAddress: addAddressPadding(call.contractAddress),\n calldata: CallData.toHex(call.calldata),\n };\n });\n}\n"],"mappings":";AAAA,SAAS,mBAAyB,gBAAgB;AAE3C,SAAS,eAAe,OAAsB;AACnD,UAAQ,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS;AAC5D,WAAO;AAAA,MACL,YAAY,KAAK;AAAA,MACjB,iBAAiB,kBAAkB,KAAK,eAAe;AAAA,MACvD,UAAU,SAAS,MAAM,KAAK,QAAQ;AAAA,IACxC;AAAA,EACF,CAAC;AACH;","names":[]}
1
+ {"version":3,"sources":["../src/utils.ts"],"sourcesContent":["import {\n addAddressPadding,\n Call,\n CallData,\n hash,\n typedData,\n TypedDataRevision,\n} from \"starknet\";\nimport { Policy } from \"./types\";\nimport wasm from \"@cartridge/account-wasm/controller\";\n\nexport function normalizeCalls(calls: Call | Call[]) {\n return (Array.isArray(calls) ? calls : [calls]).map((call) => {\n return {\n entrypoint: call.entrypoint,\n contractAddress: addAddressPadding(call.contractAddress),\n calldata: CallData.toHex(call.calldata),\n };\n });\n}\n\nexport function toWasmPolicies(policies: Policy[]): wasm.Policy[] {\n return policies.map((richPolicy) => {\n if (\"target\" in richPolicy) {\n return {\n target: richPolicy.target,\n method: richPolicy.method,\n };\n } else {\n const domainHash = typedData.getStructHash(\n richPolicy.types,\n \"StarknetDomain\",\n richPolicy.domain,\n TypedDataRevision.ACTIVE,\n );\n const typeHash = typedData.getTypeHash(\n richPolicy.types,\n richPolicy.primaryType,\n TypedDataRevision.ACTIVE,\n );\n\n return {\n scope_hash: hash.computePoseidonHash(domainHash, typeHash),\n };\n }\n });\n}\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAIA,SAAS,eAAe,OAAsB;AACnD,UAAQ,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS;AAC5D,WAAO;AAAA,MACL,YAAY,KAAK;AAAA,MACjB,iBAAiB,kBAAkB,KAAK,eAAe;AAAA,MACvD,UAAU,SAAS,MAAM,KAAK,QAAQ;AAAA,IACxC;AAAA,EACF,CAAC;AACH;AAEO,SAAS,eAAe,UAAmC;AAChE,SAAO,SAAS,IAAI,CAAC,eAAe;AAClC,QAAI,YAAY,YAAY;AAC1B,aAAO;AAAA,QACL,QAAQ,WAAW;AAAA,QACnB,QAAQ,WAAW;AAAA,MACrB;AAAA,IACF,OAAO;AACL,YAAM,aAAa,UAAU;AAAA,QAC3B,WAAW;AAAA,QACX;AAAA,QACA,WAAW;AAAA,QACX,kBAAkB;AAAA,MACpB;AACA,YAAM,WAAW,UAAU;AAAA,QACzB,WAAW;AAAA,QACX,WAAW;AAAA,QACX,kBAAkB;AAAA,MACpB;AAEA,aAAO;AAAA,QACL,YAAY,KAAK,oBAAoB,YAAY,QAAQ;AAAA,MAC3D;AAAA,IACF;AAAA,EACF,CAAC;AACH;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cartridge/controller",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "Cartridge Controller",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -31,13 +31,12 @@
31
31
  "fast-deep-equal": "^3.1.3",
32
32
  "query-string": "^7.1.1",
33
33
  "starknet": "^6.11.0",
34
- "@cartridge/account-wasm": "^0.5.0",
35
- "@cartridge/utils": "^0.5.0"
34
+ "@cartridge/account-wasm": "^0.5.1"
36
35
  },
37
36
  "devDependencies": {
38
37
  "@types/node": "^20.6.0",
39
38
  "typescript": "^5.4.5",
40
- "@cartridge/tsconfig": "^0.5.0"
39
+ "@cartridge/tsconfig": "^0.5.1"
41
40
  },
42
41
  "scripts": {
43
42
  "build:deps": "tsup --dts-resolve",
package/src/controller.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { AsyncMethodReturns } from "@cartridge/penpal";
2
- import { normalize } from "@cartridge/utils";
3
2
 
4
3
  import ControllerAccount from "./account";
5
4
  import { KeychainIFrame, ProfileIFrame } from "./iframe";
@@ -82,7 +81,7 @@ export default class ControllerProvider extends BaseProvider {
82
81
  methods: {
83
82
  openSettings: this.openSettings.bind(this),
84
83
  openPurchaseCredits: this.openPurchaseCredits.bind(this),
85
- openExecute: normalize(() => this.openExecute.bind(this)),
84
+ openExecute: this.openExecute.bind(this),
86
85
  },
87
86
  rpcUrl: this.rpc.toString(),
88
87
  username,
@@ -4,6 +4,7 @@ import { ec, stark, WalletAccount } from "starknet";
4
4
  import SessionAccount from "./account";
5
5
  import { KEYCHAIN_URL } from "../constants";
6
6
  import BaseProvider from "../provider";
7
+ import { toWasmPolicies } from "src/utils";
7
8
 
8
9
  interface SessionRegistration {
9
10
  username: string;
@@ -132,7 +133,7 @@ export default class SessionProvider extends BaseProvider {
132
133
  ownerGuid: sessionRegistration.ownerGuid,
133
134
  chainId: this._chainId,
134
135
  expiresAt: parseInt(sessionRegistration.expiresAt),
135
- policies: this._policies,
136
+ policies: toWasmPolicies(this._policies),
136
137
  });
137
138
 
138
139
  return this.account;
@@ -10,6 +10,7 @@ import { KEYCHAIN_URL } from "src/constants";
10
10
  import { Policy } from "src/types";
11
11
  import SessionAccount from "src/session/account";
12
12
  import BaseProvider from "src/provider";
13
+ import { toWasmPolicies } from "src/utils";
13
14
 
14
15
  interface SessionRegistration {
15
16
  username: string;
@@ -123,7 +124,7 @@ export default class TelegramProvider extends BaseProvider {
123
124
  ownerGuid: sessionRegistration.ownerGuid,
124
125
  chainId: this._chainId,
125
126
  expiresAt: parseInt(sessionRegistration.expiresAt),
126
- policies: this._policies,
127
+ policies: toWasmPolicies(this._policies),
127
128
  });
128
129
 
129
130
  return this.account;
package/src/types.ts CHANGED
@@ -8,10 +8,11 @@ import {
8
8
  import {
9
9
  AddInvokeTransactionResult,
10
10
  Signature,
11
+ StarknetDomain,
12
+ StarknetType,
11
13
  TypedData,
12
14
  } from "@starknet-io/types-js";
13
15
  import { KeychainIFrame, ProfileIFrame } from "./iframe";
14
- import wasm from "@cartridge/account-wasm/controller";
15
16
 
16
17
  export type Session = {
17
18
  chainId: constants.StarknetChainId;
@@ -24,10 +25,20 @@ export type Session = {
24
25
  };
25
26
  };
26
27
 
27
- export type Policy = wasm.Policy & {
28
+ export type Policy = CallPolicy | TypedDataPolicy;
29
+
30
+ export type CallPolicy = {
31
+ target: string;
32
+ method: string;
28
33
  description?: string;
29
34
  };
30
35
 
36
+ export type TypedDataPolicy = {
37
+ types: Record<string, StarknetType[]>;
38
+ primaryType: string;
39
+ domain: StarknetDomain;
40
+ };
41
+
31
42
  export enum ResponseCodes {
32
43
  SUCCESS = "SUCCESS",
33
44
  NOT_CONNECTED = "NOT_CONNECTED",
@@ -172,7 +183,8 @@ export type ProfileOptions = IFrameOptions & {
172
183
  export type ProfileContextTypeVariant =
173
184
  | "inventory"
174
185
  | "trophies"
175
- | "achievements";
186
+ | "achievements"
187
+ | "activity";
176
188
 
177
189
  export type ColorMode = "light" | "dark";
178
190
 
package/src/utils.ts CHANGED
@@ -1,4 +1,13 @@
1
- import { addAddressPadding, Call, CallData } from "starknet";
1
+ import {
2
+ addAddressPadding,
3
+ Call,
4
+ CallData,
5
+ hash,
6
+ typedData,
7
+ TypedDataRevision,
8
+ } from "starknet";
9
+ import { Policy } from "./types";
10
+ import wasm from "@cartridge/account-wasm/controller";
2
11
 
3
12
  export function normalizeCalls(calls: Call | Call[]) {
4
13
  return (Array.isArray(calls) ? calls : [calls]).map((call) => {
@@ -9,3 +18,30 @@ export function normalizeCalls(calls: Call | Call[]) {
9
18
  };
10
19
  });
11
20
  }
21
+
22
+ export function toWasmPolicies(policies: Policy[]): wasm.Policy[] {
23
+ return policies.map((richPolicy) => {
24
+ if ("target" in richPolicy) {
25
+ return {
26
+ target: richPolicy.target,
27
+ method: richPolicy.method,
28
+ };
29
+ } else {
30
+ const domainHash = typedData.getStructHash(
31
+ richPolicy.types,
32
+ "StarknetDomain",
33
+ richPolicy.domain,
34
+ TypedDataRevision.ACTIVE,
35
+ );
36
+ const typeHash = typedData.getTypeHash(
37
+ richPolicy.types,
38
+ richPolicy.primaryType,
39
+ TypedDataRevision.ACTIVE,
40
+ );
41
+
42
+ return {
43
+ scope_hash: hash.computePoseidonHash(domainHash, typeHash),
44
+ };
45
+ }
46
+ });
47
+ }