Skip to content

Commit

Permalink
feat(minajs): improve tx send and add value utils
Browse files Browse the repository at this point in the history
  • Loading branch information
mrcnk committed Oct 9, 2024
1 parent 8107d7d commit 5eea25e
Show file tree
Hide file tree
Showing 37 changed files with 505 additions and 30 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ jobs:
- run: bun i --no-save
- run: bun run build
- run: bun run test
- run: bunx pkg-pr-new publish './packages/klesia-sdk' './packages/accounts' './packages/connect' './packages/providers' './packages/shared'
- run: bunx pkg-pr-new publish './packages/klesia-sdk' './packages/accounts' './packages/connect' './packages/providers' './packages/utils'
2 changes: 1 addition & 1 deletion apps/klesia/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"dependencies": {
"@hono/node-server": "^1.12.2",
"@hono/zod-openapi": "^0.16.0",
"@mina-js/shared": "workspace:*",
"@mina-js/utils": "workspace:*",
"@urql/core": "^5.0.6",
"bigint-quantile": "^0.0.2",
"dayjs": "^1.11.13",
Expand Down
2 changes: 1 addition & 1 deletion apps/klesia/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import "dotenv/config";
import { getConnInfo } from "@hono/node-server/conninfo";
import { OpenAPIHono, createRoute } from "@hono/zod-openapi";
import { PublicKeySchema } from "@mina-js/shared";
import { PublicKeySchema } from "@mina-js/utils";
import { rateLimiter } from "hono-rate-limiter";
import { cors } from "hono/cors";
import { logger } from "hono/logger";
Expand Down
17 changes: 11 additions & 6 deletions apps/klesia/src/methods/mina.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { SignedTransactionSchema } from "@mina-js/shared";
import { gql } from "@urql/core";
import { calculateQuantile } from "bigint-quantile";
import { match } from "ts-pattern";
import {
SendDelegationBodySchema,
SendTransactionBodySchema,
SendZkAppBodySchema,
} from "../schema";
import { getNodeClient } from "../utils/node";

export const PRIORITY = {
Expand Down Expand Up @@ -91,8 +95,8 @@ const sendTransaction = async ({
const client = getNodeClient();
return match(type)
.with("payment", async () => {
const { signature, data: input } =
SignedTransactionSchema.parse(signedTransaction);
const { signature, input } =
SendTransactionBodySchema.parse(signedTransaction);
const { data } = await client.mutation(
gql`
mutation {
Expand All @@ -108,8 +112,8 @@ const sendTransaction = async ({
return data.sendPayment.payment.hash;
})
.with("delegation", async () => {
const { signature, data: input } =
SignedTransactionSchema.parse(signedTransaction);
const { signature, input } =
SendDelegationBodySchema.parse(signedTransaction);
const { data } = await client.mutation(
gql`
mutation {
Expand All @@ -125,6 +129,7 @@ const sendTransaction = async ({
return data.sendDelegation.delegation.hash;
})
.with("zkapp", async () => {
const { input } = SendZkAppBodySchema.parse(signedTransaction);
const { data } = await client.mutation(
gql`
mutation {
Expand All @@ -135,7 +140,7 @@ const sendTransaction = async ({
}
}
`,
{ input: signedTransaction },
{ input },
);
return data.sendZkapp.zkapp.hash;
})
Expand Down
34 changes: 32 additions & 2 deletions apps/klesia/src/schema.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,40 @@
import { PublicKeySchema } from "@mina-js/shared";
import {
PublicKeySchema,
TransportableDelegationPayload,
TransportableTransactionPayload,
} from "@mina-js/utils";
import { z } from "zod";
import { SendZkappInput } from "./zkapp";

export const KlesiaNetwork = z.enum(["devnet", "mainnet", "zeko_devnet"]);
export const PublicKeyParamsSchema = z.array(PublicKeySchema).length(1);
export const EmptyParamsSchema = z.array(z.string()).length(0).optional();
export const SendTransactionSchema = z.array(z.any(), z.string()).length(2);
export const SignatureSchema = z.union([
z.object({
rawSignature: z.string(),
}),
z.object({ field: z.string(), scalar: z.string() }),
]);
export const SendTransactionBodySchema = z.object({
input: TransportableTransactionPayload,
signature: SignatureSchema,
});
export const SendDelegationBodySchema = z.object({
input: TransportableDelegationPayload,
signature: SignatureSchema,
});
export const SendZkAppBodySchema = z.object({
input: SendZkappInput,
});
export const SendableSchema = z.union([
SendTransactionBodySchema,
SendDelegationBodySchema,
SendZkAppBodySchema,
]);
export const SendTransactionSchema = z.tuple([
SendableSchema,
z.enum(["payment", "delegation", "zkapp"]),
]);

export const RpcMethod = z.enum([
"mina_getTransactionCount",
Expand Down
184 changes: 184 additions & 0 deletions apps/klesia/src/zkapp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
import { z } from "zod";

// Helper schemas
const PublicKey = z.string();
const Signature = z.string();
const Field = z.string();
const TokenId = z.string();
const UInt32 = z.number().int();
const UInt64 = z.number().int();
const BooleanSchema = z.boolean();
const AuthRequired = z.enum([
"None",
"Proof",
"Signature",
"Either",
"Impossible",
]);
const Sign = z.enum(["Positive", "Negative"]);
const Memo = z.string();
const ZkappProof = z.string();

// Complex nested schemas
const VerificationKeyWithHashInput = z.object({
data: z.string(),
hash: Field,
});

const PermissionsInput = z.object({
editState: AuthRequired,
access: AuthRequired,
send: AuthRequired,
receive: AuthRequired,
setDelegate: AuthRequired,
setPermissions: AuthRequired,
setVerificationKey: z.object({
auth: AuthRequired,
txnVersion: UInt32,
}),
setZkappUri: AuthRequired,
editActionState: AuthRequired,
setTokenSymbol: AuthRequired,
incrementNonce: AuthRequired,
setVotingFor: AuthRequired,
setTiming: AuthRequired,
});

const TimingInput = z.object({
initialMinimumBalance: UInt64,
cliffTime: UInt32,
cliffAmount: UInt64,
vestingPeriod: UInt32,
vestingIncrement: UInt64,
});

const AccountUpdateModificationInput = z.object({
appState: z.array(Field).optional(),
delegate: PublicKey.optional(),
verificationKey: VerificationKeyWithHashInput.optional(),
permissions: PermissionsInput.optional(),
zkappUri: z.string().optional(),
tokenSymbol: z.string().optional(),
timing: TimingInput.optional(),
votingFor: Field.optional(),
});

const BalanceChangeInput = z.object({
magnitude: UInt64,
sgn: Sign,
});

const CurrencyAmountIntervalInput = z.object({
lower: UInt64,
upper: UInt64,
});

const LengthIntervalInput = z.object({
lower: UInt32,
upper: UInt32,
});

const GlobalSlotSinceGenesisIntervalInput = z.object({
lower: UInt32,
upper: UInt32,
});

const EpochLedgerPreconditionInput = z.object({
hash: Field.optional(),
totalCurrency: CurrencyAmountIntervalInput.optional(),
});

const EpochDataPreconditionInput = z.object({
ledger: EpochLedgerPreconditionInput,
seed: Field.optional(),
startCheckpoint: Field.optional(),
lockCheckpoint: Field.optional(),
epochLength: LengthIntervalInput.optional(),
});

const NetworkPreconditionInput = z.object({
snarkedLedgerHash: Field.optional(),
blockchainLength: LengthIntervalInput.optional(),
minWindowDensity: LengthIntervalInput.optional(),
totalCurrency: CurrencyAmountIntervalInput.optional(),
globalSlotSinceGenesis: GlobalSlotSinceGenesisIntervalInput.optional(),
stakingEpochData: EpochDataPreconditionInput,
nextEpochData: EpochDataPreconditionInput,
});

const AccountPreconditionInput = z.object({
balance: CurrencyAmountIntervalInput.optional(),
nonce: LengthIntervalInput.optional(),
receiptChainHash: Field.optional(),
delegate: PublicKey.optional(),
state: z.array(Field),
actionState: Field.optional(),
provedState: BooleanSchema.optional(),
isNew: BooleanSchema.optional(),
});

const PreconditionsInput = z.object({
network: NetworkPreconditionInput,
account: AccountPreconditionInput,
validWhile: GlobalSlotSinceGenesisIntervalInput.optional(),
});

const MayUseTokenInput = z.object({
parentsOwnToken: BooleanSchema,
inheritFromParent: BooleanSchema,
});

const AuthorizationKindStructuredInput = z.object({
isSigned: BooleanSchema,
isProved: BooleanSchema,
verificationKeyHash: Field,
});

const AccountUpdateBodyInput = z.object({
publicKey: PublicKey,
tokenId: TokenId,
update: AccountUpdateModificationInput,
balanceChange: BalanceChangeInput,
incrementNonce: BooleanSchema,
events: z.array(z.array(Field)),
actions: z.array(z.array(Field)),
callData: Field,
callDepth: z.number().int(),
preconditions: PreconditionsInput,
useFullCommitment: BooleanSchema,
implicitAccountCreationFee: BooleanSchema,
mayUseToken: MayUseTokenInput,
authorizationKind: AuthorizationKindStructuredInput,
});

const ControlInput = z.object({
proof: ZkappProof.optional(),
signature: Signature.optional(),
});

const ZkappAccountUpdateInput = z.object({
body: AccountUpdateBodyInput,
authorization: ControlInput,
});

const FeePayerBodyInput = z.object({
publicKey: PublicKey,
fee: UInt64,
validUntil: UInt32.optional(),
nonce: UInt32,
});

const ZkappFeePayerInput = z.object({
body: FeePayerBodyInput,
authorization: Signature,
});

const ZkappCommandInput = z.object({
feePayer: ZkappFeePayerInput,
accountUpdates: z.array(ZkappAccountUpdateInput),
memo: Memo,
});

export const SendZkappInput = z.object({
zkappCommand: ZkappCommandInput,
});
2 changes: 1 addition & 1 deletion apps/klesia/tsup.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { defineConfig } from "tsup";
import sharedConfig from "../../packages/shared/tsup.config";
import sharedConfig from "../../packages/utils/tsup.config";

export default defineConfig({
...sharedConfig,
Expand Down
Binary file modified bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion packages/accounts/src/accounts/mnemonic-to-account.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect, it } from "bun:test";
import { Test } from "@mina-js/shared";
import { Test } from "@mina-js/utils";
import { mnemonicToAccount } from "./mnemonic-to-account";

it("matches the snapshot", () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect, it } from "bun:test";
import { Test } from "@mina-js/shared";
import { Test } from "@mina-js/utils";
import { privateKeyToAccount } from "./private-key-to-account";

it("matches default values", () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/accounts/src/accounts/private-key-to-account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
SignedFieldsSchema,
SignedMessageSchema,
SignedTransactionSchema,
} from "@mina-js/shared";
} from "@mina-js/utils";
import MinaSigner from "mina-signer";
import type { PrivateKeyAccount } from "../types";
import { toAccount } from "./to-account";
Expand Down
2 changes: 1 addition & 1 deletion packages/accounts/src/accounts/to-account.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type PublicKey, PublicKeySchema } from "@mina-js/shared";
import { type PublicKey, PublicKeySchema } from "@mina-js/utils";
import type {
AccountSource,
CustomSource,
Expand Down
2 changes: 1 addition & 1 deletion packages/accounts/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type {
SignedFields,
SignedMessage,
SignedTransaction,
} from "@mina-js/shared";
} from "@mina-js/utils";
import type { HDKey } from "@scure/bip32";
import type { Simplify } from "type-fest";
import type { z } from "zod";
Expand Down
2 changes: 1 addition & 1 deletion packages/accounts/src/validation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FieldSchema, TransactionPayload } from "@mina-js/shared";
import { FieldSchema, TransactionPayload } from "@mina-js/utils";
import { z } from "zod";

export const SignFieldsParamsSchema = z
Expand Down
2 changes: 1 addition & 1 deletion packages/accounts/tsup.config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import sharedConfig from "../shared/tsup.config";
import sharedConfig from "../utils/tsup.config";

export default sharedConfig;
2 changes: 1 addition & 1 deletion packages/connect/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"cleanup": "rimraf dist .turbo"
},
"dependencies": {
"@mina-js/shared": "workspace:*",
"@mina-js/utils": "workspace:*",
"@mina-js/accounts": "workspace:*",
"@mina-js/klesia-sdk": "workspace:*",
"@mina-js/providers": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/connect/src/client.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, it } from "bun:test";
import { privateKeyToAccount, toAccount } from "@mina-js/accounts";
import { Test } from "@mina-js/shared";
import { Test } from "@mina-js/utils";
import { createWalletClient } from "./client";

const PUBLIC_KEY = "B62qmWKtvNQTtUqo1LxfEEDLyWMg59cp6U7c4uDC7aqgaCEijSc3Hx5";
Expand Down
2 changes: 1 addition & 1 deletion packages/connect/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type {
SignTransaction,
} from "@mina-js/accounts";
import { createClient } from "@mina-js/klesia-sdk";
import type { PartiallyFormedTransactionProperties } from "@mina-js/shared";
import type { PartiallyFormedTransactionProperties } from "@mina-js/utils";
import { match } from "ts-pattern";
import { createStore } from "./store";

Expand Down
2 changes: 1 addition & 1 deletion packages/connect/tsup.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { defineConfig } from "tsup";
import sharedConfig from "../shared/tsup.config";
import sharedConfig from "../utils/tsup.config";

export default defineConfig({
...sharedConfig,
Expand Down
2 changes: 1 addition & 1 deletion packages/klesia-sdk/tsup.config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import sharedConfig from "../shared/tsup.config";
import sharedConfig from "../utils/tsup.config";

export default sharedConfig;
Loading

0 comments on commit 5eea25e

Please sign in to comment.