diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 826ecf4..50b21fd 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -14,7 +14,14 @@ jobs: pull-requests: write strategy: matrix: - step: ['format:check', 'lint:check', 'build', 'test:unit', 'test:integration'] + step: + [ + 'format:check', + 'lint:check', + 'build', + 'test:unit', + 'test:integration', + ] steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 diff --git a/README.md b/README.md index 20a0c2c..847b9d2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ - # ArNS - Arweave Name Token (ANT) This repository contains the source code used for Arweave Name Tokens used to resolve ArNS names on ar-io gateways. For official documentation on ANT's refer to the [ArNS ANT Docs]. For official documentation on ArNS refer to the [ArNS Docs]. @@ -9,13 +8,10 @@ The ANT [SmartWeave] Contract is a standardized contract that contains the speci ## ANT Contract -ANT contracts need to include the following methods and match the general schema of the [ANT Contract Schema] to be usable for ArNS name resolutions. +ANT contracts need to include the following methods and match the general schema of the [ANT Contract Schema] to be usable for ArNS name resolutions. ### Methods - - - ### `transfer` Transfers the ownership of the ANT. @@ -24,7 +20,6 @@ Transfers the ownership of the ANT. | ------ | ------ | --------------------- | -------- | --------------------------- | | target | string | "^[a-zA-Z0-9_-]{43}$" | true | Address to transfer ANT to. | - ### `setRecord` Sets a record for a given subdomain. @@ -35,7 +30,6 @@ Sets a record for a given subdomain. | transactionId | string | "^[a-zA-Z0-9_-]{43}$" | true | Transaction ID for the record. | | ttlSeconds | number | Min: 900, Max: 2,592,000 | false | Time-to-live in seconds for record. | - ### `setName` Sets the name of the ANT. @@ -44,7 +38,6 @@ Sets the name of the ANT. | ---- | ------ | ------- | -------- | --------------------- | | name | string | N/A | true | New name for the ANT. | - ### `setTicker` Sets the ticker symbol for the ANT. @@ -53,7 +46,6 @@ Sets the ticker symbol for the ANT. | ------ | ------ | ------- | -------- | -------------------------- | | ticker | string | N/A | true | New ticker symbol for ANT. | - ### `setController` Adds a new controller to the ANT. @@ -136,14 +128,13 @@ Make sure to update the variables at the top of each tool's `.ts` file, as well - [Permaweb Cookbook] - [Warp] -[ANT Contract Schema]:./initial-state.json -[AR.IO Gateways]:https://ar.io/docs/gateway-network/#overview -[ArNS Docs]:https://ar.io/docs/arns/ -[ArNS ANT Docs]:https://ar.io/docs/arns/#arweave-name-token-ant -[ArNS Service]:https://github.com/ar-io/arns-service -[ArNS Portal]:https://arns.app -[Permaweb Cookbook]:https://cookbook.arweave.dev/concepts/arns.html -[AJV]:https://ajv.js.org/guide/getting-started.html -[Warp]:https://academy.warp.cc -[SmartWeave]:https://github.com/ArweaveTeam/SmartWeave - +[ANT Contract Schema]: ./initial-state.json +[AR.IO Gateways]: https://ar.io/docs/gateway-network/#overview +[ArNS Docs]: https://ar.io/docs/arns/ +[ArNS ANT Docs]: https://ar.io/docs/arns/#arweave-name-token-ant +[ArNS Service]: https://github.com/ar-io/arns-service +[ArNS Portal]: https://arns.app +[Permaweb Cookbook]: https://cookbook.arweave.dev/concepts/arns.html +[AJV]: https://ajv.js.org/guide/getting-started.html +[Warp]: https://academy.warp.cc +[SmartWeave]: https://github.com/ArweaveTeam/SmartWeave diff --git a/build.js b/build.js index b64218d..f65a684 100644 --- a/build.js +++ b/build.js @@ -30,7 +30,7 @@ const { setRecordSchema, removeRecordSchema, transferSchema, - evolveSchema + evolveSchema, } = require('./schemas'); // build our validation source code @@ -44,7 +44,7 @@ const ajv = new Ajv({ setRecordSchema, removeRecordSchema, transferSchema, - evolveSchema + evolveSchema, ], code: { source: true, esm: true }, }); @@ -58,7 +58,7 @@ const moduleCode = standaloneCode(ajv, { validateSetTicker: '#/definitions/setTicker', validateBalance: '#/definitions/balance', validateTransferTokens: '#/definitions/transfer', - validateEvolve: '#/definitions/evolve' + validateEvolve: '#/definitions/evolve', }); // Now you can write the module code to file diff --git a/src/actions/write/evolve.ts b/src/actions/write/evolve.ts index 78acdf5..c6fdcc9 100644 --- a/src/actions/write/evolve.ts +++ b/src/actions/write/evolve.ts @@ -14,7 +14,10 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -import { INVALID_INPUT_MESSAGE, NON_CONTRACT_OWNER_MESSAGE } from '../../constants'; +import { + INVALID_INPUT_MESSAGE, + NON_CONTRACT_OWNER_MESSAGE, +} from '../../constants'; import { ANTState, ContractResult, PstAction } from '../../types'; // composed by ajv at build import { validateEvolve } from '../../validations'; @@ -26,7 +29,7 @@ export const evolve = async ( state: ANTState, { caller, input: { value } }: PstAction, ): Promise => { - if (!validateEvolve({value})) { + if (!validateEvolve({ value })) { throw new ContractError(INVALID_INPUT_MESSAGE); } const owner = state.owner; diff --git a/src/actions/write/transferTokens.ts b/src/actions/write/transferTokens.ts index 021fa3f..937659b 100644 --- a/src/actions/write/transferTokens.ts +++ b/src/actions/write/transferTokens.ts @@ -34,7 +34,6 @@ export const transferTokens = async ( throw new ContractError(INVALID_INPUT_MESSAGE); } - if (caller === target) { throw new ContractError('Invalid token transfer'); } diff --git a/src/types.ts b/src/types.ts index 8aaed30..7768d7f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -15,17 +15,17 @@ * along with this program. If not, see . */ -export type ANTRecord = { - transactionId: string, - ttlSeconds: number, -} +export type ANTRecord = { + transactionId: string; + ttlSeconds: number; +}; export type ANTState = { ticker: string; // A short token symbol, shown in block explorers and marketplaces name: string; // The friendly name of the token, shown in block explorers and marketplaces owner: string; // The owner of this contract who can execute specific methods controllers: string[]; // The controller of the records, who can add/change subdomains and their settings - records: Record + records: Record; balances: { // A list of all outstanding, positive, token balances [address: string]: number; diff --git a/tests/evolve.test.ts b/tests/evolve.test.ts index af0294d..498a2d4 100644 --- a/tests/evolve.test.ts +++ b/tests/evolve.test.ts @@ -41,7 +41,6 @@ describe('Testing evolve...', () => { true, ); _srcTxId = await warp.saveSource(srcTx, true); - }); it('Should evolve the ANT', async () => { @@ -49,11 +48,10 @@ describe('Testing evolve...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner[1]); const evolveResult = await contract.evolve(_srcTxId); - + const { cachedValue } = await contract.readState(); expect(evolveResult?.originalTxId).toBeDefined(); diff --git a/tests/removeController.test.ts b/tests/removeController.test.ts index 58f0992..3059b8c 100644 --- a/tests/removeController.test.ts +++ b/tests/removeController.test.ts @@ -31,7 +31,6 @@ describe('Testing removeController...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner[1]); const result = await contract.writeInteraction({ @@ -42,7 +41,6 @@ describe('Testing removeController...', () => { expect(result).toBeDefined(); expect(result?.originalTxId).toBeDefined(); - const { cachedValue } = await contract.readState(); const state = cachedValue.state; expect(state.controllers).not.toContain(defaultOwner[0]); diff --git a/tests/removeRecord.test.ts b/tests/removeRecord.test.ts index b9ef875..b405bd7 100644 --- a/tests/removeRecord.test.ts +++ b/tests/removeRecord.test.ts @@ -33,7 +33,6 @@ describe('Testing removeRecord...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner[1]); const subDomain = 'test'; @@ -48,8 +47,6 @@ describe('Testing removeRecord...', () => { expect(setResult).toBeDefined(); expect(setResult?.originalTxId).toBeDefined(); - - const result = await contract.writeInteraction({ function: 'removeRecord', subDomain, @@ -58,7 +55,6 @@ describe('Testing removeRecord...', () => { expect(result).toBeDefined(); expect(result?.originalTxId).toBeDefined(); - const { cachedValue } = await contract.readState(); const state = cachedValue.state; expect(Object.keys(state.records)).not.toContain(subDomain); @@ -69,7 +65,6 @@ describe('Testing removeRecord...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner[1]); await contract.writeInteraction({ @@ -78,14 +73,13 @@ describe('Testing removeRecord...', () => { transactionId: defaultOwner[0], ttlSeconds: MIN_TTL_LENGTH, }); - contract.connect(defaultOwner2[1]); await contract.writeInteraction({ function: 'removeRecord', subDomain: 'test', }); - + const { cachedValue: newCachedValue } = await contract.readState(); const newState = newCachedValue.state as ANTState; expect(newState.records['test']).not.toEqual(undefined); @@ -100,7 +94,6 @@ describe('Testing removeRecord...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner[1]); @@ -108,7 +101,6 @@ describe('Testing removeRecord...', () => { function: 'setController', target: defaultOwner2[0], }); - contract.connect(defaultOwner2[1]); await contract.writeInteraction({ @@ -117,13 +109,12 @@ describe('Testing removeRecord...', () => { transactionId, ttlSeconds, }); - await contract.writeInteraction({ function: 'removeRecord', subDomain, }); - + const { cachedValue: newCachedValue } = await contract.readState(); const newState = newCachedValue.state as ANTState; expect(newState.records[subDomain]).toEqual(undefined); diff --git a/tests/setController.test.ts b/tests/setController.test.ts index 0ce5a9b..8ac7437 100644 --- a/tests/setController.test.ts +++ b/tests/setController.test.ts @@ -32,7 +32,6 @@ describe('Testing setController...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner[1]); @@ -44,7 +43,6 @@ describe('Testing setController...', () => { expect(result).toBeDefined(); expect(result?.originalTxId).toBeDefined(); - const { cachedValue } = await contract.readState(); const state = cachedValue.state; expect(state.controllers).toContain(defaultOwner2[0]); @@ -55,7 +53,6 @@ describe('Testing setController...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner2[1]); @@ -65,7 +62,7 @@ describe('Testing setController...', () => { function: 'setController', target: 'HACKED', }); - + expect(writeInteraction?.originalTxId).not.toBe(undefined); const { cachedValue: newCachedValue } = await contract.readState(); const newState = newCachedValue.state as ANTState; diff --git a/tests/setName.test.ts b/tests/setName.test.ts index 0ab0026..9004c00 100644 --- a/tests/setName.test.ts +++ b/tests/setName.test.ts @@ -32,7 +32,6 @@ describe('Testing setName...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner[1]); @@ -46,7 +45,6 @@ describe('Testing setName...', () => { expect(result).toBeDefined(); expect(result?.originalTxId).toBeDefined(); - const { cachedValue } = await contract.readState(); const state = cachedValue.state; expect(state.name).toEqual(name); @@ -57,7 +55,6 @@ describe('Testing setName...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner2[1]); const { cachedValue: prevCachedValue } = await contract.readState(); @@ -66,7 +63,7 @@ describe('Testing setName...', () => { function: 'setName', name: 'HACKED', }); - + expect(writeInteraction?.originalTxId).not.toBe(undefined); const { cachedValue: newCachedValue } = await contract.readState(); const newState = newCachedValue.state as ANTState; @@ -78,7 +75,6 @@ describe('Testing setName...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner[1]); @@ -86,13 +82,13 @@ describe('Testing setName...', () => { function: 'setController', target: defaultOwner2[0], }); - + contract.connect(defaultOwner2[1]); await contract.writeInteraction({ function: 'setName', name: 'My New Token Renamed', }); - + const { cachedValue: newCachedValue } = await contract.readState(); const newState = newCachedValue.state as ANTState; expect(newState.name).toEqual('My New Token Renamed'); diff --git a/tests/setRecord.test.ts b/tests/setRecord.test.ts index a96ca99..2808182 100644 --- a/tests/setRecord.test.ts +++ b/tests/setRecord.test.ts @@ -26,15 +26,12 @@ describe('Testing setRecord...', () => { const defaultOwner2 = Object.entries(wallets)[1]; const warp: Warp = global.warp; - it('Should set the record of the ANT', async () => { const ANT = await ANTDeployer(warp, { address: defaultOwner[0], wallet: defaultOwner[1], }); - - const contract = warp.contract(ANT).connect(defaultOwner[1]); const subDomain = 'test'; @@ -48,7 +45,6 @@ describe('Testing setRecord...', () => { expect(result).toBeDefined(); expect(result?.originalTxId).toBeDefined(); - const { cachedValue } = await contract.readState(); const state = cachedValue.state; expect(Object.keys(state.records)).toContain(subDomain); @@ -59,7 +55,6 @@ describe('Testing setRecord...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner[1]); await contract.writeInteraction({ @@ -68,21 +63,21 @@ describe('Testing setRecord...', () => { transactionId: 'q8fnqsybd98-DRk6F6wdbBSkTouUShmnIA-pW4N-Hzs', ttlSeconds: MIN_TTL_LENGTH, }); - + await contract.writeInteraction({ function: 'setRecord', subDomain: 'dao', transactionId: '8MaeajVdPOhf3fCFDbrRuZXVRhhgNOJjbmgp8kjl2Jc', ttlSeconds: MIN_TTL_LENGTH, }); - + await contract.writeInteraction({ function: 'setRecord', subDomain: 'remove_this', ttlSeconds: 1000, transactionId: 'BYEeajVdPOhf3fCFDbrRuZXVRhhgNOJjbmgp8kjl2Jc', }); - + const { cachedValue: newCachedValue } = await contract.readState(); const newState = newCachedValue.state as ANTState; expect(newState.records['same_as_root']).toEqual({ @@ -104,7 +99,6 @@ describe('Testing setRecord...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner[1]); const writeInteraction = await contract.writeInteraction({ @@ -113,7 +107,7 @@ describe('Testing setRecord...', () => { transactionId: 'q8fnqsybd98-DRk6F6wdbBSkTouUShmnIA-pW4N-Hzs', ttlSeconds: 900, }); - + expect(writeInteraction?.originalTxId).not.toBe(undefined); const { cachedValue: newCachedValue } = await contract.readState(); const newState = newCachedValue.state as ANTState; @@ -165,7 +159,6 @@ describe('Testing setRecord...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner[1]); const writeInteraction = await contract.writeInteraction({ @@ -173,7 +166,7 @@ describe('Testing setRecord...', () => { subDomain: '@', ...input, }); - + expect(writeInteraction?.originalTxId).not.toBe(undefined); }, ); @@ -183,7 +176,6 @@ describe('Testing setRecord...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner2[1]); const { cachedValue: prevCachedValue } = await contract.readState(); @@ -201,7 +193,7 @@ describe('Testing setRecord...', () => { transactionId: 'HACKgF0LtJhtWWihirRm7qQehoxDe01vReZyrFYkAc4', ttlSeconds: MIN_TTL_LENGTH, }); - + const { cachedValue: newCachedValue } = await contract.readState(); const newState = newCachedValue.state as ANTState; expect(newState.records).toEqual(prevState.records); @@ -228,7 +220,6 @@ describe('Testing setRecord...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner[1]); @@ -236,14 +227,12 @@ describe('Testing setRecord...', () => { function: 'setController', target: defaultOwner2[0], }); - contract.connect(defaultOwner2[1]); // this wallet is only a controller await contract.writeInteraction({ function: 'setRecord', ...input, }); - const { cachedValue: newCachedValue } = await contract.readState(); const newState = newCachedValue.state as ANTState; diff --git a/tests/setTicker.test.ts b/tests/setTicker.test.ts index 8831c07..2bf5c0e 100644 --- a/tests/setTicker.test.ts +++ b/tests/setTicker.test.ts @@ -32,7 +32,6 @@ describe('Testing setTicker...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner[1]); const ticker = 'my-new-ticker'; @@ -45,7 +44,6 @@ describe('Testing setTicker...', () => { expect(result).toBeDefined(); expect(result?.originalTxId).toBeDefined(); - const { cachedValue } = await contract.readState(); const state = cachedValue.state; expect(state.ticker).toEqual(ticker); @@ -56,7 +54,6 @@ describe('Testing setTicker...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner2[1]); const { cachedValue: prevCachedValue } = await contract.readState(); @@ -65,7 +62,7 @@ describe('Testing setTicker...', () => { function: 'setTicker', name: 'ANT-HACKED', }); - + expect(writeInteraction?.originalTxId).not.toBe(undefined); const { cachedValue: newCachedValue } = await contract.readState(); const newState = newCachedValue.state as ANTState; @@ -78,7 +75,6 @@ describe('Testing setTicker...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner[1]); @@ -86,13 +82,13 @@ describe('Testing setTicker...', () => { function: 'setController', target: defaultOwner2[0], }); - + contract.connect(defaultOwner2[1]); await contract.writeInteraction({ function: 'setTicker', ticker, }); - + const { cachedValue: newCachedValue } = await contract.readState(); const newState = newCachedValue.state as ANTState; expect(newState.ticker).toEqual(ticker); diff --git a/tests/transferTokens.test.ts b/tests/transferTokens.test.ts index 87e8488..41d05ac 100644 --- a/tests/transferTokens.test.ts +++ b/tests/transferTokens.test.ts @@ -33,7 +33,6 @@ describe('Testing transfer...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner[1]); @@ -41,7 +40,7 @@ describe('Testing transfer...', () => { function: 'transfer', target: defaultOwner2[0], }); - + expect(writeInteraction?.originalTxId).not.toBe(undefined); const { cachedValue: newCachedValue } = await contract.readState(); const newState = newCachedValue.state as ANTState; @@ -55,7 +54,6 @@ describe('Testing transfer...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner2[1]); const { cachedValue: prevCachedValue } = await contract.readState(); @@ -65,7 +63,7 @@ describe('Testing transfer...', () => { function: 'transfer', target: defaultOwner[0], }); - + const { cachedValue: newCachedValue } = await contract.readState(); const newState = newCachedValue.state as ANTState; expect(writeInteraction?.originalTxId).not.toBe(undefined); @@ -77,7 +75,6 @@ describe('Testing transfer...', () => { address: defaultOwner[0], wallet: defaultOwner[1], }); - const contract = warp.contract(ANT).connect(defaultOwner[1]); @@ -85,7 +82,7 @@ describe('Testing transfer...', () => { function: 'setController', target: defaultOwner2[0], }); - + contract.connect(defaultOwner2[1]); // this wallet is only a controller const { cachedValue: prevCachedValue } = await contract.readState(); const prevState = prevCachedValue.state as ANTState; @@ -95,7 +92,6 @@ describe('Testing transfer...', () => { qty: 1, }); - expect(writeInteraction?.originalTxId).not.toBe(undefined); const { cachedValue: newCachedValue } = await contract.readState(); const newState = newCachedValue.state as ANTState; diff --git a/tests/utils/helper.ts b/tests/utils/helper.ts index 506e121..9bb90c1 100644 --- a/tests/utils/helper.ts +++ b/tests/utils/helper.ts @@ -31,9 +31,7 @@ export async function mineBlocks( arweave: Arweave, blocks: number, ): Promise { - for (let i = 0; i < blocks; i++) { - - } + for (let i = 0; i < blocks; i++) {} } export async function createLocalWallet( diff --git a/tools/deploy-contract.ts b/tools/deploy-contract.ts index 634864e..3de4bc4 100644 --- a/tools/deploy-contract.ts +++ b/tools/deploy-contract.ts @@ -14,19 +14,16 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +import { JWKInterface } from 'arweave/node/lib/wallet'; import * as fs from 'fs'; import path from 'path'; -import { - ContractDeploy, - PstState, -} from 'warp-contracts'; +import { ContractDeploy, PstState } from 'warp-contracts'; import { keyfile } from './constants'; import { arweave, initialize, warp } from './utilities'; -import { JWKInterface } from 'arweave/node/lib/wallet'; (async () => { - initialize() + initialize(); // Get the key file used for the distribution // load local wallet diff --git a/tools/set-controller.ts b/tools/set-controller.ts index 821350c..f5917a2 100644 --- a/tools/set-controller.ts +++ b/tools/set-controller.ts @@ -11,7 +11,6 @@ import { keyfile } from './constants'; import { initialize, warp } from './utilities'; (async () => { - initialize(); //~~~~~~~~~~~~~~~~~~~~~~~~~~UPDATE THE BELOW~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // This is the Arweave Name Token Contract TX ID that will have a controller set @@ -32,7 +31,5 @@ import { initialize, warp } from './utilities'; target, }); - console.log( - `Deployed transaction ID: ${writeInteraction}`, - ); + console.log(`Deployed transaction ID: ${writeInteraction}`); })(); diff --git a/tools/set-record.ts b/tools/set-record.ts index 0c34bf4..f63f11b 100644 --- a/tools/set-record.ts +++ b/tools/set-record.ts @@ -1,5 +1,6 @@ import { JWKInterface } from 'arweave/node/lib/wallet'; import * as fs from 'fs'; + import { keyfile } from './constants'; import { initialize, warp } from './utilities'; @@ -17,7 +18,7 @@ import { initialize, warp } from './utilities'; // This is the Arweave Name Token Contract TX ID that will have a subdomain added/modified const contractTxId = 'bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM'; - + // Get the key file used for the distribution const wallet: JWKInterface = JSON.parse(fs.readFileSync(keyfile).toString()); diff --git a/tools/transfer.ts b/tools/transfer.ts index 3bb347d..43832e1 100644 --- a/tools/transfer.ts +++ b/tools/transfer.ts @@ -16,6 +16,7 @@ */ import { JWKInterface } from 'arweave/node/lib/wallet'; import * as fs from 'fs'; + import { keyfile } from './constants'; import { initialize, warp } from './utilities';