diff --git a/.gitignore b/.gitignore index 80d25ea..c64ebad 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ /target/ .envrc -.DS_Store \ No newline at end of file +.DS_Store +node_modules +.yarn diff --git a/src/signers/common.rs b/src/signers/common.rs index 59431eb..f0b1784 100644 --- a/src/signers/common.rs +++ b/src/signers/common.rs @@ -27,14 +27,11 @@ pub async fn handle_eth_sign_transaction( let tx_envelope = tx_request.build(&signer).await?; println!("tx_envelope: {:?}", tx_envelope.tx_type()); println!("tx_envelope: {:?}", tx_envelope); - tx_envelope.signature_hash(); let mut encoded_tx = vec![]; - encoded_tx.push(tx_envelope.tx_type() as u8); tx_envelope.encode(&mut encoded_tx); println!("encoded_tx: {:?}", encoded_tx); let rlp_hex = hex::encode_prefixed(encoded_tx); - println!("rlp_hex: {:?}", rlp_hex); Ok(JsonRpcReply { diff --git a/test/index.js b/test/index.js new file mode 100644 index 0000000..2c36097 --- /dev/null +++ b/test/index.js @@ -0,0 +1,123 @@ +const axios = require('axios') +const readlineSync = require('readline-sync'); +const { createPublicClient, http, parseEther, createWalletClient, formatEther } = require('viem'); +const { privateKeyToAccount } = require('viem/accounts'); +const { anvil } = require('viem/chains') + +const DEAD_ADDRESS = '0x000000000000000000000000000000000000dEaD' + +async function main() { + console.log('Welcome to Upnode signer-proxy integration test') + + const publicClient = createPublicClient({ + chain: anvil, + transport: http() + }) + + const testWalletClient = createWalletClient({ + chain: anvil, + transport: http(), + }) + + // test dummy account, don't use in the production!!! + const testAccount = privateKeyToAccount('0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80') + + let blockNumber, chainId; + + try { + blockNumber = await publicClient.getBlockNumber() + chainId = await publicClient.chain.id + } catch (err) { + console.error(err) + console.log("Can't connect to the chain, please start anvil") + } + + console.log('Chain', chainId, 'connected block number', blockNumber) + + const endpoint = readlineSync.question('Enter signer endpoint: ') + + console.log('Getting wallet address...') + + const addressResponse = await axios.get(`${endpoint}/address`); + const address = addressResponse.data.address + + console.log('Wallet Address:', address) + + { + // Transfer some fund to the wallet + const hash = await testWalletClient.sendTransaction({ + account: testAccount, + to: address, + value: parseEther('0.0002'), + }) + + await publicClient.waitForTransactionReceipt({ hash }) + } + + // Get target balance before + const balanceBefore = await publicClient.getBalance({ + address: DEAD_ADDRESS, + }) + + console.log('Balance Before:', formatEther(balanceBefore)) + + const nonce = await publicClient.getTransactionCount({ address }) + + const transaction = { + from: address, + to: DEAD_ADDRESS, + value: parseEther('0.0001').toString(), + gas: 21500, + gasPrice: 1000000000, + nonce, + data: '0x123456', + chainId: chainId, + }; + + const txResponse = await axios.post(endpoint, { + jsonrpc: '2.0', + method: 'eth_signTransaction', + params: [transaction], + id: 1, + }) + const rawTx = txResponse.data.result + + console.log('Signed Tx:', rawTx) + + { + // Submit signed transaction + const hash = await publicClient.sendRawTransaction({ + serializedTransaction: rawTx, + }) + + console.log('Transaction submitted hash:', hash) + setTimeout(() => console.log("If it has been taking long then there's something wrong..."), 5000) + + await publicClient.waitForTransactionReceipt({ hash }) + const transaction = await publicClient.getTransaction({ hash }) + + console.log('Transaction confirmed') + + if (transaction.input != '0x123456') { + console.error('!!! Transaction input is not matched !!!') + } + } + + // Get target balance before + const balanceAfter = await publicClient.getBalance({ + address: DEAD_ADDRESS, + }) + + console.log('Balance After:', formatEther(balanceAfter)) + + if (balanceAfter - balanceBefore === parseEther('0.0001')) { + console.log('Test passed') + } else { + console.log('!!! Incorrect balance diff:', formatEther(balanceAfter - balanceBefore), '!!!') + } +} + +main().then(() => process.exit(0)).catch(err => { + console.error(err) + process.exit(1) +}) diff --git a/test/package.json b/test/package.json new file mode 100644 index 0000000..e435234 --- /dev/null +++ b/test/package.json @@ -0,0 +1,16 @@ +{ + "name": "signer-proxy-integration-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "node index.js" + }, + "author": "", + "license": "ISC", + "dependencies": { + "axios": "^1.7.4", + "readline-sync": "^1.4.10", + "viem": "^2.20.0" + } +} diff --git a/test/yarn.lock b/test/yarn.lock new file mode 100644 index 0000000..ebe8803 --- /dev/null +++ b/test/yarn.lock @@ -0,0 +1,241 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10c0 + +"@adraffy/ens-normalize@npm:1.10.0": + version: 1.10.0 + resolution: "@adraffy/ens-normalize@npm:1.10.0" + checksum: 10c0/78ae700847a2516d5a0ae12c4e23d09392a40c67e73b137eb7189f51afb1601c8d18784aeda2ed288a278997824dc924d1f398852c21d41ee2c4c564f2fb4d26 + languageName: node + linkType: hard + +"@noble/curves@npm:1.4.0": + version: 1.4.0 + resolution: "@noble/curves@npm:1.4.0" + dependencies: + "@noble/hashes": "npm:1.4.0" + checksum: 10c0/31fbc370df91bcc5a920ca3f2ce69c8cf26dc94775a36124ed8a5a3faf0453badafd2ee4337061ffea1b43c623a90ee8b286a5a81604aaf9563bdad7ff795d18 + languageName: node + linkType: hard + +"@noble/curves@npm:^1.4.0": + version: 1.5.0 + resolution: "@noble/curves@npm:1.5.0" + dependencies: + "@noble/hashes": "npm:1.4.0" + checksum: 10c0/89faed98e7ff1fee086777afcf63b7ec237121ebfe09495eb9ff7f73c7dd696000c795a24a1bedadc804b592d4b3c655f2e4a9fe9a3afe312a9e6376558d3737 + languageName: node + linkType: hard + +"@noble/curves@npm:~1.4.0": + version: 1.4.2 + resolution: "@noble/curves@npm:1.4.2" + dependencies: + "@noble/hashes": "npm:1.4.0" + checksum: 10c0/65620c895b15d46e8087939db6657b46a1a15cd4e0e4de5cd84b97a0dfe0af85f33a431bb21ac88267e3dc508618245d4cb564213959d66a84d690fe18a63419 + languageName: node + linkType: hard + +"@noble/hashes@npm:1.4.0, @noble/hashes@npm:^1.4.0, @noble/hashes@npm:~1.4.0": + version: 1.4.0 + resolution: "@noble/hashes@npm:1.4.0" + checksum: 10c0/8c3f005ee72e7b8f9cff756dfae1241485187254e3f743873e22073d63906863df5d4f13d441b7530ea614b7a093f0d889309f28b59850f33b66cb26a779a4a5 + languageName: node + linkType: hard + +"@scure/base@npm:~1.1.6": + version: 1.1.7 + resolution: "@scure/base@npm:1.1.7" + checksum: 10c0/2d06aaf39e6de4b9640eb40d2e5419176ebfe911597856dcbf3bc6209277ddb83f4b4b02cb1fd1208f819654268ec083da68111d3530bbde07bae913e2fc2e5d + languageName: node + linkType: hard + +"@scure/bip32@npm:1.4.0": + version: 1.4.0 + resolution: "@scure/bip32@npm:1.4.0" + dependencies: + "@noble/curves": "npm:~1.4.0" + "@noble/hashes": "npm:~1.4.0" + "@scure/base": "npm:~1.1.6" + checksum: 10c0/6849690d49a3bf1d0ffde9452eb16ab83478c1bc0da7b914f873e2930cd5acf972ee81320e3df1963eb247cf57e76d2d975b5f97093d37c0e3f7326581bf41bd + languageName: node + linkType: hard + +"@scure/bip39@npm:1.3.0": + version: 1.3.0 + resolution: "@scure/bip39@npm:1.3.0" + dependencies: + "@noble/hashes": "npm:~1.4.0" + "@scure/base": "npm:~1.1.6" + checksum: 10c0/1ae1545a7384a4d9e33e12d9e9f8824f29b0279eb175b0f0657c0a782c217920054f9a1d28eb316a417dfc6c4e0b700d6fbdc6da160670107426d52fcbe017a8 + languageName: node + linkType: hard + +"abitype@npm:1.0.5": + version: 1.0.5 + resolution: "abitype@npm:1.0.5" + peerDependencies: + typescript: ">=5.0.4" + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + checksum: 10c0/dc954877fba19e2b7a70f1025807d69fa5aabec8bd58ce94e68d1a5ec1697fff3fe5214b4392508db7191762150f19a2396cf66ffb1d3ba8c1f37a89fd25e598 + languageName: node + linkType: hard + +"asynckit@npm:^0.4.0": + version: 0.4.0 + resolution: "asynckit@npm:0.4.0" + checksum: 10c0/d73e2ddf20c4eb9337e1b3df1a0f6159481050a5de457c55b14ea2e5cb6d90bb69e004c9af54737a5ee0917fcf2c9e25de67777bbe58261847846066ba75bc9d + languageName: node + linkType: hard + +"axios@npm:^1.7.4": + version: 1.7.4 + resolution: "axios@npm:1.7.4" + dependencies: + follow-redirects: "npm:^1.15.6" + form-data: "npm:^4.0.0" + proxy-from-env: "npm:^1.1.0" + checksum: 10c0/5ea1a93140ca1d49db25ef8e1bd8cfc59da6f9220159a944168860ad15a2743ea21c5df2967795acb15cbe81362f5b157fdebbea39d53117ca27658bab9f7f17 + languageName: node + linkType: hard + +"combined-stream@npm:^1.0.8": + version: 1.0.8 + resolution: "combined-stream@npm:1.0.8" + dependencies: + delayed-stream: "npm:~1.0.0" + checksum: 10c0/0dbb829577e1b1e839fa82b40c07ffaf7de8a09b935cadd355a73652ae70a88b4320db322f6634a4ad93424292fa80973ac6480986247f1734a1137debf271d5 + languageName: node + linkType: hard + +"delayed-stream@npm:~1.0.0": + version: 1.0.0 + resolution: "delayed-stream@npm:1.0.0" + checksum: 10c0/d758899da03392e6712f042bec80aa293bbe9e9ff1b2634baae6a360113e708b91326594c8a486d475c69d6259afb7efacdc3537bfcda1c6c648e390ce601b19 + languageName: node + linkType: hard + +"follow-redirects@npm:^1.15.6": + version: 1.15.6 + resolution: "follow-redirects@npm:1.15.6" + peerDependenciesMeta: + debug: + optional: true + checksum: 10c0/9ff767f0d7be6aa6870c82ac79cf0368cd73e01bbc00e9eb1c2a16fbb198ec105e3c9b6628bb98e9f3ac66fe29a957b9645bcb9a490bb7aa0d35f908b6b85071 + languageName: node + linkType: hard + +"form-data@npm:^4.0.0": + version: 4.0.0 + resolution: "form-data@npm:4.0.0" + dependencies: + asynckit: "npm:^0.4.0" + combined-stream: "npm:^1.0.8" + mime-types: "npm:^2.1.12" + checksum: 10c0/cb6f3ac49180be03ff07ba3ff125f9eba2ff0b277fb33c7fc47569fc5e616882c5b1c69b9904c4c4187e97dd0419dd03b134174756f296dec62041e6527e2c6e + languageName: node + linkType: hard + +"isows@npm:1.0.4": + version: 1.0.4 + resolution: "isows@npm:1.0.4" + peerDependencies: + ws: "*" + checksum: 10c0/46f43b07edcf148acba735ddfc6ed985e1e124446043ea32b71023e67671e46619c8818eda8c34a9ac91cb37c475af12a3aeeee676a88a0aceb5d67a3082313f + languageName: node + linkType: hard + +"mime-db@npm:1.52.0": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 10c0/0557a01deebf45ac5f5777fe7740b2a5c309c6d62d40ceab4e23da9f821899ce7a900b7ac8157d4548ddbb7beffe9abc621250e6d182b0397ec7f10c7b91a5aa + languageName: node + linkType: hard + +"mime-types@npm:^2.1.12": + version: 2.1.35 + resolution: "mime-types@npm:2.1.35" + dependencies: + mime-db: "npm:1.52.0" + checksum: 10c0/82fb07ec56d8ff1fc999a84f2f217aa46cb6ed1033fefaabd5785b9a974ed225c90dc72fff460259e66b95b73648596dbcc50d51ed69cdf464af2d237d3149b2 + languageName: node + linkType: hard + +"proxy-from-env@npm:^1.1.0": + version: 1.1.0 + resolution: "proxy-from-env@npm:1.1.0" + checksum: 10c0/fe7dd8b1bdbbbea18d1459107729c3e4a2243ca870d26d34c2c1bcd3e4425b7bcc5112362df2d93cc7fb9746f6142b5e272fd1cc5c86ddf8580175186f6ad42b + languageName: node + linkType: hard + +"readline-sync@npm:^1.4.10": + version: 1.4.10 + resolution: "readline-sync@npm:1.4.10" + checksum: 10c0/0a4d0fe4ad501f8f005a3c9cbf3cc0ae6ca2ced93e9a1c7c46f226bdfcb6ef5d3f437ae7e9d2e1098ee13524a3739c830e4c8dbc7f543a693eecd293e41093a3 + languageName: node + linkType: hard + +"signer-proxy-integration-test@workspace:.": + version: 0.0.0-use.local + resolution: "signer-proxy-integration-test@workspace:." + dependencies: + axios: "npm:^1.7.4" + readline-sync: "npm:^1.4.10" + viem: "npm:^2.20.0" + languageName: unknown + linkType: soft + +"viem@npm:^2.20.0": + version: 2.20.0 + resolution: "viem@npm:2.20.0" + dependencies: + "@adraffy/ens-normalize": "npm:1.10.0" + "@noble/curves": "npm:1.4.0" + "@noble/hashes": "npm:1.4.0" + "@scure/bip32": "npm:1.4.0" + "@scure/bip39": "npm:1.3.0" + abitype: "npm:1.0.5" + isows: "npm:1.0.4" + webauthn-p256: "npm:0.0.5" + ws: "npm:8.17.1" + peerDependencies: + typescript: ">=5.0.4" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/6e59a90be6323e152cfe8bfbe617645da0262db29616d2802fb66a5088e9482cc37d4b6dbf90a151a6ea767a4959141c80dd7761742b996d6552008e9e521c5e + languageName: node + linkType: hard + +"webauthn-p256@npm:0.0.5": + version: 0.0.5 + resolution: "webauthn-p256@npm:0.0.5" + dependencies: + "@noble/curves": "npm:^1.4.0" + "@noble/hashes": "npm:^1.4.0" + checksum: 10c0/8a445dddaf0e699363a0a7bca51742f672dbbec427c1a97618465bfc418df0eff10d3f1cf5e43bcd0cd0dc5abcdaad7914916c06c84107eaf226f5a1d0690c13 + languageName: node + linkType: hard + +"ws@npm:8.17.1": + version: 8.17.1 + resolution: "ws@npm:8.17.1" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 10c0/f4a49064afae4500be772abdc2211c8518f39e1c959640457dcee15d4488628620625c783902a52af2dd02f68558da2868fd06e6fd0e67ebcd09e6881b1b5bfe + languageName: node + linkType: hard