Does the JS SDK support BigInt or not?

So the Algorand docs say that ASA IDs are unsigned 64-bit integers. But if I try to pass a BigInt to the makeAssetTransferTxnWithSuggestedParamsFromObject() function, I get the error “Asset index must be a positive number and smaller than 2^53-1”. If I just turn it into an Int instead, everything is fine.

The asset IDs returned from something like the Algoexplorer Indexer appear to be integers as well:

{
  "asset": {
    "created-at-round": 17183022,
    "deleted": false,
    "index": 393730434,  // <------
    "params": { ... }
  },
  "current-round": 18381128
}

When doing something like accountInformation() for a given wallet, I’ve got setIntDecoding(algosdk.IntDecoding.BIGINT) chained on there but everything is still returning an Int. Confirming with typeof accountInfo.assets[0]['asset-id'], for example, returns number.

Is this not a problem if an ASA ID is ever larger than 2.1 billion? Are they just assigned in ascending numerical order, in which case it won’t be a problem for a (little) while?

I’m jumping through all kinds of hoops to get GraphQL to try and support BigInt, but if it turns out they’re all just fine as Int's then I’ll undo all that junk! :slight_smile:

Thanks for any help!

Can you try something like the following (note the let totalIssuance = BigInt(‘18446744073709551615’):wink:

let params = await client.getTransactionParams().do();
params.fee = 1000;
params.flatFee = true;
let note = undefined;
// Asset creation specific parameters
// The following parameters are asset specific
// Throughout the example these will be re-used. 
// We will also change the manager later in the example
let addr = creatorAccount.addr;
// Whether user accounts will need to be unfrozen before transacting    
let defaultFrozen = false;
// integer number of decimals for asset unit calculation
let decimals = 0;
// total number of this asset available for circulation   
let totalIssuance = BigInt('18446744073709551615');
// Used to display asset units to user    
let unitName = "STOK";
// Friendly name of the asset    
let assetName = "stok";
// Optional string pointing to a URL relating to the asset
let assetURL = "http://someurl";
// Optional hash commitment of some sort relating to the asset. 32 character length.
let assetMetadataHash = undefined;

let manager = creatorAccount.addr;
// Specified address is considered the asset reserve
// (it has no special privileges, this is only informational)
let reserve = creatorAccount.addr;
// Specified address can freeze or unfreeze user asset holdings 
let freeze = creatorAccount.addr;
// Specified address can revoke user asset holdings and send 
// them to other addresses    
let clawback = creatorAccount.addr;

// signing and sending "txn" allows "addr" to create an asset
let txn = algosdk.makeAssetCreateTxnWithSuggestedParams(addr, note,
        totalIssuance, decimals, defaultFrozen, manager, reserve, freeze,
    clawback, unitName, assetName, assetURL, assetMetadataHash, params);

Looks like that created the transaction okay:

Transaction {
  name: 'Transaction',
  tag: <Buffer 54 58>,
  from: {
    publicKey: Uint8Array(32) [
      190, 193, 233,  33, 237, 144,  34, 252,
       49, 192, 150,  84,  37,  40,  85, 246,
       67,  32, 141, 204, 139, 205, 205, 174,
       53, 153, 154,  16, 242,  35,  90, 181
    ],
    checksum: Uint8Array(4) [ 93, 80, 158, 27 ]
  },
  note: Uint8Array(0) [],
  assetTotal: 18446744073709551615n,
  assetDecimals: 0,
  assetDefaultFrozen: false,
  assetUnitName: 'STOK',
  assetName: 'stok',
  assetURL: 'http://someurl',
  assetManager: {
    publicKey: Uint8Array(32) [
      190, 193, 233,  33, 237, 144,  34, 252,
       49, 192, 150,  84,  37,  40,  85, 246,
       67,  32, 141, 204, 139, 205, 205, 174,
       53, 153, 154,  16, 242,  35,  90, 181
    ],
    checksum: Uint8Array(4) [ 93, 80, 158, 27 ]
  },
  assetReserve: {
    publicKey: Uint8Array(32) [
      190, 193, 233,  33, 237, 144,  34, 252,
       49, 192, 150,  84,  37,  40,  85, 246,
       67,  32, 141, 204, 139, 205, 205, 174,
       53, 153, 154,  16, 242,  35,  90, 181
    ],
    checksum: Uint8Array(4) [ 93, 80, 158, 27 ]
  },
  assetFreeze: {
    publicKey: Uint8Array(32) [
      190, 193, 233,  33, 237, 144,  34, 252,
       49, 192, 150,  84,  37,  40,  85, 246,
       67,  32, 141, 204, 139, 205, 205, 174,
       53, 153, 154,  16, 242,  35,  90, 181
    ],
    checksum: Uint8Array(4) [ 93, 80, 158, 27 ]
  },
  assetClawback: {
    publicKey: Uint8Array(32) [
      190, 193, 233,  33, 237, 144,  34, 252,
       49, 192, 150,  84,  37,  40,  85, 246,
       67,  32, 141, 204, 139, 205, 205, 174,
       53, 153, 154,  16, 242,  35,  90, 181
    ],
    checksum: Uint8Array(4) [ 93, 80, 158, 27 ]
  },
  type: 'acfg',
  flatFee: true,
  genesisHash: <Buffer c0 61 c4 d8 fc 1d bd de d2 d7 60 4b e4 56 8e 3f 6d 04 19 87 ac 37 bd e4 b6 20 b5 ab 39 24 8a df>,
  fee: 1000,
  firstRound: 18437240,
  lastRound: 18438240,
  genesisID: 'mainnet-v1.0',
  appArgs: [],
  lease: Uint8Array(0) [],
  group: undefined
}

So maybe it’s just setting an asset ID that isn’t liking BigInt? Here’s where I’m seeing the error:

algosdk.makeAssetTransferTxnWithSuggestedParamsFromObject({
  from: escrowAccount.addr,
  to: escrowAccount.addr,
  amount: 0,
  assetIndex: BigInt(id),
  suggestedParams,
})

I totally missed the issue you were having. The JS SDK has an issue handling larger assetid/appid numbers than 2^53. This will be fixed in the future. It will be a long time before it matters (>10,000 years), so for now you are pretty safe just using number.

2 Likes