Skip to content

feat(passkey-crypto): add removePasskeyFromWallet function#8646

Open
derranW26 wants to merge 1 commit intomasterfrom
passkey/ticket-5-remove-passkey-from-wallet
Open

feat(passkey-crypto): add removePasskeyFromWallet function#8646
derranW26 wants to merge 1 commit intomasterfrom
passkey/ticket-5-remove-passkey-from-wallet

Conversation

@derranW26
Copy link
Copy Markdown
Contributor

@derranW26 derranW26 commented Apr 28, 2026

Summary

  • Bumps @bitgo/public-types to 6.1.0 to import canonical WebAuthnOtpDevice type (replaces local stub)
  • Adds removePasskeyFromWallet() to modules/sdk-core/src/bitgo/passkey/
  • Infers coin and keychainId from fetched wallet (walletId-only interface)
  • Validates device.id, wallet coin, and wallet keys before proceeding
  • Verifies wallet passphrase via decrypt() before issuing any DELETE — wrong passphrase aborts cleanly with no side effects
  • DELETEs /api/v2/key/{keychainId}/webauthndevice/{device.id} using MongoDB ObjectId (not credentialId)

Test plan

  • Unit: successful passkey removal — verifies decrypt called with correct args, DELETE called with device.id
  • Unit: wrong passphrase — verifies error thrown with lockout message, DELETE NOT called
  • Unit: missing encryptedPrv — verifies descriptive error thrown, no decrypt or DELETE called
  • Unit: empty device.id — verifies error thrown, no API calls made
  • Unit: wallet with no coin — verifies descriptive error, no downstream calls
  • Unit: wallet with no keys — verifies descriptive error, no downstream calls
  • Unit: wallet fetch failure — verifies error propagation
  • Unit: DELETE failure — verifies error propagation after successful passphrase check

TICKET: WCN-190

@derranW26 derranW26 force-pushed the passkey/ticket-5-remove-passkey-from-wallet branch from 895e229 to f01d766 Compare April 28, 2026 14:38
@derranW26 derranW26 changed the base branch from master to WCN-186/passkey-crypto-package April 28, 2026 14:38
@derranW26 derranW26 changed the base branch from WCN-186/passkey-crypto-package to master April 28, 2026 14:40
@derranW26 derranW26 force-pushed the passkey/ticket-5-remove-passkey-from-wallet branch from f01d766 to 834fe16 Compare May 4, 2026 05:04
@derranW26 derranW26 marked this pull request as ready for review May 4, 2026 05:07
@derranW26 derranW26 requested review from a team as code owners May 4, 2026 05:07
@derranW26 derranW26 force-pushed the passkey/ticket-5-remove-passkey-from-wallet branch 2 times, most recently from 9877398 to 4c6a78f Compare May 4, 2026 14:25
@derranW26
Copy link
Copy Markdown
Contributor Author

@claude review this PR

Copy link
Copy Markdown
Contributor

@mohammadalfaiyazbitgo mohammadalfaiyazbitgo left a comment

Choose a reason for hiding this comment

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

can we move this to passkey module?

@derranW26 derranW26 force-pushed the passkey/ticket-5-remove-passkey-from-wallet branch 2 times, most recently from e6d52f4 to ebd4c33 Compare May 4, 2026 18:57
Comment on lines +16 to +36
// Fetch wallet to infer coin and keychainId
const walletData = await bitgo.get(bitgo.url(`/wallet/${walletId}`, 2)).result();

const coin = walletData.coin;
if (!coin || typeof coin !== 'string') {
throw new Error(`Wallet ${walletId} has no coin type. Cannot remove passkey.`);
}

const keys = walletData.keys as string[] | undefined;
if (!keys || keys.length === 0) {
throw new Error(`Wallet ${walletId} has no keys. Cannot remove passkey.`);
}
const keychainId = keys[0];

// Fetch user keychain
const keychain = await bitgo.get(bitgo.url(`/${coin}/key/${keychainId}`, 2)).result();

if (!keychain.encryptedPrv) {
throw new Error(`Keychain ${keychainId} has no encryptedPrv. Cannot verify passphrase before passkey removal.`);
}

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.

simplify using the sdk-core methods.

@derranW26 derranW26 force-pushed the passkey/ticket-5-remove-passkey-from-wallet branch from ebd4c33 to c493bd2 Compare May 4, 2026 19:56
@derranW26 derranW26 changed the title feat(sdk-core): add removePasskeyFromWallet function feat(passkey-crypto): add removePasskeyFromWallet function May 5, 2026
Removes a WebAuthn passkey credential from a wallet's user keychain.
Uses idiomatic sdk-core methods (wallets().get(), keychains().get(),
decryptKeychainPrivateKey) instead of raw HTTP calls. Verifies the
wallet passphrase before issuing the DELETE to prevent accidental
lockout. Validates device.id before proceeding.

TICKET: WCN-190
@derranW26 derranW26 force-pushed the passkey/ticket-5-remove-passkey-from-wallet branch from c493bd2 to 18f301a Compare May 5, 2026 17:17
Comment on lines +43 to +44
"@types/proxyquire": "^1.3.31",
"proxyquire": "^2.1.3"
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.

you shouldn't need this, you should be able to mock responses via sinon and the other testing utilities we have.

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