diff --git a/.changeset/a2a-handshake-return-reply-nonce.md b/.changeset/a2a-handshake-return-reply-nonce.md new file mode 100644 index 00000000..280dcd1c --- /dev/null +++ b/.changeset/a2a-handshake-return-reply-nonce.md @@ -0,0 +1,5 @@ +--- +"@agentcommercekit/ack-id": patch +--- + +Return the freshly generated `replyNonce` from `createA2AHandshakeMessage` when responding to a handshake, so callers can correlate the next leg. diff --git a/packages/ack-id/src/a2a/sign-message.test.ts b/packages/ack-id/src/a2a/sign-message.test.ts index fed6068d..cbc4b0de 100644 --- a/packages/ack-id/src/a2a/sign-message.test.ts +++ b/packages/ack-id/src/a2a/sign-message.test.ts @@ -149,4 +149,19 @@ describe("createA2AHandshakeMessage", () => { expect.objectContaining({ kind: "data", data: { jwt: result.sig } }), ) }) + + it("returns the fresh replyNonce when requestNonce is provided", async () => { + const result = await createA2AHandshakeMessage( + "agent", + { + recipient: userDid, + vc: testCredential, + requestNonce: "initiator-nonce", + }, + { did: agentDid, jwtSigner }, + ) + + expect(result.nonce).toBe("test-nonce-1234") + expect(result.nonce).not.toBe("initiator-nonce") + }) }) diff --git a/packages/ack-id/src/a2a/sign-message.ts b/packages/ack-id/src/a2a/sign-message.ts index a4a041bc..c6c61188 100644 --- a/packages/ack-id/src/a2a/sign-message.ts +++ b/packages/ack-id/src/a2a/sign-message.ts @@ -122,7 +122,9 @@ export async function createA2AHandshakeMessage( return { sig: jwt, jti, - nonce: payload.nonce, + // When replying, callers need the freshly generated replyNonce for the next + // handshake leg — not the peer's original request nonce in payload.nonce. + nonce: payload.replyNonce ?? payload.nonce, message, } }