Skip to content

Commit 2be76ea

Browse files
authored
feat(accounts): add zkapp command signing (#7)
1 parent c15809e commit 2be76ea

File tree

6 files changed

+77
-6
lines changed

6 files changed

+77
-6
lines changed

packages/accounts/src/accounts/__snapshots__/private-key-to-account.spec.ts.snap

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,32 @@ exports[`signs fields 1`] = `
5353
"signature": "7mXCUvhLhFvG9ptrdfNceCrpThkCUyg1ct2z8uwY7eQbKz7UNmhv33TbuDjTznaypJtXRiMJyQWDnf27TH1FSXG7uJHTKAd9",
5454
}
5555
`;
56+
57+
exports[`signs a zkapp command 1`] = `
58+
{
59+
"data": {
60+
"feePayer": {
61+
"fee": "100000000",
62+
"feePayer": "B62qmWKtvNQTtUqo1LxfEEDLyWMg59cp6U7c4uDC7aqgaCEijSc3Hx5",
63+
"memo": "Test",
64+
"nonce": "0",
65+
"validUntil": "null",
66+
},
67+
"zkappCommand": {
68+
"accountUpdates": [],
69+
"feePayer": {
70+
"authorization": "7mXWqNfmqMTM5uSCS2xLfsRBLTjGZKTtpEakdsrdQz1EUgYXogSvKxxtfGbBkqQ2mZRMA3uPAM8riaCF56pkqpZBLr2kNBLa",
71+
"body": {
72+
"fee": "100000000",
73+
"nonce": "0",
74+
"publicKey": "B62qmWKtvNQTtUqo1LxfEEDLyWMg59cp6U7c4uDC7aqgaCEijSc3Hx5",
75+
"validUntil": null,
76+
},
77+
},
78+
"memo": "E4YVT4x3A9rUhmjkjGn8ZYBLZn7zK4cfvnMtBYZFdWkg37n2s3nrP",
79+
},
80+
},
81+
"publicKey": "B62qmWKtvNQTtUqo1LxfEEDLyWMg59cp6U7c4uDC7aqgaCEijSc3Hx5",
82+
"signature": "7mXWqNfmqMTM5uSCS2xLfsRBLTjGZKTtpEakdsrdQz1EUgYXogSvKxxtfGbBkqQ2mZRMA3uPAM8riaCF56pkqpZBLr2kNBLa",
83+
}
84+
`;

packages/accounts/src/accounts/private-key-to-account.spec.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,35 @@ it("signs a transaction", async () => {
3333
expect(signedTransaction).toMatchSnapshot();
3434
});
3535

36+
it("signs a zkapp command", async () => {
37+
const account = privateKeyToAccount({
38+
privateKey: Test.accounts[0].privateKey,
39+
});
40+
const command = {
41+
zkappCommand: {
42+
accountUpdates: [],
43+
memo: "E4YM2vTHhWEg66xpj52JErHUBU4pZ1yageL4TVDDpTTSsv8mK6YaH",
44+
feePayer: {
45+
body: {
46+
publicKey: "B62qmWKtvNQTtUqo1LxfEEDLyWMg59cp6U7c4uDC7aqgaCEijSc3Hx5",
47+
fee: "100000000",
48+
validUntil: "100000",
49+
nonce: "1",
50+
},
51+
authorization: "",
52+
},
53+
},
54+
feePayer: {
55+
feePayer: "B62qmWKtvNQTtUqo1LxfEEDLyWMg59cp6U7c4uDC7aqgaCEijSc3Hx5",
56+
fee: "100000000",
57+
nonce: "0",
58+
memo: "Test",
59+
},
60+
};
61+
const signedTransaction = await account.signTransaction({ command });
62+
expect(signedTransaction).toMatchSnapshot();
63+
});
64+
3665
it("creates a nullifier", async () => {
3766
const account = privateKeyToAccount({
3867
privateKey: Test.accounts[0].privateKey,

packages/accounts/src/accounts/private-key-to-account.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,14 @@ export function privateKeyToAccount({
2929
async signMessage({ message }) {
3030
return SignedMessageSchema.parse(client.signMessage(message, privateKey));
3131
},
32-
async signTransaction({ transaction }) {
32+
async signTransaction(signable) {
33+
if ("transaction" in signable) {
34+
return SignedTransactionSchema.parse(
35+
client.signTransaction(signable.transaction, privateKey),
36+
);
37+
}
3338
return SignedTransactionSchema.parse(
34-
client.signTransaction(transaction, privateKey),
39+
client.signTransaction(signable.command as never, privateKey),
3540
);
3641
},
3742
async createNullifier({ message }) {

packages/accounts/src/types.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type {
44
SignedFields,
55
SignedMessage,
66
SignedTransaction,
7+
TransactionOrZkAppCommandProperties,
78
} from "@mina-js/utils";
89
import type { HDKey } from "@scure/bip32";
910
import type { Simplify } from "type-fest";
@@ -12,7 +13,6 @@ import type {
1213
CreateNullifierParamsSchema,
1314
SignFieldsParamsSchema,
1415
SignMessageParamsSchema,
15-
SignTransactionParamsSchema,
1616
} from "./validation";
1717

1818
export enum MinaKeyConst {
@@ -81,7 +81,6 @@ export type { HDKey };
8181
export type SignFieldsParams = z.infer<typeof SignFieldsParamsSchema>;
8282
export type SignMessageParams = z.infer<typeof SignMessageParamsSchema>;
8383
export type CreateNullifierParams = z.infer<typeof CreateNullifierParamsSchema>;
84-
export type SignTransactionParams = z.infer<typeof SignTransactionParamsSchema>;
8584

8685
/**
8786
* Signer methods
@@ -92,5 +91,5 @@ export type CreateNullifier = (
9291
params: CreateNullifierParams,
9392
) => Promise<Nullifier>;
9493
export type SignTransaction = (
95-
params: SignTransactionParams,
94+
params: TransactionOrZkAppCommandProperties,
9695
) => Promise<SignedTransaction>;

packages/utils/src/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type {
1414
SignedTransactionSchema,
1515
StoredCredentialSchema,
1616
TransactionBodySchema,
17+
TransactionOrZkAppCommandSchema,
1718
TransactionPayloadSchema,
1819
TransactionReceiptSchema,
1920
ZkAppCommandBodySchema,
@@ -32,6 +33,9 @@ export type TransactionPayload = z.infer<typeof TransactionPayloadSchema>;
3233
export type PartialTransaction = z.infer<typeof PartialTransactionSchema>;
3334
export type ZkAppCommandBody = z.infer<typeof ZkAppCommandBodySchema>;
3435
export type ZkAppCommandProperties = z.infer<typeof ZkAppCommandPayload>;
36+
export type TransactionOrZkAppCommandProperties = z.infer<
37+
typeof TransactionOrZkAppCommandSchema
38+
>;
3539
export type Sendable = z.infer<typeof SendableSchema>;
3640

3741
/**

packages/utils/src/validation.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ export const ZkAppCommandPayload = z
7979
})
8080
.strict();
8181

82+
export const TransactionOrZkAppCommandSchema = z.union([
83+
TransactionPayloadSchema,
84+
ZkAppCommandPayload,
85+
]);
86+
8287
/**
8388
* Return type schemas
8489
*/
@@ -122,7 +127,7 @@ export const NullifierSchema = z
122127

123128
export const SignedTransactionSchema = z
124129
.object({
125-
signature: SignatureSchema,
130+
signature: z.union([SignatureSchema, z.string()]),
126131
publicKey: PublicKeySchema,
127132
data: z.union([TransactionBodySchema, ZkAppCommandBodySchema]),
128133
})

0 commit comments

Comments
 (0)