diff --git a/modules/abstract-lightning/package.json b/modules/abstract-lightning/package.json index dd6e83e069..1847f495b8 100644 --- a/modules/abstract-lightning/package.json +++ b/modules/abstract-lightning/package.json @@ -39,7 +39,7 @@ ] }, "dependencies": { - "@bitgo/public-types": "6.22.0", + "@bitgo/public-types": "6.43.0", "@bitgo/sdk-core": "^38.0.0", "@bitgo/statics": "^58.54.0", "@bitgo/utxo-lib": "^11.24.0", diff --git a/modules/bitgo/package.json b/modules/bitgo/package.json index 13bd25bf3b..ce4fe59d0f 100644 --- a/modules/bitgo/package.json +++ b/modules/bitgo/package.json @@ -140,7 +140,7 @@ "superagent": "^9.0.1" }, "devDependencies": { - "@bitgo/public-types": "6.22.0", + "@bitgo/public-types": "6.43.0", "@bitgo/sdk-opensslbytes": "^2.1.0", "@bitgo/sdk-test": "^9.1.57", "@openpgp/web-stream-tools": "0.0.14", diff --git a/modules/express/package.json b/modules/express/package.json index c44cb9a9e9..52d8c8b7d0 100644 --- a/modules/express/package.json +++ b/modules/express/package.json @@ -60,7 +60,7 @@ "superagent": "^9.0.1" }, "devDependencies": { - "@bitgo/public-types": "6.22.0", + "@bitgo/public-types": "6.43.0", "@bitgo/sdk-lib-mpc": "^10.15.0", "@bitgo/sdk-test": "^9.1.57", "@types/argparse": "^1.0.36", diff --git a/modules/sdk-coin-flrp/package.json b/modules/sdk-coin-flrp/package.json index 9a12613156..5dec033f40 100644 --- a/modules/sdk-coin-flrp/package.json +++ b/modules/sdk-coin-flrp/package.json @@ -48,7 +48,7 @@ "nock": "^13.3.1" }, "dependencies": { - "@bitgo/public-types": "6.22.0", + "@bitgo/public-types": "6.43.0", "@bitgo/sdk-core": "^38.0.0", "@bitgo/secp256k1": "^1.11.0", "@bitgo/statics": "^58.54.0", diff --git a/modules/sdk-coin-sol/package.json b/modules/sdk-coin-sol/package.json index 8128e8ce49..bc7b836ca4 100644 --- a/modules/sdk-coin-sol/package.json +++ b/modules/sdk-coin-sol/package.json @@ -57,7 +57,7 @@ }, "dependencies": { "@bitgo/logger": "^1.4.0", - "@bitgo/public-types": "6.22.0", + "@bitgo/public-types": "6.43.0", "@bitgo/sdk-core": "^38.0.0", "@bitgo/sdk-lib-mpc": "^10.15.0", "@bitgo/statics": "^58.54.0", diff --git a/modules/sdk-core/package.json b/modules/sdk-core/package.json index 0c01439ee8..4e5edc95fa 100644 --- a/modules/sdk-core/package.json +++ b/modules/sdk-core/package.json @@ -40,7 +40,7 @@ ] }, "dependencies": { - "@bitgo/public-types": "6.22.0", + "@bitgo/public-types": "6.43.0", "@bitgo/sdk-lib-mpc": "^10.15.0", "@bitgo/secp256k1": "^1.11.0", "@bitgo/sjcl": "^1.1.0", diff --git a/modules/sdk-core/src/bitgo/pendingApproval/pendingApproval.ts b/modules/sdk-core/src/bitgo/pendingApproval/pendingApproval.ts index 5ca48252d4..822ef5bab4 100644 --- a/modules/sdk-core/src/bitgo/pendingApproval/pendingApproval.ts +++ b/modules/sdk-core/src/bitgo/pendingApproval/pendingApproval.ts @@ -31,6 +31,8 @@ type PreApproveResult = { halfSigned?: string; }; +// TODO(WCN-541): add optional attestation pass-through for PUT /pendingapprovals/:id (deferred +// until multisig attestation, WCN-539, is verified end-to-end on staging). type ApprovePendingApprovalRequestBody = { state: 'approved'; otp: string | undefined; diff --git a/modules/sdk-core/src/bitgo/tss/common.ts b/modules/sdk-core/src/bitgo/tss/common.ts index 7903038740..83ec34bad7 100644 --- a/modules/sdk-core/src/bitgo/tss/common.ts +++ b/modules/sdk-core/src/bitgo/tss/common.ts @@ -111,6 +111,8 @@ export async function sendSignatureShare( const urlPath = '/wallet/' + walletId + '/txrequests/' + txRequestId + addendum + '/signatureshares'; const reqTracer = reqId || new RequestTracer(); bitgo.setRequestTracer(reqTracer); + // TODO(WCN-541): add optional attestation pass-through for MPC /signatureshares, first round + // only (deferred until multisig attestation, WCN-539, is verified end-to-end on staging). return bitgo .post(bitgo.url(urlPath, 2)) .send({ diff --git a/modules/sdk-core/src/bitgo/utils/tss/baseTSSUtils.ts b/modules/sdk-core/src/bitgo/utils/tss/baseTSSUtils.ts index 2b983ccdd7..1d830a3ede 100644 --- a/modules/sdk-core/src/bitgo/utils/tss/baseTSSUtils.ts +++ b/modules/sdk-core/src/bitgo/utils/tss/baseTSSUtils.ts @@ -514,6 +514,8 @@ export default class BaseTssUtils extends MpcUtils implements ITssUtil preview?: boolean, reqId?: IRequestTracer ): Promise { + // TODO(WCN-541): add optional attestation pass-through for MPC /txrequests (deferred until + // multisig attestation, WCN-539, is verified end-to-end on staging). const whitelistedParams = { intent: { ...intentOptions, diff --git a/modules/sdk-core/src/bitgo/wallet/BuildParams.ts b/modules/sdk-core/src/bitgo/wallet/BuildParams.ts index a635b2057b..a7f4499828 100644 --- a/modules/sdk-core/src/bitgo/wallet/BuildParams.ts +++ b/modules/sdk-core/src/bitgo/wallet/BuildParams.ts @@ -64,6 +64,27 @@ export const BuildParamsOffchain = t.partial({ idfUserId: t.unknown, }); +/** + * WebAuthn attestation proving a passkey user signed off on this withdrawal intent. + * Pure pass-through — the SDK does not validate or interpret this payload. + * + * @bitgo/public-types' TxSendBody now declares this field natively (WCN-539), so /tx/send and + * /tx/initiate no longer need a local copy. This one remains for BuildParams (custodial + * /tx/build), which has no upstream equivalent yet. + * + * TODO(WCN-541): add attestation pass-through for MPC (/txrequests, /signatureshares) and + * /pendingapprovals — see the TODO(WCN-541) markers in baseTSSUtils.ts, common.ts, and + * pendingApproval.ts. + */ +export const AttestationPayload = t.type({ + signature: t.string, + credentialId: t.string, + clientDataJSON: t.string, + authenticatorData: t.string, +}); + +export type AttestationPayload = t.TypeOf; + export const BuildParams = t.exact( t.intersection([ BuildParamsUTXO, @@ -135,6 +156,8 @@ export const BuildParams = t.exact( feeToken: t.unknown, // Bridging parameters for cross-chain operations (e.g., BTC to sBTC) bridgingParams: t.unknown, + // WebAuthn attestation for the withdrawal intent (WCN-539) — pass-through only. + attestation: AttestationPayload, }), ]) ); diff --git a/modules/sdk-core/src/bitgo/wallet/iWallet.ts b/modules/sdk-core/src/bitgo/wallet/iWallet.ts index a9663e6bbc..067660bcb6 100644 --- a/modules/sdk-core/src/bitgo/wallet/iWallet.ts +++ b/modules/sdk-core/src/bitgo/wallet/iWallet.ts @@ -38,6 +38,7 @@ import { TxRequest, } from '../utils'; import { SerializedNtilde } from '../../account-lib/mpc/tss/ecdsa/types'; +import { AttestationPayload } from './BuildParams'; import { IAddressBook } from '../address-book'; import { WalletUser, AddressQueryResult } from '@bitgo/public-types'; import { SubmitTransactionResponse } from '../inscriptionBuilder'; @@ -203,6 +204,8 @@ export interface PrebuildTransactionOptions { idfUserId?: string; idfVersion?: number; comment?: string; + /** WebAuthn attestation for the withdrawal intent (WCN-539) — pass-through only. */ + attestation?: AttestationPayload; [index: string]: unknown; tokenName?: string; nftCollectionId?: string; @@ -883,6 +886,8 @@ export interface SubmitTransactionOptions { }; comment?: string; txRequestId?: string; + /** WebAuthn attestation for the withdrawal intent (WCN-539) — pass-through only. */ + attestation?: AttestationPayload; } export interface SendOptions { diff --git a/modules/sdk-core/test/unit/bitgo/wallet/BuildParams.ts b/modules/sdk-core/test/unit/bitgo/wallet/BuildParams.ts index e88da25a62..e1f619b3ba 100644 --- a/modules/sdk-core/test/unit/bitgo/wallet/BuildParams.ts +++ b/modules/sdk-core/test/unit/bitgo/wallet/BuildParams.ts @@ -1,5 +1,5 @@ import * as assert from 'assert'; -import { BuildParams } from '../../../../src/bitgo/wallet/BuildParams'; +import { BuildParams, buildParamKeys, AttestationPayload } from '../../../../src/bitgo/wallet/BuildParams'; describe('BuildParams', function () { it('enforces codec', function () { @@ -74,4 +74,36 @@ describe('BuildParams', function () { } ); }); + + it('should whitelist attestation (WCN-539) while stripping unrelated unknown params', function () { + const attestation = { + signature: 'sig', + credentialId: 'cred-id', + clientDataJSON: 'client-data', + authenticatorData: 'auth-data', + }; + assert.deepStrictEqual( + BuildParams.encode({ + recipients: [{ amount: '10000', address: '2N9Ego9KidiZR8tMP82g6RaggQtcbR9zNzH' }], + attestation, + unknownField: 'should be stripped', + } as any), + { + recipients: [{ amount: '10000', address: '2N9Ego9KidiZR8tMP82g6RaggQtcbR9zNzH' }], + attestation, + } + ); + assert.ok(buildParamKeys.includes('attestation'), 'buildParamKeys must include attestation'); + }); + + it('AttestationPayload codec requires all four fields', function () { + const valid = { + signature: 'sig', + credentialId: 'cred-id', + clientDataJSON: 'client-data', + authenticatorData: 'auth-data', + }; + assert.strictEqual(AttestationPayload.is(valid), true); + assert.strictEqual(AttestationPayload.is({ ...valid, signature: undefined }), false); + }); }); diff --git a/modules/sdk-core/test/unit/bitgo/wallet/SendTransactionRequest.ts b/modules/sdk-core/test/unit/bitgo/wallet/SendTransactionRequest.ts index c1030ff859..12e3b09906 100644 --- a/modules/sdk-core/test/unit/bitgo/wallet/SendTransactionRequest.ts +++ b/modules/sdk-core/test/unit/bitgo/wallet/SendTransactionRequest.ts @@ -24,4 +24,13 @@ describe('SendTransactionRequest', function () { addressType: 'p2sh', }); }); + + it('preserves attestation (WCN-539: @bitgo/public-types TxSendBody declares it natively)', function () { + const attestation = { signature: 'sig', credentialId: 'c', clientDataJSON: 'cd', authenticatorData: 'ad' }; + + assert.deepStrictEqual(TxSendBody.encode({ txHex: '00', attestation } as any), { + txHex: '00', + attestation, + }); + }); }); diff --git a/yarn.lock b/yarn.lock index 4eabf566b6..23d7ac50a3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -997,10 +997,10 @@ monocle-ts "^2.3.13" newtype-ts "^0.3.5" -"@bitgo/public-types@6.22.0": - version "6.22.0" - resolved "https://registry.npmjs.org/@bitgo/public-types/-/public-types-6.22.0.tgz#bbef2866c9b2d35e4a6179f7c400abc4f419d0ec" - integrity sha512-FueZVrrAKfevkoC9/TtKQLq5S19PzKfsNSj+0uHt1rEoKJ5vS1Icf/M/8pIwYVR11Kn3mjWzqbYJrJUZI/3FHQ== +"@bitgo/public-types@6.43.0": + version "6.43.0" + resolved "https://registry.npmjs.org/@bitgo/public-types/-/public-types-6.43.0.tgz#3d749f011ae7cad1c992ccc49c7b9cc24dbc5e1a" + integrity sha512-aYzRp7IH/Xbyi8/CzlYDiPpJmtQN0BlJGanqupDj4YTMJ9UjwIJLaUjOtJuVTT+ZrChcgdDZgajnmPDdPV2J1w== dependencies: fp-ts "^2.0.0" io-ts "npm:@bitgo-forks/io-ts@2.1.4"