UNPKG

caver-js

Version:

caver-js is a JavaScript API library that allows developers to interact with a Klaytn node

1,093 lines (928 loc) 79.7 kB
/* Copyright 2021 The caver-js Authors This file is part of the caver-js library. The caver-js library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. The caver-js library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the caver-js. If not, see <http://www.gnu.org/licenses/>. */ const chai = require('chai') const sinon = require('sinon') const sinonChai = require('sinon-chai') const chaiAsPromised = require('chai-as-promised') chai.use(chaiAsPromised) chai.use(sinonChai) const expect = chai.expect const testRPCURL = require('../testrpc') const Caver = require('../../index') const SignatureData = require('../../packages/caver-wallet/src/keyring/signatureData') let caver const sandbox = sinon.createSandbox() describe('caver.validator.validateSignedMessage', () => { beforeEach(() => { caver = new Caver(testRPCURL) }) afterEach(() => { sandbox.restore() }) context('caver.validator.validateSignedMessage with AccountKeyLegacy', () => { const address = '0xa84a1ce657e9d5b383cece6f4ba365e23fa234dd' const privateKey = '0x7db91b4606aa4421eeb85d03601562f966693e38957d5e79a29edda0e85b2225' const getAccountKeyResult = { keyType: 1, key: {} } const message = 'Some Message' const hashedMessage = '0xa4b1069c1000981f4fdca0d62302dfff77c2d0bc17f283d961e2dc5961105b18' const signature = [ '0x1b', '0x8213e560e7bbe1f2e28fd69cbbb41c9108b84c98cd7c2c88d3c8e3549fd6ab10', '0x3ca40c9e20c1525348d734a6724db152b9244bff6e0ff0c2b811d61d8f874f00', ] it('CAVERJS-UNIT-VALIDATOR-001: should return true when valid signatures with array format', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKey) const ret = await caver.validator.validateSignedMessage(message, signature, keyring.address) expect(ret).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-002: should return true when valid signatures with array format when message is hashed', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKey) const ret = await caver.validator.validateSignedMessage(hashedMessage, signature, keyring.address, true) expect(ret).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-003: should return true when valid signatures with SignatureData format', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKey) const ret = await caver.validator.validateSignedMessage(message, new SignatureData(signature), keyring.address) expect(ret).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-004: should return true when valid signatures with SignatureData array format', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKey) const ret = await caver.validator.validateSignedMessage(message, [new SignatureData(signature)], keyring.address) expect(ret).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-005: should return false when invalid signatures is passed as a parameter', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKey) const invalid = [ '0x1c', '0xa5c9ff1df09258a6f9262f1fae43a306ec77592287787cbd3ee0419dd8d2bfeb', '0x4c903d3dda703554cf7b65aa2c0dc819c86d36cf2dbf0ff5071667fb5551a706', ] const ret = await caver.validator.validateSignedMessage(message, invalid, keyring.address) expect(ret).to.be.false }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-006: should return true when korean-format message are passed as a parameter', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const kMessage = '하이' const kAddress = '0x82B4deC52696c7777b4453986496612a0a2B1e99' const kSignedMessage = '0x85e6ae815bb80814ba8f63b3b16941f0740f471a048efb79b31428dcb61345132bd48cbf9594a243243a97951fbd3cc555101158c76168bbcb0b2e1a0de08b2d1b' // pub key // "0xf2a480ed864b9fa3856e2841aa0851463ce34ba9c43a503d08e9ab5dcfd4136cc5fddab6ea35271f43fb75597eed634056c8b0e211a134e26ed1e01b9161a132" const v = `0x${kSignedMessage.substring(2).substring(128, 130)}` const r = `0x${kSignedMessage.substring(2).substring(0, 64)}` const s = `0x${kSignedMessage.substring(2).substring(64, 128)}` const sig = [v, r, s] const ret = await caver.validator.validateSignedMessage(kMessage, sig, kAddress) expect(ret).to.be.true }).timeout(100000) }) context('caver.validator.validateSignedMessage with AccountKeyPublic', () => { // Below private key is decoupled from the address const address = '0xa84a1ce657e9d5b383cece6f4ba365e23fa234dd' const privateKey = '0xf95c224b63f5658281ad853b3f582051eb9bca9b3e5475a8d3e4315abf42cb02' const getAccountKeyResult = { keyType: 2, key: { x: '0x89632f9a5aa49b30ddea62574c4b0e23cf05b934f667dd94eb3a4f394ca0bba3', y: '0x6726b313ef93fbfc1295b87f62f1c1c9fdb0dbc6f583eae6db0cbd5c715f19cd', }, } const message = 'Some Message' const hashedMessage = '0xa4b1069c1000981f4fdca0d62302dfff77c2d0bc17f283d961e2dc5961105b18' const signature = [ '0x1c', '0xa5c9ff1df09258a6f9262f1fae43a306ec77592287787cbd3ee0419dd8d2bfeb', '0x4c903d3dda703554cf7b65aa2c0dc819c86d36cf2dbf0ff5071667fb5551a706', ] it('CAVERJS-UNIT-VALIDATOR-006: should return true when valid signatures with array format', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKey) const ret = await caver.validator.validateSignedMessage(message, signature, keyring.address) expect(ret).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-007: should return true when valid signatures with array format when message is hashed', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKey) const ret = await caver.validator.validateSignedMessage(hashedMessage, signature, keyring.address, true) expect(ret).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-008: should return true when valid signatures with SignatureData format', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKey) const ret = await caver.validator.validateSignedMessage(message, new SignatureData(signature), keyring.address) expect(ret).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-009: should return true when valid signatures with SignatureData array format', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKey) const ret = await caver.validator.validateSignedMessage(message, [new SignatureData(signature)], keyring.address) expect(ret).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-010: should return false when invalid signatures are passed as a parameter', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKey) const invalidSig = [ '0x1b', '0x883c4174fada447e95b09e3f27b2e27f419179366230bbcd5046ff946d1e4a90', '0x052f9e19394e593547370ec5216703c6b698377d4f5fa422bf0e1cb26698dad2', ] const ret = await caver.validator.validateSignedMessage(message, [new SignatureData(invalidSig)], keyring.address) expect(ret).to.be.false }).timeout(100000) }) context('caver.validator.validateSignedMessage with AccountKeyFail', () => { const address = '0xa84a1ce657e9d5b383cece6f4ba365e23fa234dd' const getAccountKeyResult = { keyType: 3, key: {} } const message = 'Some Message' const signature = [ '0x1c', '0xa5c9ff1df09258a6f9262f1fae43a306ec77592287787cbd3ee0419dd8d2bfeb', '0x4c903d3dda703554cf7b65aa2c0dc819c86d36cf2dbf0ff5071667fb5551a706', ] it('CAVERJS-UNIT-VALIDATOR-011: should return false when accountKey is AccountKeyFail', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const ret = await caver.validator.validateSignedMessage(message, signature, address) expect(ret).to.be.false }).timeout(100000) }) context('caver.validator.validateSignedMessage with AccountKeyWeightedMultiSig', () => { // Below private keys is decoupled from the address const address = '0xa84a1ce657e9d5b383cece6f4ba365e23fa234dd' const privateKeys = [ '0xc707902dba449d0ce3b47675db728ad795b63a4ae748dc4f7265e05305ae7424', '0x9611e74d616659598c56707b47779f99cae268c70a53163348cea01f8f872447', '0x24777022e1b8c993451c855b1f74561dff057caa825a01f4d87ab2f2b46aaaf7', ] const getAccountKeyResult = { keyType: 4, key: { threshold: 3, keys: [ { weight: 2, key: { x: '0x2459bce1b37d5c517854842574f7fc78d7e76238c1c8b1619f0189a397fbf9c2', y: '0xeeacaae1117b6994df2b5bc2990157f9c7a74c9ef211d6cb49b1a624911ec87b', }, }, { weight: 1, key: { x: '0x334aa344adf4e5758d4d75a8cc89495d0cb809433960ea6459e31de4f1ac7ac1', y: '0x10a3971d6c139a38d16d83fe87024127b8326c8d16de7187a5adf0b1f7c28ada', }, }, { weight: 1, key: { x: '0x0xd9fbf7476758d2f4db78379bf0b9d2207207f638b39c831b8034cc35d0f87ab', y: '0xaa6fcac353e85bde5e7a11173aa8ef1f546df4276816daa7b8b5e4985285f1ab0', }, }, ], }, } const message = 'Some Message' const hashedMessage = '0xa4b1069c1000981f4fdca0d62302dfff77c2d0bc17f283d961e2dc5961105b18' const signatures = [ [ '0x1b', '0x883c4174fada447e95b09e3f27b2e27f419179366230bbcd5046ff946d1e4a90', '0x052f9e19394e593547370ec5216703c6b698377d4f5fa422bf0e1cb26698dad2', ], [ '0x1c', '0x8119b63a28a9c20ef8266b4d99e1f05c1bfa773e1376f19802f898b117311556', '0x23d265b2cb102a2d81bf829aae1e9d579d7bf32110e3e62728070ebae466c131', ], [ '0x1c', '0xa9770147c523ef699959b804c2dd9ba1b61b3c6bdd8eac57c0a72efd5c5c566c', '0x2904d93e0510d76120de0e0cd8eeb4842867edde58c29efe389c8a82705ce00e', ], ] it('CAVERJS-UNIT-VALIDATOR-012: should return true when valid signatures with array format', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKeys) const ret = await caver.validator.validateSignedMessage(message, signatures, keyring.address) expect(ret).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-013: should return true when valid signatures with array format when message is hashed', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKeys) const ret = await caver.validator.validateSignedMessage(hashedMessage, signatures, keyring.address, true) expect(ret).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-014: should return true when valid signatures with SignatureData array format', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKeys) const formattedSignatures = [] for (const sig of signatures) formattedSignatures.push(new SignatureData(sig)) const ret = await caver.validator.validateSignedMessage(message, formattedSignatures, keyring.address) expect(ret).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-015: should return true if threshold is satisfied', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKeys) const formattedSignatures = [] formattedSignatures.push(new SignatureData(signatures[0])) // weight 2 formattedSignatures.push(new SignatureData(signatures[1])) // wieght 1 const ret = await caver.validator.validateSignedMessage(message, formattedSignatures, keyring.address) expect(ret).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-016: should return false if threshold is not satisfied', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKeys) const formattedSignatures = [] formattedSignatures.push(new SignatureData(signatures[1])) // wieght 1 formattedSignatures.push(new SignatureData(signatures[2])) // wieght 1 const ret = await caver.validator.validateSignedMessage(message, formattedSignatures, keyring.address) expect(ret).to.be.false }).timeout(100000) // This test case should be chagned to expect false after fork. it('CAVERJS-UNIT-VALIDATOR-017: should return true when threshold is satisfied but includes invalid siganture though', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKeys) const formattedSignatures = [] for (const sig of signatures) formattedSignatures.push(new SignatureData(sig)) formattedSignatures.push( new SignatureData([ '0x1b', '0x8213e560e7bbe1f2e28fd69cbbb41c9108b84c98cd7c2c88d3c8e3549fd6ab10', '0x3ca40c9e20c1525348d734a6724db152b9244bff6e0ff0c2b811d61d8f874f00', ]) ) const ret = await caver.validator.validateSignedMessage(message, formattedSignatures, keyring.address) expect(ret).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-018: should return false when invalid signatures are passed as a parameter', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKeys) const invalidSig = [ [ '0x1b', '0xa7373f18960e9f9085781b35c539aa82fe02f076d36b8f56fe199c1262a26691', '0x0d003bc30f79b510a189f98a776b2419995bc3fc88a2e63094e2fb022323ff3c', ], [ '0x1c', '0xdc92f3a0e46c4522a635ddf07a3f970bae4c6e546b3afc5f2fac8b60054ffcec', '0x02b30df9d85a3a1cf2e03c01f5a32544ef68a65ff48ad25428dabe95405aef25', ], ] const ret = await caver.validator.validateSignedMessage(message, invalidSig, keyring.address) expect(ret).to.be.false }).timeout(100000) }) context('caver.validator.validateSignedMessage with AccountKeyRoleBased', () => { // Below private keys is decoupled from the address const address = '0xa84a1ce657e9d5b383cece6f4ba365e23fa234dd' const privateKeys = [ [ '0x91be7ec09a17222740fe356b5b2721722abc38b7b40334cda94a478993e51668', '0x4f4b3517caae10ae4571eb1f30e649f1fa10c6a3c690e555db473623cad8a171', ], [ '0xd9d77f73890681e7dfe26fba7bb19479112bc902129be2d19ad514b0d0f4cc54', '0xf38971e17d4ee376498adba83ef951e93ee7aedeea350d1820c7b8436a5a6286', ], [ '0x609afc089f497c8752664a34e03e305d0c9550f0efaa41c3636bc40e92fa6e83', '0xf2263c847c9989660cc7319c16611cf5ddb8d3b7d15a45b2f93ef79cc48c582a', ], ] const getAccountKeyResult = { keyType: 5, key: [ { keyType: 4, key: { threshold: 2, keys: [ { weight: 1, key: { x: '0x1bd81d8db362bb71ada110b6ce3c5c2cb83a09408b737514dbdd00aec664cb15', y: '0xc32180d23b23e0adff616ad7e47c47055c429f49729a564cfdef3a20d30c6484', }, }, { weight: 1, key: { x: '0x37f5234c9f99ebf5cf4e54038d1fcd6c18f3dc80217d41581c22190310ab4546', y: '0x542eaa9a24a5aa5d4a6c5729c24c7b82006747408218dffdc3712635fc04bf2a', }, }, ], }, }, { keyType: 4, key: { threshold: 2, keys: [ { weight: 1, key: { x: '0x2524a74b1cdaca02dcba217dfc4c12e1ed211f0625a5625d3d46eba97e2b6f3e', y: '0x7dfb71b9444a455a88a2c65d5bcc17a4fbd78be0f0c638570d2e380273210ee0', }, }, { weight: 1, key: { x: '0x0784d5e42363fb1828981e83506bcb3d0ee99bf5817513a0e828087b61ecbe78', y: '0xb9fd0686c949e722a201d568e83029cd5abaf2cd59b140ef7e6790a936576f20', }, }, ], }, }, { keyType: 4, key: { threshold: 2, keys: [ { weight: 1, key: { x: '0x953ba821d928da92be9455db80413b7f777ac1fccd2fc08c975e7d70631278fa', y: '0x35288de9c9b87588209c7aab345bd13244e68221b9fbeed7f60ba3769ba7efd8', }, }, { weight: 1, key: { x: '0x8b3f3ee33166683a0f6084f3d6030c184bb8901cf948447705b51399b752a766', y: '0x10135ab0b296efbdd68477f56541deaadd63cc253bcea61caac08596c2338fbc', }, }, ], }, }, ], } const message = 'Some Message' const hashedMessage = '0xa4b1069c1000981f4fdca0d62302dfff77c2d0bc17f283d961e2dc5961105b18' // signatures with roleTransactionKey const signatures = [ [ '0x1b', '0xa7373f18960e9f9085781b35c539aa82fe02f076d36b8f56fe199c1262a26691', '0x0d003bc30f79b510a189f98a776b2419995bc3fc88a2e63094e2fb022323ff3c', ], [ '0x1c', '0xdc92f3a0e46c4522a635ddf07a3f970bae4c6e546b3afc5f2fac8b60054ffcec', '0x02b30df9d85a3a1cf2e03c01f5a32544ef68a65ff48ad25428dabe95405aef25', ], ] // signatures with roleAccountUpdateKey const roleAccountUpdateKeySignatures = [ [ '0x1b', '0x2a163fa0cb6b191c4773b11bf177b1e51175db340b4d6c74046119d5d96b2946', '0x1282daa48dd3cc500f5aa145bb87cd1f68bc7b9bf92cdd158c2075041002fc60', ], [ '0x1c', '0x671fd9e070a42dc5e5ffd97b39fdceba4f670cad06f455513f021436a95f1ea1', '0x0d01a612c20481f92c51be655a9603afd93a2a9134e12e2b45bf463cb7c02f26', ], ] // signatures with roleFeePayerKey const roleFeePayerKeySignatures = [ [ '0x1b', '0x4e0fd15eb17809eed3f3b92de7a5d785fa462d4a26c671355c78f2e0ec643cf4', '0x520fac71728145f92018466b724da7ab447b4ef07037d48efe3c3db6b6c5680d', ], [ '0x1c', '0x84bb6abdafa54f456ade2de682a86ca8937f9bb5495966b856e9b6dd5b74c051', '0x256e505d8e406b7ea7f37834b46b343fdc0658808762f94884921b8e9f3c5275', ], ] it('CAVERJS-UNIT-VALIDATOR-019: should return true when valid signatures with array format', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKeys) const ret = await caver.validator.validateSignedMessage(message, signatures, keyring.address) expect(ret).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-020: should return true when valid signatures with array format when message is hashed', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKeys) const ret = await caver.validator.validateSignedMessage(hashedMessage, signatures, keyring.address, true) expect(ret).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-021: should return true when valid signatures with SignatureData array format', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKeys) const formattedSignatures = [] for (const sig of signatures) formattedSignatures.push(new SignatureData(sig)) const ret = await caver.validator.validateSignedMessage(message, formattedSignatures, keyring.address) expect(ret).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-022: should return true if threshold is satisfied', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKeys) const formattedSignatures = [] formattedSignatures.push(new SignatureData(signatures[0])) // weight 2 formattedSignatures.push(new SignatureData(signatures[1])) // wieght 1 const ret = await caver.validator.validateSignedMessage(message, formattedSignatures, keyring.address) expect(ret).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-023: should return false if threshold is not satisfied', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKeys) const formattedSignatures = [] formattedSignatures.push(new SignatureData(signatures[1])) // wieght 1 formattedSignatures.push(new SignatureData(signatures[2])) // wieght 1 const ret = await caver.validator.validateSignedMessage(message, formattedSignatures, keyring.address) expect(ret).to.be.false }).timeout(100000) // This test case should be chagned to expect false after fork. it('CAVERJS-UNIT-VALIDATOR-024: should return true when threshold is satisfied but includes invalid siganture though', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKeys) const formattedSignatures = [] for (const sig of signatures) formattedSignatures.push(new SignatureData(sig)) formattedSignatures.push( new SignatureData([ '0x1b', '0x8213e560e7bbe1f2e28fd69cbbb41c9108b84c98cd7c2c88d3c8e3549fd6ab10', '0x3ca40c9e20c1525348d734a6724db152b9244bff6e0ff0c2b811d61d8f874f00', ]) ) const ret = await caver.validator.validateSignedMessage(message, formattedSignatures, keyring.address) expect(ret).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-025: should return false if signature is signed by roleAccountUpateKey', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKeys) const formattedSignatures = [] for (const sig of roleAccountUpdateKeySignatures) formattedSignatures.push(new SignatureData(sig)) const ret = await caver.validator.validateSignedMessage(message, formattedSignatures, keyring.address) expect(ret).to.be.false }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-026: should return false if signature is signed by roleFeePayerKey', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) const keyring = caver.wallet.keyring.create(address, privateKeys) const formattedSignatures = [] for (const sig of roleFeePayerKeySignatures) formattedSignatures.push(new SignatureData(sig)) const ret = await caver.validator.validateSignedMessage(message, formattedSignatures, keyring.address) expect(ret).to.be.false }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-027: should return true with AccountKeyLegacy in roleTransactionKey', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves({ keyType: 5, key: [{ keyType: 1, key: {} }, getAccountKeyResult.key[1], getAccountKeyResult.key[2]], }) const keyring = caver.wallet.keyring.create(address, privateKeys) const signatureWithAccountKeyLegacy = [ '0x1b', '0x8213e560e7bbe1f2e28fd69cbbb41c9108b84c98cd7c2c88d3c8e3549fd6ab10', '0x3ca40c9e20c1525348d734a6724db152b9244bff6e0ff0c2b811d61d8f874f00', ] const ret = await caver.validator.validateSignedMessage(message, signatureWithAccountKeyLegacy, keyring.address) expect(ret).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-028: should return true with AccountKeyPublic in roleTransactionKey', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves({ keyType: 5, key: [ { keyType: 2, key: { x: '0x89632f9a5aa49b30ddea62574c4b0e23cf05b934f667dd94eb3a4f394ca0bba3', y: '0x6726b313ef93fbfc1295b87f62f1c1c9fdb0dbc6f583eae6db0cbd5c715f19cd', }, }, getAccountKeyResult.key[1], getAccountKeyResult.key[2], ], }) const keyring = caver.wallet.keyring.create(address, privateKeys) const signatureWithAccountKeyPublic = [ '0x1c', '0xa5c9ff1df09258a6f9262f1fae43a306ec77592287787cbd3ee0419dd8d2bfeb', '0x4c903d3dda703554cf7b65aa2c0dc819c86d36cf2dbf0ff5071667fb5551a706', ] const ret = await caver.validator.validateSignedMessage(message, signatureWithAccountKeyPublic, keyring.address) expect(ret).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-029: should return false with AccountKeyFail in roleTransactionKey', async () => { const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves({ keyType: 5, key: [{ keyType: 3, key: {} }, getAccountKeyResult.key[1], getAccountKeyResult.key[2]], }) const keyring = caver.wallet.keyring.create(address, privateKeys) const ret = await caver.validator.validateSignedMessage(message, signatures, keyring.address) expect(ret).to.be.false }).timeout(100000) }) }) describe('caver.validator.validateSender', () => { beforeEach(() => { caver = new Caver(testRPCURL) }) afterEach(() => { sandbox.restore() }) context('caver.validator.validateSender with AccountKeyLegacy', () => { const txObj = { from: '0xf21460730845e3652aa3cc9bc13b345e4f53984a', to: '0x59177716c34ac6e49e295a0e78e33522f14d61ee', value: '0x1', chainId: '0x7e3', gasPrice: '0x5d21dba00', nonce: '0x0', gas: '0x2faf080', signatures: [ '0x0fe9', '0xecdec357060dbbb4bd3790e98b1733ec3a0b02b7e4ec7a5622f93cd9bee229fe', '0x0a4a5e28753e7c1d999b286fb07933c5bf353079b8ed4d1ed509a838b48be02c', ], } function setStubResult() { const getAccountKeyResult = { keyType: 1, key: {} } const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) } it('CAVERJS-UNIT-VALIDATOR-030: should validate signatures in the tx', async () => { setStubResult() const tx = caver.transaction.legacyTransaction.create(txObj) const isValid = await caver.validator.validateSender(tx) expect(isValid).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-031: should return false when signatures in the tx are invalid', async () => { setStubResult() const tx = caver.transaction.legacyTransaction.create(txObj) tx.signatures = [ { V: '0x0fe9', R: '0x86c8ecbfd892be41d48443a2243274beb6daed3f72895045965a3baede4c350e', S: '0x69ea748aff6e4c106d3a8ba597d8f134745b76f12dacb581318f9da07351511a', }, ] const isValid = await caver.validator.validateSender(tx) expect(isValid).to.be.false }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-058: should validate a signature in the ethereum access list tx', async () => { setStubResult() let tx = caver.transaction.ethereumAccessList.create({ from: '0x30be91c80566da777d30e659b6746174ecc61576', gas: '0x9c40', nonce: '0xe1e', gasPrice: '0x5d21dba00', chainId: '0x2710', signatures: [ '0x1', '0x653a6840880708f4fe3f3a542ebf4669c6aec6d4575fa099b7158de61012d46a', '0x37510415d55c633b4c70509cd2ca371ae9d17b26ca6fc5b9d622b94d366845ec', ], to: '0x79ebe19c4f0987b8531c5d3e728aa29d978be9d6', input: '0xa9059cbb0000000000000000000000008a4c9c443bb0645df646a2d5bb55def0ed1e885a0000000000000000000000000000000000000000000000000000000000003039', value: '0x1', accessList: [ { address: '0x4468d2cb2c0beb70ca4ab22a3be9a32ecc75411a', storageKeys: [ '0x0000000000000000000000000000000000000000000000000000000000000003', '0x0000000000000000000000000000000000000000000000000000000000000007', ], }, ], }) let isValid = await caver.validator.validateSender(tx) expect(isValid).to.be.true tx = caver.transaction.ethereumAccessList.create({ from: '0x30be91c80566da777d30e659b6746174ecc61576', gas: '0x9c40', nonce: '0xe25', gasPrice: '0x5d21dba00', chainId: '0x2710', signatures: [ '0x0', '0xecccb764fe1af4cf8cd8bb003621beaeb0c62357b77ff9f43dc745fd0fff0245', '0x19c68d66686efce41c63fbb19a2f824b96acc28810ee3cd2254977de0a311c23', ], to: '0x79ebe19c4f0987b8531c5d3e728aa29d978be9d6', input: '0xa9059cbb0000000000000000000000008a4c9c443bb0645df646a2d5bb55def0ed1e885a0000000000000000000000000000000000000000000000000000000000003039', value: '0x1', accessList: [ { address: '0x4468d2cb2c0beb70ca4ab22a3be9a32ecc75411a', storageKeys: [ '0x0000000000000000000000000000000000000000000000000000000000000003', '0x0000000000000000000000000000000000000000000000000000000000000007', ], }, ], }) isValid = await caver.validator.validateSender(tx) expect(isValid).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-059: should validate a signature in the ethereum dynamic fee tx', async () => { setStubResult() let tx = caver.transaction.ethereumDynamicFee.create({ from: '0x30be91c80566da777d30e659b6746174ecc61576', gas: '0x9c40', nonce: '0xe20', chainId: '0x2710', signatures: [ '0x1', '0x6eccacfc39fa6b2a3216443d7307c29928323b1afd1c468ce51737ddf3f1c5e9', '0x12f5f4b8af6019281cc77fab330f6d8643aa08b2d1c56bd8158dd0ed0ed1d34a', ], to: '0x79ebe19c4f0987b8531c5d3e728aa29d978be9d6', input: '0xa9059cbb0000000000000000000000008a4c9c443bb0645df646a2d5bb55def0ed1e885a0000000000000000000000000000000000000000000000000000000000003039', value: '0x1', maxFeePerGas: '0x5d21dba00', maxPriorityFeePerGas: '0x5d21dba00', accessList: [ { address: '0x4468d2cb2c0beb70ca4ab22a3be9a32ecc75411a', storageKeys: [ '0x0000000000000000000000000000000000000000000000000000000000000003', '0x0000000000000000000000000000000000000000000000000000000000000007', ], }, ], }) let isValid = await caver.validator.validateSender(tx) expect(isValid).to.be.true tx = caver.transaction.ethereumDynamicFee.create({ from: '0x30be91c80566da777d30e659b6746174ecc61576', gas: '0x9c40', nonce: '0xe22', chainId: '0x2710', signatures: [ '0x0', '0x5a7fda9e8161b872e901687ecf85e1226866d7c244a54d7e7b39ab4932a22cf', '0x42293506f0cd10e23815a922167e8e89e8b37cff2d302c82a6da8fccd17335d9', ], to: '0x79ebe19c4f0987b8531c5d3e728aa29d978be9d6', input: '0xa9059cbb0000000000000000000000008a4c9c443bb0645df646a2d5bb55def0ed1e885a0000000000000000000000000000000000000000000000000000000000003039', value: '0x1', maxFeePerGas: '0x5d21dba00', maxPriorityFeePerGas: '0x5d21dba00', accessList: [ { address: '0x4468d2cb2c0beb70ca4ab22a3be9a32ecc75411a', storageKeys: [ '0x0000000000000000000000000000000000000000000000000000000000000003', '0x0000000000000000000000000000000000000000000000000000000000000007', ], }, ], }) isValid = await caver.validator.validateSender(tx) expect(isValid).to.be.true }).timeout(100000) }) context('caver.validator.validateSender with AccountKeyPublic', () => { const txObj = { from: '0xf21460730845e3652aa3cc9bc13b345e4f53984a', to: '0x59177716c34ac6e49e295a0e78e33522f14d61ee', value: '0x1', chainId: '0x7e3', gasPrice: '0x5d21dba00', nonce: '0x0', gas: '0x2faf080', signatures: [ [ '0x0fea', '0x2b5934c6d26bb3e65edf099d79c57c743d2f70744ca09d3ba9a1099edff9f173', '0x0797886edff4b449c1a599943e3a6003ae9e46b3f3f34862ced327e43fba3a6a', ], ], } function setStubResult() { const getAccountKeyResult = { keyType: 2, key: { x: '0x8bb6aaeb2d96d024754d3b50babf116cece68977acbe8ba6a66f14d5217c60d9', y: '0x6af020a0568661e7c72e753e80efe084a3aed9f9ac87bf44d09ce67aad3d4e01', }, } const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) } it('CAVERJS-UNIT-VALIDATOR-032: should validate signatures in the tx', async () => { setStubResult() const tx = caver.transaction.valueTransfer.create(txObj) const isValid = await caver.validator.validateSender(tx) expect(isValid).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-033: should return false when signatures in the tx are invalid', async () => { setStubResult() const tx = caver.transaction.valueTransfer.create(txObj) tx.signatures = [ { V: '0x0fe9', R: '0x86c8ecbfd892be41d48443a2243274beb6daed3f72895045965a3baede4c350e', S: '0x69ea748aff6e4c106d3a8ba597d8f134745b76f12dacb581318f9da07351511a', }, ] const isValid = await caver.validator.validateSender(tx) expect(isValid).to.be.false }).timeout(100000) }) context('caver.validator.validateSender with AccountKeyFail', () => { const txObj = { from: '0xf21460730845e3652aa3cc9bc13b345e4f53984a', to: '0x59177716c34ac6e49e295a0e78e33522f14d61ee', value: '0x1', chainId: '0x7e3', gasPrice: '0x5d21dba00', nonce: '0x0', gas: '0x2faf080', signatures: [ [ '0x0fea', '0x2b5934c6d26bb3e65edf099d79c57c743d2f70744ca09d3ba9a1099edff9f173', '0x0797886edff4b449c1a599943e3a6003ae9e46b3f3f34862ced327e43fba3a6a', ], ], } function setStubResult() { const getAccountKeyResult = { keyType: 3, key: {} } const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) } it('CAVERJS-UNIT-VALIDATOR-034: should validate signatures in the tx', async () => { setStubResult() const tx = caver.transaction.valueTransfer.create(txObj) const isValid = await caver.validator.validateSender(tx) expect(isValid).to.be.false }).timeout(100000) }) context('caver.validator.validateSender with AccountKeyWeightedMultiSig', () => { const txObj = { from: '0xf21460730845e3652aa3cc9bc13b345e4f53984a', to: '0x59177716c34ac6e49e295a0e78e33522f14d61ee', value: '0x1', chainId: '0x7e3', gasPrice: '0x5d21dba00', nonce: '0x0', gas: '0x2faf080', signatures: [ [ '0x0fea', '0x2b5934c6d26bb3e65edf099d79c57c743d2f70744ca09d3ba9a1099edff9f173', '0x0797886edff4b449c1a599943e3a6003ae9e46b3f3f34862ced327e43fba3a6a', ], [ '0x0fe9', '0x63177648732ef855f800eb9f80f68501abb507f84c0d660286a6e0801334a1d2', '0x620a996623c114f2df35b11ec8ac4f3758d3ad89cf81ba13614e51908cfe9218', ], [ '0x0fe9', '0x86c8ecbfd892be41d48443a2243274beb6daed3f72895045965a3baede4c350e', '0x69ea748aff6e4c106d3a8ba597d8f134745b76f12dacb581318f9da07351511a', ], ], } function setStubResult() { const getAccountKeyResult = { keyType: 4, key: { threshold: 3, keys: [ { weight: 2, key: { x: '0x8bb6aaeb2d96d024754d3b50babf116cece68977acbe8ba6a66f14d5217c60d9', y: '0x6af020a0568661e7c72e753e80efe084a3aed9f9ac87bf44d09ce67aad3d4e01', }, }, { weight: 1, key: { x: '0xc7751c794337a93e4db041fb5401c2c816cf0a099d8fd4b1f3f555aab5dfead2', y: '0x417521bb0c03d8637f350df15ef6a6cb3cdb806bd9d10bc71982dd03ff5d9ddd', }, }, { weight: 1, key: { x: '0x3919091ba17c106dd034af508cfe00b963d173dffab2c7702890e25a96d107ca', y: '0x1bb4f148ee1984751e57d2435468558193ce84ab9a7731b842e9672e40dc0f22', }, }, ], }, } const getAccoutKeyStub = sandbox.stub(caver.validator.klaytnCall, 'getAccountKey') getAccoutKeyStub.resolves(getAccountKeyResult) } it('CAVERJS-UNIT-VALIDATOR-035: should validate signatures in the tx', async () => { setStubResult() const tx = caver.transaction.valueTransfer.create(txObj) const isValid = await caver.validator.validateSender(tx) expect(isValid).to.be.true }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-036: should return false when signatures in the tx are invalid', async () => { setStubResult() const tx = caver.transaction.valueTransfer.create(txObj) tx.signatures = [ { V: '0x0fe9', R: '0x86c8ecbfd892be41d48443a2243274beb6daed3f72895045965a3baede4c350e', S: '0x69ea748aff6e4c106d3a8ba597d8f134745b76f12dacb581318f9da07351511a', }, ] const isValid = await caver.validator.validateSender(tx) expect(isValid).to.be.false }).timeout(100000) it('CAVERJS-UNIT-VALIDATOR-037: should return false when signatures weight sum is less than threshold', async () => { setStubResult() const tx = caver.transaction.valueTransfer.create(txObj) tx.signatures = txObj.signatures[0] const isValid = await caver.validator.validateSender(tx) expect(isValid).to.be.false }).timeout(100000) }) context('caver.validator.validateSender with AccountKeyRoleBased', () => { const txObj = { from: '0xf21460730845e3652aa3cc9bc13b345e4f53984a', to: '0x59177716c34ac6e49e295a0e78e33522f14d61ee', value: '0x1', chainId: '0x7e3', gasPrice: '0x5d21dba00', nonce: '0x0', gas: '0x2faf080', signatures: [ [ '0x0fea', '0x2b5934c6d26bb3e65edf099d79c57c743d2f70744ca09d3ba9a1099edff9f173', '0x0797886edff4b449c1a599943e3a6003ae9e46b3f3f34862ced327e43fba3a6a', ], [ '0x0fe9', '0x63177648732ef855f800eb9f80f68501abb507f84c0d660286a6e0801334a1d2', '0x620a996623c114f2df35b11ec8ac4f3758d3ad89cf81ba13614e51908cfe9218', ], [ '0x0fe9', '0x86c8ecbfd892be41d48443a2243274beb6daed3f72895045965a3baede4c350e', '0x69ea748aff6e4c106d3a8ba597d8f134745b76f12dacb581318f9da07351511a', ], ], } function setStubResult(roleNum, fakeKey) { const getAccountKeyResult = { k