Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: decouple from snjs #194

Merged
merged 17 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,9 @@
"devDependencies": {
"c8": "^7.12.0",
"happy-dom": "^6.0.4",
"starknet": "^5.18.0",
"starknet4": "npm:[email protected]",
"typescript": "^4.6.4",
"vite": "^3.0.0",
"vite-plugin-dts": "^1.4.0",
"vitest": "^0.19.1"
},
"peerDependencies": {
"starknet": "^5.18.0"
},
"peerDependenciesMeta": {
"starknet": {
"optional": false
}
}
}
212 changes: 191 additions & 21 deletions packages/core/src/StarknetWindowObject.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,55 @@
import type { AccountInterface, ProviderInterface } from "starknet"
import type {
AccountInterface as AccountInterfaceV4,
ProviderInterface as ProviderInterfaceV4,
} from "starknet4"
type FELT = string

export type AccountChangeEventHandler = (accounts: string[]) => void
dhruvkelawala marked this conversation as resolved.
Show resolved Hide resolved
type Call = {
avimak marked this conversation as resolved.
Show resolved Hide resolved

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Call type : This type name already exists in Starknet.js, but their definition are not the same, generating confusion when coding. My proposal is to rename in the interface Call to CallParameters.

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<string, unknown> {
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<string, StarknetType[]>
primaryType: string
domain: StarknetDomain
message: Record<string, unknown>
}

export type AccountChangeEventHandler = (accounts?: string[]) => void

export type NetworkChangeEventHandler = (network?: string) => void

Expand All @@ -18,22 +63,126 @@ export type WalletEvents =
handler: NetworkChangeEventHandler
}

// EIP-747:
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-747.md
/**
* 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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Type string for abi is not working properly.
Only any[] is working properly.

}
}
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
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
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-3085.md

/**
* 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
Expand All @@ -43,19 +192,24 @@ export interface AddStarknetChainParameters {
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
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 SwitchStarknetChainParameter {
export interface SwitchStarknetChainParameters {
chainId: string // A 0x-prefixed hexadecimal string
}

export type RpcMessage =
| {
type: "wallet_requestAccounts"
params?: RequestAccountsParameters
result: string[]
}
| {
type: "wallet_watchAsset"
params: WatchAssetParameters
Expand All @@ -68,9 +222,29 @@ export type RpcMessage =
}
| {
type: "wallet_switchStarknetChain"
params: SwitchStarknetChainParameter
params: SwitchStarknetChainParameters
result: boolean
}
| {
type: "starknet_addInvokeTransaction"
params: AddInvokeTransactionParameters
result: AddInvokeTransactionResult
}
| {
type: "starknet_addDeclareTransaction"
params: AddDeclareTransactionParameters
result: AddDeclareTransactionResult
}
| {
type: "starknet_addDeployAccountTransaction"
params: AddDeployAccountTransactionParameters
result: AddDeployAccountTransactionResult
}
| {
type: "starknet_signTypedData"
params: TypedData
result: string[]
}
avimak marked this conversation as resolved.
Show resolved Hide resolved

export interface IStarknetWindowObject {
id: string
Expand All @@ -80,7 +254,6 @@ export interface IStarknetWindowObject {
request: <T extends RpcMessage>(
call: Omit<T, "result">,
) => Promise<T["result"]>
enable: (options?: { starknetVersion?: "v4" | "v5" }) => Promise<string[]>
avimak marked this conversation as resolved.
Show resolved Hide resolved
isPreauthorized: () => Promise<boolean>
on: <E extends WalletEvents>(
event: E["type"],
Expand All @@ -90,18 +263,15 @@ export interface IStarknetWindowObject {
event: E["type"],
handleEvent: E["handler"],
) => void
account?: AccountInterface | AccountInterfaceV4
provider?: ProviderInterface | ProviderInterfaceV4
selectedAddress?: string
chainId?: string
isConnected: boolean
}

export interface ConnectedStarknetWindowObject extends IStarknetWindowObject {
isConnected: true
account: AccountInterface | AccountInterfaceV4
provider: ProviderInterface | ProviderInterfaceV4
selectedAddress: string
chainId: string
isConnected: true
}

export interface DisconnectedStarknetWindowObject
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/__test__/wallet.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function makePreAuthorized(isPreauthorized: boolean) {
export function makeConnected(isConnected: boolean) {
return (wallet: WalletMock) => ({
...makePreAuthorized(true)(wallet),
enable: async () => [],
request: async () => [],
isConnected,
})
}
19 changes: 13 additions & 6 deletions packages/core/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
import type {
ConnectedStarknetWindowObject,
RequestAccountsParameters,
StarknetWindowObject,
} from "./StarknetWindowObject"
import discovery, { WalletProvider } from "./discovery"
Expand All @@ -17,11 +18,19 @@ export type {
NetworkChangeEventHandler,
RpcMessage,
StarknetWindowObject,
SwitchStarknetChainParameter,
SwitchStarknetChainParameters,
WalletEvents,
WatchAssetParameters,
DisconnectedStarknetWindowObject,
IStarknetWindowObject,
RequestAccountsParameters,
AddDeclareTransactionParameters,
AddDeclareTransactionResult,
AddDeployAccountTransactionParameters,
AddDeployAccountTransactionResult,
AddInvokeTransactionParameters,
AddInvokeTransactionResult,
TypedData,
} from "./StarknetWindowObject"
export type { WalletProvider } from "./discovery"

Expand Down Expand Up @@ -59,9 +68,7 @@ interface GetStarknetResult {
getLastConnectedWallet: () => Promise<StarknetWindowObject | null | undefined> // Returns the last wallet connected when it's still connected
enable: (
wallet: StarknetWindowObject,
options?: {
starknetVersion?: "v4" | "v5"
},
options?: RequestAccountsParameters,
) => Promise<ConnectedStarknetWindowObject> // Connects to a wallet
disconnect: (options?: DisconnectOptions) => Promise<void> // Disconnects from a wallet
}
Expand Down Expand Up @@ -121,7 +128,7 @@ export function getStarknet(
return firstPreAuthorizedWallet
},
enable: async (wallet, options) => {
await wallet.enable(options ?? { starknetVersion: "v5" })
await wallet.request({ type: "wallet_requestAccounts", params: options })
if (!wallet.isConnected) {
throw new Error("Failed to connect to wallet")
}
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/wallet/isWalletObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export const isWalletObj = (wallet: any): boolean => {
"request",
"isConnected",
"provider",
"enable",
"isPreauthorized",
"on",
"off",
Expand Down
Loading