feat(signer): add Tari L1 signer#23
Conversation
|
Important Review skippedReview was skipped due to path filters ⛔ Files ignored due to path filters (1)
CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including You can disable this status message by setting the ## 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 resolvedPossibly related PRs
Poem
|
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (7)
types/tapplet/account.ts (1)
1-4: Clean interface definition for AccountDataThis 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.warnThe implementation uses
console.warnfor what appears to be normal operation logging. Consider usingconsole.logfor informational messages and reservingconsole.warnfor 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
OotleWalletStoreStateappears 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 & Actionshooks/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
PickMatchingwould 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
⛔ Files ignored due to path filters (1)
package-lock.jsonis 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 ignoresAdding 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 loggingAdding 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 appropriateIncrementing the patch version is appropriate for this feature addition. Following semantic versioning practices.
26-27: Good addition of Zustand for state managementAdding 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 patternGood 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 updateProper inclusion of
handleBridgeToEthereumandhandleBridgeToTariin 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 storeGood 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 improvementProperly destructured
tariAccountfrom the Zustand store, providing access to the new account data structure.
68-68: Parameter naming clarificationGood update to use the more descriptive parameter name
ethAddressinstead of the genericaddress, making the code more self-documenting.
103-103: Proper null handling with optional chainingGood use of optional chaining with
tariAccount?.addressto safely access the address property even if the account data hasn't been loaded yet.store/signer.ts (2)
4-8: Well-designed generic interfaceThe
SignerStoreinterface is well-structured with a generic type parameter that extendsTariL1Signer. This provides type safety while allowing for potential future extensions to support different signer implementations.
1-20: Good implementation of a Zustand storeOverall, 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.
| "scripts": { | ||
| "dev": "next dev", | ||
| "build": "next build", | ||
| "build": "next build --debug && next-sitemap && next export", |
There was a problem hiding this comment.
💡 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 buildLength 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
--debugflag to isolate the issue:- "build": "next build --debug && next-sitemap && next export", + "build": "next build && next-sitemap && next export",
- Ensure
next-sitemapandnext exportare installed and correctly configured.
Once fixed, rerun:
npm run build| 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) | ||
| } | ||
| }, | ||
| })) |
There was a problem hiding this comment.
🛠️ 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.
| 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 | |
| } | |
| }, | |
| })) |
| // TODO how can we get tari address to send XTM? | ||
| const tariColdWalletAddress = 'placeholder' | ||
|
|
||
| // | ||
| await signer?.sendOneSided({ | ||
| amount, | ||
| paymentId, | ||
| address: tariColdWalletAddress, | ||
| message: paymentId, |
There was a problem hiding this comment.
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_ADDRESSAdditionally, 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.
| // 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, | |
| }) |
| /* eslint-disable @typescript-eslint/no-unsafe-function-type */ | ||
| export type ExtractMethods<T> = PickMatching<T, Function> | ||
| export type SignerMethods = ExtractMethods<TariL1Signer> |
There was a problem hiding this comment.
🛠️ 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.
| /* 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)
|
|
||
| window.addEventListener('message', event_ref, false) | ||
|
|
||
| window.parent.postMessage({ ...req, id, type: 'signer-call' }, '*') |
There was a problem hiding this comment.
🛠️ 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.
| window.parent.postMessage({ ...req, id, type: 'signer-call' }, '*') | |
| window.parent.postMessage({ ...req, id, type: 'signer-call' }, window.location.origin) |
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
clients/tari-l1-signer.ts (1)
126-126: Consider restricting the target origin for security.The
postMessagecall 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
⛔ Files ignored due to path filters (1)
package-lock.jsonis 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:
- The referenced
./utils/imageLoader.tsfile exists- The
NEXT_PUBLIC_PATHenvironment variable is documented and properly set in your deployment environmentsclients/tari-l1-signer.ts (2)
58-69: Implement thegetAccountmethod fully.The
getAccountmethod 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 ofgetTariBalance.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: [], }) }
| public async isConnected(): Promise<boolean> { | ||
| return this.sendRequest({ | ||
| methodName: 'isConnected', | ||
| args: [], | ||
| }) | ||
| } |
There was a problem hiding this comment.
🛠️ 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:
- A connection state variable
- Connection events (connect/disconnect)
- Error handling for connection failures
This will help ensure UI components accurately reflect the true connection state.
| 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' }, '*') | ||
| }) | ||
| } |
There was a problem hiding this comment.
🛠️ 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.
| 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)
| export type SendOneSidedRequest = { | ||
| amount: string | ||
| address: string | ||
| message?: string |
There was a problem hiding this comment.
message is actually a payment ID, so it shouldn't be optional.
Add
TariL1Signerand use it to send tx in Tari Universe.Summary by CodeRabbit
New Features
Improvements
Chores
.gitignorehandling for editor configuration files.Cleanup