wormhole/staging/algorand/test/testlib.js

121 lines
3.8 KiB
JavaScript

/**
*
* Pricecaster Testing Library.
*
* Copyright 2022 Wormhole Project Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
const web3EthAbi = require('web3-eth-abi')
const web3Utils = require('web3-utils')
const elliptic = require('elliptic')
class TestLib {
/**
* Create a packed and signed VAA for testing.
* See https://github.com/certusone/wormhole/blob/dev.v2/design/0001_generic_message_passing.md
*
* @param {} guardianSetIndex The guardian set index
* @param {*} signers The list of private keys for signing the VAA
* @param {*} timestamp The timestamp of VAA
* @param {*} nonce The nonce.
* @param {*} emitterChainId The emitter chain identifier
* @param {*} emitterAddress The emitter chain address, prefixed with 0x
* @param {*} sequence The sequence.
* @param {*} consistencyLevel The reported consistency level
* @param {*} payload This VAA Payload hex string, prefixed with 0x
*/
createSignedVAA (guardianSetIndex,
signers,
timestamp,
nonce,
emitterChainId,
emitterAddress,
sequence,
consistencyLevel,
payload) {
const body = [
web3EthAbi.encodeParameter('uint32', timestamp).substring(2 + (64 - 8)),
web3EthAbi.encodeParameter('uint32', nonce).substring(2 + (64 - 8)),
web3EthAbi.encodeParameter('uint16', emitterChainId).substring(2 + (64 - 4)),
web3EthAbi.encodeParameter('bytes32', emitterAddress).substring(2),
web3EthAbi.encodeParameter('uint64', sequence).substring(2 + (64 - 16)),
web3EthAbi.encodeParameter('uint8', consistencyLevel).substring(2 + (64 - 2)),
payload.substr(2)
]
const hash = web3Utils.keccak256(web3Utils.keccak256('0x' + body.join('')))
// console.log('VAA body Hash: ', hash)
let signatures = ''
for (const i in signers) {
// eslint-disable-next-line new-cap
const ec = new elliptic.ec('secp256k1')
const key = ec.keyFromPrivate(signers[i])
const signature = key.sign(hash.substr(2), { canonical: true })
const packSig = [
web3EthAbi.encodeParameter('uint8', i).substring(2 + (64 - 2)),
this.zeroPadBytes(signature.r.toString(16), 32),
this.zeroPadBytes(signature.s.toString(16), 32),
web3EthAbi.encodeParameter('uint8', signature.recoveryParam).substr(2 + (64 - 2))
]
signatures += packSig.join('')
}
const vm = [
web3EthAbi.encodeParameter('uint8', 1).substring(2 + (64 - 2)),
web3EthAbi.encodeParameter('uint32', guardianSetIndex).substring(2 + (64 - 8)),
web3EthAbi.encodeParameter('uint8', signers.length).substring(2 + (64 - 2)),
signatures,
body.join('')
].join('')
return vm
}
zeroPadBytes (value, length) {
while (value.length < 2 * length) {
value = '0' + value
}
return value
}
shuffle (array) {
let currentIndex = array.length; let randomIndex
// While there remain elements to shuffle...
while (currentIndex !== 0) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex)
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]]
}
return array
}
}
module.exports = {
TestLib
}