From b830ebb70502ad3ecc6a8ff3f7d98a0840f67bf4 Mon Sep 17 00:00:00 2001 From: Ariel Date: Thu, 6 Oct 2022 21:40:56 +0200 Subject: [PATCH] use spl-governance serializers (#9) * use spl-governance serializers * fix demo app setting GENERATE_SOURCEMAP=false due to https://github.com/facebook/create-react-app/pull/11752 also using react-app-rewired due to https://github.com/facebook/create-react-app/pull/12021 and https://github.com/solana-labs/oyster/issues/538 --- .../config-overrides.js | 16 +++ packages/react-app-example-daos/package.json | 10 +- packages/solana-dao-sdk/package.json | 2 +- packages/solana-dao-sdk/src/index.test.ts | 1 - packages/solana-dao-sdk/src/index.ts | 6 - .../src/internal/governance/model.ts | 29 ---- .../src/internal/serialization.ts | 132 +----------------- yarn.lock | 50 ++++++- 8 files changed, 74 insertions(+), 172 deletions(-) create mode 100644 packages/react-app-example-daos/config-overrides.js delete mode 100644 packages/solana-dao-sdk/src/internal/governance/model.ts diff --git a/packages/react-app-example-daos/config-overrides.js b/packages/react-app-example-daos/config-overrides.js new file mode 100644 index 0000000..5b42727 --- /dev/null +++ b/packages/react-app-example-daos/config-overrides.js @@ -0,0 +1,16 @@ +// config-overrides.js +module.exports = { + webpack: function (config, env) { + config.module.rules = config.module.rules.map((rule) => { + if (rule.oneOf instanceof Array) { + rule.oneOf[rule.oneOf.length - 1].exclude = [ + /\.(js|mjs|jsx|cjs|ts|tsx)$/, + /\.html$/, + /\.json$/, + ]; + } + return rule; + }); + return config; + }, +}; \ No newline at end of file diff --git a/packages/react-app-example-daos/package.json b/packages/react-app-example-daos/package.json index c713875..617578b 100644 --- a/packages/react-app-example-daos/package.json +++ b/packages/react-app-example-daos/package.json @@ -26,10 +26,9 @@ "web-vitals": "^2.1.4" }, "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test", - "eject": "react-scripts eject" + "start": "GENERATE_SOURCEMAP=false react-app-rewired start", + "build": "react-app-rewired build", + "test": "react-app-rewired test" }, "eslintConfig": { "extends": [ @@ -48,5 +47,8 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "react-app-rewired": "^2.2.1" } } diff --git a/packages/solana-dao-sdk/package.json b/packages/solana-dao-sdk/package.json index 2814f9d..56aae4c 100644 --- a/packages/solana-dao-sdk/package.json +++ b/packages/solana-dao-sdk/package.json @@ -33,7 +33,7 @@ "homepage": "https://github.com/nation-io/sdk#readme", "dependencies": { "@solana/web3.js": "^1.62.0", - "borsh": "^0.7.0" + "@solana/spl-governance": "^0.3.14" }, "devDependencies": { "@open-wc/building-rollup": "^2.0.2", diff --git a/packages/solana-dao-sdk/src/index.test.ts b/packages/solana-dao-sdk/src/index.test.ts index 7d0ab00..618068e 100644 --- a/packages/solana-dao-sdk/src/index.test.ts +++ b/packages/solana-dao-sdk/src/index.test.ts @@ -1,6 +1,5 @@ import { SolanaDao } from "./index"; import { PublicKey } from "@solana/web3.js"; -import { BN } from "bn.js"; describe("SolanaDao", () => { test("calling getDao return a value", async () => { diff --git a/packages/solana-dao-sdk/src/index.ts b/packages/solana-dao-sdk/src/index.ts index e53c6e7..eed818d 100644 --- a/packages/solana-dao-sdk/src/index.ts +++ b/packages/solana-dao-sdk/src/index.ts @@ -1,5 +1,4 @@ import { Connection, clusterApiUrl, PublicKey } from '@solana/web3.js'; -import { AccountType } from './internal/governance/model'; import { RealmV2Serializer } from './internal/serialization'; import BN from 'bn.js'; @@ -37,11 +36,6 @@ export class SolanaDao { return null; } const buffer: Buffer = accountInfo.data; - // first field must be the account type - const accountType = buffer[0]; - if (accountType !== AccountType.RealmV2.valueOf()) { - return null; - } const realm = this.serializer.deserialize(buffer); return { diff --git a/packages/solana-dao-sdk/src/internal/governance/model.ts b/packages/solana-dao-sdk/src/internal/governance/model.ts deleted file mode 100644 index afcd6c1..0000000 --- a/packages/solana-dao-sdk/src/internal/governance/model.ts +++ /dev/null @@ -1,29 +0,0 @@ -/** - * These types are literally a from the ones in the smart contract - * https://github.com/solana-labs/solana-program-library/blob/6dfc68db1370c65076e8a860db74fd6483161d8a/governance/program/src/state/enums.rs#L7 - */ -export enum AccountType { - Uninitialized = 0, - RealmV1 = 1, - TokenOwnerRecordV1 = 2, - GovernanceV1 = 3, - ProgramGovernanceV1 = 4, - ProposalV1 = 5, - SignatoryRecordV1 = 6, - VoteRecordV1 = 7, - ProposalInstructionV1 = 8, - MintGovernanceV1 = 9, - TokenGovernanceV1 = 10, - RealmConfig = 11, - VoteRecordV2 = 12, - ProposalTransactionV2 = 13, - ProposalV2 = 14, - ProgramMetadata = 15, - RealmV2 = 16, - TokenOwnerRecordV2 = 17, - GovernanceV2 = 18, - ProgramGovernanceV2 = 19, - MintGovernanceV2 = 20, - TokenGovernanceV2 = 21, - SignatoryRecordV2 = 22, - } \ No newline at end of file diff --git a/packages/solana-dao-sdk/src/internal/serialization.ts b/packages/solana-dao-sdk/src/internal/serialization.ts index 1fdd1d3..7e9a374 100644 --- a/packages/solana-dao-sdk/src/internal/serialization.ts +++ b/packages/solana-dao-sdk/src/internal/serialization.ts @@ -1,135 +1,9 @@ -import { PublicKey } from '@solana/web3.js'; -import { BinaryReader, BinaryWriter, deserialize, Schema } from 'borsh'; -import { AccountType } from './governance/model'; -import BN from 'bn.js'; - -export const extendBorsh = () => { - (BinaryReader.prototype as any).readPubkey = function () { - const reader = this as unknown as BinaryReader; - const array = reader.readFixedArray(32); - const pk = new PublicKey(array); - return pk; - }; - - (BinaryWriter.prototype as any).writePubkey = function (value: PublicKey) { - const writer = this as unknown as BinaryWriter; - writer.writeFixedArray(value.toBuffer()); - }; -}; - -extendBorsh(); - -// TODO move to some constants.ts -export const SYSTEM_PROGRAM_ID = new PublicKey( - '11111111111111111111111111111111', - ); - -class RealmConfig { - accountType = AccountType.RealmConfig; - realm: PublicKey; - minCommunityTokensToCreateGovernance: BN; - councilMint?: PublicKey; - - constructor(args: { - realm: PublicKey; - minCommunityTokensToCreateGovernance: BN; - councilMint?: PublicKey; - }) { - this.realm = args.realm; - this.minCommunityTokensToCreateGovernance = args.minCommunityTokensToCreateGovernance; - this.councilMint = args.councilMint; - } -} - -class Realm { - accountType = AccountType.RealmV2; - communityMint: PublicKey; - config: RealmConfig; - reserved: Uint8Array; - votingProposalCount: number; - authority?: PublicKey; - name: string; - - constructor(args: { - communityMint: PublicKey; - reserved: Uint8Array; - config: RealmConfig; - votingProposalCount: number; - authority?: PublicKey; - name: string; - }) { - this.communityMint = args.communityMint; - this.config = args.config; - this.reserved = args.reserved; - this.votingProposalCount = args.votingProposalCount; - this.authority = args.authority; - this.name = args.name; - } -} - -enum MintMaxVoteWeightSourceType { - SupplyFraction = 0, - Absolute = 1, -} - -class MintMaxVoteWeightSource { - type = MintMaxVoteWeightSourceType.SupplyFraction; - value: BN; - - constructor(args: { value: BN }) { - this.value = args.value; - } -} - -const realmV2BorshSchema: Schema = new Map( - [ - [ - RealmConfig, - { - kind: 'struct', - fields: [ - ['legacy1', 'u8'], - ['legacy2', 'u8'], - ['reserved', [6]], - ['minCommunityTokensToCreateGovernance', 'u64'], - ['communityMintMaxVoteWeightSource', MintMaxVoteWeightSource], - ['councilMint', { kind: 'option', type: 'pubkey' }], - ], - }, - ], - [ - Realm, - { - kind: 'struct', - fields: [ - ['accountType', 'u8'], - ['communityMint', 'pubkey'], - ['config', RealmConfig], - ['reserved', [6]], - ['votingProposalCount', 'u16'], - ['authority', { kind: 'option', type: 'pubkey' }], - ['name', 'string'], - ['reserved_v2', [128]], - ], - }, - ], - [ - MintMaxVoteWeightSource, - { - kind: 'struct', - fields: [ - ['type', 'u8'], - ['value', 'u64'], - ], - }, - ] - ] -) +import { deserializeBorsh, getGovernanceSchemaForAccount, GovernanceAccountType, Realm } from '@solana/spl-governance'; export class RealmV2Serializer { - deserialize(buffer: Buffer) { + deserialize(buffer: Buffer): Realm { try { - return deserialize(realmV2BorshSchema, Realm, buffer); + return deserializeBorsh(getGovernanceSchemaForAccount(GovernanceAccountType.RealmV2), Realm, buffer) as Realm; } catch (e) { throw e; } diff --git a/yarn.lock b/yarn.lock index 92e432d..e2f2e27 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3801,7 +3801,19 @@ dependencies: buffer "~6.0.3" -"@solana/web3.js@^1.62.0": +"@solana/spl-governance@^0.3.14": + version "0.3.14" + resolved "https://registry.yarnpkg.com/@solana/spl-governance/-/spl-governance-0.3.14.tgz#4bd2357702ca03e7058e79959f52b8c0eafa40b3" + integrity sha512-wht51cpEgr+Fa6G8B75l+HkRbhyUrOjObFpYkUxfHiS8a+U/3p3gNzaOhxlrSMlLa++TTPuGNc+IiSpKEa8x0g== + dependencies: + "@solana/web3.js" "^1.22.0" + bignumber.js "^9.0.1" + bn.js "^5.1.3" + borsh "^0.3.1" + bs58 "^4.0.1" + superstruct "^0.15.2" + +"@solana/web3.js@^1.22.0", "@solana/web3.js@^1.62.0": version "1.63.1" resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.63.1.tgz#88a19a17f5f4aada73ad70a94044c1067cab2b4d" integrity sha512-wgEdGVK5FTS2zENxbcGSvKpGZ0jDS6BUdGu8Gn6ns0CzgJkK83u4ip3THSnBPEQ5i/jrqukg998BwV1H67+qiQ== @@ -4045,6 +4057,13 @@ dependencies: "@babel/types" "^7.3.0" +"@types/bn.js@^4.11.5": + version "4.11.6" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" + integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== + dependencies: + "@types/node" "*" + "@types/bn.js@^5.1.1": version "5.1.1" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682" @@ -5320,6 +5339,11 @@ bigint-buffer@^1.1.5: dependencies: bindings "^1.3.0" +bignumber.js@^9.0.1: + version "9.1.0" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.0.tgz#8d340146107fe3a6cb8d40699643c302e8773b62" + integrity sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A== + bin-links@^3.0.0: version "3.0.3" resolved "https://registry.npmjs.org/bin-links/-/bin-links-3.0.3.tgz" @@ -5358,7 +5382,7 @@ bluebird@^3.5.5: resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -bn.js@^5.0.0, bn.js@^5.2.0: +bn.js@^5.0.0, bn.js@^5.1.3, bn.js@^5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== @@ -5396,6 +5420,16 @@ boolbase@^1.0.0, boolbase@~1.0.0: resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== +borsh@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.3.1.tgz#c31c3a149610e37913deada80e89073fb15cf55b" + integrity sha512-gJoSTnhwLxN/i2+15Y7uprU8h3CKI+Co4YKZKvrGYUy0FwHWM20x5Sx7eU8Xv4HQqV+7rb4r3P7K1cBIQe3q8A== + dependencies: + "@types/bn.js" "^4.11.5" + bn.js "^5.0.0" + bs58 "^4.0.0" + text-encoding-utf-8 "^1.0.2" + borsh@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.7.0.tgz#6e9560d719d86d90dc589bca60ffc8a6c51fec2a" @@ -12004,6 +12038,13 @@ react-app-polyfill@^3.0.0: regenerator-runtime "^0.13.9" whatwg-fetch "^3.6.2" +react-app-rewired@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/react-app-rewired/-/react-app-rewired-2.2.1.tgz#84901ee1e3f26add0377ebec0b41bcdfce9fc211" + integrity sha512-uFQWTErXeLDrMzOJHKp0h8P1z0LV9HzPGsJ6adOtGlA/B9WfT6Shh4j2tLTTGlXOfiVx6w6iWpp7SOC5pvk+gA== + dependencies: + semver "^5.6.0" + react-dev-utils@^12.0.1: version "12.0.1" resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-12.0.1.tgz#ba92edb4a1f379bd46ccd6bcd4e7bc398df33e73" @@ -13186,6 +13227,11 @@ superstruct@^0.14.2: resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.14.2.tgz#0dbcdf3d83676588828f1cf5ed35cda02f59025b" integrity sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ== +superstruct@^0.15.2: + version "0.15.5" + resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.15.5.tgz#0f0a8d3ce31313f0d84c6096cd4fa1bfdedc9dab" + integrity sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ== + supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz"