Skip to content

feat: implement approval gate for wallet commands and add SSE transpo…#16

Open
andrew-virtuals wants to merge 3 commits into
mainfrom
feat/policy-guardrail
Open

feat: implement approval gate for wallet commands and add SSE transpo…#16
andrew-virtuals wants to merge 3 commits into
mainfrom
feat/policy-guardrail

Conversation

@andrew-virtuals
Copy link
Copy Markdown
Contributor

@andrew-virtuals andrew-virtuals commented May 12, 2026

…rt creation


Note

Medium Risk
Introduces a new approval gate that opens an SSE WALLET stream around message/typed-data signing and transaction sends; mistakes here could block or alter wallet flows. Changes touch transaction broadcasting and signature generation paths, but are scoped to CLI wallet commands.

Overview
Adds a reusable withApprovalGate helper that creates a provider, connects an SSE transport on the WALLET stream, runs a wallet operation, then disconnects.

Updates wallet CLI operations that require approvals—sign-message, sign-typed-data, send-transaction, and the Crossmint card top-up verification signature—to execute inside this gate, moving the chain-support validation for send-transaction into the gated block.

Extends agentFactory with createSseTransport to configure and connect SseTransport (context + supported chain IDs) for the requested streams.

Reviewed by Cursor Bugbot for commit 14d8f65. Bugbot is set up for automated code reviews on this repo. Configure here.

Comment thread src/lib/walletGate.ts Outdated
Comment thread src/commands/wallet.ts
}

const transactionHash = await provider.sendTransaction(chainId, {
to: opts.to,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Redundant getSupportedChainIds call in send-transaction path

Low Severity

In the send-transaction command, provider.getSupportedChainIds() is called twice on the same provider instance within a single withApprovalGate invocation — once inside createSseTransport (to populate providerSupportedChainIds in the transport context) and again in the callback at line 142 for chain validation. Since both calls happen on the same provider, the second call is redundant work (likely an additional network round-trip). The withApprovalGate API could expose the already-fetched chain IDs to avoid this duplication.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 23a4560. Configure here.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 14d8f65. Configure here.

Comment thread src/commands/wallet.ts
if (!json && isTTY()) {
process.stdout.write(" Signing wallet verification...");
}
signature = await provider.signMessage(
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Topup command creates redundant expensive provider adapter

Low Severity

In the topup command, createProviderAdapter() is called at line 285 for chain validation, and then withApprovalGate at line 369 internally calls createProviderAdapter() a second time (plus creates an SSE transport). Before this PR, the single provider was reused for both validation and signing. Each createProviderFromConfig call potentially involves API calls (wallet ID lookup, builder code fetch) and creates a full PrivyAlchemyEvmProviderAdapter, making this a meaningful duplication of expensive work in the card+challenge flow.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 14d8f65. Configure here.

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.

2 participants