Skip to content

Conversation

dckc
Copy link
Contributor

@dckc dckc commented Sep 24, 2025

In order to be able to see stuff like when we last did an installAndStart on mainnet without using the private key, I asked a bot to add a watch mode:

image

VIBE CODING NOTE: I didn't even look at the code other than watching it scroll by. watch-mode-aider-chat.md is a transcript.

main /code prompts:

  • fix: change events to query in the [query in the] TransactionHistory component
    • due to v50 upgrade?
  • refactor the code in preparation for adding a read-only / watch-only mode.
  • read-only / watch-only mode as discussed
  • can we default devnet to agoric10utru593dspjwfewcgdak8lvp9tkz0xttvcnxv and mainnet to agoric1e80twfutmrm3wrk3fysjcnef4j82mq8dn6nmcq ?

dckc and others added 10 commits September 22, 2025 13:25
Co-authored-by: aider (anthropic/claude-sonnet-4-20250514) <[email protected]>
Co-authored-by: aider (anthropic/claude-sonnet-4-20250514) <[email protected]>
…oncerns

Co-authored-by: aider (anthropic/claude-sonnet-4-20250514) <[email protected]>
… support, a watch address input, and modified the components to support a read-only state.

The next step would be to modify the child components (`WalletEntriesCard`, `ContractControlCard`, and `CreatorFacetCard`) to accept and handle the `readOnly` prop. Would you like me to help you update those components?

Typically, this would involve:
1. Adding `readOnly?: boolean` to the component props
2. Disabling buttons when `readOnly` is true
3. Adding tooltips to explain why buttons are disabled

Would you like me to show you how to modify those components?

Co-authored-by: aider (anthropic/claude-sonnet-4-20250514) <[email protected]>
…eatorFacetCard components. Could you please add those files to the chat so I can update them?

Specifically, I'd like to see:
- `ui/src/components/ContractControlCard.tsx`
- `ui/src/components/CreatorFacetCard.tsx`

Could you share those files?

USER: I added these files to the chat: ui/src/components/ContractControlCard.tsx ui/src/components/CreatorFacetCard.tsx
Let me know if there are others we should add.

A: ui/src/components/ContractControlCard.tsx
```tsx
<<<<<<< SEARCH
interface ContractControlCardProps {
  contractAddress: string;
  contractName: string;
  onCreateInstance: (instanceName: string) => void;
}
=======
interface ContractControlCardProps {
  contractAddress: string;
  contractName: string;
  onCreateInstance: (instanceName: string) => void;
  readOnly?: boolean;
}
>>>>>>> REPLACE
```

ui/src/components/ContractControlCard.tsx
```tsx
<<<<<<< SEARCH
const ContractControlCard: React.FC<ContractControlCardProps> = ({
  contractAddress,
  contractName,
  onCreateInstance,
}) => {
=======
const ContractControlCard: React.FC<ContractControlCardProps> = ({
  contractAddress,
  contractName,
  onCreateInstance,
  readOnly = false,
}) => {
>>>>>>> REPLACE
```

ui/src/components/ContractControlCard.tsx
```tsx
<<<<<<< SEARCH
      <input
        type="text"
        value={instanceName}
        onChange={(e) => setInstanceName(e.target.value)}
        placeholder="Instance name..."
        style={{
          flex: 1,
          padding: '0.5rem',
          border: '1px solid #ccc',
          borderRadius: '4px',
          fontSize: '1em'
        }}
      />
=======
      <input
        type="text"
        value={instanceName}
        onChange={(e) => setInstanceName(e.target.value)}
        placeholder="Instance name..."
        disabled={readOnly}
        style={{
          flex: 1,
          padding: '0.5rem',
          border: '1px solid #ccc',
          borderRadius: '4px',
          fontSize: '1em',
          backgroundColor: readOnly ? '#f0f0f0' : 'white',
          color: readOnly ? '#666' : 'black'
        }}
      />
>>>>>>> REPLACE
```

ui/src/components/ContractControlCard.tsx
```tsx
<<<<<<< SEARCH
      <button
        onClick={() => onCreateInstance(instanceName)}
        disabled={!instanceName.trim()}
        style={{
          padding: '0.5rem 1rem',
          backgroundColor: !instanceName.trim() ? '#ccc' : '#6f42c1',
          color: 'white',
          border: 'none',
          borderRadius: '4px',
          cursor: !instanceName.trim() ? 'not-allowed' : 'pointer',
          fontSize: '1em'
        }}
      >
        Create Instance
      </button>
=======
      <button
        onClick={() => onCreateInstance(instanceName)}
        disabled={!instanceName.trim() || readOnly}
        title={readOnly ? 'Connect wallet to create instances' : ''}
        style={{
          padding: '0.5rem 1rem',
          backgroundColor: (!instanceName.trim() || readOnly) ? '#ccc' : '#6f42c1',
          color: 'white',
          border: 'none',
          borderRadius: '4px',
          cursor: (!instanceName.trim() || readOnly) ? 'not-allowed' : 'pointer',
          fontSize: '1em'
        }}
      >
        Create Instance
      </button>
>>>>>>> REPLACE
```

ui/src/components/CreatorFacetCard.tsx
```tsx
<<<<<<< SEARCH
interface CreatorFacetCardProps {
  contractAddress: string;
  contractName: string;
  onCreateFacet: (facetName: string) => void;
}
=======
interface CreatorFacetCardProps {
  contractAddress: string;
  contractName: string;
  onCreateFacet: (facetName: string) => void;
  readOnly?: boolean;
}
>>>>>>> REPLACE
```

ui/src/components/CreatorFacetCard.tsx
```tsx
<<<<<<< SEARCH
const CreatorFacetCard: React.FC<CreatorFacetCardProps> = ({
  contractAddress,
  contractName,
  onCreateFacet,
}) => {
=======
const CreatorFacetCard: React.FC<CreatorFacetCardProps> = ({
  contractAddress,
  contractName,
  onCreateFacet,
  readOnly = false,
}) => {
>>>>>>> REPLACE
```

ui/src/components/CreatorFacetCard.tsx
```tsx
<<<<<<< SEARCH
      <input
        type="text"
        value={facetName}
        onChange={(e) => setFacetName(e.target.value)}
        placeholder="Facet name..."
        style={{
          flex: 1,
          padding: '0.5rem',
          border: '1px solid #ccc',
          borderRadius: '4px',
          fontSize: '1em'
        }}
      />
=======
      <input
        type="text"
        value={facetName}
        onChange={(e) => setFacetName(e.target.value)}
        placeholder="Facet name..."
        disabled={readOnly}
        style={{
          flex: 1,
          padding: '0.5rem',
          border: '1px solid #ccc',
          borderRadius: '4px',
          fontSize: '1em',
          backgroundColor: readOnly ? '#f0f0f0' : 'white',
          color: readOnly ? '#666' : 'black'
        }}
      />
>>>>>>> REPLACE
```

ui/src/components/CreatorFacetCard.tsx
```tsx
<<<<<<< SEARCH
      <button
        onClick={() => onCreateFacet(facetName)}
        disabled={!facetName.trim()}
        style={{
          padding: '0.5rem 1rem',
          backgroundColor: !facetName.trim() ? '#ccc' : '#6f42c1',
          color: 'white',
          border: 'none',
          borderRadius: '4px',
          cursor: !facetName.trim() ? 'not-allowed' : 'pointer',
          fontSize: '1em'
        }}
      >
        Create Facet
      </button>
=======
      <button
        onClick={() => onCreateFacet(facetName)}
        disabled={!facetName.trim() || readOnly}
        title={readOnly ? 'Connect wallet to create facets' : ''}
        style={{
          padding: '0.5rem 1rem',
          backgroundColor: (!facetName.trim() || readOnly) ? '#ccc' : '#6f42c1',
          color: 'white',
          border: 'none',
          borderRadius: '4px',
          cursor: (!facetName.trim() || readOnly) ? 'not-allowed' : 'pointer',
          fontSize: '1em'
        }}
      >
        Create Facet
      </button>
>>>>>>> REPLACE
```

Now I'll need to update the `Admin.tsx` to pass the `readOnly` prop to these components. Would you like me to show those changes?

Co-authored-by: aider (anthropic/claude-sonnet-4-20250514) <[email protected]>
Co-authored-by: aider (anthropic/claude-sonnet-4-20250514) <[email protected]>
Co-authored-by: aider (anthropic/claude-sonnet-4-20250514) <[email protected]>
Co-authored-by: aider (anthropic/claude-sonnet-4-20250514) <[email protected]>
…riesCard

Co-authored-by: aider (anthropic/claude-sonnet-4-20250514) <[email protected]>
Co-authored-by: aider (anthropic/claude-sonnet-4-20250514) <[email protected]>
Copy link

netlify bot commented Sep 24, 2025

Deploy Preview for ymax0 ready!

Name Link
🔨 Latest commit 5ffec93
🔍 Latest deploy log https://app.netlify.com/projects/ymax0/deploys/68d403ee28f50c0008b979d0
😎 Deploy Preview https://deploy-preview-17--ymax0.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces a read-only/watch mode for the admin interface, allowing users to view wallet state and transaction history without connecting a wallet or using private keys. The implementation includes service layer refactoring, UI updates for watch mode functionality, and environment-specific default addresses.

Key Changes

  • Added watch-only mode with address input and default addresses for devnet/mainnet
  • Refactored contract operations into a dedicated ContractService class
  • Extracted wallet-related functionality into reusable service functions

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
ui/src/services/walletService.ts New service containing invitation redemption logic
ui/src/services/contractService.ts New service class for contract operations (terminate, upgrade, etc.)
ui/src/components/WalletEntriesCard.tsx Added watch mode UI with connection section and read-only states
ui/src/components/InvitationItem.tsx Added read-only prop support with disabled styling
ui/src/components/Admin.tsx Major refactoring to support watch mode using custom hooks and service classes

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

const fetchTransactions = async () => {
if (!walletAddress) return;

const url = `${endpoints.API}/cosmos/tx/v1beta1/txs?query=message.sender='${walletAddress}'&order_by=ORDER_BY_DESC&limit=${transactionLimit}`;
Copy link

Copilot AI Sep 24, 2025

Choose a reason for hiding this comment

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

The query parameter should be events instead of query based on the original code and Cosmos SDK API. This change may cause the transaction fetching to fail.

Suggested change
const url = `${endpoints.API}/cosmos/tx/v1beta1/txs?query=message.sender='${walletAddress}'&order_by=ORDER_BY_DESC&limit=${transactionLimit}`;
const url = `${endpoints.API}/cosmos/tx/v1beta1/txs?events=message.sender='${walletAddress}'&order_by=ORDER_BY_DESC&limit=${transactionLimit}`;

Copilot uses AI. Check for mistakes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@copilot this was a fix, necessary to restore the TransactionHistory component to working order.

The Agoric chain has been upgrade from Cosmos SDK 0.47 to 0.50; perhaps that made this change necessary. Can you find docs to confirm, please?

);

}, [wallet, purses, watcherRef.current]);
}, [effectiveAddress, watcherRef.current, handleInvocationCompletion, fetchTransactions]);
Copy link

Copilot AI Sep 24, 2025

Choose a reason for hiding this comment

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

The dependency array includes handleInvocationCompletion and fetchTransactions which are functions defined in custom hooks. This will cause the effect to re-run on every render since these functions are recreated each time.

Copilot uses AI. Check for mistakes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@copilot would this explain why the thing is going into an infinite loop, re-fetching the transactions and re-displaying them?

@dckc dckc marked this pull request as draft September 25, 2025 19:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant