coinbase / build-onchain-apps

Accelerate your onchain creativity with the Build Onchain Apps Template. ⛵️
https://buildonchainapps.xyz
MIT License
712 stars 119 forks source link

Documentation Request: use contract hook with contract address passed as param #280

Open michaelcohen716 opened 9 months ago

michaelcohen716 commented 9 months ago

Is your documentation request related to a problem? Please describe.

Current generateContractHook hooks have fixed addresses. Documentation requested for passing the contract address to that hook

GioLogist commented 9 months ago

These are defined per contract type, in src/hooks/contracts.ts. Can you elaborate on the kind of documentation you're looking for?

michaelcohen716 commented 9 months ago

for a factory pattern, it's not obvious how to generate contract hooks where the address is dynamically passed from a frontend component

Zizzamia commented 9 months ago

where the address is dynamically passed from a frontend component

out of curiosity, why the address is dynamic?

michaelcohen716 commented 9 months ago

I just mean dynamically passed. the current hook examples hardcode the contract address.

Zizzamia commented 9 months ago

Can you show us a code example on how you think it should behave, so I can better follow the type of developer experience you wish to have.

And thank you again for helping us shape this. We really appreciate your input.

michaelcohen716 commented 9 months ago
export const useCoffeeFactoryContract = generateContractHook({
  abi: CoffeeFactoryABI, // deploy different kinds of coffee from this contract
  [baseSepolia.id]: {
    chain: baseSepolia,
    address: '0xabcbcbcb...',
  },
});

code below does not work obviously.

export const useCoffeeContract = (contractAddress) => generateContractHook({
  abi: CoffeeABI, // instances of CoffeeContract
  [baseSepolia.id]: {
    chain: baseSepolia,
    address: contractAddress,
  },
});

I hacked this clunky version quickly and it works, but I'm sure there's a way to do it nicely with generateContractHook:

import { getContract } from 'wagmi/actions';
export function useCoffeeContract(contractAddress, walletClient) {
  const contract = getContract({
    address,
    abi: CoffeeABI,
    walletClient,
  });
 return {
    contract,
    abi: CoffeeABI,
    address,
    status: 'ready',
  };
}
Zizzamia commented 9 months ago

@Sneh1999 thoughts on this one?

Sneh1999 commented 9 months ago

@michaelcohen716 we are actually building onchain-kit which will provide utilities/functions which are generic similar to what you are requesting.

Build on chain apps on the other hand can be thought of more like a toolkit which gives you already setup end to end web3 examples/experiences of common use cases.

When onchain-kit gains momentum, you will see us replacing a lot of common functionality. We will add documentation for functions like these within onchain-kit itself and just use them here.

CC @Zizzamia feel free to add your thoughts

Zizzamia commented 9 months ago

the current hook examples hardcode the contract address.

I still believe the hook, should not be dynamic, as that could cause some security issue.

I still don't understand the use case for address is dynamically passed from a frontend component, it feels a quite rare experience.

@michaelcohen716 what am I missing? Can you share a bit more what are you trying to build.

michaelcohen716 commented 9 months ago

hey - i think me calling it "dynamically passed" is tripping the conversation up. i'm really just asking about any factory pattern. like, if i was building uniswap, how would i generate a hook for an individual pool. there are thousands, so I need to pass the contract address for a specific pool

Zizzamia commented 9 months ago

Ok, that's very interesting, and also a bit of an edge case.

@Sneh1999 @cnasc what's your take, is it something we should document or explore as experience?

michaelcohen716 commented 9 months ago

i would probably dispute the "edge case" characterization. it would be necessary for many AMMs or NFT marketplaces. I figured out how to do it, but a basic hook standard in the docs could be useful to others. not a huge deal either way, didn't mean to blow this out of proportion as mission critical or anything

cnasc commented 9 months ago

@michaelcohen716 sorry for the delay here, this got lost in a bunch of GH notifications.

When you said

code below does not work obviously.

export const useCoffeeContract = (contractAddress) => generateContractHook({
  abi: CoffeeABI, // instances of CoffeeContract
  [baseSepolia.id]: {
    chain: baseSepolia,
    address: contractAddress,
  },
});

What issue did you run into? Something like the following should work (haven't had a chance to try, just made sure it typechecked)

export const useCoffeeContract = (contractAddress: `0x${string}`) => generateContractHook({
  abi: CoffeeABI, // instances of CoffeeContract
  [baseSepolia.id]: {
    chain: baseSepolia,
    address: contractAddress,
  },
});
Zizzamia commented 9 months ago

not a huge deal either way, didn't mean to blow this out of proportion as mission critical or anything

All good, we just really love unpack each case scenario. :)