Skip to content

Commit

Permalink
Merge pull request #8 from instytutfi/feature/accounts-loader
Browse files Browse the repository at this point in the history
  • Loading branch information
mciszczon authored Nov 24, 2024
2 parents 91dae03 + 74b343c commit 9d8c348
Show file tree
Hide file tree
Showing 12 changed files with 192 additions and 17 deletions.
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ Or use our favorite package manager.

## Usage

### Hive Blog Loader
In your Astro project, edit the `/src/content/config.ts` and define any collections using the loaders
that this package provides:

In your Astro project, edit the `/src/content/config.ts`:
### Hive Blog Loader

```ts
import { defineCollection } from "astro:content";
Expand All @@ -30,11 +31,22 @@ export const collections = {
blog: defineCollection({
type: "content_layer",
loader: hiveBlogLoader("hive.coding") // Selected username
}),
accounts: defineCollection({
type: "content_layer",
loader: hiveAccountsLoader("hive.coding") // or ["acc1", "acc2"] for multiple accounts
})
};
```

For now only `hiveBlogLoader` is available, more coming soon!
## Learn more

- [Astro](https://astro.build/)
- [Content Layer API](https://astro.build/blog/content-layer-deep-dive/)

## Support

If you have any questions or need help, please join our [Discord server](https://discord.gg/3u9v7b4w).

## Contributing

Expand Down
Binary file modified bun.lockb
Binary file not shown.
20 changes: 10 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@onhive.io/astro-loader",
"version": "0.1.2",
"version": "0.2.0",
"author": "mietek.dev <[email protected]>",
"repository": {
"type": "git",
Expand All @@ -22,21 +22,21 @@
"prepare": "bunx husky"
},
"dependencies": {
"@hiveio/dhive": "^1.3.1-beta"
"@hiveio/dhive": "^1.3.2"
},
"devDependencies": {
"@eslint/js": "^9.13.0",
"@faker-js/faker": "^9.1.0",
"@eslint/js": "^9.15.0",
"@faker-js/faker": "^9.2.0",
"@types/bun": "latest",
"eslint": "^9.13.0",
"eslint": "^9.15.0",
"eslint-config-prettier": "^9.1.0",
"globals": "^15.11.0",
"husky": "^9.1.6",
"globals": "^15.12.0",
"husky": "^9.1.7",
"lint-staged": "^15.2.10",
"prettier": "^3.3.3",
"tsup": "^8.3.0",
"typescript": "^5.6.3",
"typescript-eslint": "^8.11.0"
"tsup": "^8.3.5",
"typescript": "^5.7.2",
"typescript-eslint": "^8.15.0"
},
"peerDependencies": {
"astro": "^4.16.7"
Expand Down
37 changes: 37 additions & 0 deletions src/adapters/accounts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import type { DynamicGlobalProperties, ExtendedAccount } from "@hiveio/dhive";
import { type Account } from "~/schema/accounts.ts";
import { balanceToMoney, vestsToHive } from "~/schema/utils.ts";

const adaptAccount = (
account: ExtendedAccount,
params: DynamicGlobalProperties
): Account => {
const jsonMetadata = JSON.parse(account.posting_json_metadata);

return {
id: account.id.toString(),
name: account.name,
created: new Date(account.created),
wallet: {
hive: {
liquid: balanceToMoney(account.balance as string, 3)!,
frozen: vestsToHive(account.vesting_shares as string, params)
},
hbd: {
liquid: balanceToMoney(account.hbd_balance as string, 3)!,
frozen: balanceToMoney(account.savings_hbd_balance as string, 3)!
}
},
postCount: account.post_count,
profile: {
name: jsonMetadata.profile.name,
about: jsonMetadata.profile.about,
coverImage: jsonMetadata.profile.cover_image,
profileImage: jsonMetadata.profile.profile_image,
website: jsonMetadata.profile.website,
location: jsonMetadata.profile.location
}
};
};

export { adaptAccount };
9 changes: 9 additions & 0 deletions src/api/accounts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { hive } from "~/api/common";
import type { Account } from "~/schema/accounts.ts";
import { adaptAccount } from "~/adapters/accounts.ts";

export async function getAccounts(usernames: string[]): Promise<Account[]> {
const params = await hive.database.getDynamicGlobalProperties();
const accounts = await hive.database.getAccounts(usernames);
return accounts.map((acc) => adaptAccount(acc, params));
}
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { hiveBlogLoader } from "~/loaders/blogLoader";

export type { Post } from "~/schema/posts.ts";
export type { Community } from "~/schema/community.ts";
export type { Communities } from "~/schema/communities.ts";
24 changes: 24 additions & 0 deletions src/loaders/accountsLoader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { Loader } from "astro/loaders";
import { typeToZ } from "~/schema/utils.ts";
import type { Account } from "~/schema/accounts.ts";
import { getAccounts } from "~/api/accounts.ts";

export function hiveAccountsLoader(username: string | string[]): Loader {
return {
name: "hive-accounts-loader",
load: async function (this: Loader, { store, logger }) {
logger.debug(`Fetching accounts [usernames: ${username}]`);
const data = await getAccounts(
Array.isArray(username) ? username : [username]
);
store.clear();
data.forEach((account) => {
store.set({
id: account.id.toString(),
data: { ...account }
});
});
},
schema: typeToZ<Account[]>
};
}
52 changes: 52 additions & 0 deletions src/schema/accounts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
export type Account = {
id: string;
name: string;
created: Date;
wallet: Wallet;
postCount: number;
profile: Profile;
};

export type Profile = {
name: string;
about: string;
coverImage: string;
profileImage: string;
website: string;
location: string;
};

export type Wallet = {
hive: {
liquid: Money;
frozen: Money;
};
hbd: {
liquid: Money;
frozen: Money;
};
};

export interface MoneyInterface {
currency: string;
amount: string;
precision: number;

asFloat(): number;
}

export class Money implements MoneyInterface {
currency: string;
amount: string;
precision: number;

constructor(currency: string, amount: string, precision: number) {
this.currency = currency;
this.amount = parseFloat(amount).toFixed(precision).toString();
this.precision = precision;
}

asFloat(): number {
return parseFloat(this.amount);
}
}
2 changes: 1 addition & 1 deletion src/schema/community.ts → src/schema/communities.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type Community = {
export type Communities = {
id: string;
name: string;
};
4 changes: 2 additions & 2 deletions src/schema/posts.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Community } from "~/schema/community.ts";
import type { Communities } from "~/schema/communities.ts";

export type Post = {
id: string;
Expand All @@ -7,7 +7,7 @@ export type Post = {
description: string;
created: Date;
updated?: Date;
community?: Community;
community?: Communities;
category: string;
tags: string[];
image?: string;
Expand Down
25 changes: 25 additions & 0 deletions src/schema/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
import { z } from "astro/zod";
import { Money } from "~/schema/accounts.ts";
import type { DynamicGlobalProperties } from "@hiveio/dhive";

export function typeToZ<T>() {
return z.custom<T>(() => true) as z.ZodType<T>;
}

export function balanceToMoney(
balance: string,
precision: number
): Money | null {
const [amount, currency] = balance.split(" ");
if (!amount || !currency) {
throw new Error(`Invalid balance: ${balance}`);
}
return new Money(currency, amount, precision);
}

export const vestsToHive = (
vests: string,
params: DynamicGlobalProperties
): Money => {
const [v] = vests.split(" ");
const [totalFund] = (params.total_vesting_fund_hive as string).split(" ");
const [totalShares] = (params.total_vesting_shares as string).split(" ");
const hive =
(parseFloat(v!) * parseFloat(totalFund!)) / parseFloat(totalShares!);
return new Money("HIVE", hive.toString(), 3);
};
16 changes: 16 additions & 0 deletions src/tests/api/accounts.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { describe, test, expect } from "bun:test";
import { getAccounts } from "~/api/accounts.ts";

describe("getAccounts", () => {
test("returns accounts", async () => {
const accounts = await getAccounts(["hive.coding", "mciszczon"]);
expect(accounts).toBeArray();
expect(accounts.length).toEqual(2);
const acc1 = accounts[0]!;
expect(acc1.name).toEqual("hive.coding");
const acc2 = accounts[1]!;
expect(acc2.name).toEqual("mciszczon");
expect(acc2.wallet.hive.liquid.asFloat()).toBeNumber();
expect(acc2.wallet.hive.frozen.asFloat()).toBeNumber();
});
});

0 comments on commit 9d8c348

Please sign in to comment.