diff --git a/package-lock.json b/package-lock.json index d071a8ed..76470ae0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@fastify/type-provider-typebox": "^2.1.0", "@sinclair/typebox": "^0.24.20", "@types/node": "^18.13.0", + "bignumber.js": "^9.1.1", "bitcoinjs-lib": "^6.1.0", "env-schema": "^5.2.0", "fastify": "^4.3.0", @@ -2951,6 +2952,14 @@ "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" }, + "node_modules/bignumber.js": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz", + "integrity": "sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==", + "engines": { + "node": "*" + } + }, "node_modules/bintrees": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz", @@ -14840,6 +14849,11 @@ "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" }, + "bignumber.js": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz", + "integrity": "sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==" + }, "bintrees": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz", diff --git a/package.json b/package.json index 6d6056f6..e5af288d 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "@fastify/type-provider-typebox": "^2.1.0", "@sinclair/typebox": "^0.24.20", "@types/node": "^18.13.0", + "bignumber.js": "^9.1.1", "bitcoinjs-lib": "^6.1.0", "env-schema": "^5.2.0", "fastify": "^4.3.0", diff --git a/src/api/util/ordinal-satoshi.ts b/src/api/util/ordinal-satoshi.ts index d1df412a..d09036b6 100644 --- a/src/api/util/ordinal-satoshi.ts +++ b/src/api/util/ordinal-satoshi.ts @@ -1,3 +1,5 @@ +import BigNumber from 'bignumber.js'; + const HALVING_BLOCKS = 210_000; const DIFFICULTY_ADJUST_BLOCKS = 2016; const INITIAL_SUBSIDY = 50; @@ -13,6 +15,10 @@ export enum SatoshiRarity { mythic = 'mythic', } +/** + * Ordinal Satoshi calculator. Mostly translated from the original Rust implementation at + * https://github.com/casey/ord/blob/master/src/sat.rs + */ export class OrdinalSatoshi { public blockHeight: number; public cycle: number; @@ -75,7 +81,8 @@ export class OrdinalSatoshi { } public get percentile(): string { - return `${(this.ordinal / (SAT_SUPPLY - 1)) * 100.0}%`; + const percentile = new BigNumber((this.ordinal / (SAT_SUPPLY - 1)) * 100.0); + return `${percentile.toFixed()}%`; } public get rarity(): SatoshiRarity { diff --git a/tests/ordinal-satoshi.test.ts b/tests/ordinal-satoshi.test.ts index f44406cf..28a14ef9 100644 --- a/tests/ordinal-satoshi.test.ts +++ b/tests/ordinal-satoshi.test.ts @@ -80,8 +80,7 @@ describe('OrdinalSatoshi', () => { expect(sat.epoch).toBe(0); expect(sat.name).toBe('nvtdijuwxdx'); expect(sat.offset).toBe(200); - // TODO: Convert scientific notation to number. - // expect(sat.percentile).toBe('0.000000000009523809534285719%'); + expect(sat.percentile).toBe('0.000000000009523809534285719%'); expect(sat.period).toBe(0); expect(sat.blockHeight).toBe(0); });