Unboxed-Software / solana-course

A complete course for learning Solana, including creating and transferring tokens, making NFTs, on-chain app development, and more.
https://solana.com/developers
Mozilla Public License 2.0
397 stars 134 forks source link

Which JS borsh library to use? #183

Closed nathandem closed 1 year ago

nathandem commented 1 year ago

First off, thank you this great learning resource. It helped me get into Solana more than any other!

My question: should @project-serum/borsh still be used as the default JS borsh library in the course?

I recon that the API of this library is much better (shorter and cleaner) than that of borsh - see example below.

The original Serum organization is dead at this point. The source code of the package is not publicly available. We can't expect any updates to happen in the future (e.g. to swap BN.js for the native bigint) or worse the clear list of accountable maintainer means that an exploit could more easily sneak in. So wouldn't it wiser to now suggest people to use Near's borsh npm package instead?

Alternatively, are you guys aware of another reliable/maintained borsh js client with a nice API?


For ref, the comparison of borsh vs @project-serum/borsh:

import * as sborsh from "@project-serum/borsh";
import * as nborsh from "borsh";
import BN from "bn.js";

// serialization & deserialization of a simple price account with @project-serum/borsh

const priceAccountSchema = sborsh.struct([sborsh.u64("price")]);

const sbuff = Buffer.alloc(8);
priceAccountSchema.encode({ price: new BN("123") }, sbuff);
console.log(sbuff);

const { price } = priceAccountSchema.decode(sbuff);
console.log(`price: ${price}`);

// serialization & deserialization of a simple price account with near's borsh

class PriceAccount {
  price: BN = new BN("0");

  constructor(fields: { price: BN } | undefined = undefined) {
    if (fields) {
      this.price = fields.price;
    }
  }
}

const schema = new Map([
  [
    PriceAccount,
    {
      kind: "struct",
      fields: [["price", "u64"]],
    },
  ],
]);

const nbuffer = Buffer.from(
  nborsh.serialize(schema, new PriceAccount({ price: new BN("123") }))
);
console.log(nbuffer);

const priceData = nborsh.deserialize(schema, PriceAccount, nbuffer);
console.log(`price: ${priceData.price}`);
mikemaccana commented 1 year ago

Alternatively, are you guys aware of another reliable/maintained borsh js client with a nice API?

Oh I can answer this - new web3.js uses @metaplex-foundation/umi-serializers which is byte for byte compatible with borsh by default (the author @lorisleiva just confirmed it).

mikemaccana commented 1 year ago

@jamesrp13 we can close this, we'll update the course anyway for the new web3.js