From fae8def95fab6c259cf9731fc4814489e9bef92a Mon Sep 17 00:00:00 2001 From: Toni Tabak Date: Tue, 2 Apr 2024 19:00:42 +0200 Subject: [PATCH 1/2] feat: integrate starknet types --- packages/core/package.json | 3 + packages/core/src/StarknetWindowObject.ts | 24 -- packages/core/src/__test__/wallet.mock.ts | 3 +- packages/core/src/main.ts | 22 +- packages/core/src/rpcMessage.ts | 330 ---------------------- packages/core/src/types.ts | 6 +- packages/core/src/wallet/filter.ts | 3 +- packages/core/src/wallet/scan.ts | 2 +- packages/core/src/wallet/sort.ts | 2 +- packages/core/src/walletEvents.ts | 17 -- pnpm-lock.yaml | 8 + 11 files changed, 30 insertions(+), 390 deletions(-) delete mode 100644 packages/core/src/StarknetWindowObject.ts delete mode 100644 packages/core/src/rpcMessage.ts delete mode 100644 packages/core/src/walletEvents.ts diff --git a/packages/core/package.json b/packages/core/package.json index 54040f8..e64b329 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -29,6 +29,9 @@ "dev": "vite build --watch", "test": "vitest" }, + "dependencies": { + "starknet-types": "^0.0.4" + }, "devDependencies": { "c8": "^7.12.0", "happy-dom": "^6.0.4", diff --git a/packages/core/src/StarknetWindowObject.ts b/packages/core/src/StarknetWindowObject.ts deleted file mode 100644 index 8a83961..0000000 --- a/packages/core/src/StarknetWindowObject.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { RequestFn } from "./rpcMessage" -import { WalletEventHandlers } from "./walletEvents" - -type WalletEventListener = ( - event: E, - handleEvent: WalletEventHandlers[E], -) => void - -// Implement the StarknetWindowObject interface with the improved request method -export interface StarknetWindowObject { - id: string - name: string - version: string - icon: string | { dark: string; light: string } - request: RequestFn - on: WalletEventListener - off: WalletEventListener -} - -declare global { - interface Window { - [key: `starknet_${string}`]: StarknetWindowObject | undefined - } -} diff --git a/packages/core/src/__test__/wallet.mock.ts b/packages/core/src/__test__/wallet.mock.ts index 1197086..36f45d7 100644 --- a/packages/core/src/__test__/wallet.mock.ts +++ b/packages/core/src/__test__/wallet.mock.ts @@ -1,6 +1,5 @@ -import { StarknetWindowObject } from "../StarknetWindowObject" import wallets from "../discovery" -import { Permission } from "../rpcMessage" +import type { Permission, StarknetWindowObject } from "starknet-types" type WalletMock = Pick diff --git a/packages/core/src/main.ts b/packages/core/src/main.ts index 1deeaff..c6e11c3 100644 --- a/packages/core/src/main.ts +++ b/packages/core/src/main.ts @@ -1,17 +1,15 @@ -import { type StarknetWindowObject } from "./StarknetWindowObject" import discovery, { type WalletProvider } from "./discovery" import { LocalStorageWrapper } from "./localStorageStore" -import { Permission } from "./rpcMessage" import type { GetStarknetOptions, GetStarknetResult } from "./types" import { pipe } from "./utils" import { filterBy, filterByAuthorized } from "./wallet/filter" import { isWalletObj } from "./wallet/isWalletObject" import { scanObjectForWallets } from "./wallet/scan" import { sortBy } from "./wallet/sort" - -export type { StarknetWindowObject } from "./StarknetWindowObject" +import { Permission, type StarknetWindowObject } from "starknet-types" export type { + StarknetWindowObject, AddDeclareTransactionParameters, AddDeclareTransactionResult, AddDeployAccountTransactionParameters, @@ -30,16 +28,12 @@ export type { IsParamsOptional, RpcTypeToMessageMap, RequestFnCall, -} from "./rpcMessage" - -export type { - WalletEvents, AccountChangeEventHandler, NetworkChangeEventHandler, WalletEventHandlers, -} from "./walletEvents" - -export { Permission } from "./rpcMessage" + Permission, + WalletEvents, +} from "starknet-types" export type { DisconnectOptions, @@ -57,6 +51,12 @@ const defaultOptions: GetStarknetOptions = { storageFactoryImplementation: (name: string) => new LocalStorageWrapper(name), } +declare global { + interface Window { + [key: `starknet_${string}`]: StarknetWindowObject | undefined + } +} + export function getStarknet( options: Partial = {}, ): GetStarknetResult { diff --git a/packages/core/src/rpcMessage.ts b/packages/core/src/rpcMessage.ts deleted file mode 100644 index 5792d5f..0000000 --- a/packages/core/src/rpcMessage.ts +++ /dev/null @@ -1,330 +0,0 @@ -export enum StarknetChainId { - SN_MAIN = "0x534e5f4d41494e", - SN_GOERLI = "0x534e5f474f45524c49", - SN_SEPOLIA = "0x534e5f5345504f4c4941", -} - -export enum Permission { - Accounts = "accounts", -} - -type FELT = string - -type Call = { - contract_address: FELT - entrypoint: string - calldata?: FELT[] -} - -type SIERRA_ENTRY_POINT = { - selector: FELT - function_idx: number -} - -type StarknetMerkleType = { - name: string - type: "merkletree" - contains: string -} - -/** - * A single type, as part of a struct. The `type` field can be any of the EIP-712 supported types. - * - * Note that the `uint` and `int` aliases like in Solidity, and fixed point numbers are not supported by the EIP-712 - * standard. - */ -type StarknetType = - | { - name: string - type: string - } - | StarknetMerkleType - -/** - * The EIP712 domain struct. Any of these fields are optional, but it must contain at least one field. - */ -interface StarknetDomain extends Record { - name?: string - version?: string - chainId?: string | number -} - -/** - * The complete typed data, with all the structs, domain data, primary type of the message, and the message itself. - */ -export interface TypedData { - types: Record - primaryType: string - domain: StarknetDomain - message: Record -} - -/** - * INVOKE_TXN_V1 - * @see https://github.com/starkware-libs/starknet-specs/blob/master/api/starknet_api_openrpc.json - */ -export interface AddInvokeTransactionParameters { - /** - * Calls to invoke by the account - */ - calls: Call[] -} -export interface AddInvokeTransactionResult { - /** - * The hash of the invoke transaction - */ - transaction_hash: FELT -} - -/** - * BROADCASTED_DECLARE_TXN_V2 - * @see https://github.com/starkware-libs/starknet-specs/blob/master/api/starknet_api_openrpc.json - */ -export interface AddDeclareTransactionParameters { - /** - * The hash of the Cairo assembly resulting from the Sierra compilation - */ - compiled_class_hash: FELT - contract_class: { - /** - * The list of Sierra instructions of which the program consists - */ - sierra_program: FELT[] - /** - * The version of the contract class object. Currently, the Starknet OS supports version 0.1.0 - */ - contract_class_version: string - /** - * Entry points by type - */ - entry_points_by_type: { - CONSTRUCTOR: SIERRA_ENTRY_POINT[] - EXTERNAL: SIERRA_ENTRY_POINT[] - L1_HANDLER: SIERRA_ENTRY_POINT[] - } - /** - * The class ABI, as supplied by the user declaring the class - */ - abi?: string - } -} -export interface AddDeclareTransactionResult { - /** - * The hash of the declare transaction - */ - transaction_hash: FELT - /** - * The hash of the declared class - */ - class_hash: FELT -} - -/** - * DEPLOY_ACCOUNT_TXN_V1 - * @see https://github.com/starkware-libs/starknet-specs/blob/master/api/starknet_api_openrpc.json - */ -export interface AddDeployAccountTransactionParameters { - /** - * The salt for the address of the deployed contract - */ - contract_address_salt: FELT - /** - * The parameters passed to the constructor - */ - constructor_calldata: FELT[] - /** - * The hash of the deployed contract's class - */ - class_hash: FELT -} -export interface AddDeployAccountTransactionResult { - /** - * The hash of the deploy transaction - */ - transaction_hash: FELT - /** - * The address of the new contract - */ - contract_address: FELT -} - -/** - * EIP-1102: - * @see https://eips.ethereum.org/EIPS/eip-1102 - */ -export interface RequestAccountsParameters { - /** - * If true, the wallet will not show the wallet-unlock UI in case of a locked wallet, - * nor the dApp-approve UI in case of a non-allowed dApp. - */ - silentMode?: boolean -} - -/** - * EIP-747: - * @see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-747.md - */ -export interface WatchAssetParameters { - type: "ERC20" // The asset's interface, e.g. 'ERC20' - options: { - address: string // The hexadecimal Starknet address of the token contract - symbol?: string // A ticker symbol or shorthand, up to 5 alphanumerical characters - decimals?: number // The number of asset decimals - image?: string // A string url of the token logo - name?: string // The name of the token - not in spec - } -} - -/** - * EIP-3085: - * @see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-3085.md - */ -export interface AddStarknetChainParameters { - id: string - chainId: string // A 0x-prefixed hexadecimal string - chainName: string - rpcUrls?: string[] - blockExplorerUrls?: string[] - - nativeCurrency?: { - address: string // Not part of the standard, but required by Starknet as it can work with any ERC20 token as the fee token - name: string - symbol: string // 2-6 characters long - decimals: number - } // Currently ignored. - iconUrls?: string[] // Currently ignored. -} - -export interface SwitchStarknetChainParameters { - chainId: string // A 0x-prefixed hexadecimal string -} - -// see https://community.starknet.io/t/snip-deployment-interface-between-dapps-and-wallets/101923 -export interface GetDeploymentDataResult { - address: FELT // the expected address, used to double-check the returned data - class_hash: FELT // The class hash of the contract to deploy - salt: FELT // The salt used for the computation of the account address - calldata: FELT[] // An array of felts - sigdata?: FELT[] // An optional array of felts to be added in the signature - version: 0 | 1 // Cairo version (an integer) -} - -/** - * Maps each RPC message type to its corresponding parameters and result type. - */ -export interface RpcTypeToMessageMap { - /** - * Get permissions from the wallet. - * @returns An array of permissions. - */ - wallet_getPermissions: { params?: never; result: Permission[] } - - /** - * Request accounts from the wallet. - * @param params Optional parameters for requesting accounts. - * @returns An array of account addresses as strings. - */ - wallet_requestAccounts: { - params?: RequestAccountsParameters - result: string[] - } - - /** - * Watch an asset in the wallet. - * @param params The parameters required to watch an asset. - * @returns A boolean indicating if the operation was successful. - */ - wallet_watchAsset: { params: WatchAssetParameters; result: boolean } - - /** - * Add a new Starknet chain to the wallet. - * @param params The parameters required to add a new chain. - * @returns A boolean indicating if the operation was successful. - */ - wallet_addStarknetChain: { - params: AddStarknetChainParameters - result: boolean - } - - /** - * Switch the current Starknet chain in the wallet. - * @param params The parameters required to switch chains. - * @returns A boolean indicating if the operation was successful. - */ - wallet_switchStarknetChain: { - params: SwitchStarknetChainParameters - result: boolean - } - - /** - * Request the current chain ID from the wallet. - * @returns The current Starknet chain ID. - */ - wallet_requestChainId: { params?: never; result: StarknetChainId } - - /** - * Get deployment data for a contract. - * @returns The deployment data result. - */ - wallet_deploymentData: { params?: never; result: GetDeploymentDataResult } - - /** - * Add an invoke transaction to the wallet. - * @param params The parameters required for the invoke transaction. - * @returns The result of adding the invoke transaction. - */ - starknet_addInvokeTransaction: { - params: AddInvokeTransactionParameters - result: AddInvokeTransactionResult - } - - /** - * Add a declare transaction to the wallet. - * @param params The parameters required for the declare transaction. - * @returns The result of adding the declare transaction. - */ - starknet_addDeclareTransaction: { - params: AddDeclareTransactionParameters - result: AddDeclareTransactionResult - } - - /** - * Add a deploy account transaction to the wallet. - * @param params The parameters required for the deploy account transaction. - * @returns The result of adding the deploy account transaction. - */ - starknet_addDeployAccountTransaction: { - params: AddDeployAccountTransactionParameters - result: AddDeployAccountTransactionResult - } - - /** - * Sign typed data using the wallet. - * @param params The typed data to sign. - * @returns An array of signatures as strings. - */ - starknet_signTypedData: { params: TypedData; result: string[] } - - /** - * Get the list of supported specifications. - * @returns An array of supported specification strings. - */ - starknet_supportedSpecs: { params?: never; result: string[] } -} - -export type RpcMessage = { - [K in keyof RpcTypeToMessageMap]: { type: K } & RpcTypeToMessageMap[K] -}[keyof RpcTypeToMessageMap] - -export type IsParamsOptional = - undefined extends RpcTypeToMessageMap[T]["params"] ? true : false - -export type RequestFnCall = { - type: T -} & (IsParamsOptional extends true - ? { params?: RpcTypeToMessageMap[T]["params"] } - : { params: RpcTypeToMessageMap[T]["params"] }) - -export type RequestFn = ( - call: RequestFnCall, -) => Promise diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 775775e..9d12178 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -1,9 +1,11 @@ -import { StarknetWindowObject } from "./StarknetWindowObject" import { WalletProvider } from "./discovery" import { IStorageWrapper } from "./localStorageStore" -import { RequestAccountsParameters } from "./rpcMessage" import { FilterList } from "./wallet/filter" import { Sort } from "./wallet/sort" +import type { + RequestAccountsParameters, + StarknetWindowObject, +} from "starknet-types" export type { WalletProvider } from "./discovery" diff --git a/packages/core/src/wallet/filter.ts b/packages/core/src/wallet/filter.ts index c504827..13911af 100644 --- a/packages/core/src/wallet/filter.ts +++ b/packages/core/src/wallet/filter.ts @@ -1,6 +1,5 @@ -import { type StarknetWindowObject } from "../StarknetWindowObject" import type { WalletProvider } from "../discovery" -import { Permission } from "../rpcMessage" +import { Permission, type StarknetWindowObject } from "starknet-types" export type FilterList = string[] interface FilterByOptions { diff --git a/packages/core/src/wallet/scan.ts b/packages/core/src/wallet/scan.ts index a1df808..c48ad3e 100644 --- a/packages/core/src/wallet/scan.ts +++ b/packages/core/src/wallet/scan.ts @@ -1,4 +1,4 @@ -import type { StarknetWindowObject } from "../StarknetWindowObject" +import type { StarknetWindowObject } from "starknet-types" export function scanObjectForWallets( obj: Record, diff --git a/packages/core/src/wallet/sort.ts b/packages/core/src/wallet/sort.ts index a58f35b..5443842 100644 --- a/packages/core/src/wallet/sort.ts +++ b/packages/core/src/wallet/sort.ts @@ -1,6 +1,6 @@ -import { StarknetWindowObject } from "../StarknetWindowObject" import { WalletProvider } from "../discovery" import { shuffle } from "../utils" +import { type StarknetWindowObject } from "starknet-types" export type Sort = string[] | "random" | null | undefined diff --git a/packages/core/src/walletEvents.ts b/packages/core/src/walletEvents.ts deleted file mode 100644 index 4933fda..0000000 --- a/packages/core/src/walletEvents.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { StarknetChainId } from "./rpcMessage" - -export type AccountChangeEventHandler = (accounts?: string[]) => void - -export type NetworkChangeEventHandler = ( - chainId?: StarknetChainId, - accounts?: string[], -) => void - -export interface WalletEventHandlers { - accountsChanged: AccountChangeEventHandler - networkChanged: NetworkChangeEventHandler -} - -export type WalletEvents = { - [E in keyof WalletEventHandlers]: { type: E; handler: WalletEventHandlers[E] } -}[keyof WalletEventHandlers] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cecadd2..f0bc587 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,6 +65,10 @@ importers: version: 3.0.0 packages/core: + dependencies: + starknet-types: + specifier: ^0.0.4 + version: 0.0.4 devDependencies: c8: specifier: ^7.12.0 @@ -4341,6 +4345,10 @@ packages: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: true + /starknet-types@0.0.4: + resolution: {integrity: sha512-PklqFeSp9gMqbzW5IbO8l1s3xsNZYkNG/x/gsytgYCIl6H/cqiwCZolVTneyTibvrdHOQ8kP3PXwfdsypudYqw==} + dev: false + /stream-transform@2.1.3: resolution: {integrity: sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==} dependencies: From 3f6ef54dfdb0c44431bfae9d9c682777addc1ada Mon Sep 17 00:00:00 2001 From: Toni Tabak Date: Wed, 3 Apr 2024 13:08:34 +0200 Subject: [PATCH 2/2] chore: fix --- packages/core/src/__test__/wallet.mock.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/__test__/wallet.mock.ts b/packages/core/src/__test__/wallet.mock.ts index 36f45d7..87d6ecc 100644 --- a/packages/core/src/__test__/wallet.mock.ts +++ b/packages/core/src/__test__/wallet.mock.ts @@ -1,5 +1,5 @@ import wallets from "../discovery" -import type { Permission, StarknetWindowObject } from "starknet-types" +import { Permission, type StarknetWindowObject } from "starknet-types" type WalletMock = Pick