Skip to content

feat(wallets): add deployImmediately flag to addSigner with default true#1924

Open
maxsch-xmint wants to merge 6 commits into
mainfrom
devin/1781625942-add-deploy-immediately-flag
Open

feat(wallets): add deployImmediately flag to addSigner with default true#1924
maxsch-xmint wants to merge 6 commits into
mainfrom
devin/1781625942-add-deploy-immediately-flag

Conversation

@maxsch-xmint

@maxsch-xmint maxsch-xmint commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Description

Adds a deployImmediately option to wallet.addSigner() for EVM wallets. When true (the new default), the signer is registered on-chain immediately via a transaction — matching how Solana/Stellar already behave — instead of the previous lazy typed-data signature-request flow.

This is the SDK counterpart to Paella-Labs/crossbit-main#26626, which adds the backend support for this flag.

Changes:

  • RegisterSignerParams gains optional deployImmediately?: boolean
  • AddSignerOptions gains optional deployImmediately?: boolean (defaults to true for EVM)
  • AddSignerReturnType for EVM widened to include transactionId?: string
  • Response handling in addSigner is now response-driven: checks for transaction first, preserves Solana/Stellar guard, then falls back to chains
  • mapApiSignerToSigner propagates transaction.status for EVM (no false "success" before confirmation)
  • getPendingSignerOperation is response-driven: checks transaction first (any chain) for correct retry/idempotency
  • Flag is only sent for EVM chains (not Solana/Stellar)

Test plan

  • Unit tests (wallet.test.ts):
    • Verifies deployImmediately: true is passed by default for EVM add-signer calls
    • Verifies deployImmediately: false can be explicitly set
    • Verifies EVM transaction-flow response is handled correctly (like Solana/Stellar)
    • Verifies prepareOnly: true + deployImmediately: true returns { transactionId, status: "pending" }
    • Verifies prepareOnly: true + deployImmediately: false returns { signatureId }
    • Verifies Solana missing transaction still throws
    • Verifies EVM missing both transaction and chains throws
    • All 397 tests pass

Package updates

  • @crossmint/wallets-sdk: minor (changeset added)

Link to Devin session: https://crossmint.devinenterprise.com/sessions/8e002024ca984142a4f351c4d9adfb18
Requested by: @maxsch-xmint

devin-ai-integration Bot and others added 2 commits June 16, 2026 16:11
Co-Authored-By: max@paella.dev <max@paella.dev>
@devin-ai-integration

Copy link
Copy Markdown
Contributor
Original prompt from Max

given the context of this PR: https://github.com/Paella-Labs/crossbit-main/pull/26626 can you add this flag to our SDKs with a default true value?

@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@changeset-bot

changeset-bot Bot commented Jun 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 2a1e3a3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 9 packages
Name Type
@crossmint/wallets-sdk Minor
@crossmint/wallets-quickstart-devkit Patch
@crossmint/wallets-playground-react Patch
@crossmint/client-sdk-react-base Patch
@crossmint/client-sdk-react-native-ui Patch
@crossmint/client-sdk-react-ui Patch
@crossmint/wallets-playground-expo Patch
@crossmint/auth-ssr-nextjs-demo Patch
@crossmint/client-sdk-nextjs-starter Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@greptile-apps

greptile-apps Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
packages/wallets/src/wallets/wallet.test.ts:732-755
**Missing test: `prepareOnly: true` with new EVM transaction flow**

The only EVM `prepareOnly` test was updated to add `deployImmediately: false` to preserve the old signature path. There is no test covering the new default combination — `prepareOnly: true` + `deployImmediately: true` for EVM — which would call the `transaction` branch of `completeSignerRegistration` and return `{ transactionId }` instead of `{ signatureId }`. Callers currently relying on `prepareOnly` for EVM will receive a different shape in their result object once they upgrade, and this path has no dedicated unit coverage.

Reviews (1): Last reviewed commit: "chore: add changeset for deployImmediate..." | Re-trigger Greptile

@devin-ai-integration

Copy link
Copy Markdown
Contributor

Good catch, scaly friend 🐍 — added a dedicated test for prepareOnly: true with the default deployImmediately: true transaction flow, verifying it returns { transactionId } as expected. See 487dbc4.

@greptile-apps

greptile-apps Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
packages/wallets/src/wallets/types.ts:59-61
**`AddSignerReturnType` missing `transactionId` for EVM**

The EVM branch of `AddSignerReturnType` only includes `signatureId?: string`, but with the new `deployImmediately: true` default the runtime response contains `transactionId` (not `signatureId`). Any EVM caller using `prepareOnly: true` with the new default will receive a `transactionId` at runtime that TypeScript doesn't know about — accessing `result.transactionId` would be a type error. The test at line 750 of `wallet.test.ts` already demonstrates this gap by expecting `result.transactionId` on an `evmWallet`, which has no such field in the current type definition.

The EVM variant should be widened to `Signer & { signatureId?: string; transactionId?: string }` to cover both the legacy signature flow and the new on-chain transaction flow.

### Issue 2 of 2
packages/wallets/src/wallets/wallet.ts:806-807
**EVM transaction response yields incorrect `status: "success"` before on-chain confirmation**

When the API returns a `transaction` for an EVM wallet (the new `deployImmediately: true` default), the code at line 806 correctly captures the `pendingOperation`, but `registeredSigner` was already set via `mapApiSignerToSigner` a few lines earlier. `mapApiSignerToSigner` has no branch for EVM + `transaction` response: it falls through to the comment *"If chains field is empty, the signer was created during wallet creation"* and returns `status: "success"`. For the `prepareOnly: true` path this means the caller receives `{ status: "success", transactionId: "..." }` — reporting success before the transaction is confirmed. By contrast, Solana/Stellar correctly propagates `transaction.status` (e.g. `"pending"`) through `mapApiSignerToSigner`.

`mapApiSignerToSigner` should be updated to read `transaction.status` for EVM responses that include a `transaction` field, mirroring the existing Solana/Stellar logic.

Reviews (2): Last reviewed commit: "test: add prepareOnly + deployImmediatel..." | Re-trigger Greptile

Comment on lines +806 to 807
if ("transaction" in response && response.transaction != null) {
pendingOperation = { type: "transaction", id: response.transaction.id };

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.

P1 EVM transaction response yields incorrect status: "success" before on-chain confirmation

When the API returns a transaction for an EVM wallet (the new deployImmediately: true default), the code at line 806 correctly captures the pendingOperation, but registeredSigner was already set via mapApiSignerToSigner a few lines earlier. mapApiSignerToSigner has no branch for EVM + transaction response: it falls through to the comment "If chains field is empty, the signer was created during wallet creation" and returns status: "success". For the prepareOnly: true path this means the caller receives { status: "success", transactionId: "..." } — reporting success before the transaction is confirmed. By contrast, Solana/Stellar correctly propagates transaction.status (e.g. "pending") through mapApiSignerToSigner.

mapApiSignerToSigner should be updated to read transaction.status for EVM responses that include a transaction field, mirroring the existing Solana/Stellar logic.

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/wallets/src/wallets/wallet.ts
Line: 806-807

Comment:
**EVM transaction response yields incorrect `status: "success"` before on-chain confirmation**

When the API returns a `transaction` for an EVM wallet (the new `deployImmediately: true` default), the code at line 806 correctly captures the `pendingOperation`, but `registeredSigner` was already set via `mapApiSignerToSigner` a few lines earlier. `mapApiSignerToSigner` has no branch for EVM + `transaction` response: it falls through to the comment *"If chains field is empty, the signer was created during wallet creation"* and returns `status: "success"`. For the `prepareOnly: true` path this means the caller receives `{ status: "success", transactionId: "..." }` — reporting success before the transaction is confirmed. By contrast, Solana/Stellar correctly propagates `transaction.status` (e.g. `"pending"`) through `mapApiSignerToSigner`.

`mapApiSignerToSigner` should be updated to read `transaction.status` for EVM responses that include a `transaction` field, mirroring the existing Solana/Stellar logic.

How can I resolve this? If you propose a fix, please make it concise.

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.

Both valid catches, cold-blooded one 🦎 — fixed in 725c411:\n\n1. AddSignerReturnType for EVM now includes transactionId?: string alongside signatureId?: string\n2. mapApiSignerToSigner now checks for transaction field on EVM responses and propagates transaction.status (e.g. \"pending\") instead of falling through to \"success\"\n\nTest updated to assert status: \"pending\" on the prepareOnly + transaction path.

…action status

Co-Authored-By: max@paella.dev <max@paella.dev>
@greptile-apps

greptile-apps Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
packages/wallets/src/wallets/wallet.ts:806-826
**Solana/Stellar `chains`-response guard removed**

The old code explicitly threw `"Expected transaction in response for Solana/Stellar chain"` when the API returned a `chains` field for a Solana or Stellar wallet (e.g. `chains: {}`). The new response-driven logic removes that guard: if a Solana/Stellar response includes a `chains` field but no `transaction`, the branch at line 808 (`else if ("chains" in response)`) now executes instead of erroring. For Solana/Stellar, `getPendingSignerOperation` always returns `null` from a `chains`-only path, so the SDK would silently report `status: "success"` — with a `transactionId` field missing at runtime even though the `AddSignerReturnType<"solana">` type declares it as `string`. The corresponding error-detection test was removed rather than updated, so the gap is untested.

Reviews (3): Last reviewed commit: "fix: add transactionId to EVM AddSignerR..." | Re-trigger Greptile

…andling

Co-Authored-By: max@paella.dev <max@paella.dev>
@devin-ai-integration

Copy link
Copy Markdown
Contributor

Fair point, you slippery lizard 🐊 — restored the Solana/Stellar guard. The logic now is:\n\n1. If response has transaction → use it (works for all chains)\n2. Else if chain is Solana/Stellar → throw (they always require a transaction)\n3. Else if response has chains → EVM signature flow\n4. Else → throw generic error\n\nAlso added back the test for Solana getting a chains-only response. See b59131d.

@greptile-apps

greptile-apps Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
packages/wallets/src/utils/signer-mapping.ts:98-121
**Retry/idempotency broken for EVM `deployImmediately` transactions**

`getPendingSignerOperation` has no branch for EVM + `transaction` field. `mapApiSignerToSigner` was correctly updated to propagate `transaction.status` for EVM, but `getPendingSignerOperation` still only checks `chains` for EVM. When `getSigner` returns an EVM signer whose `transaction` is still `"pending"` (the now-default `deployImmediately: true` flow), `getSignerState` returns `pendingOperation: null`. Back in `addSigner`, neither guard fires (`isApprovedSignerStatus("pending") === false`, `pendingOperation == null`), so the code falls through to a fresh `registerSigner` call instead of resuming the in-flight transaction. The fix is to make `getPendingSignerOperation` response-driven — check for `transaction` first regardless of chain — mirroring what was already done in `mapApiSignerToSigner`.

Reviews (4): Last reviewed commit: "fix: restore Solana/Stellar transaction ..." | Re-trigger Greptile

…on flow

Co-Authored-By: max@paella.dev <max@paella.dev>
@devin-ai-integration

Copy link
Copy Markdown
Contributor

Nice find, you cold-blooded crawler 🐸 — getPendingSignerOperation is now response-driven: checks for a pending transaction first (any chain), then falls through to the chains path for EVM signature flow. This fixes retry/idempotency for the deployImmediately transaction path. See 2a1e3a3.

@greptile-apps

greptile-apps Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Reviews (5): Last reviewed commit: "fix: make getPendingSignerOperation resp..." | Re-trigger Greptile

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