Skip to content

Commit

Permalink
Merging the develop branch into the main branch (v3.5.0)
Browse files Browse the repository at this point in the history
This merge contains the following set of changes:

- Sending direct deposits (tokens and native as well) to the account (#87)

- Prepared for review (#88)

- Implemented ability to add extra funds during gift-card creating (#89)
  • Loading branch information
EvgenKor authored Jul 10, 2023
2 parents e3c88b8 + ed3d2cc commit c262031
Show file tree
Hide file tree
Showing 8 changed files with 3,660 additions and 1,337 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ Suppose you already done local running and set appropriated parameters and setti

`get-token-balance` get the linked account balance (tokens)

`get-token-allowance <spender>` check token allowance to spend by provided address

`testnet-mint <amount>` mint some unshielded tokens (available on testnets only)

`transfer <to> <amount>` transfer native coins to the destination L1 address
Expand All @@ -75,7 +77,9 @@ Suppose you already done local running and set appropriated parameters and setti

`deposit-shielded-ephemeral <amount> <index>` deposit some tokens from the internal ephemeral address (permit scheme)

`direct-deposit <shielded address> <amount> [times]` send tokens to the pool directly to receive it on the specified zkAddress. Specify `times` numeric value to repeat the operation several times
`direct-deposit <amount> [times]` send tokens to the pool directly to receive it on own account. Additional approve transaction will be initiated if needed. Specify `times` numeric value to repeat the operation several times

`direct-deposit-native <amount> [times]` send native coins to the pool directly to wrap and receive it on own account. Specify `times` numeric value to repeat the operation several times

`transfer-shielded <shielded address> <amount> [times | +]` move shielded tokens to the another zkBob account (inside a pool). You can specify `times` numeric value to repeat the operation several times ***OR*** enter the multitransfer mode with adding `+` sign at the end of the command

Expand All @@ -85,6 +89,8 @@ Suppose you already done local running and set appropriated parameters and setti

`compliance-report` generate compliance report: history + evidence of transactions ownership

`pending-dd` print pending direct deposits for the account

## Transactions configuration

`max-transfer` calculate maximum available token amount for outcoming transaction (transfer or withdrawal)
Expand Down
40 changes: 31 additions & 9 deletions client-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@
"feeDecimals": 2,
"depositScheme": "permit"
},
"BOB-goerli": {
"BOB2USDC-goerli": {
"chainId": 5,
"poolAddress": "0x49661694a71B3Dab9F25E86D5df2809B170c56E6",
"tokenAddress": "0x97a4ab97028466FE67F18A6cd67559BAABE391b8",
"tokenAddress": "0x28B531401Ee3f17521B3772c13EAF3f86C2Fe780",
"relayerUrls": ["https://dev-relayer.thgkjlr.website/"],
"delegatedProverUrls": [],
"coldStorageConfigPath": "",
"feeDecimals": 2,
"depositScheme": "permit"
"depositScheme": "usdc-polygon",
"ddSubgraph": "zkbob-bob-goerli"
},
"WETH-goerli": {
"chainId": 5,
Expand All @@ -30,7 +31,9 @@
"delegatedProverUrls": [],
"coldStorageConfigPath": "",
"minTxAmount": 0,
"depositScheme": "permit2"
"depositScheme": "permit2",
"isNative": true,
"ddSubgraph": "zkbob-eth-goerli"
},
"USDC-goerli": {
"chainId": 5,
Expand All @@ -51,7 +54,8 @@
"delegatedProverUrls": [],
"coldStorageConfigPath": "",
"feeDecimals": 2,
"depositScheme": "permit"
"depositScheme": "permit",
"ddSubgraph": "zkbob-bob-goerli-opt"
}
},

Expand Down Expand Up @@ -89,19 +93,37 @@

"minters": {
"BOB-sepolia": "",
"BOB-goerli": "",
"BOB2USDC-goerli": "",
"WETH-goerli": "",
"USDC-goerli": "",
"BOB-op-goerli": ""
},

"cloudApi": {
"BOB-sepolia": "http://45.77.217.163:8701",
"BOB-goerli": "",
"BOB2USDC-goerli": "",
"WETH-goerli": "",
"USDC-goerli": "",
"BOB-op-goerli": ""
},

"redemptionUrls": {
"BOB-sepolia": "https://staging--zkbob.netlify.app",
"BOB-goerli": "",
"BOB-op-goerli": ""
"BOB2USDC-goerli": "https://staging--zkbob.netlify.app",
"WETH-goerli": "https://staging--zkbob.netlify.app",
"USDC-goerli": "https://staging--zkbob.netlify.app",
"BOB-op-goerli": "https://staging--zkbob.netlify.app"
},

"migrations": {
"BOB2USDC-goerli": {
"oldTokens": {
"BOB": {
"tokenAddress": "0x97a4ab97028466FE67F18A6cd67559BAABE391b8",
"firstTimestamp": 0,
"lastTimestamp": 1688651376
}
}
}
}
}
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "zkbob-console",
"version": "3.4.0",
"version": "3.5.0",
"license": "MIT",
"author": "Dmitry Vdovin <voidxnull@gmail.com>",
"homepage": "https://github.com/zkBob/zkbob-console",
Expand Down Expand Up @@ -38,8 +38,8 @@
"tslib": "^2.3.1",
"uuid": "^9.0.0",
"web3": "^1.7.1",
"zeropool-support-js": "https://github.com/zkBob/zeropool-support-js#0.8.0",
"zkbob-client-js": "5.0.0"
"zeropool-support-js": "https://github.com/zkBob/zeropool-support-js#0.9.0",
"zkbob-client-js": "5.1.0"
},
"devDependencies": {
"@parcel/compressor-gzip": "^2.0.1",
Expand Down
94 changes: 57 additions & 37 deletions src/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import HDWalletProvider from '@truffle/hdwallet-provider';
import { v4 as uuidv4 } from 'uuid';
import { env } from './environment';
import Web3 from 'web3';
import { DirectDepositType, DirectDeposit } from 'zkbob-client-js/lib/dd';
import { PreparedTransaction } from 'zkbob-client-js/lib/networks/network';

const PERMIT2_CONTRACT = '0x000000000022D473030F116dDEE9F6B43aC78BA3';

Expand Down Expand Up @@ -218,12 +220,29 @@ export class Account {
return env.pools[this.getCurrentPool()].delegatedProverUrls
}

public tokenSymbol(): string {
public tokenSymbol(timestamp: number | undefined = undefined): string {
if (timestamp !== undefined) {
const migrationConf = env.migrations[this.getCurrentPool()];
if (migrationConf) {
const oldTokens = migrationConf.oldTokens;
if (oldTokens) {
for (const oldTokenName of Object.keys(oldTokens)) {
const oldConfig = oldTokens[oldTokenName];
if (timestamp >= (oldConfig.firstTimestamp ?? 0) &&
timestamp < oldConfig.lastTimestamp)
{
return oldTokenName;
}
}
}
}
}

return this.tokenSymbols[this.getCurrentPool()] ?? 'UNK';
}

public shTokenSymbol(): string {
return `sh${this.tokenSymbol()}`;
public shTokenSymbol(timestamp: number | undefined = undefined): string {
return `sh${this.tokenSymbol(timestamp)}`;
}

public depositScheme(): DepositType {
Expand Down Expand Up @@ -464,7 +483,11 @@ export class Account {
}

public async generateComplianceReport(startTimestamp: number | undefined, endTimestamp: number | undefined): Promise<ComplianceHistoryRecord[]> {
return this.zpClient.getComplianceReport(startTimestamp, endTimestamp);
return this.getZpClient().getComplianceReport(startTimestamp, endTimestamp);
}

public async getPendingDirectDeposits(): Promise<DirectDeposit[]> {
return this.getZpClient().getPendingDDs();
}

public async rollback(index: bigint): Promise<bigint> {
Expand All @@ -479,11 +502,14 @@ export class Account {
return this.getZpClient().cleanState();
}

// TODO: Support multiple tokens
public async getTokenBalance(): Promise<string> {
return await this.getClient().getTokenBalance(this.getTokenAddr());
}

public async getTokenAllowance(spender: string): Promise<bigint> {
return await this.getClient().allowance(this.getTokenAddr(), spender);
}

public async mint(amount: bigint): Promise<string> {
const minterAddr = env.minters[this.getCurrentPool()];
if (minterAddr) {
Expand Down Expand Up @@ -631,28 +657,39 @@ export class Account {
}

// returns txHash in promise
public async directDeposit(to: string, amount: bigint): Promise<string> {
if (await this.verifyShieldedAddress(to)) {
const ddFee = (await this.getZpClient().directDepositFee());
const amountWithFeeWei = await this.getZpClient().shieldedAmountToWei(amount + ddFee);
public async directDeposit(amount: bigint, ddType: DirectDepositType = DirectDepositType.Token): Promise<string> {
const ddFee = (await this.getZpClient().directDepositFee());
const amountWithFeeWei = await this.getZpClient().shieldedAmountToWei(amount + ddFee);

const ddContract = await this.getClient().getDirectDepositContract(this.getPoolAddr());
const ddContract = await this.getClient().getDirectDepositContract(this.getPoolAddr());

if (ddType == DirectDepositType.Token) {
let totalApproveAmount = amountWithFeeWei;
const currentAllowance = await this.getClient().allowance(this.getTokenAddr(), ddContract);
if (totalApproveAmount > currentAllowance) {
totalApproveAmount -= currentAllowance;
console.log(`Increasing allowance for the direct deposit contact (${ddContract}) to spend our tokens (+ ${await this.weiToHuman(totalApproveAmount)} ${this.tokenSymbol()})`);
await this.getClient().increaseAllowance(this.getTokenAddr(), ddContract, totalApproveAmount.toString());
console.log(`Approving allowance for ${ddContract} to spend max amount of our tokens`);
const maxTokensAmount = 2n ** 256n - 1n;
const txHash = await this.getClient().approve(this.getTokenAddr(), ddContract, maxTokensAmount.toString());
console.log(`Approve txHash: ${txHash}`);
} else {
console.log(`Current allowance (${await this.weiToHuman(currentAllowance)} ${this.tokenSymbol()}) is greater or equal than needed (${await this.weiToHuman(totalApproveAmount)} ${this.tokenSymbol()}). Skipping approve`);
}

console.log('Making direct deposit...');
return await this.getClient().directDeposit(this.getPoolAddr(), amountWithFeeWei.toString(), to);
} else {
throw new Error(`Invalid zkAddress. Please check it!`)
}

console.log('Making direct deposit...');

let txHash = '';
await this.getZpClient().directDeposit(
ddType,
await this.getRegularAddress(),
amount,
async (tx: PreparedTransaction) => {
txHash = await this.getClient().sendTransaction(tx.to, tx.amount, tx.data);
return txHash;
}
);

return txHash;
}

// returns txHash in promise
Expand Down Expand Up @@ -702,33 +739,16 @@ export class Account {
}

public async giftCardBalance(giftCard: GiftCardProperties): Promise<bigint> {
const proverMode = this.config.pools[this.getCurrentPool()].delegatedProverUrls.length > 0 ?
ProverMode.DelegatedWithFallback :
ProverMode.Local;

const giftCardAccountConfig: AccountConfig = {
sk: giftCard.sk,
pool: this.getZpClient().currentPool(),
birthindex: giftCard.birthIndex,
proverMode,
}
return await this.getZpClient().giftCardBalance(giftCardAccountConfig);
return await this.getZpClient().giftCardBalance(giftCard);
}

public async redeemGiftCard(giftCard: GiftCardProperties): Promise<{jobId: string, txHash: string}> {
const proverMode = this.config.pools[this.getCurrentPool()].delegatedProverUrls.length > 0 ?
ProverMode.DelegatedWithFallback :
ProverMode.Local;

const giftCardAccountConfig: AccountConfig = {
sk: giftCard.sk,
pool: this.getZpClient().currentPool(),
birthindex: giftCard.birthIndex,
proverMode,
}

console.log('Redeeming gift-card...');
const jobId: string = await this.getZpClient().redeemGiftCard(giftCardAccountConfig);
const jobId: string = await this.getZpClient().redeemGiftCard(giftCard, proverMode);
console.log(`Please wait relayer provide txHash for job ${jobId}...`);

return {jobId, txHash: (await this.getZpClient().waitJobTxHash(jobId))};
Expand Down
Loading

0 comments on commit c262031

Please sign in to comment.