Skip to content

Commit

Permalink
examples/onchain-signer: Add encryptCallData()
Browse files Browse the repository at this point in the history
  • Loading branch information
matevz committed Dec 24, 2024
1 parent 3a19c03 commit 7273f83
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 35 deletions.
24 changes: 22 additions & 2 deletions examples/onchain-signer/contracts/Gasless.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
pragma solidity ^0.8.20;

import {encryptCallData} from "@oasisprotocol/sapphire-contracts/contracts/CalldataEncryption.sol";
import {EIP155Signer} from "@oasisprotocol/sapphire-contracts/contracts/EIP155Signer.sol";

struct EthereumKeypair {
Expand All @@ -25,8 +26,27 @@ contract Gasless {
bytes memory innercall
) external view returns (bytes memory output) {
bytes memory data = abi.encode(innercallAddr, innercall);
return
EIP155Signer.sign(
kp.addr,
kp.secret,
EIP155Signer.EthTx({
nonce: kp.nonce,
gasPrice: 100_000_000_000,
gasLimit: 250000,
to: address(this),
value: 0,
data: encryptCallData(abi.encodeCall(this.proxy, data)),
chainId: block.chainid
})
);
}

// Call will invoke proxy().
function makeProxyTxPlain(
address innercallAddr,
bytes memory innercall
) external view returns (bytes memory output) {
bytes memory data = abi.encode(innercallAddr, innercall);
return
EIP155Signer.sign(
kp.addr,
Expand Down
12 changes: 11 additions & 1 deletion examples/onchain-signer/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,17 @@ const config: HardhatUserConfig = {
'sapphire-testnet': { ...sapphireTestnet, accounts },
'sapphire-localnet': { ...sapphireLocalnet, accounts },
},
solidity: '0.8.20',
solidity: {
version: '0.8.20',
settings: {
// XXX: Needs to match https://github.com/oasisprotocol/sapphire-paratime/blob/main/contracts/hardhat.config.ts
optimizer: {
enabled: true,
runs: (1 << 32) - 1,
},
viaIR: true,
},
},
};

export default config;
74 changes: 42 additions & 32 deletions examples/onchain-signer/test/CommentBox.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { expect } from 'chai';
import { Context } from 'mocha';
import { ethers } from 'hardhat';
import { parseEther, Wallet } from 'ethers';
import { CommentBox, Gasless } from '../typechain-types';
Expand Down Expand Up @@ -33,55 +34,64 @@ describe('CommentBox', function () {
console.log(' . gasless pubkey', wallet.address);
});

it('Should comment', async function () {
this.timeout(10000);
async function commentGasless(t: Context, comment: string, plain: boolean) {
const provider = ethers.provider;

const innercall = commentBox.interface.encodeFunctionData('comment', [
comment,
]);

const prevCommentCount = await commentBox.commentCount();
let tx: string;
if (plain) {
tx = await gasless.makeProxyTxPlain(
await commentBox.getAddress(),
innercall,
);
} else {
tx = await gasless.makeProxyTx(await commentBox.getAddress(), innercall);
}

const tx = await commentBox.comment('Hello, world!');
await tx.wait();
// TODO: https://github.com/oasisprotocol/sapphire-paratime/issues/179
const response = await provider.broadcastTransaction(tx);
await response.wait();

// Sapphire Mainnet/Testnet: Wait a few moments for nodes to catch up.
const chainId = (await ethers.provider.getNetwork()).chainId;
if (chainId == BigInt(23294) || chainId == BigInt(23295)) {
await new Promise((r) => setTimeout(r, 6_000));
}
const receipt = await provider.getTransactionReceipt(response.hash);
if (!receipt || receipt.status != 1) throw new Error('tx failed');

expect(await commentBox.commentCount()).eq(prevCommentCount + BigInt(1));
});
}

it('Should comment gasless', async function () {
this.timeout(10000);
it('Should comment', async function () {
const prevCommentCount = await commentBox.commentCount();

const provider = ethers.provider;
const tx = await commentBox.comment('Hello, world!');
await tx.wait();

expect(await commentBox.commentCount()).eq(prevCommentCount + BigInt(1));
});

it('Should comment gasless (encrypted)', async function () {
// You can set up sapphire-localnet image and run the test like this:
// docker run -it -p8545:8545 -p8546:8546 ghcr.io/oasisprotocol/sapphire-localnet -to 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
// docker run -it -p8544-8548:8544-8548 ghcr.io/oasisprotocol/sapphire-localnet
// npx hardhat test --grep proxy --network sapphire-localnet
const chainId = (await provider.getNetwork()).chainId;
const chainId = (await ethers.provider.getNetwork()).chainId;
if (chainId == BigInt(1337)) {
this.skip();
}

const innercall = commentBox.interface.encodeFunctionData('comment', [
'Hello, free world!',
]);
await commentGasless(this, 'Hello, c10l world', false);
});

// Sapphire Mainnet/Testnet: Wait a few moments for nodes to catch up.
if (chainId == BigInt(23294) || chainId == BigInt(23295)) {
await new Promise((r) => setTimeout(r, 6_000));
it('Should comment gasless (plain)', async function () {
// You can set up sapphire-localnet image and run the test like this:
// docker run -it -p8544-8548:8544-8548 ghcr.io/oasisprotocol/sapphire-localnet
// npx hardhat test --grep proxy --network sapphire-localnet
const chainId = (await ethers.provider.getNetwork()).chainId;
if (chainId == BigInt(1337)) {
this.skip();
}

const tx = await gasless.makeProxyTx(
await commentBox.getAddress(),
innercall,
);

// TODO: https://github.com/oasisprotocol/sapphire-paratime/issues/179
const response = await provider.broadcastTransaction(tx);
await response.wait();

const receipt = await provider.getTransactionReceipt(response.hash);
if (!receipt || receipt.status != 1) throw new Error('tx failed');
await commentGasless(this, 'Hello, plain world', true);
});
});

0 comments on commit 7273f83

Please sign in to comment.