Skip to content

feat(signer): add Tari L1 signer#23

Merged
Niferu merged 12 commits into
developmentfrom
feat/tapplet
May 13, 2025
Merged

feat(signer): add Tari L1 signer#23
Niferu merged 12 commits into
developmentfrom
feat/tapplet

Conversation

@karczuRF

@karczuRF karczuRF commented May 8, 2025

Copy link
Copy Markdown
Contributor

Add TariL1Signer and use it to send tx in Tari Universe.

Summary by CodeRabbit

  • New Features

    • Introduced a new Tari Layer 1 signer integration for sending transactions and managing accounts.
    • Added state management for Tari account and signer using Zustand.
    • Defined new types for account and signer data structures.
  • Improvements

    • Updated bridging functionality to use the new Tari signer and account management.
    • Enhanced dependency tracking in bridge-related hooks for more accurate updates.
    • Improved error logging during Ethereum fee estimation.
  • Chores

    • Updated build scripts to include debug mode and added new dependencies.
    • Improved .gitignore handling for editor configuration files.
    • Configured Next.js for static export and custom image loading.
    • Added a custom image loader for optimized image URLs.
  • Cleanup

    • Removed obsolete Tari wallet client and wallet address hook.

@coderabbitai

coderabbitai Bot commented May 8, 2025

Copy link
Copy Markdown

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

## Walkthrough

This update replaces the previous Tari wallet integration with a new architecture using a `TariL1Signer` class and Zustand state stores for managing the Tari account and signer. It removes the mock client and static address hook, introduces new types, updates bridging logic, and modifies scripts and dependencies for improved state management and type safety.

## Changes

| Files / Groups                                         | Change Summary |
|--------------------------------------------------------|---------------|
| `.gitignore`                                           | Updated to ignore all `.vscode` files except `.vscode/extensions.json`. |
| `app/page.tsx`                                         | Switched from `useTariWalletAddress` to `useTariAccount`; updated prop and parameter names for Tari account and Ethereum address. |
| `clients/tari-l1-signer.ts`                            | Added new `TariL1Signer` class for window messaging-based Tari L1 signing and one-sided transaction sending. |
| `clients/tari-wallet-client.ts`, `hooks/use-tari-wallet-address.ts` | Deleted mock Tari wallet client and static wallet address hook. |
| `hooks/use-bridge-info.ts`                             | Added bridge handler callbacks to `useMemo` dependencies in `useBridgeInfo`. |
| `hooks/use-bridge-to-ethereum-fees/use-bridge-to-ethereum-fees.ts` | Added error logging for fee estimation failures. |
| `hooks/use-bridge-to-ethereum.ts`                      | Refactored to use `useTariSigner` and `useTariAccount`; replaced token transfer logic to use `TariL1Signer.sendOneSided`. |
| `package.json`                                         | Added `zustand` dependency and enhanced build script with `--debug` flag. |
| `store/account.ts`                                     | Introduced Zustand store for Tari account state and retrieval logic. |
| `store/signer.ts`                                      | Introduced Zustand store for managing the `TariL1Signer` instance. |
| `types/tapplet/account.ts`                             | Added new `AccountData` interface for account objects. |
| `types/tapplet/index.ts`                               | Added barrel file re-exporting account and signer types. |
| `types/tapplet/signer.ts`                              | Added types for signer parameters, utility types, and structured request/response for signer methods. |
| `next.config.ts`                                       | Added `output: 'export'` and custom image loader configuration using environment variable. |
| `utils/imageLoader.ts`                                 | Added custom image loader function formatting image URLs with width, quality, and transformation parameters. |
| `utils/truncate.ts`                                    | Changed `sepLen` variable declaration from `var` to `const`. |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant App
    participant SignerStore
    participant AccountStore
    participant TariL1Signer

    App->>SignerStore: setSigner(new TariL1Signer)
    App->>AccountStore: setTariAccount()
    AccountStore->>SignerStore: get signer
    AccountStore->>TariL1Signer: getAccount()
    TariL1Signer-->>AccountStore: AccountData
    AccountStore-->>App: Update tariAccount state

    App->>TariL1Signer: sendOneSided({amount, address, message})
    TariL1Signer->>window: postMessage (send transaction request)
    window-->>TariL1Signer: message event (transaction result)
    TariL1Signer-->>App: Promise resolved

Possibly related PRs

  • Wrap token / connect api #7: Introduced the original Tari wallet address hook and mock wallet client, which are now replaced and refactored in this PR.

Poem

A bunny hopped in, with code to refine,
Out went the mocks, in came Zustand’s design.
A signer now listens, accounts in a row,
One-sided transactions, ready to go!
With types all aligned and new scripts to run,
The bridge to Tari is robust and fun!
🐇✨


<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=tari-project/wxtm-bridge-frontend&utm_content=23):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

@karczuRF karczuRF marked this pull request as draft May 8, 2025 23:18

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🧹 Nitpick comments (7)
types/tapplet/account.ts (1)

1-4: Clean interface definition for AccountData

This interface provides a clear contract for Tari account data. Consider using camelCase (accountId) instead of snake_case (account_id) for consistency with typical TypeScript naming conventions, unless deliberately matching an external API format.

export interface AccountData {
-  account_id: number
+  accountId: number
  address: string
}
store/signer.ts (1)

10-17: Consider using console.log instead of console.warn

The implementation uses console.warn for what appears to be normal operation logging. Consider using console.log for informational messages and reserving console.warn for actual warning conditions.

- console.warn('🛜🛜 set signer ', signer)
+ console.log('🛜🛜 set signer ', signer)
store/account.ts (1)

5-13: Consider renaming the OotleWalletStoreState type.

The type OotleWalletStoreState appears to be a naming artifact from a different component or previous implementation. It should be renamed to match the current store's purpose.

interface State {
  tariAccount?: AccountData
}

interface Actions {
  setTariAccount: () => Promise<void>
}

-type OotleWalletStoreState = State & Actions
+type TariAccountStoreState = State & Actions
hooks/use-bridge-to-ethereum.ts (2)

10-13: Remove commented code.

The commented import line should be removed as it's no longer needed and creates unnecessary clutter.

-// import { useTariWalletAddress } from './use-tari-wallet-address'
import { parseWxtmTokenAmount } from '@/utils/parse-wxtm-token-amount'
import useTariSigner from '@/store/signer'
import useTariAccount from '@/store/account'

24-26: Remove commented code.

Similar to the import, this commented line should be removed to avoid clutter.

-  // const { tariWalletAddress } = useTariWalletAddress()
  const { signer } = useTariSigner()
  const { tariAccount } = useTariAccount()
types/tapplet/signer.ts (1)

13-15: Add JSDoc comments to utility types.

The utility types like PickMatching would benefit from JSDoc comments explaining their purpose and usage.

+/**
+ * Utility type that picks properties from type T that match type V
+ */
export type PickMatching<T, V> = {
  [K in keyof T as T[K] extends V ? K : never]: T[K]
}
clients/tari-l1-signer.ts (1)

91-97: Use optional chaining for nested properties.

The code checks for multiple nested properties individually, which can be simplified using optional chaining.

if (
-  resp &&
-  resp.data &&
-  resp.data.id &&
+  resp?.data?.id &&
  resp.data.id === id &&
  resp.data.type === 'signer-call'
) {
🧰 Tools
🪛 Biome (1.9.4)

[error] 92-94: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8922cc7 and db93b44.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (14)
  • .gitignore (1 hunks)
  • app/page.tsx (4 hunks)
  • clients/tari-l1-signer.ts (1 hunks)
  • clients/tari-wallet-client.ts (0 hunks)
  • hooks/use-bridge-info.ts (1 hunks)
  • hooks/use-bridge-to-ethereum-fees/use-bridge-to-ethereum-fees.ts (1 hunks)
  • hooks/use-bridge-to-ethereum.ts (2 hunks)
  • hooks/use-tari-wallet-address.ts (0 hunks)
  • package.json (2 hunks)
  • store/account.ts (1 hunks)
  • store/signer.ts (1 hunks)
  • types/tapplet/account.ts (1 hunks)
  • types/tapplet/index.ts (1 hunks)
  • types/tapplet/signer.ts (1 hunks)
💤 Files with no reviewable changes (2)
  • hooks/use-tari-wallet-address.ts
  • clients/tari-wallet-client.ts
🧰 Additional context used
🧬 Code Graph Analysis (5)
store/signer.ts (1)
clients/tari-l1-signer.ts (1)
  • TariL1Signer (16-79)
store/account.ts (1)
types/tapplet/account.ts (1)
  • AccountData (1-4)
app/page.tsx (1)
store/account.ts (1)
  • useTariAccount (19-41)
clients/tari-l1-signer.ts (2)
types/tapplet/signer.ts (5)
  • TariL1SignerParameters (3-6)
  • SignerMethodNames (19-19)
  • SignerRequest (24-28)
  • SignerReturnType (20-22)
  • SignerResponse (30-35)
types/tapplet/account.ts (1)
  • AccountData (1-4)
types/tapplet/signer.ts (1)
clients/tari-l1-signer.ts (1)
  • TariL1Signer (16-79)
🪛 Biome (1.9.4)
clients/tari-l1-signer.ts

[error] 92-94: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

types/tapplet/signer.ts

[error] 17-17: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

🔇 Additional comments (12)
.gitignore (1)

42-45: Good addition of editor-specific ignores

Adding specific rules for editor configuration files is a good practice. Ignoring .vscode/* while allowing the extensions.json file to be committed ensures team members can share recommended extensions without version controlling personal editor settings.

hooks/use-bridge-to-ethereum-fees/use-bridge-to-ethereum-fees.ts (1)

23-25: Good addition of error logging

Adding error logging here will improve observability when fee estimation fails, which is a helpful enhancement for debugging in production environments.

package.json (2)

3-3: Version increment is appropriate

Incrementing the patch version is appropriate for this feature addition. Following semantic versioning practices.


26-27: Good addition of Zustand for state management

Adding Zustand (v5.0.4) is appropriate for managing the Tari signer state. This modern state management library will help with the implementation of the TariL1Signer functionality.

types/tapplet/index.ts (1)

1-2: Well-structured barrel export pattern

Good use of the barrel export pattern to consolidate type exports from multiple modules. This provides a clean API for consumers by allowing them to import from a single entry point.

hooks/use-bridge-info.ts (1)

22-28: Good dependency array update

Proper inclusion of handleBridgeToEthereum and handleBridgeToTari in the dependency array. This ensures the memoized value is recalculated when these callback references change, preventing stale closures and potential bugs.

app/page.tsx (4)

13-13: LGTM - Transition to Zustand store

Good replacement of the previous hook with the new Zustand store import, aligning with the new architecture for managing Tari account state.


30-30: State management improvement

Properly destructured tariAccount from the Zustand store, providing access to the new account data structure.


68-68: Parameter naming clarification

Good update to use the more descriptive parameter name ethAddress instead of the generic address, making the code more self-documenting.


103-103: Proper null handling with optional chaining

Good use of optional chaining with tariAccount?.address to safely access the address property even if the account data hasn't been loaded yet.

store/signer.ts (2)

4-8: Well-designed generic interface

The SignerStore interface is well-structured with a generic type parameter that extends TariL1Signer. This provides type safety while allowing for potential future extensions to support different signer implementations.


1-20: Good implementation of a Zustand store

Overall, this is a well-structured Zustand store implementation. It properly initializes the signer to null and provides a method to update it. The store pattern will facilitate better state management and reuse across components.

Comment thread package.json Outdated
"scripts": {
"dev": "next dev",
"build": "next build",
"build": "next build --debug && next-sitemap && next export",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify the enhanced build script

The build script now includes additional steps with the debug flag, sitemap generation, and static export. These are good improvements for debugging and deployment.

Before merging, verify the enhanced build process completes successfully with all the new steps:


🏁 Script executed:

#!/bin/bash
# Quick check to verify the build script works as expected
npm run build

Length of output: 784


Fix failing build script in package.json

The build command (next build --debug && next-sitemap && next export) is erroring with
ENOENT: no such file or directory, uv_resident_set_memory, preventing a successful build.

Steps to address:

  • Verify your Node.js version (node -v) meets Next.js requirements (>=16.x).
  • Temporarily remove the --debug flag to isolate the issue:
    - "build": "next build --debug && next-sitemap && next export",
    + "build": "next build && next-sitemap && next export",
  • Ensure next-sitemap and next export are installed and correctly configured.

Once fixed, rerun:

npm run build

Comment thread store/account.ts
Comment on lines +19 to +41
export const useTariAccount = create<OotleWalletStoreState>()((set) => ({
...initialState,
setTariAccount: async () => {
console.warn('Try to set the Tari acc')
const signer = useTariSigner.getState().signer
console.warn('Try to set the Tari signer', signer)
try {
if (!signer) {
return
}
const account = await signer.getAccount()
console.warn('Try to set the Tari account: ', account)
set({
tariAccount: {
account_id: account.account_id,
address: account.address,
},
})
} catch (error) {
console.error('Could not set the Tari account: ', error)
}
},
}))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Review the debug console statements and implement proper error handling.

The setTariAccount function contains multiple console.warn statements that should be removed or changed to appropriate logging levels before production deployment. Additionally, the error handling could be improved to provide more context or user feedback.

-    console.warn('Try to set the Tari acc')
     const signer = useTariSigner.getState().signer
-    console.warn('Try to set the Tari signer', signer)
     try {
       if (!signer) {
+        console.debug('No signer available to set Tari account')
         return
       }
       const account = await signer.getAccount()
-      console.warn('Try to set the Tari account: ', account)
+      console.debug('Setting Tari account:', account)
       set({
         tariAccount: {
           account_id: account.account_id,
           address: account.address,
         },
       })
     } catch (error) {
-      console.error('Could not set the Tari account: ', error)
+      console.error('Failed to set Tari account:', error)
+      // Consider adding user feedback mechanism here
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const useTariAccount = create<OotleWalletStoreState>()((set) => ({
...initialState,
setTariAccount: async () => {
console.warn('Try to set the Tari acc')
const signer = useTariSigner.getState().signer
console.warn('Try to set the Tari signer', signer)
try {
if (!signer) {
return
}
const account = await signer.getAccount()
console.warn('Try to set the Tari account: ', account)
set({
tariAccount: {
account_id: account.account_id,
address: account.address,
},
})
} catch (error) {
console.error('Could not set the Tari account: ', error)
}
},
}))
export const useTariAccount = create<OotleWalletStoreState>()((set) => ({
...initialState,
setTariAccount: async () => {
const signer = useTariSigner.getState().signer
try {
if (!signer) {
console.debug('No signer available to set Tari account')
return
}
const account = await signer.getAccount()
console.debug('Setting Tari account:', account)
set({
tariAccount: {
account_id: account.account_id,
address: account.address,
},
})
} catch (error) {
console.error('Failed to set Tari account:', error)
// Consider adding user feedback mechanism here
}
},
}))

Comment on lines +46 to +53
// TODO how can we get tari address to send XTM?
const tariColdWalletAddress = 'placeholder'

//
await signer?.sendOneSided({
amount,
paymentId,
address: tariColdWalletAddress,
message: paymentId,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Replace the placeholder cold wallet address.

The code uses a placeholder for the Tari cold wallet address, which needs to be replaced with the actual address before deployment.

-    // TODO how can we get tari address to send XTM?
-    const tariColdWalletAddress = 'placeholder'
+    // Retrieves the cold wallet address from configuration or a secure source
+    const tariColdWalletAddress = config.TARI_COLD_WALLET_ADDRESS

Additionally, consider adding appropriate error handling for the case when the signer is null:

-    await signer?.sendOneSided({
+    if (!signer) {
+      throw new Error('Tari signer not initialized')
+    }
+    await signer.sendOneSided({
       amount,
       address: tariColdWalletAddress,
       message: paymentId,
     })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// TODO how can we get tari address to send XTM?
const tariColdWalletAddress = 'placeholder'
//
await signer?.sendOneSided({
amount,
paymentId,
address: tariColdWalletAddress,
message: paymentId,
// Retrieves the cold wallet address from configuration or a secure source
const tariColdWalletAddress = config.TARI_COLD_WALLET_ADDRESS
if (!signer) {
throw new Error('Tari signer not initialized')
}
await signer.sendOneSided({
amount,
address: tariColdWalletAddress,
message: paymentId,
})

Comment thread types/tapplet/signer.ts
Comment on lines +16 to +18
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
export type ExtractMethods<T> = PickMatching<T, Function>
export type SignerMethods = ExtractMethods<TariL1Signer>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Avoid using 'Function' as a type.

The Function type is too general and can lead to type safety issues. It's better to use more specific function types.

/* eslint-disable @typescript-eslint/no-unsafe-function-type */
-export type ExtractMethods<T> = PickMatching<T, Function>
+export type ExtractMethods<T> = PickMatching<T, (...args: any[]) => any>
export type SignerMethods = ExtractMethods<TariL1Signer>

This change maintains the functionality while using a more specific function type signature.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
export type ExtractMethods<T> = PickMatching<T, Function>
export type SignerMethods = ExtractMethods<TariL1Signer>
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
export type ExtractMethods<T> = PickMatching<T, (...args: any[]) => any>
export type SignerMethods = ExtractMethods<TariL1Signer>
🧰 Tools
🪛 Biome (1.9.4)

[error] 17-17: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

Comment thread clients/tari-l1-signer.ts

window.addEventListener('message', event_ref, false)

window.parent.postMessage({ ...req, id, type: 'signer-call' }, '*')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider restricting the target origin for security.

The postMessage call uses '*' as the target origin, which allows any window to receive the message. This could potentially be a security issue.

- window.parent.postMessage({ ...req, id, type: 'signer-call' }, '*')
+ window.parent.postMessage({ ...req, id, type: 'signer-call' }, window.location.origin)

If the parent window needs to be of a different origin, then consider using a specific origin instead of the wildcard '*'.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
window.parent.postMessage({ ...req, id, type: 'signer-call' }, '*')
window.parent.postMessage({ ...req, id, type: 'signer-call' }, window.location.origin)

Comment thread clients/tari-l1-signer.ts Outdated
Comment thread clients/tari-l1-signer.ts Outdated
@karczuRF karczuRF marked this pull request as ready for review May 13, 2025 10:14

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
clients/tari-l1-signer.ts (1)

126-126: Consider restricting the target origin for security.

The postMessage call uses '*' as the target origin, which allows any window to receive the message. This could potentially be a security issue.

- window.parent.postMessage({ ...req, id, type: 'signer-call' }, '*')
+ window.parent.postMessage({ ...req, id, type: 'signer-call' }, window.location.origin)

If the parent window needs to be of a different origin, then consider using a specific origin instead of the wildcard '*'.

🧹 Nitpick comments (1)
clients/tari-l1-signer.ts (1)

113-118: Use optional chaining for cleaner code.

The multiple condition checks can be simplified using optional chaining as suggested by the static analysis.

- if (
-   resp &&
-   resp.data &&
-   resp.data.id &&
-   resp.data.id === id &&
-   resp.data.type === 'signer-call'
- ) {
+ if (resp?.data?.id === id && resp.data.type === 'signer-call') {
🧰 Tools
🪛 Biome (1.9.4)

[error] 113-115: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between db93b44 and 4ef2cb5.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (9)
  • app/page.tsx (5 hunks)
  • clients/tari-l1-signer.ts (1 hunks)
  • hooks/use-bridge-info.ts (1 hunks)
  • hooks/use-bridge-to-ethereum.ts (2 hunks)
  • next.config.ts (1 hunks)
  • package.json (2 hunks)
  • store/account.ts (1 hunks)
  • utils/imageLoader.ts (1 hunks)
  • utils/truncate.ts (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • utils/truncate.ts
  • utils/imageLoader.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • package.json
  • store/account.ts
  • hooks/use-bridge-to-ethereum.ts
  • hooks/use-bridge-info.ts
  • app/page.tsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
clients/tari-l1-signer.ts (2)
types/tapplet/signer.ts (5)
  • TariL1SignerParameters (3-6)
  • SignerMethodNames (19-19)
  • SignerRequest (24-28)
  • SignerReturnType (20-22)
  • SignerResponse (30-35)
types/tapplet/account.ts (1)
  • AccountData (1-4)
🪛 Biome (1.9.4)
clients/tari-l1-signer.ts

[error] 113-115: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (3)
next.config.ts (1)

9-13: Export configuration and custom image loader look good!

The changes configure Next.js for static export with output: 'export' and set up a custom image loader. This is a necessary configuration when using Next.js Image components in a static export, as the default loader requires the Next.js server.

Make sure that:

  1. The referenced ./utils/imageLoader.ts file exists
  2. The NEXT_PUBLIC_PATH environment variable is documented and properly set in your deployment environments
clients/tari-l1-signer.ts (2)

58-69: Implement the getAccount method fully.

The getAccount method contains a TODO comment and manually reshapes the response. Before deployment, finalize the response structure and remove the TODO comment.

public async getAccount(): Promise<AccountData> {
-   // TODO what do we need as response?
    const resp = await this.sendRequest({
      methodName: 'getAccount',
      args: [],
    })

    return {
      account_id: resp.account_id,
      address: resp.address,
    }
}

93-99: Complete implementation of getTariBalance.

The TODO comment indicates this functionality needs implementation on the Tari Universe side. Ensure this is tracked and completed before release.

public async getTariBalance(): Promise<string> {
-   //TODO implement on TU side
    return this.sendRequest({
      methodName: 'getTariBalance',
      args: [],
    })
}

Comment thread clients/tari-l1-signer.ts
Comment on lines +47 to +52
public async isConnected(): Promise<boolean> {
return this.sendRequest({
methodName: 'isConnected',
args: [],
})
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Implement proper connection checking.

The isConnected method sends a request to check connection, but there's no client-side state tracking of connection status. Consider adding:

  1. A connection state variable
  2. Connection events (connect/disconnect)
  3. Error handling for connection failures

This will help ensure UI components accurately reflect the true connection state.

Comment thread clients/tari-l1-signer.ts
Comment on lines +102 to +128
function sendSignerCall<MethodName extends SignerMethodNames>(
req: Omit<SignerRequest<MethodName>, 'id'>,
id: number,
): Promise<SignerReturnType<MethodName>> {
return new Promise<SignerReturnType<MethodName>>((resolve, reject) => {
const event_ref = (resp: MessageEvent<SignerResponse<MethodName>>) => {
if (resp.data.resultError) {
window.removeEventListener('message', event_ref)
reject(resp.data.resultError)
}
if (
resp &&
resp.data &&
resp.data.id &&
resp.data.id === id &&
resp.data.type === 'signer-call'
) {
window.removeEventListener('message', event_ref)
resolve(resp.data.result)
}
}

window.addEventListener('message', event_ref, false)

window.parent.postMessage({ ...req, id, type: 'signer-call' }, '*')
})
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add timeout handling for message responses.

The current implementation of sendSignerCall lacks a timeout mechanism. If the parent window never responds, the promise will never resolve or reject, potentially causing the UI to hang.

function sendSignerCall<MethodName extends SignerMethodNames>(
  req: Omit<SignerRequest<MethodName>, 'id'>,
  id: number,
): Promise<SignerReturnType<MethodName>> {
  return new Promise<SignerReturnType<MethodName>>((resolve, reject) => {
    const event_ref = (resp: MessageEvent<SignerResponse<MethodName>>) => {
      // existing code...
    }

    window.addEventListener('message', event_ref, false)
    window.parent.postMessage({ ...req, id, type: 'signer-call' }, '*')
    
+   // Add timeout to prevent hanging promises
+   const timeoutId = setTimeout(() => {
+     window.removeEventListener('message', event_ref)
+     reject(new Error('Request timed out after 30 seconds'))
+   }, 30000)
  })
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function sendSignerCall<MethodName extends SignerMethodNames>(
req: Omit<SignerRequest<MethodName>, 'id'>,
id: number,
): Promise<SignerReturnType<MethodName>> {
return new Promise<SignerReturnType<MethodName>>((resolve, reject) => {
const event_ref = (resp: MessageEvent<SignerResponse<MethodName>>) => {
if (resp.data.resultError) {
window.removeEventListener('message', event_ref)
reject(resp.data.resultError)
}
if (
resp &&
resp.data &&
resp.data.id &&
resp.data.id === id &&
resp.data.type === 'signer-call'
) {
window.removeEventListener('message', event_ref)
resolve(resp.data.result)
}
}
window.addEventListener('message', event_ref, false)
window.parent.postMessage({ ...req, id, type: 'signer-call' }, '*')
})
}
function sendSignerCall<MethodName extends SignerMethodNames>(
req: Omit<SignerRequest<MethodName>, 'id'>,
id: number,
): Promise<SignerReturnType<MethodName>> {
return new Promise<SignerReturnType<MethodName>>((resolve, reject) => {
const event_ref = (resp: MessageEvent<SignerResponse<MethodName>>) => {
if (resp.data.resultError) {
window.removeEventListener('message', event_ref)
reject(resp.data.resultError)
}
if (
resp &&
resp.data &&
resp.data.id &&
resp.data.id === id &&
resp.data.type === 'signer-call'
) {
window.removeEventListener('message', event_ref)
resolve(resp.data.result)
}
}
window.addEventListener('message', event_ref, false)
window.parent.postMessage({ ...req, id, type: 'signer-call' }, '*')
// Add timeout to prevent hanging promises
const timeoutId = setTimeout(() => {
window.removeEventListener('message', event_ref)
reject(new Error('Request timed out after 30 seconds'))
}, 30000)
})
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 113-115: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

Comment thread clients/tari-l1-signer.ts
export type SendOneSidedRequest = {
amount: string
address: string
message?: string

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

message is actually a payment ID, so it shouldn't be optional.

@Niferu Niferu merged commit 8e09262 into development May 13, 2025
2 checks passed
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.

4 participants