version : v1.2.1 14/june/2024, details for invoke params with Starknet.js v6 version : v1.2.0 27/may/2024, in accordance with official spec https://github.com/starkware-libs/starknet-specs/wallet-api/wallet_rpc.json
version : v1.1.0 02/may/2024 version : v1.0.2 08/feb/2024
version : v1.0.1 07/feb/2024
This document is a documentation of the new interface between DAPPS and Starknet browser wallets.
- Starknet Wallet API
- Connect the wallet :
- Subscription to events :
- Available commands :
- wallet_getPermissions :
- wallet_requestAccounts :
- wallet_watchAsset :
- wallet_addStarknetChain :
- wallet_switchStarknetChain :
- wallet_requestChainId :
- wallet_deploymentData :
- wallet_addInvokeTransaction :
- wallet_addDeclareTransaction :
- wallet_signTypedData :
- wallet_supportedSpecs :
- wallet_supportedWalletApi :
- Wallet API version :
You have first to select which wallet to use.
import { StarknetWindowObject, connect } from "get-starknet"; // v4.0.0 mini
const myWallet: StarknetWindowObject = await connect({ modalMode: "alwaysAsk", modalTheme: "light" });
You can now use the commands proposed by the wallet (here with Starknet.js v6.8.0 mini) :
const myCall: Call = myContract.populate(
"increase_balance",
{ amount: 200 });
const myRequest = {
type: "wallet_addInvokeTransaction",
params: [myCall],
}
const response = await myWallet.request(myRequest);
You can subscribe to 2 events :
accountsChanged
: Triggered each time you change the current account in the wallet.networkChanged
: Triggered each time you change the current network in the wallet.
At each change of network, both account and network events are occurring.
At each change of account, only the account event is occurring.
const handleAccount: AccountChangeEventHandler = (accounts: string[] | undefined) => {
if (accounts?.length) {
const textAddr = accounts[0] // hex string
setChangedAccount(textAddr); // from a useState
};
};
myWallet?.on("accountsChanged", handleAccount);
const handleNetwork: NetworkChangeEventHandler = (chainId?: string, accounts?: string[]) => {
if (!!chainId) { setRespChangedNetwork(chainId) }; // from a useState
}
myWallet?.on("networkChanged", handleNetwork);
Similar to subscription, using .off
method.
wallet.off("accountsChanged", handleAccount);
wallet.off('networkChanged', handleNetwork);
All these commands can be used with myWallet.request()
:
Indicate if the active account is authorized by the wallet to interact with the DAPP.
No parameters.
response : Permission[]
enum Permission {
Accounts = "accounts",
}
- If authorized, returns an array of strings. The first item content is
accounts
(equal toPermission.Accounts
enum). - If not authorized, the response is an empty array.
const resp = await myWallet.request(type: "wallet_getPermissions");
// resp = ["accounts"]
Get the account address of the wallet active account.
interface RequestAccountsParameters {
silentMode?: boolean
}
response : string[]
- Returns an array of hex string ; just use the first element.
- Optional silentMode : 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.
const resp = await myWallet.request(type: "wallet_requestAccounts");
// resp = ["0x067f5a62ec72010308cee6368a8488c8df74f1d375b989f96d48cde1c88c7929"]
Add a token in the list of assets displayed by the wallet.
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
}
}
response : boolean
- The wallet opens a window to ask if you agree to add this token in the display list. If you agree, returns
true
. - The optional parameters are rather useless, as they are automatically recovered by the blockchain data. Whatever you provide, the blockchain data are priority.
- If the address is not an ERC20, the method fails with this error :
interface NOT_ERC20 {
code: 111;
}
message: 'An error occurred (NOT_ERC20)';
- If the token is already displayed, the result is
true
. - If the user decline the proposal, the method fails with this error :
interface USER_REFUSED_OP {
code: 113;
message: 'An error occurred (USER_REFUSED_OP)';
}
- Other errors :
interface INVALID_REQUEST_PAYLOAD {
code: 114;
message: 'An error occurred (INVALID_REQUEST_PAYLOAD)';
}
interface UNKNOWN_ERROR {
code: 163;
message: 'An error occurred (UNKNOWN_ERROR)';
}
const addrxASTR = "0x005EF67D8c38B82ba699F206Bf0dB59f1828087A710Bad48Cc4d51A2B0dA4C29";
const myAsset: WatchAssetParameters = {
type: "ERC20",
options: {
address: addrxASTR,
decimals: 10,
name: "xAstraly",
symbol: "xASTR"
}
}
const resp = await myWallet.request(type: "wallet_watchAsset", params: myAsset);
// resp = true
Add a new network in the list of networks of the wallet.
interface AddStarknetChainParameters {
id: string
chain_id: string // A 0x-prefixed hexadecimal string
chain_name: string
rpc_ urls?: string[]
block_explorer_urls?: string[]
native_currency?: {
type: 'ERC20'; // The asset's interface, e.g. 'ERC20'
options: {
address: string // A 0x-prefixed hexadecimal string
name?: string
symbol?: string // 2-6 characters long
decimals?: number
image?: string // A string url of the token logo
}
}
icon_urls?: string[] // Currently ignored.
}
response : boolean
- The wallet opens a window to ask if you agree to add this network in the wallet. If you agree, returns
true
. - If something is inconsistent in the input data, fails with error :
interface INVALID_REQUEST_PAYLOAD {
code: 114;
message: 'An error occurred (INVALID_REQUEST_PAYLOAD)';
}
- If the network is already listed, the result is
true
. - If the user decline the proposal, the method fails with this error :
interface USER_REFUSED_OP {
code: 113;
message: 'An error occurred (USER_REFUSED_OP)';
}
- Other error :
interface UNKNOWN_ERROR {
code: 163;
message: 'An error occurred (UNKNOWN_ERROR)';
}
const myChain: AddStarknetChainParameters = {
id: "ZORG",
chainId: shortString.encodeShortString("ZORG"),
chainName: "ZORG",
rpcUrls: ["http://192.168.1.44:6060"],
nativeCurrency: {
type: "ERC20",
options: {
address: "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
name: "ETHER",
symbol: "ETH",
decimals: 18,
}
}
}
const resp = await myWallet.request(type: "wallet_addStarknetChain", params: myChain);
// resp = true
Change the current network of the wallet.
interface SwitchStarknetChainParameters {
chainId: string // A 0x-prefixed hexadecimal string of an encoded text
}
response : boolean
- The wallet opens a window to ask if you agree to change the current network in the wallet. If you agree, returns
true
. - If something is inconsistent in the input data, the method fails with this error :
interface UNLISTED_NETWORK {
code: 112;
message: 'An error occurred (UNLISTED_NETWORK)';
}
- If the network is already the current one, the result is
true
. - If the network is not existing, fails with Error 112 "Network details are incorrect".
- If the user decline the proposal, the method fails with this error :
interface USER_REFUSED_OP {
code: 113;
message: 'An error occurred (USER_REFUSED_OP)';
}
- Other error :
interface UNKNOWN_ERROR {
code: 163;
message: 'An error occurred (UNKNOWN_ERROR)';
}
const myChainId: SwitchStarknetChainParameters = {
chainId: "0x534e5f5345504f4c4941" // SN_SEPOLIA
}
const resp = await myWallet.request(type: "wallet_switchStarknetChain", params: myChainId);
// resp = true
Returns the chainId of the current network of the wallet.
No parameters.
response : string
common chainId : SN_MAIN = "0x534e5f4d41494e", SN_SEPOLIA = "0x534e5f5345504f4c4941",
- No errors possible for this method.
const resp = await myWallet.request(type: "wallet_requestChainId");
// resp = "0x534e5f5345504f4c4941"
Request the deployment data of an account created, but not yet deployed.
No parameters.
response : interface AccountDeploymentData {
address: string // the expected address, used to double-check the returned data
class_hash: string // The class hash of the contract to deploy
salt: string // The salt used for the computation of the account address
calldata: string[] // An array of felts
sigdata?: string[] // An optional array of felts to be added in the signature
version: 0 | 1 // Cairo version (an integer)
}
Provides the data that will be used by the wallet to deploy an existing account (existing in the wallet, but not yet in the network).
- If the current account is already deployed, the method fails with this error :
interface ACCOUNT_ALREADY_DEPLOYED {
code: TBD;
message: 'An error occurred (ACCOUNT_ALREADY_DEPLOYED)';
}
const resp = await myWallet.request(type: "wallet_deploymentData");
// resp = {
// address: "0x0111fb83be44a70468d51cfcf8bccd4190cf119e4b2f83530ea13b5d35b9849d",
// class_hash: "0x03a5029a79d1849f58229e22f7f2b96bdd1dc8680e6cd5530a3122839f2ab878",
// salt: ""0xd3d12fb38fcc210966bcecd2ed83ba44b67e794209b994d1bac08f37f78e8e",
// calldata: [ "0xd3d12fb38fcc210966bcecd2ed83ba44b67e794209b994d1bac08f37f78e8e", "0x0" ],
// version: 1,
// }
Send one or several transaction(s) to the network.
interface AddInvokeTransactionParameters {
calls: Call[]
}
type Call = {
contract_address: string
entry_point: string
calldata?: string[]
}
response : interface AddInvokeTransactionResult {
transaction_hash: string
}
- If the user approved the transaction in the wallet, the response is the transaction hash.
- If an error occurred with these parameters, fails with Error :
interface INVALID_REQUEST_PAYLOAD {
code: 114;
message: 'An error occurred (INVALID_REQUEST_PAYLOAD)';
}
- If the user decline the proposal, the method fails with this error :
interface USER_REFUSED_OP {
code: 113;
message: 'An error occurred (USER_REFUSED_OP)';
}
- Other error :
interface UNKNOWN_ERROR {
code: 163;
message: 'An error occurred (UNKNOWN_ERROR)';
}
const contractAddress = "0x697d3bc2e38d57752c28be0432771f4312d070174ae54eef67dd29e4afb174";
const funcName = "increase_balance";
const myCall = myContract.populate(funcName, {
amount: 200
});
const myCallAPI = {
contract_address: myCall.contractAddress,
entry_point: myCall.entrypoint,
calldata: myCall.calldata as Calldata
};
const resp = await myWallet.request(type: "wallet_addInvokeTransaction", params: [myCallAPI]);
// resp = {transaction_hash: "0x067f5a62ec72010308cee6368a8488c8df74f1d375b989f96d48cde1c88c7929"}
Declare a new class in the current network.
interface AddDeclareTransactionParameters {
compiled_class_hash: string // The hash of the Cairo assembly resulting from the Sierra compilation
contract_class: {
sierra_program: string[] // The list of Sierra instructions of which the program consists
contract_class_version: string // The version of the contract class object. Currently, the Starknet OS supports version 0.1.0
entry_points_by_type: { // Entry points by type
CONSTRUCTOR: SIERRA_ENTRY_POINT[]
EXTERNAL: SIERRA_ENTRY_POINT[]
L1_HANDLER: SIERRA_ENTRY_POINT[]
},
abi: string // The stringified class ABI, as supplied by the user declaring the class
}
class_hash?: string;
};
type SIERRA_ENTRY_POINT = {
selector: string; // selector of the function name = selector.getSelectorFromName(funcName: string);
function_idx: number;
};
response : interface AddDeclareTransactionResult {
transaction_hash: string // The hash of the declare transaction
class_hash: string // The hash of the declared class
}
- If the user approved the declaration in the wallet, the response type is
AddDeclareTransactionResult
. - If the user approved the declaration in the wallet, and if the class is already declared, the function throw an error :
interface INVALID_REQUEST_PAYLOAD {
code: 114;
message: 'An error occurred (INVALID_REQUEST_PAYLOAD)';
}
same error if an error occurred in the network.
- If the user decline the proposal, the method fails with this error :
interface USER_REFUSED_OP {
code: 113;
message: 'An error occurred (USER_REFUSED_OP)';
}
- Other error :
interface UNKNOWN_ERROR {
code: 163;
message: 'An error occurred (UNKNOWN_ERROR)';
}
const myParams: AddDeclareTransactionParameters = {
compiled_class_hash: hash.computeCompiledClassHash(contractCasm),
contract_class: {
sierra_program: contractSierra.sierra_program,
contract_class_version: "0x01",
entry_points_by_type: contractSierra.entry_points_by_type,
abi:json.stringify(contractSierra.abi),
},
}
const resp = await myWallet.request(type: "wallet_addDeclareTransaction", params: myParams);
// resp = {transaction_hash: "0x067f5a62ec72010308cee6368a8488c8df74f1d375b989f96d48cde1c88c7929", class_hash: "0x2bfd9564754d9b4a326da62b2f22b8fea7bbeffd62da4fcaea986c323b7aeb"}
Returns the signature of an EIP712 "like" message, made by the current account of the wallet.
interface TypedData {
types: Record<string, StarknetType[]>
primaryType: string
domain: StarknetDomain
message: Record<string, unknown>
}
type StarknetType =
| {
name: string
type: string
}
| StarknetEnumType
| StarknetMerkleType;
type StarknetMerkleType = {
name: string
type: "merkletree"
contains: string
};
export type StarknetEnumType = {
name: string;
type: 'enum';
contains: string;
};
interface StarknetDomain extends Record<string, unknown> {
name?: string
version?: string
chainId?: string | number
revision?: string;
}
response : string[] // Signature. Standard signature is 2 felts, but depending of the wallet, response length can be different.
- If the user accepted to sign, the response type is the signature.
- If an error occurred in the network, fails with Error :
interface INVALID_REQUEST_PAYLOAD {
code: 114;
message: 'An error occurred (INVALID_REQUEST_PAYLOAD)';
}
- If the user decline the proposal, the method fails with this error :
interface USER_REFUSED_OP {
code: 113;
message: 'An error occurred (USER_REFUSED_OP)';
}
- Other error :
interface UNKNOWN_ERROR {
code: 163;
message: 'An error occurred (UNKNOWN_ERROR)';
}
const myTypedData: TypedData = {
types: {
StarkNetDomain: [
{ name: "name", type: "string" },
{ name: "version", type: "string" },
{ name: "chainId", type: "string" },
],
Airdrop: [
{ name: "address", type: "string" },
{ name: "amount", type: "string" }
],
Validate: [
{ name: "id", type: "string" },
{ name: "from", type: "string" },
{ name: "amount", type: "string" },
{ name: "nameGamer", type: "string" },
{ name: "endDate", type: "string" },
{ name: "itemsAuthorized", type: "string*" }, // array of string
{ name: "chkFunction", type: "selector" }, // name of function
{ name: "rootList", type: "merkletree", contains: "Airdrop" } // root of a merkle tree
]
},
primaryType: "Validate",
domain: {
name: "myDapp",
version: "1",
chainId: shortString.encodeShortString("SN_GOERLI"),
message: {
id: "0x0000004f000f",
from: "0x2c94f628d125cd0e86eaefea735ba24c262b9a441728f63e5776661829a4066",
amount: "400",
nameGamer: "Hector26",
endDate: "0x27d32a3033df4277caa9e9396100b7ca8c66a4ef8ea5f6765b91a7c17f0109c",
itemsAuthorized: ["0x01", "0x03", "0x0a", "0x0e"],
chkFunction: "check_authorization",
rootList: [
{
address: "0x69b49c2cc8b16e80e86bfc5b0614a59aa8c9b601569c7b80dde04d3f3151b79",
amount: "1554785",
}
]
},
}
}
const resp = await myWallet.request(type: "wallet_signTypedData", params: myTypedData);
// resp = ["0x490864293786342333657489548354947743460397232672997805795441858116745355019", "0x2855273948349341532300559537680769749551471477465497884530979636925080056604"]
Returns a list of rpc spec versions compatible with the wallet.
No parameters.
response : string[]
- The response is an array of strings. Each string is the version of a supported starknet API version. Includes only the 2 main digits, with the
.
as separator ; example :0.7
.
const resp = await myWallet.request(type: "wallet_supportedSpecs");
// resp = ["0.6","0.7"]
Returns a list of Wallet API versions compatible with the wallet.
No parameters.
response : string[]
- The response is an array of strings. Each string is the version of a supported Wallet API version. Includes only the 2 main digits, with the
.
as separator ; example :0.7
.
const resp = await myWallet.request(type: "wallet_supportedWalletApi");
// resp = ["0.7","0.8"]
All entries of this Wallet API have an optional parameter to define the version of API used to create the request.
const myParams = {
api_version: "0.7"
}
const resp = await myWallet.request(type: "wallet_requestChainId", params: myParams);
// resp = "0x534e5f5345504f4c4941"
In case of version not supported by the Wallet, an Error is returned :
interface API_VERSION_NOT_SUPPORTED {
code: 162;
message: 'An error occurred (API_VERSION_NOT_SUPPORTED)';
}