Skip to content

Commit

Permalink
Merge #2149
Browse files Browse the repository at this point in the history
2149: Implement RemoteWallet r=popzxc a=popzxc

Prototype of the new wallet interface that supports remote zkSync keys storage.

In its current form, it contains a bunch of new breaking changes.
Most notably, `getXXX` methods were removed from the abstract interface and were made protected in the `Wallet` class. This is because:
- these methods are undocumented parts of the public interface,
- have a very limited usage potential, which can be covered by using `BatchBuilder` (which is documented and is recommended for this purpose).


Co-authored-by: Igor Aleksanov <[email protected]>
  • Loading branch information
bors-matterlabs-dev[bot] and popzxc authored Jan 31, 2022
2 parents eeb1f21 + 88c55e3 commit c878015
Show file tree
Hide file tree
Showing 7 changed files with 786 additions and 383 deletions.
82 changes: 45 additions & 37 deletions core/tests/ts-tests/tests/tester/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Tester } from './tester';
import { expect } from 'chai';
import { Wallet, types, Create2WalletSigner } from 'zksync';
import { BigNumber, ethers } from 'ethers';
import { SignedTransaction, TxEthSignature } from 'zksync/build/types';
import { ChangePubKey, SignedTransaction, TxEthSignature } from 'zksync/build/types';
import { submitSignedTransactionsBatch } from 'zksync/build/wallet';
import { MAX_TIMESTAMP } from 'zksync/build/utils';
import { Transaction } from 'zksync';
Expand Down Expand Up @@ -192,7 +192,7 @@ Tester.prototype.testMultipleBatchSigners = async function (wallets: Wallet[], t
validFrom: 0,
validUntil: MAX_TIMESTAMP
};
const transfer = await sender.getTransfer(transferArgs);
const transfer = (await sender.signSyncTransfer(transferArgs)).tx;
batch.push({ tx: transfer });

const messagePart = await sender.getTransferEthMessagePart(transferArgs);
Expand Down Expand Up @@ -246,8 +246,8 @@ Tester.prototype.testMultipleWalletsWrongSignature = async function (
validFrom: 0,
validUntil: MAX_TIMESTAMP
};
const transfer1 = await from.getTransfer(_transfer1);
const transfer2 = await to.getTransfer(_transfer2);
const transfer1 = (await from.signSyncTransfer(_transfer1)).tx;
const transfer2 = (await to.signSyncTransfer(_transfer2)).tx;
// transfer1 and transfer2 are from different wallets.
const batch: SignedTransaction[] = [{ tx: transfer1 }, { tx: transfer2 }];

Expand Down Expand Up @@ -295,7 +295,7 @@ Tester.prototype.testBackwardCompatibleEthMessages = async function (
validFrom: 0,
validUntil: MAX_TIMESTAMP
};
const transfer = await from.getTransfer(_transfer);
const transfer = (await from.signSyncTransfer(_transfer)).tx as Transfer;
// Resolve all the information needed for human-readable message.
const stringAmount = from.provider.tokenSet.formatToken(_transfer.token, transfer.amount);
let stringFee = from.provider.tokenSet.formatToken(_transfer.token, transfer.fee);
Expand All @@ -322,7 +322,7 @@ Tester.prototype.testBackwardCompatibleEthMessages = async function (
validFrom: 0,
validUntil: MAX_TIMESTAMP
};
const withdraw = await to.getWithdrawFromSyncToEthereum(_withdraw);
const withdraw = (await to.signWithdrawFromSyncToEthereum(_withdraw)).tx as Withdraw;
stringFee = from.provider.tokenSet.formatToken(_transfer.token, 0);
const withdrawMessage =
`Withdraw ${stringAmount} ${stringToken}\n` +
Expand Down Expand Up @@ -414,17 +414,20 @@ Tester.prototype.testSubsidyForCREATE2ChangePubKey = async function (create2Wall

// Now we submit the CREATE2 ChangePubKey
const create2data = (create2Wallet.ethSigner() as Create2WalletSigner).create2WalletData;
const cpkTx = await create2Wallet.getChangePubKey({
feeToken: token,
fee: subsidyYotalFee,
nonce: 0,
validFrom: 0,
validUntil: MAX_TIMESTAMP,
ethAuthData: {
type: 'CREATE2',
...create2data
}
});
const cpkTx = (
await create2Wallet.signSetSigningKey({
feeToken: token,
fee: subsidyYotalFee,
nonce: 0,
validFrom: 0,
validUntil: MAX_TIMESTAMP,
ethAuthType: 'CREATE2'
})
).tx as ChangePubKey;
cpkTx.ethAuthData = {
type: 'CREATE2',
...create2data
};
await expect(transport.request('tx_submit', [cpkTx, null])).to.be.rejected;

// The transaction is submitted successfully
Expand Down Expand Up @@ -486,26 +489,31 @@ Tester.prototype.testSubsidyForBatch = async function (create2Wallet: Wallet, to
).to.be.true;

const create2data = (create2Wallet.ethSigner() as Create2WalletSigner).create2WalletData;
const cpkTx = await create2Wallet.getChangePubKey({
feeToken: token,
fee: BigNumber.from(0),
nonce: 0,
validFrom: 0,
validUntil: MAX_TIMESTAMP,
ethAuthData: {
type: 'CREATE2',
...create2data
}
});
const transferTx = await create2Wallet.getTransfer({
token,
fee: subsidyYotalFee,
nonce: 1,
validFrom: 0,
validUntil: MAX_TIMESTAMP,
amount: BigNumber.from('1'),
to: create2Wallet.address()
});
const cpkTx = (
await create2Wallet.signSetSigningKey({
feeToken: token,
fee: BigNumber.from(0),
nonce: 0,
validFrom: 0,
validUntil: MAX_TIMESTAMP,
ethAuthType: 'CREATE2'
})
).tx as ChangePubKey;
cpkTx.ethAuthData = {
type: 'CREATE2',
...create2data
};
const transferTx = (
await create2Wallet.signSyncTransfer({
token,
fee: subsidyYotalFee,
nonce: 1,
validFrom: 0,
validUntil: MAX_TIMESTAMP,
amount: BigNumber.from('1'),
to: create2Wallet.address()
})
).tx;
const txs = [{ tx: cpkTx }, { tx: transferTx }];

await expect(transport.request('submit_txs_batch', [txs, []]), 'Submitted transaction with the wrong fee').to.be
Expand Down
16 changes: 8 additions & 8 deletions core/tests/ts-tests/tests/tester/swap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Tester.prototype.testSwapMissingSignatures = async function (
) {
const { totalFee: fee } = await this.syncProvider.getTransactionFee('Swap', walletA.address(), tokenA);

const orderA = await walletA.getOrder({
const orderA = await walletA.signOrder({
tokenSell: tokenA,
tokenBuy: tokenB,
amount,
Expand All @@ -52,7 +52,7 @@ Tester.prototype.testSwapMissingSignatures = async function (
})
});

const orderB = await walletB.getOrder({
const orderB = await walletB.signOrder({
tokenSell: tokenB,
tokenBuy: tokenA,
amount: amount.mul(2),
Expand Down Expand Up @@ -98,7 +98,7 @@ Tester.prototype.testSwapNFT = async function (
const { totalFee: fee } = await this.syncProvider.getTransactionFee('Swap', walletA.address(), token);
expect(await walletB.getNFT(nft), 'wallet does not own an NFT').to.exist;

const orderA = await walletA.getOrder({
const orderA = await walletA.signOrder({
tokenSell: token,
tokenBuy: nft,
amount,
Expand All @@ -108,7 +108,7 @@ Tester.prototype.testSwapNFT = async function (
})
});

const orderB = await walletB.getOrder({
const orderB = await walletB.signOrder({
tokenSell: nft,
tokenBuy: token,
amount: 1,
Expand Down Expand Up @@ -143,7 +143,7 @@ Tester.prototype.testSwap = async function (
const stateABefore = (await this.syncProvider.getState(walletA.address())).committed;
const stateBBefore = (await this.syncProvider.getState(walletB.address())).committed;

const orderA = await walletA.getOrder({
const orderA = await walletA.signOrder({
tokenSell: tokenA,
tokenBuy: tokenB,
amount,
Expand All @@ -153,7 +153,7 @@ Tester.prototype.testSwap = async function (
})
});

const orderB = await walletB.getOrder({
const orderB = await walletB.signOrder({
tokenSell: tokenB,
tokenBuy: tokenA,
amount: amount.mul(2),
Expand Down Expand Up @@ -207,7 +207,7 @@ Tester.prototype.testSwapBatch = async function (
const nonceBefore = await walletA.getNonce();

// these are limit orders, so they can be reused
const orderA = await walletA.getLimitOrder({
const orderA = await walletA.signLimitOrder({
tokenSell: tokenA,
tokenBuy: tokenB,
ratio: utils.weiRatio({
Expand All @@ -216,7 +216,7 @@ Tester.prototype.testSwapBatch = async function (
})
});

const orderB = await walletB.getLimitOrder({
const orderB = await walletB.signLimitOrder({
tokenSell: tokenB,
tokenBuy: tokenA,
ratio: utils.weiRatio({
Expand Down
2 changes: 1 addition & 1 deletion sdk/zksync.js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "zksync",
"version": "0.11.6",
"version": "0.12.0-alpha.1",
"license": "MIT",
"main": "build/index.js",
"types": "build/index.d.ts",
Expand Down
88 changes: 8 additions & 80 deletions sdk/zksync.js/src/abstract-wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,14 @@ import { BatchBuilder, BatchBuilderInternalTx } from './batch-builder';
import {
AccountState,
Address,
ChangePubKey,
ChangePubKeyCREATE2,
ChangePubKeyECDSA,
ChangePubKeyOnchain,
ChangePubkeyTypes,
ForcedExit,
MintNFT,
NFT,
Nonce,
Order,
PubKeyHash,
SignedTransaction,
Swap,
TokenLike,
Transfer,
TxEthSignature,
Withdraw,
WithdrawNFT,
TokenRatio,
WeiRatio,
Toggle2FARequest,
Expand Down Expand Up @@ -208,16 +198,6 @@ export abstract class AbstractWallet {

// Transfer part

abstract getTransfer(transfer: {
to: Address;
token: TokenLike;
amount: BigNumberish;
fee: BigNumberish;
nonce: number;
validFrom: number;
validUntil: number;
}): Promise<Transfer>;

abstract signSyncTransfer(transfer: {
to: Address;
token: TokenLike;
Expand All @@ -240,16 +220,6 @@ export abstract class AbstractWallet {

// ChangePubKey part

abstract getChangePubKey(changePubKey: {
feeToken: TokenLike;
fee: BigNumberish;
nonce: number;
ethAuthData?: ChangePubKeyOnchain | ChangePubKeyECDSA | ChangePubKeyCREATE2;
ethSignature?: string;
validFrom: number;
validUntil: number;
}): Promise<ChangePubKey>;

abstract signSetSigningKey(changePubKey: {
feeToken: TokenLike;
fee: BigNumberish;
Expand All @@ -271,16 +241,6 @@ export abstract class AbstractWallet {

// Withdraw part

abstract getWithdrawFromSyncToEthereum(withdraw: {
ethAddress: string;
token: TokenLike;
amount: BigNumberish;
fee: BigNumberish;
nonce: number;
validFrom: number;
validUntil: number;
}): Promise<Withdraw>;

abstract signWithdrawFromSyncToEthereum(withdraw: {
ethAddress: string;
token: TokenLike;
Expand All @@ -304,15 +264,6 @@ export abstract class AbstractWallet {

// Forced exit part

abstract getForcedExit(forcedExit: {
target: Address;
token: TokenLike;
fee: BigNumberish;
nonce: number;
validFrom?: number;
validUntil?: number;
}): Promise<ForcedExit>;

abstract signSyncForcedExit(forcedExit: {
target: Address;
token: TokenLike;
Expand All @@ -333,17 +284,22 @@ export abstract class AbstractWallet {

// Swap part

abstract getLimitOrder(order: {
async signLimitOrder(order: {
tokenSell: TokenLike;
tokenBuy: TokenLike;
ratio: TokenRatio | WeiRatio;
recipient?: Address;
nonce?: Nonce;
validFrom?: number;
validUntil?: number;
}): Promise<Order>;
}): Promise<Order> {
return await this.signOrder({
...order,
amount: 0
});
}

abstract getOrder(order: {
abstract signOrder(order: {
tokenSell: TokenLike;
tokenBuy: TokenLike;
ratio: TokenRatio | WeiRatio;
Expand All @@ -354,16 +310,6 @@ export abstract class AbstractWallet {
validUntil?: number;
}): Promise<Order>;

abstract signOrder(order: Order): Promise<Order>;

abstract getSwap(swap: {
orders: [Order, Order];
feeToken: number;
amounts: [BigNumberish, BigNumberish];
nonce: number;
fee: BigNumberish;
}): Promise<Swap>;

abstract signSyncSwap(swap: {
orders: [Order, Order];
feeToken: number;
Expand All @@ -382,14 +328,6 @@ export abstract class AbstractWallet {

// Mint NFT part

abstract getMintNFT(mintNFT: {
recipient: string;
contentHash: string;
feeToken: TokenLike;
fee: BigNumberish;
nonce: number;
}): Promise<MintNFT>;

abstract signMintNFT(mintNFT: {
recipient: string;
contentHash: string;
Expand All @@ -408,16 +346,6 @@ export abstract class AbstractWallet {

// Withdraw NFT part

abstract getWithdrawNFT(withdrawNFT: {
to: string;
token: TokenLike;
feeToken: TokenLike;
fee: BigNumberish;
nonce: number;
validFrom: number;
validUntil: number;
}): Promise<WithdrawNFT>;

abstract signWithdrawNFT(withdrawNFT: {
to: string;
token: number;
Expand Down
1 change: 1 addition & 0 deletions sdk/zksync.js/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { Wallet, Transaction, ETHOperation, submitSignedTransaction, submitSignedTransactionsBatch } from './wallet';
export { RemoteWallet } from './remote-wallet';
export { Provider, ETHProxy, getDefaultProvider } from './provider';
export { RestProvider, getDefaultRestProvider } from './rest-provider';
export { SyncProvider } from './provider-interface';
Expand Down
Loading

0 comments on commit c878015

Please sign in to comment.