-
-
Notifications
You must be signed in to change notification settings - Fork 939
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
WIP: Starknet Snap docs #1509
base: main
Are you sure you want to change the base?
WIP: Starknet Snap docs #1509
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
|
||
# Starknet | ||
|
||
You can interact with users' Starknet accounts in MetaMask by installing the Starknet Snap. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think a better way to say this is, "by connecting to the Starknet Snap for MetaMask."
Some notes on connect vs install:
|
wallet/how-to/use-non-evm-networks/starknet/connect-to-starknet.md
Outdated
Show resolved
Hide resolved
wallet/how-to/use-non-evm-networks/starknet/connect-to-starknet.md
Outdated
Show resolved
Hide resolved
|
||
## Connect using `get-starknet` | ||
|
||
### 1. Add `get-starknet` to your project |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
### 1. Add `get-starknet` to your project | |
### 0. Set up a React project | |
If you don't have an existing React project you can set it up as follow: | |
<Tabs> | |
<TabItem value="yarn" label="Yarn" default> | |
\```bash | |
yarn create react-app get-starknet-tutorial | |
\``` | |
</TabItem> | |
<TabItem value="npm" label="npm"> | |
\```bash | |
npm create react-app get-starknet-tutorial | |
\``` | |
</TabItem> | |
</Tabs> | |
### 1. Add `get-starknet` to your project |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could give the command line on how to set up an empty react project.
wallet/how-to/use-non-evm-networks/starknet/connect-to-starknet.md
Outdated
Show resolved
Hide resolved
wallet/how-to/use-non-evm-networks/starknet/connect-to-starknet.md
Outdated
Show resolved
Hide resolved
wallet/how-to/use-non-evm-networks/starknet/send-starknet-transactions.md
Outdated
Show resolved
Hide resolved
wallet/how-to/use-non-evm-networks/starknet/send-starknet-transactions.md
Outdated
Show resolved
Hide resolved
wallet/how-to/use-non-evm-networks/starknet/send-starknet-transactions.md
Outdated
Show resolved
Hide resolved
wallet/how-to/use-non-evm-networks/starknet/send-starknet-transactions.md
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still need some changes on api commented with "needs check" because the api changed. I will do a separate review for them.
"params": { | ||
"addressIndex": 1, | ||
"deploy": true, | ||
"chainId": "0x1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could provide here an existing chainId, maybe the testnet one ? Or make clear what the chain id should be at the beginning of the page.
</TabItem> | ||
</Tabs> | ||
|
||
## `starkNet_estimateAccountDeployFee` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needs check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@khanti42 working on this time
</TabItem> | ||
</Tabs> | ||
|
||
## `starkNet_estimateFee` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needs check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@khanti42 working on this time
|
||
### Returns | ||
|
||
The list of the stored user accounts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are two new optional return parameters in the account: upgradeRequired
and deployRequired
.
User accounts type is as follow :
export type AccContract = {
addressSalt: string;
publicKey: string; // in hex
address: string; // in hex
addressIndex: number;
derivationPath: string;
deployTxnHash: string; // in hex
chainId: string; // in hex
upgradeRequired?: boolean; // whether the account requires an upgrade to Cairo 1
deployRequired?: boolean; // whether the account requires to be deployed
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@khanti42 I have questions about this one (raised in chat)
</TabItem> | ||
</Tabs> | ||
|
||
## `starkNet_signMessage` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needs check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@khanti42 working on this time
</TabItem> | ||
</Tabs> | ||
|
||
## `starkNet_verifyMessage` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needs check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@khanti42 working on this time
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some suggestions on the intro pages.
@@ -0,0 +1,9 @@ | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need a _category_.json
file for this section because there is already an index.md
file.
sidebar_position: 5 | ||
--- | ||
|
||
# Sign Starknet data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@khanti42 thanks for all your feedback. Can you please add code to this one as well?
|
||
### Snap ID error | ||
|
||
Ensure you're using the correct Snap ID for the StarkNet Snap. Incorrect IDs will result in failed connections. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure you're using the correct Snap ID for the StarkNet Snap. Incorrect IDs will result in failed connections. | |
Ensure you're using the correct Snap ID for the StarkNet Snap. Incorrect IDs will result in failed connections. | |
The Starknet Snap ID is the name of the npm package of the snap: `@consensys/starknet-snap`. |
### Stale wallet data | ||
|
||
If the wallet address or account information doesn't update after reconnection, always listen for account or network changes and handle them appropriately. Use event listeners: | ||
|
||
```javascript | ||
ethereum.on('accountsChanged', (accounts) => { | ||
// Handle account change | ||
}); | ||
ethereum.on('chainChanged', (chainId) => { | ||
// Handle network change | ||
}); | ||
``` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not apply to the snap we can remove this part.
### Stale wallet data | |
If the wallet address or account information doesn't update after reconnection, always listen for account or network changes and handle them appropriately. Use event listeners: | |
```javascript | |
ethereum.on('accountsChanged', (accounts) => { | |
// Handle account change | |
}); | |
ethereum.on('chainChanged', (chainId) => { | |
// Handle network change | |
}); | |
``` |
## 1. Connection issues | ||
|
||
### Wallet connection fails or doesn't respond. | ||
|
||
Ensure that MetaMask is installed and the StarkNet Snap is properly set up. You can check if the Snap is available using: | ||
|
||
```javascript | ||
const availableWallets = getAvailableWallets(); | ||
if (!availableWallets.some(wallet => wallet.type === 'snap')) { | ||
alert('Please install StarkNet Snap in MetaMask to proceed.'); | ||
} | ||
``` | ||
|
||
### The `connect()` function returns null or undefined. | ||
|
||
Verify that the Snap is installed and MetaMask has granted permission for the dapp to connect. Always include error handling in the connect method to manage issues: | ||
|
||
```javascript | ||
try { | ||
const res = await connect(); | ||
if (!res) { | ||
console.log('No wallet connected'); | ||
} | ||
} catch (error) { | ||
console.error('Error connecting to wallet:', error); | ||
} | ||
``` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
## 1. Connection issues | |
### Wallet connection fails or doesn't respond. | |
Ensure that MetaMask is installed and the StarkNet Snap is properly set up. You can check if the Snap is available using: | |
```javascript | |
const availableWallets = getAvailableWallets(); | |
if (!availableWallets.some(wallet => wallet.type === 'snap')) { | |
alert('Please install StarkNet Snap in MetaMask to proceed.'); | |
} | |
``` | |
### The `connect()` function returns null or undefined. | |
Verify that the Snap is installed and MetaMask has granted permission for the dapp to connect. Always include error handling in the connect method to manage issues: | |
```javascript | |
try { | |
const res = await connect(); | |
if (!res) { | |
console.log('No wallet connected'); | |
} | |
} catch (error) { | |
console.error('Error connecting to wallet:', error); | |
} | |
``` | |
When using get-starknet MetaMask detection, connection and starknet snap installation is handled automatically. | |
In case you are using `invokeSnaps` directly then this needs to be handled manually. | |
You need to check first that MetaMask is installed : | |
```typescript | |
interface MetaMaskProvider { | |
isMetaMask: boolean; | |
request(options: { method: string }): Promise<void>; | |
} | |
declare global { | |
interface Window { | |
ethereum?: MetaMaskProvider; | |
} | |
} | |
/** | |
* Detects if MetaMask is installed and supports Snaps by invoking the 'wallet_getSnaps' method. | |
* | |
* @param {any} provider - The provider object, typically obtained from MetaMask. | |
* @returns {Promise<boolean>} - A promise that resolves to `true` if the provider supports Snaps, and `false` otherwise. | |
*/ | |
const isSupportSnap = async (provider: any): Promise<boolean> => { | |
try { | |
await provider.request({ | |
method: 'wallet_getSnaps', | |
}); | |
return true; | |
} catch { | |
return false; | |
} | |
}; | |
/** | |
* Type guard function to check if a given object is a valid MetaMaskProvider. | |
* | |
* @param {unknown} obj - The object to check. | |
* @returns {boolean} - `true` if the object is a MetaMask provider, `false` otherwise. | |
*/ | |
function isMetaMaskProvider(obj: unknown): obj is MetaMaskProvider { | |
return ( | |
obj !== null && | |
typeof obj === 'object' && | |
obj.hasOwnProperty('isMetaMask') && | |
obj.hasOwnProperty('request') | |
); | |
} | |
/** | |
* Detects a MetaMask provider by listening for the 'eip6963:announceProvider' event. | |
* | |
* @param {Window & typeof globalThis} windowObject - The window object used to access global browser features. | |
* @param {Object} options - Optional parameters, including a timeout for the detection process. | |
* @param {number} [options.timeout=3000] - The time to wait (in milliseconds) for the provider to announce itself. | |
* @returns {Promise<MetaMaskProvider | null>} - A promise that resolves to a MetaMaskProvider object if detected, or `null` if no provider is found. | |
*/ | |
function detectMetaMaskProvider( | |
windowObject: Window & typeof globalThis, | |
{ timeout = 3000 } = {}, | |
): Promise<MetaMaskProvider | null> { | |
let handled = false; | |
return new Promise<MetaMaskProvider | null>((resolve) => { | |
const handleEIP6963Provider = (event: CustomEvent) => { | |
const { info, provider } = event.detail; | |
if ( | |
['io.metamask', 'io.metamask.flask'].includes(info.rdns) && | |
isMetaMaskProvider(provider) | |
) { | |
resolve(provider); | |
handled = true; | |
} | |
}; | |
if (typeof windowObject.addEventListener === 'function') { | |
windowObject.addEventListener( | |
'eip6963:announceProvider', | |
(event: Event) => { | |
handleEIP6963Provider(event as CustomEvent); | |
}, | |
); | |
} | |
setTimeout(() => { | |
if (!handled) { | |
resolve(null); | |
} | |
}, timeout); | |
if (typeof windowObject.dispatchEvent === 'function') { | |
windowObject.dispatchEvent(new Event('eip6963:requestProvider')); | |
} | |
}); | |
} | |
/** | |
* Waits for a MetaMask provider to be detected, retrying if necessary. | |
* | |
* @param {Window & typeof globalThis} windowObject - The window object used to access global browser features. | |
* @param {Object} options - Optional parameters, including timeout and retries. | |
* @param {number} [options.timeout=1000] - The time (in milliseconds) to wait for each detection attempt. | |
* @param {number} [options.retries=0] - The number of retry attempts if no provider is detected. | |
* @returns {Promise<MetaMaskProvider | null>} - A promise that resolves to a MetaMaskProvider object if detected, or `null` if no provider is found. | |
*/ | |
async function waitForMetaMaskProvider( | |
windowObject: Window & typeof globalThis, | |
{ timeout = 1000, retries = 0 } = {}, | |
): Promise<MetaMaskProvider | null> { | |
return detectMetaMaskProvider(windowObject, { timeout }) | |
.catch(function () { | |
return null; | |
}) | |
.then(function (provider) { | |
if (provider || retries === 0) { | |
return provider; | |
} | |
return waitForMetaMaskProvider(windowObject, { | |
timeout, | |
retries: retries - 1, | |
}); | |
}); | |
} | |
/** | |
* Detects if MetaMask is installed by calling the waitForMetaMaskProvider function with retries. | |
* | |
* @param {Window & typeof globalThis} windowObject - The window object used to access global browser features. | |
* @returns {Promise<MetaMaskProvider | null>} - A promise that resolves to a MetaMaskProvider object if MetaMask is detected, or `null` otherwise. | |
*/ | |
async function detectMetamaskSupport(windowObject: Window & typeof globalThis): Promise<MetaMaskProvider | null> { | |
const provider = await waitForMetaMaskProvider(windowObject, { retries: 3 }); | |
return provider; | |
} | |
``` | |
This can be used as follow to check for Metamask Snap Support. This will check for MetaMask presence, and the support of Snap in the installed MetaMask version if any. If there is no MetaMask installed or the version of MetaMask does not support snap | |
```typescript | |
let isMetaMaskInstallRequired = false; | |
let provider = null; | |
try { | |
provider = await detectMetamaskSupport(window); | |
// Use the new detection method | |
if (provider && (await isSupportSnap(provider))) { | |
isMetaMaskInstallRequired = provider === null; | |
} else { | |
isMetaMaskInstallRequired = true; | |
} | |
} catch (err) { | |
isMetaMaskInstallRequired = true; | |
} | |
``` | |
In case MetaMask is not installed (e.g. `isMetaMaskInstallRequired=true` we can prompt the user to install MetaMask. | |
In case MetaMask is installed, we can prompt the user to install the Snap | |
```typescript | |
provider | |
.request({ | |
method: 'wallet_requestSnaps', | |
params: { | |
[snapId]: { version: snapVersion }, | |
}, | |
}) | |
.then(() => { | |
// The snap has been installed proceed accordingly. | |
}) | |
.catch(() => { | |
// The snap has not been installed (user rejected the installation) | |
}); | |
``` |
|
||
### Snap is not properly approved. | ||
|
||
Guide users through the process of approving the Snap in MetaMask. If they deny the connection, provide a retry option. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again this is handled automatically be get-starknet. When using the invokeSnaps what we describe in the previous section should already answer this.
Specifically
provider
.request({
method: 'wallet_requestSnaps',
params: {
[snapId]: { version: snapVersion },
},
})
.then(() => {
// The snap has been installed proceed accordingly.
})
.catch(() => {
// The snap has not been installed (user rejected the installation)
// Here we can provide retry options
});
|
||
# Send Starknet transactions | ||
|
||
After the account is connected, you can send a transaction using the `starknet.invoke()` function: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The connect-to-starknet
section shows how to get access to the wallet object that we use here
After the account is connected, you can send a transaction using the `starknet.invoke()` function: | |
After the account is connected, you can send a transaction using the `wallet.account.execute` function: |
wallet/how-to/use-non-evm-networks/starknet/sign-starknet-data.md
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added more comments. Some are high-level – I will return to certain pages when they're more copy-edit ready.
|
||
Starknet is a non-EVM Layer 2 network. To interact with Starknet accounts in MetaMask, you need to use the Starknet Snap. | ||
|
||
You can use the `get-starknet` library or the `wallet_invokeSnap` JSON-RPC method to connect to the Starknet Snap. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add links to get-starknet
library and wallet_invokeSnap
docs.
sidebar_position: 6 | ||
--- | ||
|
||
# Build a Basic dApp with get-starknet and React TypeScript |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# Build a Basic dApp with get-starknet and React TypeScript | |
# Create a simple Starknet dapp |
Simplify title for cleaner sidebar.
|
||
# Build a Basic dApp with get-starknet and React TypeScript | ||
|
||
In this tutorial, you'll learn how to set up a basic dApp that uses get-starknet to connect to MetaMask and display the user's wallet address. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this tutorial, you'll learn how to set up a basic dApp that uses get-starknet to connect to MetaMask and display the user's wallet address. | |
In this tutorial, you'll learn how to set up a basic dapp that uses the `get-starknet` library to connect to MetaMask and display the user's wallet address. |
# Build a Basic dApp with get-starknet and React TypeScript | ||
|
||
In this tutorial, you'll learn how to set up a basic dApp that uses get-starknet to connect to MetaMask and display the user's wallet address. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add prerequisites? yarn, text editor, etc.
|
||
In this tutorial, you'll learn how to set up a basic dApp that uses get-starknet to connect to MetaMask and display the user's wallet address. | ||
|
||
## 1. Project Setup |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
## 1. Project Setup | |
## 1. Set up the project |
It looks like this tutorial might be copy-paste and needs an editing pass? I'll refrain from adding more comments until it's more ready. Headings should be sentence case and avoid gerunds. Admonitions should be properly formatted, etc.
<!--For the dapp, the primary action to initiate interacting with Starknet accounts is to connect to the Snap, just like a dapp connects with MetaMask to interact with Ethereum accounts. Whether the user has the Starknet Snap installed already is not important. If the user needs to install the Snap, they will be prompted to do so. | ||
Despite this, we do need to explain that the user can reject the prompt to add the Snap to MetaMask and document what to expect (the response that the dapp will receive if the user rejects the request) and encourage the dapp to do something in that instance, like display a message to the user that they need to add the Snap to MetaMask in order to proceed. | ||
Also, in terms of working with Starknet specifically, we may need to explain that a user will need to take some steps to set up a Starknet account before they can actually use it with the dapp, so the dapp should thoughtfully design that onboarding flow. Whether the user needs to add the Snap (and thus they will be completely new to Starknet) or they already have it but their account is not funded or deployed, the dapp should handle those scenarios.--> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add brief intro to this page, and remove ordered lists from the headings.
Okay sorry, I still didn't push changes for the tutorial and troubleshoot section. Sorry, thought I mentioned in our sync |
@alexandratran pushed changes and suggestions, but am still working on tutorial and troubleshoot section. I ran into some issues/ errors when trying to replicate the steps for the tutorial. |
Description
Draft of Starknet Snap docs.
Issue(s) fixed
Fixes #1511
Fixes #1512
Fixes #1513
Fixes #1514
Fixes #1515
Fixes #1516
Fixes #1526
Preview
Checklist
Complete this checklist before merging your PR: