Skip to content

Commit

Permalink
chore: fix signing implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
howydev committed Dec 20, 2024
1 parent 25c6795 commit aee72be
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 54 deletions.
52 changes: 30 additions & 22 deletions account-kit/smart-contracts/src/ma-v2/account/nativeSMASigner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,6 @@ export const nativeSMASigner = <TSigner extends SmartAccountSigner>(
accountAddress: Address,
entityId: number
) => {
const apply712MessageWrap = async (digest: Hex): Promise<Hex> => {
return hashTypedData({
domain: {
chainId: Number(chain.id),
verifyingContract: accountAddress,
},
types: {
ReplaySafeHash: [{ name: "digest", type: "bytes32" }],
},
message: {
digest,
},
primaryType: "ReplaySafeHash",
});
};

return {
getDummySignature: (): Hex => {
const dummyEcdsaSignature =
Expand All @@ -83,10 +67,22 @@ export const nativeSMASigner = <TSigner extends SmartAccountSigner>(
}: {
message: SignableMessage;
}): Promise<`0x${string}`> {
const digest = await apply712MessageWrap(hashMessage(message));
const digest = await hashMessage(message);

return pack1271Signature({
validationSignature: await signer.signMessage({ raw: digest }),
validationSignature: await signer.signTypedData({
domain: {
chainId: Number(chain.id),
verifyingContract: accountAddress,
},
types: {
ReplaySafeHash: [{ name: "digest", type: "bytes32" }],
},
message: {
digest,
},
primaryType: "ReplaySafeHash",
}),
entityId,
});
},
Expand All @@ -102,10 +98,22 @@ export const nativeSMASigner = <TSigner extends SmartAccountSigner>(
const isDeferredAction =
typedDataDefinition?.primaryType === "DeferredAction" &&
typedDataDefinition?.domain?.verifyingContract === accountAddress;
const digest = isDeferredAction
? hashTypedData(typedDataDefinition)
: await apply712MessageWrap(hashTypedData(typedDataDefinition));
return signer.signMessage({ raw: digest });

return isDeferredAction
? signer.signTypedData(typedDataDefinition)
: signer.signTypedData({
domain: {
chainId: Number(chain.id),
verifyingContract: accountAddress,
},
types: {
ReplaySafeHash: [{ name: "digest", type: "bytes32" }],
},
message: {
digest: await hashTypedData(typedDataDefinition),
},
primaryType: "ReplaySafeHash",
});
},
};
};
21 changes: 12 additions & 9 deletions account-kit/smart-contracts/src/ma-v2/client/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
getContract,
keccak256,

Check warning on line 6 in account-kit/smart-contracts/src/ma-v2/client/client.test.ts

View workflow job for this annotation

GitHub Actions / Lint

'keccak256' is defined but never used
toHex,

Check warning on line 7 in account-kit/smart-contracts/src/ma-v2/client/client.test.ts

View workflow job for this annotation

GitHub Actions / Lint

'toHex' is defined but never used
hashMessage,
} from "viem";
import { LocalAccountSigner, type SmartAccountSigner } from "@aa-sdk/core";
import { createSMAV2AccountClient, type SMAV2AccountClient } from "./client.js";

Check warning on line 11 in account-kit/smart-contracts/src/ma-v2/client/client.test.ts

View workflow job for this annotation

GitHub Actions / Lint

'SMAV2AccountClient' is defined but never used
Expand All @@ -21,6 +22,9 @@ describe("MA v2 Tests", async () => {
let client: ReturnType<typeof instance.getClient> &
ReturnType<typeof publicActions>;

const isValidSigSuccess = "0x1626ba7e";
const isValidSigFail = "0xffffffff";

Check warning on line 26 in account-kit/smart-contracts/src/ma-v2/client/client.test.ts

View workflow job for this annotation

GitHub Actions / Lint

'isValidSigFail' is assigned a value but never used

beforeAll(async () => {
client = instance.getClient().extend(publicActions);
});
Expand Down Expand Up @@ -220,22 +224,21 @@ describe("MA v2 Tests", async () => {
hooks: [],
});

const message = keccak256(toHex("testmessage"));
const message = "testmessage";

console.log("outside; ", hashMessage(message));
const signature = await provider.signMessage({ message });

console.log(await provider.account.isAccountDeployed());

console.log(
await accountContract.read.isValidSignature([message, signature])
);
await expect(

Check failure on line 232 in account-kit/smart-contracts/src/ma-v2/client/client.test.ts

View workflow job for this annotation

GitHub Actions / Build and Test

src/ma-v2/client/client.test.ts > MA v2 Tests > successfully sign + validate a message for native signer

AssertionError: expected '0xffffffff' to deeply equal '0x1626ba7e' - Expected + Received - 0x1626ba7e + 0xffffffff ❯ src/ma-v2/client/client.test.ts:232:5
accountContract.read.isValidSignature([hashMessage(message), signature])
).resolves.toEqual(isValidSigSuccess);

// await expect(
// accountContract.read.isValidSignature({
// accountContract.read.isValidSignature([
// message,
// signature,
// })
// ).resolves.toBeTruthy();
// ])
// ).resolves.toEqual(isValidSigSuccess)
});

const givenConnectedProvider = async ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,6 @@ export const singleSignerMessageSigner = <TSigner extends SmartAccountSigner>(
accountAddress: Address,
entityId: number
) => {
const apply712MessageWrap = async (digest: Hex): Promise<Hex> => {
return hashTypedData({
domain: {
chainId: Number(chain.id),
salt: accountAddress,
verifyingContract: getDefaultSingleSignerValidationModuleAddress(chain),
},
types: {
ReplaySafeHash: [{ name: "digest", type: "bytes32" }],
},
message: {
digest,
},
primaryType: "ReplaySafeHash",
});
};

return {
getDummySignature: (): Hex => {
const dummyEcdsaSignature =
Expand All @@ -85,10 +68,24 @@ export const singleSignerMessageSigner = <TSigner extends SmartAccountSigner>(
}: {
message: SignableMessage;
}): Promise<`0x${string}`> {
const digest = await apply712MessageWrap(hashMessage(message));
const digest = await hashMessage(message);

return pack1271Signature({
validationSignature: await signer.signMessage({ raw: digest }),
validationSignature: await signer.signTypedData({
domain: {
chainId: Number(chain.id),
verifyingContract:
getDefaultSingleSignerValidationModuleAddress(chain),
salt: accountAddress,
},
types: {
ReplaySafeHash: [{ name: "digest", type: "bytes32" }],
},
message: {
digest,
},
primaryType: "ReplaySafeHash",
}),
entityId,
});
},
Expand All @@ -100,11 +97,28 @@ export const singleSignerMessageSigner = <TSigner extends SmartAccountSigner>(
>(
typedDataDefinition: TypedDataDefinition<typedData, primaryType>
): Promise<Hex> => {
const digest = await apply712MessageWrap(
hashTypedData(typedDataDefinition)
);
// the accounts domain already gives replay protection across accounts for deferred actions, so we don't need to apply another wrapping
const isDeferredAction =
typedDataDefinition?.primaryType === "DeferredAction" &&
typedDataDefinition?.domain?.verifyingContract === accountAddress;

return signer.signMessage({ raw: digest });
return isDeferredAction
? signer.signTypedData(typedDataDefinition)
: signer.signTypedData({
domain: {
chainId: Number(chain.id),
verifyingContract:
getDefaultSingleSignerValidationModuleAddress(chain),
salt: accountAddress,
},
types: {
ReplaySafeHash: [{ name: "digest", type: "bytes32" }],
},
message: {
digest: await hashTypedData(typedDataDefinition),
},
primaryType: "ReplaySafeHash",
});
},
};
};
1 change: 1 addition & 0 deletions account-kit/smart-contracts/src/ma-v2/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const pack1271Signature = ({
"0x00",
toHex(entityId, { size: 4 }),
"0xFF",
"0x00", // EOA type signature
validationSignature,
]);
};
Expand Down

0 comments on commit aee72be

Please sign in to comment.