浏览代码

ts: Better public key error msgs (#1098)

Paul 3 年之前
父节点
当前提交
517838e494
共有 4 个文件被更改,包括 31 次插入6 次删除
  1. 1 0
      CHANGELOG.md
  2. 3 1
      ts/src/program/common.ts
  3. 22 4
      ts/src/program/namespace/instruction.ts
  4. 5 1
      ts/src/program/namespace/state.ts

+ 1 - 0
CHANGELOG.md

@@ -21,6 +21,7 @@ incremented for features.
 
 * lang: Add `ErrorCode::AccountNotInitialized` error to separate the situation when the account has the wrong owner from when it does not exist (#[1024](https://github.com/project-serum/anchor/pull/1024))
 * lang: Called instructions now log their name by default. This can be turned off with the `no-log-ix-name` flag ([#1057](https://github.com/project-serum/anchor/pull/1057))
+* ts: Add better error msgs in the ts client if something wrong (i.e. not a pubkey or a string) is passed in as an account in an instruction accounts object ([#1098](https://github.com/project-serum/anchor/pull/1098))
 
 ## [0.18.2] - 2021-11-14
 

+ 3 - 1
ts/src/program/common.ts

@@ -58,8 +58,10 @@ export function translateAddress(address: Address): PublicKey {
   if (typeof address === "string") {
     const pk = new PublicKey(address);
     return pk;
-  } else {
+  } else if (address.constructor.prototype.constructor.name === "PublicKey") {
     return address;
+  } else {
+    throw new Error("Given address is not a PublicKey nor a string.");
   }
 }
 

+ 22 - 4
ts/src/program/namespace/instruction.ts

@@ -63,7 +63,11 @@ export default class InstructionNamespaceFactory {
 
     // Utility fn for ordering the accounts for this instruction.
     ix["accounts"] = (accs: Accounts<I["accounts"][number]> | undefined) => {
-      return InstructionNamespaceFactory.accountsArray(accs, idlIx.accounts);
+      return InstructionNamespaceFactory.accountsArray(
+        accs,
+        idlIx.accounts,
+        idlIx.name
+      );
     };
 
     return ix;
@@ -71,7 +75,8 @@ export default class InstructionNamespaceFactory {
 
   public static accountsArray(
     ctx: Accounts | undefined,
-    accounts: readonly IdlAccountItem[]
+    accounts: readonly IdlAccountItem[],
+    ixName?: string
   ): AccountMeta[] {
     if (!ctx) {
       return [];
@@ -86,12 +91,25 @@ export default class InstructionNamespaceFactory {
           const rpcAccs = ctx[acc.name] as Accounts;
           return InstructionNamespaceFactory.accountsArray(
             rpcAccs,
-            (acc as IdlAccounts).accounts
+            (acc as IdlAccounts).accounts,
+            ixName
           ).flat();
         } else {
           const account: IdlAccount = acc as IdlAccount;
+          let pubkey;
+          try {
+            pubkey = translateAddress(ctx[acc.name] as Address);
+          } catch (err) {
+            throw new Error(
+              `Wrong input type for account "${
+                acc.name
+              }" in the instruction accounts object${
+                ixName !== undefined ? ' for instruction "' + ixName + '"' : ""
+              }. Expected PublicKey or string.`
+            );
+          }
           return {
-            pubkey: translateAddress(ctx[acc.name] as Address),
+            pubkey,
             isWritable: account.isMut,
             isSigner: account.isSigner,
           };

+ 5 - 1
ts/src/program/namespace/state.ts

@@ -116,7 +116,11 @@ export class StateClient<IDL extends Idl> {
           ixItem["accounts"] = (accounts) => {
             const keys = stateInstructionKeys(programId, provider, m, accounts);
             return keys.concat(
-              InstructionNamespaceFactory.accountsArray(accounts, m.accounts)
+              InstructionNamespaceFactory.accountsArray(
+                accounts,
+                m.accounts,
+                m.name
+              )
             );
           };
           // Build transaction method.