apibara / starknet-react Goto Github PK
View Code? Open in Web Editor NEWA collection of React providers and hooks for StarkNet
Home Page: https://starknet-react.com
License: MIT License
A collection of React providers and hooks for StarkNet
Home Page: https://starknet-react.com
License: MIT License
I take the example of useContract
which use this combination.
It would give better performance and more readability to use useMemo
instead.
Plus, we will not have to wait for setState
to be called to be able to use the contract.
When using useContract
, we have to deal with the possibility that the contract is undefined, which will not be the case when using useMemo
.
Here is a little post which explain this : https://stackoverflow.com/a/56029184
The call contract response from starknet.js returns an array of strings: https://github.com/0xs34n/starknet.js/blob/cd88fc8747897002b48c48da94c4da60ba739e87/src/types/api.ts#L145.
export type CallContractResponse = {
result: string[];
};
However, the corresponding type in starknet-react
is an array of any
. Could this be restricted to an array of strings?
Currently the provider does not detect if the user has the extension installed. Need to check for window.starknet && window.starknet.version === 'uninstalled'
.
There are some use cases which may mandate using the low-level starknet.js
operations callContract
and invokeFunction
. However, today, no hook api exists for them. This is particularly useful in StarkNet where we don't need the full contract signature to call a function.
Examples:
On pxls.wtf we had the following issue: sometimes the users couldn't log because there were no connectors.
I found that it happened when the user was reloading the page (command R on chrome).
At that point, the getInstalledInjectedConnectors()
that gets called at the very beginning of my Next.js app was empty!
Right now, I fixed it the hacky way:
https://github.com/nmalzieu/pxls-frontend/blob/main/pages/_app.tsx#L111-L129
However, I wonder:
The link in the documentation is currently broken.
The hook should batch together all registered calls and send only one multicall request, then deduplex the output back to the original caller.
Hello team!
I have a local web app I am developing, pointing to Goerli with the latest starknet-react package (as of this morning) and the latest ArgentX setup.
In a page I am able to successfully invoke the mint on this NFT contract I deployed. But on another page I am failing to call a function, the totalSupply
or name
for example.
export default function ChannelList() {
const { account } = useStarknet()
const { data: channelsCount, loading, error, refresh } = useStarknetCall({ contract: useChannelContract(), method: 'totalSupply' })
const [shouldRefresh, setShouldRefresh] = useState(true)
console.log(`channelsCount: ${channelsCount}, loading: ${loading}, error: ${error}`)
useEffect(() => {
if (!account || !shouldRefresh) return
setShouldRefresh(false)
refresh()
console.log('>>> refresh')
}, [account, shouldRefresh, refresh])
return (... )
}
In the console logs I see that the hook is loading then stops, but the data returned is always undefined
.
channelsCount: undefined, loading: true, error: undefined
>>> refresh
channelsCount: undefined, loading: false, error: undefined
channelsCount: undefined, loading: false, error: undefined
I even open another page, reload, connect the wallet, then navigate to this one, so I am sure that when this component loads the first time the account is connected correctly.
Any idea why this issue?
I want to track transaction status. but invoke method always return undefined.
Is there a way to configure calls to route to a custom endpoint, for example, the Cartridge powered node: https://twitter.com/cartridge_gg/status/1524391388841975808.
As a follow-up - is there a way to specify a cascading set of endpoints => if one fails to respond, the other will be used as a back-up.
In the useEffect
of the useStarknetCall
hook, we call dispatch({ type: 'set_last_updated_at', blockHash: block.block_hash })
without waiting the refresh
to finalize.
Which leads to set loading
(and maybe lastUpdatedAt
) to early.
starknet-react/packages/core/src/hooks/call.ts
Lines 119 to 120 in 883cba7
set_call_response
and set_call_error
to be able to set the loading
property.lastUpdatedAt
property when the new data are loaded properly.Hello,
It would be useful to be able to get the method involved in the transaction ( and maybe more? ) when using useStarknetTransactionManager
.
TCALSS :
To this:
addTransaction({ status: response.code, transactionHash: response.transaction_hash, method:method })
Thank you.
I ran into the following situation:
I have some code that invokes the useStarknetCall
hook right after the useContract
hook.
let useContractParams = ReactStarknet.UseContract.Parameters.make(
~abi=Abi.taskRegistry,
~address=registryAddress,
()
)
let {contract} = ReactStarknet.useContract(useContractParams)
let useStarknetCallParams = ReactStarknet.UseStarknetCall.Parameters.make(
~contract=contract -> Belt.Option.getWithDefault(%raw("undefined")),
~method="invocations",
~args=[task.int_address],
()
)
let {data, loading, error, refresh} = ReactStarknet.useStarknetCall(useStarknetCallParams)
There's no real magic in this code as it translates to the following JS:
var match = Core.useContract(useContractParams);
var contract = match.contract;
var useStarknetCallParams = {
contract: Belt_Option.getWithDefault(contract, undefined),
method: "invocations",
args: [task.int_address]
};
var match$1 = Core.useStarknetCall(useStarknetCallParams);
I noticed an issue where if the contract is not yet loaded when the useCallback
is called inside of the useStarknetCall
hook, then the hook never refreshes it's call to StarkNet.
I had to add the following hook to the code to make it work and make the address compose:
React.useEffect1(() => {
if Belt.Option.isSome(contract) {
refresh()
}
None
}, [contract])
Which translates to the following JS:
var refresh = match$1.refresh;
React.useEffect((function () {
if (Belt_Option.isSome(contract)) {
Curry._1(refresh, undefined);
}
}), [contract]);
I wonder if it's important enough given useContract
and useStarknetCall
would typically be called in this sequence, to bake this logic or some form of it into the hook itself.
I can see that this issue does not arise during in the demo program despite the hooks being called in short succession.
NOTE When I use the trick above, there are still some wasted requests that get created without a contract_address
being specified (this may be a starknet.js
issue also).
We should add a new hook to get a transaction by its hash.
const {
data,
isLoading,
error,
isError,
refetch
} = useTransaction({ hash })
Implement a message signing hook based on wagmi
's useSignTypedData.
const { data, isError, isLoading, isSuccess, signTypedData } =
useSignTypedData({
domain,
types,
value,
})
Related to #105 since we want to match the APIs.
I I'm trying to use this library in a create-react-app app
I have this error :
Uncaught TypeError: (0 , superstruct_1.string) is not a function
at Object../node_modules/starknet/dist/utils/typedData/types.js (types.js:27:1)
at Object.options.factory (react refresh:6:1)
at __webpack_require__ (bootstrap:24:1)
at fn (hot module replacement:62:1)
at Object../node_modules/starknet/dist/utils/typedData/utils.js (utils.js:5:1)
at Object.options.factory (react refresh:6:1)
at __webpack_require__ (bootstrap:24:1)
at fn (hot module replacement:62:1)
at Object../node_modules/starknet/dist/utils/typedData/index.js (index.js:42:1)
at Object.options.factory (react refresh:6:1)
The abi from starknet-compile --abi
is an array, while the example uses a json object. It should be updated.
We should make it as easy as possible for users to test their code. The mock connector should simulate a real connector (e.g. InjectedConnector
) and expose two additional methods: accept()
and reject()
to accept and reject user requests (connect, submit, etc).
Is the second section in https://apibara.github.io/starknet-react/ missing an import declaration for InjectedConnector
?
import { StarknetProvider } from '@starknet-react/core'
function App() {
return (
<StarknetProvider connectors={[new InjectedConnector()]}>
<YourApp />
</StarknetProvider>
)
}
It seems that the latest version mandates using get-starknet
as opposed to the connectors approach which was used before. While it's great that users can now choose their preferred wallet, unfortunately, the popup is not showing to some of our users (including myself) on Chrome; even if they have ArgentX installed. It works fine on the Brave browser.
Any idea what could be causing the inconsistency in behavior?
Some apps show notifications when the transaction status changes. The library should provide a mechanism for developers to register a callback invoked every time a transaction status changes.
This is different from #6. The account interface exposes an execute
method to invoke multiple external functions in one transaction.
The proposed interface is:
const { execute, loading, error } = useStarknetExecute()
Where execute
is:
execute: ({ calls: CallArgs, metadata?: any }) => Promise<AddTransactionResponse | undefined>
type CallArgs = { args?: T, contract?: Contract, method?: string }
const { token } = useTokenContract()
const { other } = useOtherContract()
const { account } = useStarknet()
const { execute } = useStarknetExecute()
const [amount, setAmount] = useState(0)
// ...
execute({
metadata: { message: 'Approve token and swap' },
calls: [
{ contract: token, method: 'approve', args: amount && account ? [amount, account] : undefined },
{ contract: other, method: 'swap', args: amount && account ? [amount, account /*, more data here */] : undefined },
]
})
Like invoke
, execute
checks that all calls arguments are defined before making the call.
In the documentation: https://auclantis.github.io/starknet-react the Getting Started section has a wrong code.
And I think it could be nice to have the yarn/npm command sections.
I think it's easy to fix, I'd like to send the PR to fix it?
Hello there,
I have an issue regarding the number of renders for component using some hooks.
Some of them (like useStarknetCall
or useStarknetBlock
) automatically refresh their data when a new block occures.
The problem is that even when there are no new blocks, it causes a render of all components (and by extension children) using those hooks.
I created a repository to reproduce the problem, you can find it on the branch "too-many-rerender".
We will see the difference between the number of rendering and the number of real new blocks.
I know that with React, a lot of elements are memoized (callbacks, state, computed data, ...) but in some cases it can be a problem.
Especially when I used those hooks in a context/provider on top of the app, then it causes the try to rerender the whole tree.
And as you may guess, I don't want to explicitly memoize all my components.
I didn't investigate much, but maybe something could be improved with useStarknetBlock
where it seems the data
property change even if the block is not new.
Add a feature to deploy contracts to Starknet
At the moment the connector abstraction is very bare bone, consisting only of the InjectedConnector
class (and the proposed testing connector in #54). Now we have a new wallet (see #77) and so it makes sense to improve what is available.
As a React library we have a few of design goals:
Point 3 and 4 are at odds so there's going to be tradeoffs.
The new version of wagmi changed their API and now it's closer to the API in starknet-react
.
From a discussion with @Pet3ris we started thinking about aligning our API to wagmi's since now the differences are minuscule.
The changes will be:
wagmi
's namesThe semantics of the library will not change
Should be able to customize the default provider used if Argent-X is not connected.
Proposed API:
<StarknetProvider
defaultProvider={new Provider({ baseUrl: 'http://localhost:5000' })}>
</StarknetProvider>
In wagmi, the idiomatic way to check if the wallet is connected seems to be to check accountData
using useAccount
.
Is it fair to say that the idiomatic way for starknet-react
is to check the account
variable returned from the useStarknet
hook?
https://apibara.github.io/starknet-react/hooks/starknet
after running
npx create-next-app@latest --example https://github.com/auclantis/starknet-react/tree/main/examples/starknet-react-next
I tried to use the connect button and received ConnectorNotFoundError on the chrome console.
when I console log the error output from useStarknet, I'd get "could not activate Starknet" any idea what I'm missing here?
I have a use case where the data of a contract will never change.
For this reason I want to prevent my app to refresh those data and I can only do it using starknet.js
As auto-refresh is a great feature, we should give the possibility to disabled this auto refresh.
Maybe
useStarknetCall
hook const { data:approveData, approveLoading, error:approveError, reset:approveReset, invoke:approve } = useStarknetInvoke({ ethContract, method: 'approve'})
// It doesn't work
useEffect(() => {
ethContract && approve({ args: ['0x6806c42960e739918af543b733e76eb4f52a99402ec00e57794cb26cb3a6723', [100000000, 0]] })
}, [ethContract, approve])
// It doesn't work
ethContract && approve({ args: ['0x6806c42960e739918af543b733e76eb4f52a99402ec00e57794cb26cb3a6723', [100000000, 0]] })
// It works
ethContract && ethContract.approve('0x6806c42960e739918af543b733e76eb4f52a99402ec00e57794cb26cb3a6723', [100000000, 0])
(when it doesn't work, absolutely nothing happens, no error)
Here is the eth contract : https://goerli.voyager.online/contract/0x4bb0f7af15a5469be4a571c8660d9aaf39e7e67f27f774702d75e77141ef90#writeContract
Here is the eth contract ABI :
https://pastebin.com/YxyfivFr
Do you have any thoughts around supporting auto connect? It would support reconnecting when a connection has already been approved previously. Currently it seems most people do a hard connect, which prompts the user as soon as they land on a page, which I think is an anti-pattern.
I'd like to set { max_fee: 0 }
on an invoke call. As far as I understand, this is a third options argument to contract.invoke
, which this package currently does not support
PR #143 is failing to build because they added the new hook to the example, which uses the published version of the package.
The solution is to:
create-starknet-app
. The project works like create-next-app
to quickly setup a starknet application from different templates.It seems like starknet-react doesn't support disconnecting the connected wallet. Would maintainers consider supporting a disconnect()
?
Ref:
https://github.com/apibara/starknet-react/blob/main/packages/core/src/connectors/base.ts#L20=
The value of account
returned by useStarknet
should be updated when the user switches account in their wallet.
At the moment there seems to be no support in checking which network the user is connected to (e.g. Goeril or mainnet), i.e. the chainId
.
It would be nice if we could possibly add some new features (e.g. hooks) for checking this - similar to what we have for chainId
in wagmi for EVM chains.
This is crucial because when mainnet launch we would not want the users to sign the message on the wrong network to cause any inconvenience or financial loss.
Web3 React distributes connectors in their own package, while wagmi comes battery included. At the time of writing there is only one connector (Argent X) so it makes sense to include it by default.
What should we do in the future when more connectors become available?
Hello,
It seems I have a bug with multicall and hardcoded connectors. I get the error "Connector not connected" when trying to do a multicall even though I am connected through argent-x.
Here is the repo at the right commit to reproduce it:
https://github.com/starknet-id/app.starknet.id/blob/98569303571a40040da1bbbb890a76b48e68ef38/components/domains/register.tsx
I'm running into situations where an output of one call needs to be composed as the input to another contract call. Unfortunately, it seems that current argument types are based on arrays of strings and current output types have more type information (for example returning BN.js
types).
I wonder if it would make sense to decide on a default in-js representation for felts and other types and using it consistently?
Perhaps related to this: #98.
I'm observing the following object when connecting via useStarknet
:
This seems to be in violation of the types seen here:
export interface StarknetState {
account?: string
connect: (connector: Connector) => void
library: ProviderInterface
connectors: Connector[]
error?: Error
}
Should this mean that connectors
etc. need to be marked as ?
?
https://apibara.github.io/starknet-react/hooks/starknet
The connectors variable here:
is missing from the above documentation.Hello,
Could you please add an example that shows how to call a function from the account contract such that the get_caller_address() doesn't return 0?
Thanks
Hey there,
We noticed an issue happening with Braavos (it worked fine with argent-x). After reloading the page, the multicall signing panel from braavos doesn't open when clicking on the button which calls the execute. The 'error' printed was Cannot read properties of undefined (reading 'address')
. Braavos team told us this could be because the connector was not injected properly (we hardcoded it) or there is a problem in the starknet-execute. We tried to log the account in hooks/execute.js and it was undefined which is strange because window.starknet_braavos was defined. When changing the account value to window.starknet_braavos, it seems to work correctly.
Have a great day,
Thomas
Someone mentioned that the library is not working with StarkNet mainnet. We should investigate and fix this.
Hooks should be tested, in the past we had issues caused by the root provider fetching blocks after unmount. We should re-introduce tests to the project.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.