osmosis-labs / osmojs

OsmosJS makes it easy to compose and broadcast Osmosis and Cosmos messages
https://cosmology.zone/products/osmojs
Apache License 2.0
63 stars 33 forks source link

Date object parsing error #68

Open shapeshed opened 1 year ago

shapeshed commented 1 year ago

When the osmojs library parses a date object to a timestamp on the accountLockedPastTimeDenom rpc method, an error is generated within a osmojs helper function due to a floating point number being passed to a BigInt().

Test case

Here is a simple testcase equating to the following osmoisd call

osmosisd query lockup account-locked-pastime-denom osmo1ep6h8wpy348qx8rq8vcmep0dctl9epgyuvdlhn 1691405330 gamm/pool/15
import { osmosis } from 'osmojs';

const endpoint = "https://rpc.osmosis.zone:443";
const account = "osmo1ep6h8wpy348qx8rq8vcmep0dctl9epgyuvdlhn";
const denom = "gamm/pool/15"

async function main() {
    const { createRPCQueryClient } = osmosis.ClientFactory;
    const client = await createRPCQueryClient({ rpcEndpoint: endpoint });
    let d: Date = new Date();

    const locks = await client.osmosis.lockup.accountLockedPastTimeDenom({
        owner: account,
        denom: denom,
        timestamp: d,

    })

    console.log(locks)
};

main().catch(console.error);
RangeError: The number 1691405445.575 cannot be converted to a BigInt because it is not an integer
    at BigInt (<anonymous>)
    at numberToLong (/node_modules/osmojs/src/codegen/helpers.ts:256:10)
    at toTimestamp (/node_modules/osmojs/src/codegen/helpers.ts:215:19)
    at Object.encode (/node_modules/osmojs/src/codegen/osmosis/lockup/query.ts:1827:35)
    at QueryClientImpl.accountLockedPastTimeDenom (/node_modules/osmojs/src/codegen/osmosis/lockup/query.rpc.Query.ts:123:52)
    at Object.accountLockedPastTimeDenom (/node_modules/osmojs/src/codegen/osmosis/lockup/query.rpc.Query.ts:212:27)
    at main (/src/bug.ts:14:47)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

I think the issue is in this function

export function toTimestamp(date: Date): Timestamp {
  const seconds = numberToLong(date.getTime() / 1_000);
  const nanos = (date.getTime() % 1000) * 1000000;
  return {
    seconds,
    nanos
  };
}

The argument to the numberToLong function divides date.getTime() by 1_000 and eventually passing this to BigInt() causes an error. This can also be seen in the console

let d = new Date();
d.getTime();
1691405875895
d.getTime() / 1_000
1691405875.895
BigInt(d.getTime()) // works
1691405875895n 
BigInt(d.getTime() / 1_000) // fails
Uncaught RangeError: 1691405875.895 can't be converted to BigInt because it isn't an integer

I think the helpers file is generated by https://github.com/cosmology-tech/telescope but I am unfamiliar with this project. If you can suggest where to find the generated function I can draft a PR if this is a valid issue.

shapeshed commented 1 year ago

This can be avoided by removing seconds from the date object so if this is intentional this issue can be closed.

let d = new Date();
d.setSeconds(0, 0);
pyramation commented 1 year ago

@Zetazzz is this a telescope issue?

Zetazzz commented 1 year ago

Hi, Yes, I just fixed this by this PR: https://github.com/osmosis-labs/osmojs/issues/68#issuecomment-1744223400