diff --git a/apps/docs/src/pages/connect/wallet-interface.mdx b/apps/docs/src/pages/connect/wallet-interface.mdx index 17e5a99..24948a5 100644 --- a/apps/docs/src/pages/connect/wallet-interface.mdx +++ b/apps/docs/src/pages/connect/wallet-interface.mdx @@ -58,6 +58,8 @@ const { result } = await provider.request<'mina_sign'>({ method: 'mina_sign', pa ### mina_signTransaction +Sign payment or delegation: + ```ts twoslash import { createStore } from '@mina-js/connect' @@ -67,11 +69,32 @@ const { result } = await provider.request<'mina_signTransaction'>({ method: 'mina_signTransaction', params: [{ // You should probably get the right nonce from Klesia for that. - nonce: 1n, + nonce: '1', from: "B62qmWKtvNQTtUqo1LxfEEDLyWMg59cp6U7c4uDC7aqgaCEijSc3Hx5", to: "B62qmWKtvNQTtUqo1LxfEEDLyWMg59cp6U7c4uDC7aqgaCEijSc3Hx5", - amount: 3000000000n, - fee: 100000000n, + amount: '3000000000', + fee: '100000000', + }] +}) +``` + +Sign zkApp command: + +```ts twoslash +import { createStore } from '@mina-js/connect' + +const store = createStore() +const { provider } = store.getProviders()[0] +const { result } = await provider.request<'mina_signTransaction'>({ + method: 'mina_signTransaction', + params: [{ + zkappCommand: {}, + feePayer: { + feePayer: 'B62qmWKtvNQTtUqo1LxfEEDLyWMg59cp6U7c4uDC7aqgaCEijSc3Hx5', + fee: '100000000', + nonce: '1', + memo: 'Hello, Mina!', + } }] }) ``` diff --git a/bun.lockb b/bun.lockb index eaef67b..e9aa356 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/packages/accounts/src/accounts/private-key-to-account.spec.ts b/packages/accounts/src/accounts/private-key-to-account.spec.ts index fb96efd..dc6b993 100644 --- a/packages/accounts/src/accounts/private-key-to-account.spec.ts +++ b/packages/accounts/src/accounts/private-key-to-account.spec.ts @@ -23,11 +23,11 @@ it("signs a transaction", async () => { privateKey: Test.accounts[0].privateKey, }); const transaction = { - nonce: 1n, + nonce: "1", from: "B62qmWKtvNQTtUqo1LxfEEDLyWMg59cp6U7c4uDC7aqgaCEijSc3Hx5", to: "B62qmWKtvNQTtUqo1LxfEEDLyWMg59cp6U7c4uDC7aqgaCEijSc3Hx5", - amount: 3000000000n, - fee: 100000000n, + amount: "3000000000", + fee: "100000000", }; const signedTransaction = await account.signTransaction({ transaction }); expect(signedTransaction).toMatchSnapshot(); @@ -38,7 +38,9 @@ it("creates a nullifier", async () => { privateKey: Test.accounts[0].privateKey, }); const message = [1n, 2n, 3n]; - const nullifier = await account.createNullifier({ message }); + const nullifier = await account.createNullifier({ + message: message.map((el) => el.toString()), + }); expect(typeof nullifier.private.c).toBe("bigint"); }); @@ -47,6 +49,8 @@ it("signs fields", async () => { privateKey: Test.accounts[0].privateKey, }); const fields = [1n, 2n, 3n]; - const signedFields = await account.signFields({ fields }); + const signedFields = await account.signFields({ + fields: fields.map((el) => el.toString()), + }); expect(signedFields).toMatchSnapshot(); }); diff --git a/packages/accounts/src/accounts/private-key-to-account.ts b/packages/accounts/src/accounts/private-key-to-account.ts index 6cdb1b2..6d3ccb6 100644 --- a/packages/accounts/src/accounts/private-key-to-account.ts +++ b/packages/accounts/src/accounts/private-key-to-account.ts @@ -35,10 +35,20 @@ export function privateKeyToAccount({ ); }, async createNullifier({ message }) { - return NullifierSchema.parse(client.createNullifier(message, privateKey)); + return NullifierSchema.parse( + client.createNullifier( + message.map((el) => BigInt(el)), + privateKey, + ), + ); }, async signFields({ fields }) { - return SignedFieldsSchema.parse(client.signFields(fields, privateKey)); + return SignedFieldsSchema.parse( + client.signFields( + fields.map((el) => BigInt(el)), + privateKey, + ), + ); }, }); diff --git a/packages/connect/src/client.ts b/packages/connect/src/client.ts index 97c80b1..172df81 100644 --- a/packages/connect/src/client.ts +++ b/packages/connect/src/client.ts @@ -63,7 +63,7 @@ export const createWalletClient = ({ method: "mina_getBalance", params: [account.publicKey], }); - return BigInt(result); + return result; }; return match(providerSource) .with("klesia", async () => { @@ -79,7 +79,7 @@ export const createWalletClient = ({ method: "mina_getTransactionCount", params: [account.publicKey], }); - return BigInt(result); + return result; }; const getChainId = async () => { return match(providerSource) @@ -122,9 +122,9 @@ export const createWalletClient = ({ method: "mina_estimateFees", }); return { - low: BigInt(result.low), - medium: BigInt(result.medium), - high: BigInt(result.high), + low: result.low, + medium: result.medium, + high: result.high, }; }; const prepareTransactionRequest = async ( @@ -136,7 +136,7 @@ export const createWalletClient = ({ nonce = await getTransactionCount(); } if (!fee) { - fee = BigInt((await estimateFees()).medium); + fee = (await estimateFees()).medium; } return { ...transaction, diff --git a/packages/providers/src/validation.ts b/packages/providers/src/validation.ts index 441c8bc..551d37a 100644 --- a/packages/providers/src/validation.ts +++ b/packages/providers/src/validation.ts @@ -1,3 +1,4 @@ +import { ZkAppCommandPayload } from "@mina-js/utils"; import { FieldSchema, NullifierSchema, @@ -47,13 +48,13 @@ export const SignFieldsRequestParamsSchema = z export const SignTransactionRequestParamsSchema = z .object({ method: z.literal("mina_signTransaction"), - params: z.array(TransactionPayload), + params: z.array(z.union([TransactionPayload, ZkAppCommandPayload])), }) .strict(); export const SendTransactionRequestParamsSchema = z .object({ method: z.literal("mina_sendTransaction"), - params: z.array(TransactionPayload), + params: z.array(SignedTransactionSchema), }) .strict(); export const CreateNullifierRequestParamsSchema = z diff --git a/packages/utils/package.json b/packages/utils/package.json index 08533e1..330f05a 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -18,6 +18,7 @@ "cleanup": "rimraf dist .turbo" }, "dependencies": { + "mina-signer": "3.0.7", "zod": "3.23.8" }, "peerDependencies": { diff --git a/packages/utils/src/types.ts b/packages/utils/src/types.ts index 904ab2b..24ed243 100644 --- a/packages/utils/src/types.ts +++ b/packages/utils/src/types.ts @@ -10,6 +10,7 @@ import type { SignedTransactionSchema, TransactionPayload, TransactionReceiptSchema, + ZkAppCommandPayload, } from "./validation"; /** @@ -23,6 +24,7 @@ export type TransactionProperties = z.infer; export type PartiallyFormedTransactionProperties = z.infer< typeof PartiallyFormedTransactionPayload >; +export type ZkAppCommandProperties = z.infer; /** * Return types diff --git a/packages/utils/src/validation.ts b/packages/utils/src/validation.ts index b8b7ad4..56331a5 100644 --- a/packages/utils/src/validation.ts +++ b/packages/utils/src/validation.ts @@ -14,7 +14,7 @@ const JsonSchema: z.ZodType = z.lazy(() => z.union([LiteralSchema, z.array(JsonSchema), z.record(JsonSchema)]), ); -export const FieldSchema = z.coerce.bigint(); +export const FieldSchema = z.coerce.string(); export const GroupSchema = z .object({ @@ -27,14 +27,24 @@ export const PublicKeySchema = z.string().length(55).startsWith("B62"); export const PrivateKeySchema = z.string().length(52); +export const FeePayerSchema = z + .object({ + feePayer: PublicKeySchema, + fee: z.coerce.string(), + nonce: z.coerce.string(), + memo: z.string().optional(), + validUntil: z.coerce.string().optional(), + }) + .strict(); + export const DelegationPayload = z .object({ from: PublicKeySchema, to: PublicKeySchema, memo: z.string().optional(), - fee: z.coerce.bigint(), - nonce: z.coerce.bigint(), - validUntil: z.coerce.bigint().optional(), + fee: z.coerce.string(), + nonce: z.coerce.string(), + validUntil: z.coerce.string().optional(), }) .strict(); @@ -50,7 +60,7 @@ export const TransportableDelegationPayload = z .strict(); export const TransactionPayload = DelegationPayload.extend({ - amount: z.coerce.bigint(), + amount: z.coerce.string(), }).strict(); export const TransportableTransactionPayload = @@ -59,10 +69,17 @@ export const TransportableTransactionPayload = }).strict(); export const PartiallyFormedTransactionPayload = TransactionPayload.extend({ - fee: z.coerce.bigint().optional(), - nonce: z.coerce.bigint().optional(), + fee: z.coerce.string().optional(), + nonce: z.coerce.string().optional(), }); +export const ZkAppCommandPayload = z + .object({ + zkappCommand: JsonSchema, + feePayer: FeePayerSchema, + }) + .strict(); + /** * Return type schemas */