Skip to content

Commit

Permalink
fix(klesia): handle unfunded accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
mrcnk committed Sep 17, 2024
1 parent ce28b1d commit 9649399
Show file tree
Hide file tree
Showing 18 changed files with 220 additions and 76 deletions.
24 changes: 11 additions & 13 deletions apps/docs/src/pages/about.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,9 @@ MinaJS provides a set of services to interact with Mina Protocol. The services a
graph TD
classDef MinaJS fill:#C4A7E7,color:#000000
subgraph Klesia
G[Klesia RPC]:::MinaJS --> H[Mina Node]
H[Mina Node] --> G[Klesia RPC]
G[Klesia RPC]:::MinaJS --> J[Fallback Mina Node]
J[Fallback Mina Node] --> G[Klesia RPC]
end
subgraph zkApp
B[zkApp UI] --> C[MinaJS Connect]
C[MinaJS Connect]:::MinaJS --> B[zkApp UI]
B[zkApp UI] --> I1[Klesia SDK - zkApp]
I1[Klesia SDK - zkApp]:::MinaJS --> G[Klesia RPC]
I1[Klesia SDK - zkApp]:::MinaJS --> B[zkApp UI]
G[Klesia RPC]:::MinaJS --> I1[Klesia SDK - zkApp]
end
subgraph Mina Wallet
Expand All @@ -46,11 +35,20 @@ graph TD
E[Wallet UI & Connector] --> D[MinaJS Provider]
E[Wallet UI & Connector] --> F[MinaJS Account]
F[MinaJS Account]:::MinaJS --> E[Wallet UI & Connector]
I2[Klesia SDK - Wallet]:::MinaJS --> G[Klesia RPC]
G[Klesia RPC]:::MinaJS --> I2[Klesia SDK - Wallet]
E[Wallet UI & Connector] --> I2[Klesia SDK - Wallet]
I2[Klesia SDK - Wallet]:::MinaJS --> E[Wallet UI & Connector]
end
subgraph Klesia
I2[Klesia SDK - Wallet]:::MinaJS --> G[Klesia RPC]
G[Klesia RPC]:::MinaJS --> H[Mina Node]
H[Mina Node] --> G[Klesia RPC]
G[Klesia RPC]:::MinaJS --> J[Fallback Mina Node]
J[Fallback Mina Node] --> G[Klesia RPC]
G[Klesia RPC]:::MinaJS --> I2[Klesia SDK - Wallet]
C[MinaJS Connect]:::MinaJS --> G[Klesia RPC]
G[Klesia RPC] --> C[MinaJS Connect]
end
```

## Supported Chains
Expand Down
23 changes: 4 additions & 19 deletions apps/klesia/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ export const klesiaRpcRoute = api.openapi(rpcRoute, async ({ req, json }) => {
});
return json(
buildResponse({
method: RpcMethod.enum.mina_getTransactionCount,
result,
}),
200,
Expand All @@ -83,16 +82,12 @@ export const klesiaRpcRoute = api.openapi(rpcRoute, async ({ req, json }) => {
const result = await mina.getBalance({
publicKey: PublicKeySchema.parse(publicKey),
});
return json(
buildResponse({ method: RpcMethod.enum.mina_getBalance, result }),
200,
);
return json(buildResponse({ result }), 200);
})
.with({ method: RpcMethod.enum.mina_blockHash }, async () => {
if (process.env.MINA_NETWORK === "zeko_devnet") {
return json(
buildResponse({
method: RpcMethod.enum.mina_blockHash,
error: {
code: -32600,
message: "Network not supported.",
Expand All @@ -102,17 +97,11 @@ export const klesiaRpcRoute = api.openapi(rpcRoute, async ({ req, json }) => {
);
}
const result = await mina.blockHash();
return json(
buildResponse({ method: RpcMethod.enum.mina_blockHash, result }),
200,
);
return json(buildResponse({ result }), 200);
})
.with({ method: RpcMethod.enum.mina_chainId }, async () => {
const result = await mina.chainId();
return json(
buildResponse({ method: RpcMethod.enum.mina_chainId, result }),
200,
);
return json(buildResponse({ result }), 200);
})
.with(
{ method: RpcMethod.enum.mina_sendTransaction },
Expand All @@ -121,7 +110,6 @@ export const klesiaRpcRoute = api.openapi(rpcRoute, async ({ req, json }) => {
const result = await mina.sendTransaction({ signedTransaction, type });
return json(
buildResponse({
method: RpcMethod.enum.mina_sendTransaction,
result,
}),
200,
Expand All @@ -133,10 +121,7 @@ export const klesiaRpcRoute = api.openapi(rpcRoute, async ({ req, json }) => {
const result = await mina.getAccount({
publicKey: PublicKeySchema.parse(publicKey),
});
return json(
buildResponse({ method: RpcMethod.enum.mina_getAccount, result }),
200,
);
return json(buildResponse({ result }), 200);
})
.exhaustive();
});
Expand Down
73 changes: 44 additions & 29 deletions apps/klesia/src/methods/mina.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,42 @@ import { getNodeClient } from "../utils/node";

const getTransactionCount = async ({ publicKey }: { publicKey: string }) => {
const client = getNodeClient();
const { data } = await client.query(
gql`
query {
account(publicKey: $publicKey) {
nonce
try {
const { data } = await client.query(
gql`
query {
account(publicKey: $publicKey) {
nonce
}
}
}
`,
{ publicKey },
);
return data.account.nonce;
`,
{ publicKey },
);
return data.account.nonce;
} catch {
return "0";
}
};

const getBalance = async ({ publicKey }: { publicKey: string }) => {
const client = getNodeClient();
const { data } = await client.query(
gql`
query {
account(publicKey: $publicKey) {
balance {
total
try {
const { data } = await client.query(
gql`
query {
account(publicKey: $publicKey) {
balance {
total
}
}
}
}
`,
{ publicKey },
);
return data.account.balance.total;
`,
{ publicKey },
);
return data.account.balance.total;
} catch {
return "0";
}
};

const blockHash = async () => {
Expand Down Expand Up @@ -129,8 +137,9 @@ const sendTransaction = async ({

const getAccount = async ({ publicKey }: { publicKey: string }) => {
const client = getNodeClient();
const { data } = await client.query(
gql`
try {
const { data } = await client.query(
gql`
query {
account(publicKey: $publicKey) {
nonce
Expand All @@ -140,12 +149,18 @@ const getAccount = async ({ publicKey }: { publicKey: string }) => {
}
}
`,
{ publicKey },
);
return {
nonce: data.account.nonce,
balance: data.account.balance.total,
};
{ publicKey },
);
return {
nonce: data.account.nonce,
balance: data.account.balance.total,
};
} catch {
return {
nonce: "0",
balance: "0",
};
}
};

export const mina = {
Expand Down
8 changes: 3 additions & 5 deletions apps/klesia/src/utils/build-response.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import type { RpcErrorType, RpcMethodType } from "../schema";
import type { RpcErrorType } from "../schema";

export const buildResponse = ({
result,
error,
method,
}: { result?: unknown; error?: RpcErrorType; method: RpcMethodType }) => {
}: { result?: unknown; error?: RpcErrorType }) => {
if (error) {
return {
jsonrpc: "2.0",
error,
method,
};
}
return { jsonrpc: "2.0", result, method };
return { jsonrpc: "2.0", result };
};
Binary file modified bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
"private": true,
"scripts": {
"build": "turbo build",
"build:packages": "turbo build --filter=\"./packages/*\"",
"test": "turbo test",
"cleanup": "bun run --filter '*' cleanup && rimraf node_modules .turbo",
"lint": "bunx biome check .",
"format": "bunx biome check . --write --unsafe"
},
"devDependencies": {
"@biomejs/biome": "1.8.3",
"@happy-dom/global-registrator": "^14.12.3",
"@tsconfig/bun": "1.0.7",
"@types/bun": "1.1.6",
"rimraf": "^6.0.1",
Expand Down
4 changes: 2 additions & 2 deletions packages/accounts/src/accounts/mnemonic-to-account.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { expect, it } from "bun:test";
import { mnemonic } from "../test/constants";
import { Test } from "@mina-js/shared";
import { mnemonicToAccount } from "./mnemonic-to-account";

it("matches the snapshot", () => {
const mnemonicAccount = mnemonicToAccount({ mnemonic });
const mnemonicAccount = mnemonicToAccount({ mnemonic: Test.mnemonic });
expect(mnemonicAccount).toMatchSnapshot();
});
22 changes: 16 additions & 6 deletions packages/accounts/src/accounts/private-key-to-account.spec.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
import { expect, it } from "bun:test";
import { accounts } from "../test/constants";
import { Test } from "@mina-js/shared";
import { privateKeyToAccount } from "./private-key-to-account";

it("matches default values", () => {
const account = privateKeyToAccount({ privateKey: accounts[0].privateKey });
const account = privateKeyToAccount({
privateKey: Test.accounts[0].privateKey,
});
expect(account).toMatchSnapshot();
});

it("signs a message", async () => {
const account = privateKeyToAccount({ privateKey: accounts[0].privateKey });
const account = privateKeyToAccount({
privateKey: Test.accounts[0].privateKey,
});
const message = "hello world";
const signedMessage = await account.signMessage({ message });
expect(signedMessage).toMatchSnapshot();
});

it("signs a transaction", async () => {
const account = privateKeyToAccount({ privateKey: accounts[0].privateKey });
const account = privateKeyToAccount({
privateKey: Test.accounts[0].privateKey,
});
const transaction = {
nonce: 1n,
from: "B62qmWKtvNQTtUqo1LxfEEDLyWMg59cp6U7c4uDC7aqgaCEijSc3Hx5",
Expand All @@ -28,14 +34,18 @@ it("signs a transaction", async () => {
});

it("creates a nullifier", async () => {
const account = privateKeyToAccount({ privateKey: accounts[0].privateKey });
const account = privateKeyToAccount({
privateKey: Test.accounts[0].privateKey,
});
const message = [1n, 2n, 3n];
const nullifier = await account.createNullifier({ message });
expect(typeof nullifier.private.c).toBe("bigint");
});

it("signs fields", async () => {
const account = privateKeyToAccount({ privateKey: accounts[0].privateKey });
const account = privateKeyToAccount({
privateKey: Test.accounts[0].privateKey,
});
const fields = [1n, 2n, 3n];
const signedFields = await account.signFields({ fields });
expect(signedFields).toMatchSnapshot();
Expand Down
2 changes: 2 additions & 0 deletions packages/accounts/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ export { HDKey } from "@scure/bip32";
export { hex } from "@scure/base";
export { wordlist as english } from "@scure/bip39/wordlists/english";

export type { Account } from "./types";
export { generateMnemonic } from "./accounts/generate-mnemonic";
export { generatePrivateKey } from "./accounts/generate-private-key";
export { hdKeyToAccount } from "./accounts/hd-key-to-account";
export { mnemonicToAccount } from "./accounts/mnemonic-to-account";
export { privateKeyToAccount } from "./accounts/private-key-to-account";
export { toAccount } from "./accounts/to-account";
4 changes: 4 additions & 0 deletions packages/accounts/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ export type HDAccount = Simplify<
}
>;

export type Account<publicKey extends PublicKey = PublicKey> =
| JsonRpcAccount<publicKey>
| LocalAccount<publicKey>;

export type PrivateKeyAccount = Simplify<LocalAccount<"privateKey">>;

export type { HDKey };
Expand Down
5 changes: 5 additions & 0 deletions packages/connect/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,15 @@
"cleanup": "rimraf dist .turbo"
},
"dependencies": {
"@mina-js/accounts": "workspace:*",
"@mina-js/klesia-sdk": "workspace:*",
"@mina-js/providers": "workspace:*",
"ts-pattern": "^5.3.1",
"zod": "3.23.8"
},
"devDependencies": {
"@happy-dom/global-registrator": "^15.7.4"
},
"peerDependencies": {
"typescript": "^5.0.0"
}
Expand Down
15 changes: 15 additions & 0 deletions packages/connect/src/__snapshots__/client.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Bun Snapshot v1, https://goo.gl/fbAQLP

exports[`matches snapshot of local source 1`] = `
{
"getAccounts": [Function: AsyncFunction],
"getBalance": [Function: AsyncFunction],
}
`;

exports[`matches snapshot of json-rpc source 1`] = `
{
"getAccounts": [Function: AsyncFunction],
"getBalance": [Function: AsyncFunction],
}
`;
Loading

0 comments on commit 9649399

Please sign in to comment.