Browse Source

fix: allow ts to work with account names that have multiple uppercase chars in a row (#2253)

Proph3t 2 years ago
parent
commit
d441a3e6de

+ 1 - 1
ts/packages/anchor/package.json

@@ -39,7 +39,7 @@
     "bn.js": "^5.1.2",
     "bs58": "^4.0.1",
     "buffer-layout": "^1.2.2",
-    "camelcase": "^5.3.1",
+    "camelcase": "^6.3.0",
     "cross-fetch": "^3.1.5",
     "crypto-hash": "^1.3.0",
     "eventemitter3": "^4.0.7",

+ 6 - 1
ts/packages/anchor/src/coder/borsh/accounts.ts

@@ -108,7 +108,12 @@ export class BorshAccountsCoder<A extends string = string>
    */
   public static accountDiscriminator(name: string): Buffer {
     return Buffer.from(
-      sha256.digest(`account:${camelcase(name, { pascalCase: true })}`)
+      sha256.digest(
+        `account:${camelcase(name, {
+          pascalCase: true,
+          preserveConsecutiveUppercase: true,
+        })}`
+      )
     ).slice(0, ACCOUNT_DISCRIMINATOR_SIZE);
   }
 }

+ 52 - 0
ts/packages/anchor/tests/coder-accounts.spec.ts

@@ -0,0 +1,52 @@
+import * as assert from "assert";
+import { createNodeArray } from "typescript";
+import { BorshCoder } from "../src";
+import { sha256 } from "js-sha256";
+import { ACCOUNT_DISCRIMINATOR_SIZE } from "../src/coder/borsh/accounts";
+
+describe("coder.accounts", () => {
+  test("Can encode and decode user-defined accounts, including those with consecutive capital letters", () => {
+    const idl = {
+      version: "0.0.0",
+      name: "basic_0",
+      instructions: [
+        {
+          name: "initialize",
+          accounts: [],
+          args: [],
+        },
+      ],
+      accounts: [
+        {
+          name: "MemberDAO",
+          type: {
+            kind: "struct" as const,
+            fields: [
+              {
+                name: "name",
+                type: "string" as const,
+              },
+            ],
+          },
+        },
+      ],
+    };
+    const coder = new BorshCoder(idl);
+
+    const memberDAO = {
+      name: "test",
+    };
+
+    coder.accounts.encode("MemberDAO", memberDAO).then((encoded) => {
+      // start of encoded account = account discriminator
+      assert.deepEqual(
+        encoded.subarray(0, ACCOUNT_DISCRIMINATOR_SIZE),
+        Buffer.from(sha256.digest("account:MemberDAO")).subarray(
+          0,
+          ACCOUNT_DISCRIMINATOR_SIZE
+        )
+      );
+      assert.deepEqual(coder.accounts.decode("MemberDAO", encoded), memberDAO);
+    });
+  });
+});