diff --git a/.gitignore b/.gitignore index eec4cca..8e434cc 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ dist-ssr server/dist public/dist .turbo -.vscode \ No newline at end of file +.vscode +wallet.json \ No newline at end of file diff --git a/packages/atomic-toolkit/package.json b/packages/atomic-toolkit/package.json index 8229f40..ea860ad 100644 --- a/packages/atomic-toolkit/package.json +++ b/packages/atomic-toolkit/package.json @@ -42,6 +42,7 @@ "@types/lodash": "^4.14.202", "@types/node": "^18.19.3", "@urql/core": "^4.2.2", + "bignumber.js": "^9.1.2", "dotenv": "^16.3.1", "ethers": "v5", "mime": "^4.0.0", diff --git a/packages/atomic-toolkit/src/base.ts b/packages/atomic-toolkit/src/base.ts index fa46d22..a2326a9 100644 --- a/packages/atomic-toolkit/src/base.ts +++ b/packages/atomic-toolkit/src/base.ts @@ -1,5 +1,5 @@ import { Warp } from 'warp-contracts'; -import Irys from '@irys/sdk'; +import Irys, { WebIrys } from '@irys/sdk'; import Arweave from 'arweave'; // Warp @@ -22,7 +22,7 @@ import { UploadResponse } from '@irys/sdk/build/cjs/common/types'; class AtomicToolkitBase { protected warp: Warp; protected arweaveInstance: Arweave; - protected irys: Irys | null | undefined; + protected irys: WebIrys | Irys | null | undefined; protected key: JWKInterface | 'use_wallet' | null; public gql: Client; @@ -54,6 +54,7 @@ class AtomicToolkitBase { this.key = key ?? 'use_wallet'; this.irys = null; } + this.gql = new Client({ url: 'https://arweave.net/graphql', exchanges: [cacheExchange, fetchExchange], diff --git a/packages/atomic-toolkit/src/lib/utils/index.ts b/packages/atomic-toolkit/src/lib/utils/index.ts new file mode 100644 index 0000000..af5fcd6 --- /dev/null +++ b/packages/atomic-toolkit/src/lib/utils/index.ts @@ -0,0 +1,78 @@ +// Types +import * as Types from '../../types'; +import AtomicToolkitBase from '../../base'; + +import BigNumber from 'bignumber.js'; + +class Utilities extends AtomicToolkitBase { + constructor( + opts: Types.AtomicToolkitNodeOpts | Types.AtomicToolkitWebOpts, + ) { + super(opts); + } + + public async getUploadCost(size: number) { + let token: string; + let balance: { atomic: string; formatted: string }; + let cost: { atomic: string; formatted: string }; + let additional: { atomic: string; formatted: string }; + + if (this.irys) { + await this.irys.ready(); + const b = await this.irys.getLoadedBalance(); + const c = await this.irys.getPrice(size); + const a = c.minus(b); + + token = this.irys.utils.token; + balance = { + atomic: b.toString(), + formatted: this.irys.utils.fromAtomic(b).toString(), + }; + cost = { + atomic: c.toString(), + formatted: this.irys.utils.fromAtomic(c).toString(), + }; + additional = { + atomic: a.isGreaterThan(0) ? a.toString() : '0', + formatted: a.isGreaterThan(0) + ? this.irys.utils.fromAtomic(a).toString() + : '0', + }; + } else { + if (!this.key) { + throw new Error('No key provided'); + } + const wallet = this.arweaveInstance.wallets; + const address = await wallet.getAddress(this.key); + const b = BigNumber(await wallet.getBalance(address)); + const c = BigNumber( + await this.arweaveInstance.transactions.getPrice(size, address), + ); + const a = c.minus(b); + + token = 'arweave'; + balance = { + atomic: b.toString(), + formatted: this.arweaveInstance.ar.winstonToAr(b.toString()), + }; + cost = { + atomic: c.toString(), + formatted: this.arweaveInstance.ar.winstonToAr(c.toString()), + }; + additional = { + atomic: a.isGreaterThan(0) ? a.toString() : '0', + formatted: a.isGreaterThan(0) + ? this.arweaveInstance.ar.winstonToAr(a.toString()) + : '0', + }; + } + return { + token, + cost, + balance, + additional, + }; + } +} + +export default Utilities; diff --git a/packages/atomic-toolkit/src/node.ts b/packages/atomic-toolkit/src/node.ts index b4a0979..7318d08 100644 --- a/packages/atomic-toolkit/src/node.ts +++ b/packages/atomic-toolkit/src/node.ts @@ -3,6 +3,7 @@ import AtomicToolkitBase from './base'; import AtomicAssets from './lib/assets'; import Collection from './lib/collection'; +import Utilities from './lib/utils'; // Types import * as Types from './types'; @@ -10,11 +11,13 @@ import * as Types from './types'; class AtomicToolkit extends AtomicToolkitBase { public assets: AtomicAssets; public collection: Collection; + public utils: Utilities; constructor(opts: Types.AtomicToolkitNodeOpts) { super(opts); this.assets = new AtomicAssets(opts); this.collection = new Collection(opts); + this.utils = new Utilities(opts); } } diff --git a/packages/atomic-toolkit/src/web.ts b/packages/atomic-toolkit/src/web.ts index 06100b5..30a1967 100644 --- a/packages/atomic-toolkit/src/web.ts +++ b/packages/atomic-toolkit/src/web.ts @@ -3,6 +3,7 @@ import AtomicToolkitBase from './base'; import AtomicAssets from './lib/assets'; import Collection from './lib/collection'; +import Utilities from './lib/utils'; // Types import * as Types from './types'; @@ -10,6 +11,7 @@ import * as Types from './types'; class AtomicToolkitWeb extends AtomicToolkitBase { public assets: AtomicAssets; public collection: Collection; + public utils: Utilities; public arweave: Arweave; constructor(opts: Types.AtomicToolkitWebOpts) { @@ -17,6 +19,7 @@ class AtomicToolkitWeb extends AtomicToolkitBase { this.assets = new AtomicAssets(opts); this.collection = new Collection(opts); this.arweave = this.arweaveInstance; + this.utils = new Utilities(opts); } } diff --git a/packages/atomic-toolkit/tests/collection/index.test.ts b/packages/atomic-toolkit/tests/collection/index.test.ts index f981925..9d7e61b 100644 --- a/packages/atomic-toolkit/tests/collection/index.test.ts +++ b/packages/atomic-toolkit/tests/collection/index.test.ts @@ -8,7 +8,6 @@ describe('Collection GraphQL', () => { const res = await toolkit.collection.getCollection( 'naUSbwwYgZo1Zo8wD1jsWNTulydnccOTnx6eOyzy5AM', ); - console.log(res); expect(res).toBeDefined(); }); }); diff --git a/packages/atomic-toolkit/tests/tags/index.test.ts b/packages/atomic-toolkit/tests/tags/index.test.ts index df306d4..51d3441 100644 --- a/packages/atomic-toolkit/tests/tags/index.test.ts +++ b/packages/atomic-toolkit/tests/tags/index.test.ts @@ -130,7 +130,6 @@ describe('Content-Type Tags', () => { 'Contract-Src', 'Init-State', 'Contract-Manifest', - 'Indexed-By', 'License', ]; diff --git a/packages/atomic-toolkit/tests/utils/index.test.ts b/packages/atomic-toolkit/tests/utils/index.test.ts new file mode 100644 index 0000000..749ae0e --- /dev/null +++ b/packages/atomic-toolkit/tests/utils/index.test.ts @@ -0,0 +1,36 @@ +import { describe, expect, it } from 'vitest'; + +import AtomicToolkit from '../../src'; + +import Irys from '@irys/sdk'; +import * as dotenv from 'dotenv'; +dotenv.config({ path: '.env.local' }); + +import { readFileSync } from 'fs'; +const key = JSON.parse(readFileSync('./wallet.json').toString()); + +describe('Utilities', () => { + it('should return cost to upload data using arweave', async () => { + const toolkit = new AtomicToolkit({ + key, + }); + + const cost = await toolkit.utils.getUploadCost(10000); + expect(cost).toBeDefined(); + }); + it('should return cost to upload data using irys', async () => { + const irys = new Irys({ + url: 'https://node2.irys.xyz', + token: 'matic', + key: process.env.PRIVATE_KEY, + }); + + await irys.ready(); + const toolkit = new AtomicToolkit({ + irys, + }); + + const cost = await toolkit.utils.getUploadCost(131434143); + expect(cost).toBeDefined(); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fafabd5..06ef7d7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -184,6 +184,9 @@ importers: '@urql/core': specifier: ^4.2.2 version: 4.2.2(graphql@16.8.1) + bignumber.js: + specifier: ^9.1.2 + version: 9.1.2 dotenv: specifier: ^16.3.1 version: 16.3.1 @@ -8681,7 +8684,6 @@ packages: /bignumber.js@9.1.2: resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} - dev: false /binary-extensions@2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}