diff --git a/README.md b/README.md index 95fd7b5e..6a91de2e 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,17 @@ Parameter |Required |Description `mnemonic` |Yes |Mnemonic phrase for wallet recovery. Plain PrivateKey can be used as well. `rpc` |Yes |Url of RPC APIs. `name` |Yes |Distributed domain name. Currently it supports ENS, CNS (.eth, .crypto) names. (eg `ddns-action.eth`, `ddns-action.crypto`) -`contentHash` |Yes |Hash of content. Currently it supports **IPFS** hash only. +`contentHash` |Yes |Hash of content.. +`contentType` |No |Type of content. Supported types [`ipfs-ns`, `swarm-ns`]. Default `ipfs-ns` +`dryRun` |No |Execution emulation without setting new content hash. Default `false` `verbose` |No |Level of verbosity [`false` - quiet, `true` - verbose]. Default `false` +## Content type support map +Provider |ipfs-ns |swarm-ns +--- |--- |--- +ENS |Yes |Yes +CNS |Yes |No + ## Example usage ``` diff --git a/action.yaml b/action.yaml index 330d5068..1e8823df 100644 --- a/action.yaml +++ b/action.yaml @@ -14,8 +14,16 @@ inputs: description: 'Distributed domain name. Currently it supports ENS, CNS (.eth, .crypto) names. (eg `ddns-action.eth`)' required: true contentHash: - description: 'Hash of content. Currently it supports IPFS hash only.' + description: 'Hash of content.' required: true + contentType: + description: 'Type of content. Supported types [ipfs-ns, swarm-ns]' + required: false + default: 'ipfs-ns' + dryRun: + description: 'Execution emulation without setting new content hash.' + required: false + default: false verbose: description: 'Level of verbosity' required: false diff --git a/index.js b/index.js index 4f1c7250..d3c56edf 100644 --- a/index.js +++ b/index.js @@ -9,9 +9,11 @@ async function run() { const rpc = core.getInput('rpc'); const name = core.getInput('name'); const contentHash = core.getInput('contentHash'); + const contentType = core.getInput('contentType'); + const dryrun = core.getInput('dryRun'); const verbose = (core.getInput('verbose') === 'true'); - await updater.update({ mnemonic, rpc, name, contentHash, verbose }) + await updater.update({ mnemonic, rpc, name, contentHash, contentType, dryrun, verbose }) .catch(error => { throw error }); if (verbose) { diff --git a/package-lock.json b/package-lock.json index 757f6be0..2cd8a677 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "ddns-action", - "version": "0.1.0", + "version": "0.1.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index b42ac15a..46bf66a2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ddns-action", - "version": "0.1.0", + "version": "0.1.2", "description": "DDNS(Distributed Domain Name System) update action", "main": "index.js", "scripts": { @@ -30,4 +30,4 @@ "eslintIgnore": [ "*.test.js" ] -} \ No newline at end of file +} diff --git a/updater/cns/index.js b/updater/cns/index.js index 8951f8f4..af68c08e 100644 --- a/updater/cns/index.js +++ b/updater/cns/index.js @@ -35,6 +35,10 @@ function CNS(options) { } this.getContenthash = async () => { + if (verbose) { + console.log('Getting content...') + } + const tokenId = namehash(name); const resolverContract = await getResolverContract(tokenId); @@ -42,7 +46,11 @@ function CNS(options) { .call({ from: provider.addresses[0] }); } - this.setContenthash = async ({ contentHash }) => { + this.setContenthash = async ({ contentHash, contentType }) => { + if (contentType !== 'ipfs-ns') { + throw new Error('ContentType is not supported. CNS supports only ipfs-ns'); + } + const tokenId = namehash(name); const resolverContract = await getResolverContract(tokenId); diff --git a/updater/ens/index.js b/updater/ens/index.js index 36cc5d12..4a6d0913 100644 --- a/updater/ens/index.js +++ b/updater/ens/index.js @@ -3,7 +3,7 @@ const Web3 = require('web3'); const Updater = require('@triplespeeder/ens-updater/lib'); module.exports = async (options) => { - const { mnemonic, rpc, name, verbose } = options; + const { mnemonic, rpc, name, dryrun, verbose } = options; const provider = new HDWalletProvider(mnemonic, rpc); const web3 = new Web3(provider); @@ -11,8 +11,8 @@ module.exports = async (options) => { web3, ensName: name, controllerAddress: provider.addresses[0], - verbose: verbose || false, - dryrun: false + dryrun, + verbose: verbose || false }; const updater = new Updater(); await updater.setup(updaterOptions); diff --git a/updater/index.js b/updater/index.js index fa56b2c1..e4b70feb 100644 --- a/updater/index.js +++ b/updater/index.js @@ -3,12 +3,14 @@ const core = require('@actions/core'); const ensFactory = require('./ens'); const CNS = require('./cns'); +const supportedTypes = ['ipfs-ns', 'swarm-ns']; + const tldMap = [ { name: '.eth', factory: ensFactory }, { name: '.crypto', factory: (options) => { return new CNS(options) } } ] -function validate({ name, contentHash }) { +function validate({ name, contentHash, contentType }) { if (!name) { throw new Error('Name is unknown or empty'); } @@ -20,27 +22,31 @@ function validate({ name, contentHash }) { if (!contentHash) { throw new Error('ContentHash is unknown or empty'); } + + if (!supportedTypes.find(type => type === contentType)) { + throw new Error('ContentType is not supported'); + } } module.exports = { async update(options) { validate(options); - const { name, contentHash } = options; + const { name, contentHash, contentType } = options; const { factory } = tldMap.find(tld => name.endsWith(tld.name)); const updater = await factory(options); - let currentContenthash; + let current; try { - currentContenthash = await updater.getContenthash(); - if (currentContenthash.hash === contentHash) { - console.log(`IPFS hash is up to date, update is not needed ${currentContenthash.hash}`); + current = await updater.getContenthash(); + if (current.hash === contentHash) { + console.log(`Content hash is up to date. [#${current.hash}]`); return; } } catch (error) { core.warning(error); } - return updater.setContenthash({ contentType: 'ipfs-ns', contentHash }); + return updater.setContenthash({ contentType, contentHash }); } } \ No newline at end of file diff --git a/updater/index.test.js b/updater/index.test.js index 4323717f..9628fd46 100644 --- a/updater/index.test.js +++ b/updater/index.test.js @@ -22,13 +22,32 @@ test('throws when contentHash is empty', async () => { .rejects.toThrow('ContentHash is unknown or empty'); }); -describe.only('Updater: Integration tests', () => { - test('test', async () => { +test('throws when contentType is not supported', async () => { + await expect(updater.update({ name: 'test.eth', contentHash: 'qwerty', contentType: 'q' })) + .rejects.toThrow('ContentType is not supported'); +}); + +describe.skip('Updater: Integration tests', () => { + test('Upload IPSF content hash to ETH name', async () => { await updater.update({ mnemonic: process.env.DEV_PKEY, rpc: `https://mainnet.infura.io/v3/${process.env.INFURA_API_KEY}`, name: 'ddns-action.eth', contentHash: 'QmRJFpRntf1EMgmC5Tm3Rzc438PRrYCMYZPb6nD4DeaNH6', + contentType: 'ipfs-ns', + dryrun: true, + verbose: true + }); + }); + + test('Upload Swarm content hash to ETH name', async () => { + await updater.update({ + mnemonic: process.env.DEV_PKEY, + rpc: `https://mainnet.infura.io/v3/${process.env.INFURA_API_KEY}`, + name: 'ddns-action.eth', + contentHash: 'd1de9994b4d039f6548d191eb26786769f580809256b4685ef316805265ea162', + contentType: 'swarm-ns', + dryrun: true, verbose: true }); });