Skip to content

Commit 5eea25e

Browse files
committed
feat(minajs): improve tx send and add value utils
1 parent 8107d7d commit 5eea25e

37 files changed

+505
-30
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ jobs:
1212
- run: bun i --no-save
1313
- run: bun run build
1414
- run: bun run test
15-
- run: bunx pkg-pr-new publish './packages/klesia-sdk' './packages/accounts' './packages/connect' './packages/providers' './packages/shared'
15+
- run: bunx pkg-pr-new publish './packages/klesia-sdk' './packages/accounts' './packages/connect' './packages/providers' './packages/utils'

apps/klesia/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"dependencies": {
2222
"@hono/node-server": "^1.12.2",
2323
"@hono/zod-openapi": "^0.16.0",
24-
"@mina-js/shared": "workspace:*",
24+
"@mina-js/utils": "workspace:*",
2525
"@urql/core": "^5.0.6",
2626
"bigint-quantile": "^0.0.2",
2727
"dayjs": "^1.11.13",

apps/klesia/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import "dotenv/config";
22
import { getConnInfo } from "@hono/node-server/conninfo";
33
import { OpenAPIHono, createRoute } from "@hono/zod-openapi";
4-
import { PublicKeySchema } from "@mina-js/shared";
4+
import { PublicKeySchema } from "@mina-js/utils";
55
import { rateLimiter } from "hono-rate-limiter";
66
import { cors } from "hono/cors";
77
import { logger } from "hono/logger";

apps/klesia/src/methods/mina.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
import { SignedTransactionSchema } from "@mina-js/shared";
21
import { gql } from "@urql/core";
32
import { calculateQuantile } from "bigint-quantile";
43
import { match } from "ts-pattern";
4+
import {
5+
SendDelegationBodySchema,
6+
SendTransactionBodySchema,
7+
SendZkAppBodySchema,
8+
} from "../schema";
59
import { getNodeClient } from "../utils/node";
610

711
export const PRIORITY = {
@@ -91,8 +95,8 @@ const sendTransaction = async ({
9195
const client = getNodeClient();
9296
return match(type)
9397
.with("payment", async () => {
94-
const { signature, data: input } =
95-
SignedTransactionSchema.parse(signedTransaction);
98+
const { signature, input } =
99+
SendTransactionBodySchema.parse(signedTransaction);
96100
const { data } = await client.mutation(
97101
gql`
98102
mutation {
@@ -108,8 +112,8 @@ const sendTransaction = async ({
108112
return data.sendPayment.payment.hash;
109113
})
110114
.with("delegation", async () => {
111-
const { signature, data: input } =
112-
SignedTransactionSchema.parse(signedTransaction);
115+
const { signature, input } =
116+
SendDelegationBodySchema.parse(signedTransaction);
113117
const { data } = await client.mutation(
114118
gql`
115119
mutation {
@@ -125,6 +129,7 @@ const sendTransaction = async ({
125129
return data.sendDelegation.delegation.hash;
126130
})
127131
.with("zkapp", async () => {
132+
const { input } = SendZkAppBodySchema.parse(signedTransaction);
128133
const { data } = await client.mutation(
129134
gql`
130135
mutation {
@@ -135,7 +140,7 @@ const sendTransaction = async ({
135140
}
136141
}
137142
`,
138-
{ input: signedTransaction },
143+
{ input },
139144
);
140145
return data.sendZkapp.zkapp.hash;
141146
})

apps/klesia/src/schema.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,40 @@
1-
import { PublicKeySchema } from "@mina-js/shared";
1+
import {
2+
PublicKeySchema,
3+
TransportableDelegationPayload,
4+
TransportableTransactionPayload,
5+
} from "@mina-js/utils";
26
import { z } from "zod";
7+
import { SendZkappInput } from "./zkapp";
38

49
export const KlesiaNetwork = z.enum(["devnet", "mainnet", "zeko_devnet"]);
510
export const PublicKeyParamsSchema = z.array(PublicKeySchema).length(1);
611
export const EmptyParamsSchema = z.array(z.string()).length(0).optional();
7-
export const SendTransactionSchema = z.array(z.any(), z.string()).length(2);
12+
export const SignatureSchema = z.union([
13+
z.object({
14+
rawSignature: z.string(),
15+
}),
16+
z.object({ field: z.string(), scalar: z.string() }),
17+
]);
18+
export const SendTransactionBodySchema = z.object({
19+
input: TransportableTransactionPayload,
20+
signature: SignatureSchema,
21+
});
22+
export const SendDelegationBodySchema = z.object({
23+
input: TransportableDelegationPayload,
24+
signature: SignatureSchema,
25+
});
26+
export const SendZkAppBodySchema = z.object({
27+
input: SendZkappInput,
28+
});
29+
export const SendableSchema = z.union([
30+
SendTransactionBodySchema,
31+
SendDelegationBodySchema,
32+
SendZkAppBodySchema,
33+
]);
34+
export const SendTransactionSchema = z.tuple([
35+
SendableSchema,
36+
z.enum(["payment", "delegation", "zkapp"]),
37+
]);
838

939
export const RpcMethod = z.enum([
1040
"mina_getTransactionCount",

apps/klesia/src/zkapp.ts

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
import { z } from "zod";
2+
3+
// Helper schemas
4+
const PublicKey = z.string();
5+
const Signature = z.string();
6+
const Field = z.string();
7+
const TokenId = z.string();
8+
const UInt32 = z.number().int();
9+
const UInt64 = z.number().int();
10+
const BooleanSchema = z.boolean();
11+
const AuthRequired = z.enum([
12+
"None",
13+
"Proof",
14+
"Signature",
15+
"Either",
16+
"Impossible",
17+
]);
18+
const Sign = z.enum(["Positive", "Negative"]);
19+
const Memo = z.string();
20+
const ZkappProof = z.string();
21+
22+
// Complex nested schemas
23+
const VerificationKeyWithHashInput = z.object({
24+
data: z.string(),
25+
hash: Field,
26+
});
27+
28+
const PermissionsInput = z.object({
29+
editState: AuthRequired,
30+
access: AuthRequired,
31+
send: AuthRequired,
32+
receive: AuthRequired,
33+
setDelegate: AuthRequired,
34+
setPermissions: AuthRequired,
35+
setVerificationKey: z.object({
36+
auth: AuthRequired,
37+
txnVersion: UInt32,
38+
}),
39+
setZkappUri: AuthRequired,
40+
editActionState: AuthRequired,
41+
setTokenSymbol: AuthRequired,
42+
incrementNonce: AuthRequired,
43+
setVotingFor: AuthRequired,
44+
setTiming: AuthRequired,
45+
});
46+
47+
const TimingInput = z.object({
48+
initialMinimumBalance: UInt64,
49+
cliffTime: UInt32,
50+
cliffAmount: UInt64,
51+
vestingPeriod: UInt32,
52+
vestingIncrement: UInt64,
53+
});
54+
55+
const AccountUpdateModificationInput = z.object({
56+
appState: z.array(Field).optional(),
57+
delegate: PublicKey.optional(),
58+
verificationKey: VerificationKeyWithHashInput.optional(),
59+
permissions: PermissionsInput.optional(),
60+
zkappUri: z.string().optional(),
61+
tokenSymbol: z.string().optional(),
62+
timing: TimingInput.optional(),
63+
votingFor: Field.optional(),
64+
});
65+
66+
const BalanceChangeInput = z.object({
67+
magnitude: UInt64,
68+
sgn: Sign,
69+
});
70+
71+
const CurrencyAmountIntervalInput = z.object({
72+
lower: UInt64,
73+
upper: UInt64,
74+
});
75+
76+
const LengthIntervalInput = z.object({
77+
lower: UInt32,
78+
upper: UInt32,
79+
});
80+
81+
const GlobalSlotSinceGenesisIntervalInput = z.object({
82+
lower: UInt32,
83+
upper: UInt32,
84+
});
85+
86+
const EpochLedgerPreconditionInput = z.object({
87+
hash: Field.optional(),
88+
totalCurrency: CurrencyAmountIntervalInput.optional(),
89+
});
90+
91+
const EpochDataPreconditionInput = z.object({
92+
ledger: EpochLedgerPreconditionInput,
93+
seed: Field.optional(),
94+
startCheckpoint: Field.optional(),
95+
lockCheckpoint: Field.optional(),
96+
epochLength: LengthIntervalInput.optional(),
97+
});
98+
99+
const NetworkPreconditionInput = z.object({
100+
snarkedLedgerHash: Field.optional(),
101+
blockchainLength: LengthIntervalInput.optional(),
102+
minWindowDensity: LengthIntervalInput.optional(),
103+
totalCurrency: CurrencyAmountIntervalInput.optional(),
104+
globalSlotSinceGenesis: GlobalSlotSinceGenesisIntervalInput.optional(),
105+
stakingEpochData: EpochDataPreconditionInput,
106+
nextEpochData: EpochDataPreconditionInput,
107+
});
108+
109+
const AccountPreconditionInput = z.object({
110+
balance: CurrencyAmountIntervalInput.optional(),
111+
nonce: LengthIntervalInput.optional(),
112+
receiptChainHash: Field.optional(),
113+
delegate: PublicKey.optional(),
114+
state: z.array(Field),
115+
actionState: Field.optional(),
116+
provedState: BooleanSchema.optional(),
117+
isNew: BooleanSchema.optional(),
118+
});
119+
120+
const PreconditionsInput = z.object({
121+
network: NetworkPreconditionInput,
122+
account: AccountPreconditionInput,
123+
validWhile: GlobalSlotSinceGenesisIntervalInput.optional(),
124+
});
125+
126+
const MayUseTokenInput = z.object({
127+
parentsOwnToken: BooleanSchema,
128+
inheritFromParent: BooleanSchema,
129+
});
130+
131+
const AuthorizationKindStructuredInput = z.object({
132+
isSigned: BooleanSchema,
133+
isProved: BooleanSchema,
134+
verificationKeyHash: Field,
135+
});
136+
137+
const AccountUpdateBodyInput = z.object({
138+
publicKey: PublicKey,
139+
tokenId: TokenId,
140+
update: AccountUpdateModificationInput,
141+
balanceChange: BalanceChangeInput,
142+
incrementNonce: BooleanSchema,
143+
events: z.array(z.array(Field)),
144+
actions: z.array(z.array(Field)),
145+
callData: Field,
146+
callDepth: z.number().int(),
147+
preconditions: PreconditionsInput,
148+
useFullCommitment: BooleanSchema,
149+
implicitAccountCreationFee: BooleanSchema,
150+
mayUseToken: MayUseTokenInput,
151+
authorizationKind: AuthorizationKindStructuredInput,
152+
});
153+
154+
const ControlInput = z.object({
155+
proof: ZkappProof.optional(),
156+
signature: Signature.optional(),
157+
});
158+
159+
const ZkappAccountUpdateInput = z.object({
160+
body: AccountUpdateBodyInput,
161+
authorization: ControlInput,
162+
});
163+
164+
const FeePayerBodyInput = z.object({
165+
publicKey: PublicKey,
166+
fee: UInt64,
167+
validUntil: UInt32.optional(),
168+
nonce: UInt32,
169+
});
170+
171+
const ZkappFeePayerInput = z.object({
172+
body: FeePayerBodyInput,
173+
authorization: Signature,
174+
});
175+
176+
const ZkappCommandInput = z.object({
177+
feePayer: ZkappFeePayerInput,
178+
accountUpdates: z.array(ZkappAccountUpdateInput),
179+
memo: Memo,
180+
});
181+
182+
export const SendZkappInput = z.object({
183+
zkappCommand: ZkappCommandInput,
184+
});

apps/klesia/tsup.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { defineConfig } from "tsup";
2-
import sharedConfig from "../../packages/shared/tsup.config";
2+
import sharedConfig from "../../packages/utils/tsup.config";
33

44
export default defineConfig({
55
...sharedConfig,

bun.lockb

0 Bytes
Binary file not shown.

packages/accounts/src/accounts/mnemonic-to-account.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { expect, it } from "bun:test";
2-
import { Test } from "@mina-js/shared";
2+
import { Test } from "@mina-js/utils";
33
import { mnemonicToAccount } from "./mnemonic-to-account";
44

55
it("matches the snapshot", () => {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { expect, it } from "bun:test";
2-
import { Test } from "@mina-js/shared";
2+
import { Test } from "@mina-js/utils";
33
import { privateKeyToAccount } from "./private-key-to-account";
44

55
it("matches default values", () => {

0 commit comments

Comments
 (0)