Browse Source

Add support for 256-bit integers in the IDL (#2260)

* Add support for 256-bit integers in the IDL

Signed-off-by: Lucas Steuernagel <lucas.tnagel@gmail.com>

* Fix lint warnings

Signed-off-by: Lucas Steuernagel <lucas.tnagel@gmail.com>
Lucas Steuernagel 2 years ago
parent
commit
0ba2195ec7

+ 2 - 0
lang/syn/src/idl/mod.rs

@@ -195,6 +195,8 @@ pub enum IdlType {
     F64,
     U128,
     I128,
+    U256,
+    I256,
     Bytes,
     String,
     PublicKey,

+ 6 - 0
ts/packages/anchor/src/coder/borsh/idl.ts

@@ -51,6 +51,12 @@ export class IdlCoder {
       case "i128": {
         return borsh.i128(fieldName);
       }
+      case "u256": {
+        return borsh.u256(fieldName);
+      }
+      case "i256": {
+        return borsh.i256(fieldName);
+      }
       case "bytes": {
         return borsh.vecU8(fieldName);
       }

+ 4 - 0
ts/packages/anchor/src/coder/common.ts

@@ -58,6 +58,10 @@ function typeSize(idl: Idl, ty: IdlType): number {
       return 16;
     case "i128":
       return 16;
+    case "u256":
+      return 32;
+    case "i256":
+      return 32;
     case "bytes":
       return 1;
     case "string":

+ 2 - 0
ts/packages/anchor/src/idl.ts

@@ -121,6 +121,8 @@ export type IdlType =
   | "f64"
   | "u128"
   | "i128"
+  | "u256"
+  | "i256"
   | "bytes"
   | "string"
   | "publicKey"

+ 1 - 1
ts/packages/anchor/src/program/namespace/types.ts

@@ -121,7 +121,7 @@ type TypeMap = {
 } & {
   [K in "u8" | "i8" | "u16" | "i16" | "u32" | "i32" | "f32" | "f64"]: number;
 } & {
-  [K in "u64" | "i64" | "u128" | "i128"]: BN;
+  [K in "u64" | "i64" | "u128" | "i128" | "u256" | "i256"]: BN;
 };
 
 export type DecodeType<T extends IdlType, Defined> = T extends keyof TypeMap

+ 45 - 0
ts/packages/anchor/tests/coder-types.spec.ts

@@ -1,5 +1,6 @@
 import * as assert from "assert";
 import { BorshCoder } from "../src";
+import BN from "bn.js";
 
 describe("coder.types", () => {
   test("Can encode and decode user-defined types", () => {
@@ -42,4 +43,48 @@ describe("coder.types", () => {
 
     assert.deepEqual(coder.types.decode("MintInfo", encoded), mintInfo);
   });
+
+  test("Can encode and decode 256-bit integers", () => {
+    const idl = {
+      version: "0.0.0",
+      name: "basic_0",
+      instructions: [
+        {
+          name: "initialize",
+          accounts: [],
+          args: [],
+        },
+      ],
+      types: [
+        {
+          name: "IntegerTest",
+          type: {
+            kind: "struct" as const,
+            fields: [
+              {
+                name: "unsigned",
+                type: "u256" as const,
+              },
+              {
+                name: "signed",
+                type: "i256" as const,
+              },
+            ],
+          },
+        },
+      ],
+    };
+
+    const testing = {
+      unsigned: new BN(2588012355),
+      signed: new BN(-93842345),
+    };
+
+    const coder = new BorshCoder(idl);
+    const encoded = coder.types.encode("IntegerTest", testing);
+    assert.strictEqual(
+      coder.types.decode("IntegerTest", encoded).toString(),
+      testing.toString()
+    );
+  });
 });