@@ -26,13 +26,18 @@ import {
2626 CircomUtxo,
2727} from '@webb-tools/sdk-core';
2828import {
29- IAnchorDeposit,
30- IAnchor,
29+ IVAnchor,
3130 IIdentityVariableAnchorExtData,
3231 IIdentityVariableAnchorPublicInputs,
33- IAnchorDepositInfo,
3432} from '@webb-tools/interfaces';
35- import { hexToU8a, u8aToHex, getChainIdType, UTXOInputs, ZkComponents } from '@webb-tools/utils';
33+ import {
34+ hexToU8a,
35+ u8aToHex,
36+ getChainIdType,
37+ UTXOInputs,
38+ ZkComponents,
39+ ZERO_BYTES32,
40+ } from '@webb-tools/utils';
3641import { Semaphore } from '@webb-tools/semaphore';
3742import { LinkedGroup } from '@webb-tools/semaphore-group';
3843
@@ -77,7 +82,7 @@ export var proofTimeBenchmark = [];
7782// It represents a deployed contract throughout its life (e.g. maintains merkle tree state)
7883// Functionality relevant to anchors in general (proving, verifying) is implemented in static methods
7984// Functionality relevant to a particular anchor deployment (deposit, withdraw) is implemented in instance methods
80- export class IdentityVAnchor implements IAnchor {
85+ export class IdentityVAnchor implements IVAnchor {
8186 signer: ethers.Signer;
8287 contract: IdentityVAnchorContract;
8388 semaphore: Semaphore;
@@ -117,59 +122,7 @@ export class IdentityVAnchor implements IAnchor {
117122 this.smallCircuitZkComponents = smallCircuitZkComponents;
118123 this.largeCircuitZkComponents = largeCircuitZkComponents;
119124 }
120- deposit(destinationChainId: number): Promise<IAnchorDeposit> {
121- throw new Error('Method not implemented.');
122- }
123- setupWithdraw(
124- deposit: IAnchorDepositInfo,
125- index: number,
126- recipient: string,
127- relayer: string,
128- fee: bigint,
129- refreshCommitment: string | number
130- ) {
131- throw new Error('Method not implemented.');
132- }
133- withdraw(
134- deposit: IAnchorDepositInfo,
135- index: number,
136- recipient: string,
137- relayer: string,
138- fee: bigint,
139- refreshCommitment: string | number
140- ): Promise<ethers.Event> {
141- throw new Error('Method not implemented.');
142- }
143- wrapAndDeposit(
144- tokenAddress: string,
145- wrappingFee: number,
146- destinationChainId?: number
147- ): Promise<IAnchorDeposit> {
148- throw new Error('Method not implemented.');
149- }
150- bridgedWithdrawAndUnwrap(
151- deposit: IAnchorDeposit,
152- merkleProof: any,
153- recipient: string,
154- relayer: string,
155- fee: string,
156- refund: string,
157- refreshCommitment: string,
158- tokenAddress: string
159- ): Promise<ethers.Event> {
160- throw new Error('Method not implemented.');
161- }
162- bridgedWithdraw(
163- deposit: IAnchorDeposit,
164- merkleProof: any,
165- recipient: string,
166- relayer: string,
167- fee: string,
168- refund: string,
169- refreshCommitment: string
170- ): Promise<ethers.Event> {
171- throw new Error('Method not implemented.');
172- }
125+
173126 getAddress(): string {
174127 return this.contract.address;
175128 }
@@ -201,8 +154,8 @@ export class IdentityVAnchor implements IAnchor {
201154 const vAnchor = await factory.deploy(
202155 semaphore.contract.address,
203156 verifier,
204- levels,
205157 hasher,
158+ levels,
206159 handler,
207160 token,
208161 maxEdges,
@@ -221,6 +174,11 @@ export class IdentityVAnchor implements IAnchor {
221174 );
222175 createdIdentityVAnchor.latestSyncedBlock = vAnchor.deployTransaction.blockNumber!;
223176 createdIdentityVAnchor.token = token;
177+ const tx = await createdIdentityVAnchor.contract.initialize(
178+ BigNumber.from('1'),
179+ BigNumber.from(2).pow(256).sub(1)
180+ );
181+ await tx.wait();
224182 return createdIdentityVAnchor;
225183 }
226184
@@ -235,7 +193,7 @@ export class IdentityVAnchor implements IAnchor {
235193 ) {
236194 const anchor = IdentityVAnchor__factory.connect(address, signer);
237195 const maxEdges = await anchor.maxEdges();
238- const treeHeight = await anchor.levels ();
196+ const treeHeight = await anchor.outerLevels ();
239197 const groupId = await anchor.groupId();
240198 const createdAnchor = new IdentityVAnchor(
241199 anchor,
@@ -466,7 +424,7 @@ export class IdentityVAnchor implements IAnchor {
466424 return rootData.root;
467425 });
468426 let thisRoot = await this.contract.getLastRoot();
469- return [thisRoot, ...neighborRootInfos];
427+ return [thisRoot.toString() , ...neighborRootInfos.map((bignum) => bignum.toString()) ];
470428 }
471429
472430 public async getClassAndContractRoots() {
@@ -709,6 +667,7 @@ export class IdentityVAnchor implements IAnchor {
709667 relayer: string,
710668 fee: BigNumber,
711669 refund: BigNumber,
670+ wrapUnwrapToken: string,
712671 encryptedOutput1: string,
713672 encryptedOutput2: string
714673 ): Promise<{ extData: ExtData; extDataHash: BigNumber }> {
@@ -718,7 +677,7 @@ export class IdentityVAnchor implements IAnchor {
718677 relayer: toFixedHex(relayer, 20),
719678 fee: toFixedHex(fee),
720679 refund: toFixedHex(refund.toString()),
721- token: toFixedHex(this.token , 20),
680+ token: toFixedHex(wrapUnwrapToken , 20),
722681 encryptedOutput1,
723682 encryptedOutput2,
724683 };
@@ -731,7 +690,7 @@ export class IdentityVAnchor implements IAnchor {
731690 recipient,
732691 relayer,
733692 refund.toString(),
734- this.token
693+ wrapUnwrapToken
735694 );
736695 return { extData, extDataHash };
737696 }
@@ -789,7 +748,8 @@ export class IdentityVAnchor implements IAnchor {
789748 fee: BigNumberish,
790749 refund: BigNumberish,
791750 recipient: string,
792- relayer: string
751+ relayer: string,
752+ wrapUnwrapToken: string
793753 ): Promise<ethers.ContractTransaction> {
794754 const chainId = getChainIdType(await this.signer.getChainId());
795755 const randomKeypair = new Keypair();
@@ -832,104 +792,17 @@ export class IdentityVAnchor implements IAnchor {
832792 .add(outputs.reduce((sum, x) => sum.add(BigNumber.from(BigInt(x.amount))), BigNumber.from(0)))
833793 .sub(inputs.reduce((sum, x) => sum.add(BigNumber.from(BigInt(x.amount))), BigNumber.from(0)));
834794
835- const { extData, extDataHash } = await this.generateExtData(
836- recipient,
837- extAmount,
838- relayer,
839- BigNumber.from(fee),
840- BigNumber.from(refund),
841- outputs[0].encrypt(),
842- outputs[1].encrypt()
843- );
844-
845- const vanchorInput: UTXOInputs = await this.generateUTXOInputs(
846- inputs,
847- outputs,
848- chainId,
849- extAmount,
850- BigNumber.from(fee),
851- extDataHash
852- );
853-
854- const outSemaphoreProofs = this.generateOutputSemaphoreProof(outputs);
855-
856- const publicInputs = await this.setupTransaction(
857- keypair,
858- identityRootInputs,
859- identityMerkleProof,
860- outSemaphoreProofs,
861- vanchorInput,
862- extDataHash.toString()
863- );
864-
865- let tx = await this.contract.transact({ ...publicInputs }, extData, { gasLimit: '0x5B8D80' });
866-
867- // Add the leaves to the tree
868- outputs.forEach((x) => {
869- this.tree.insert(u8aToHex(x.commitment));
870- let numOfElements = this.tree.number_of_elements();
871- this.depositHistory[numOfElements - 1] = toFixedHex(this.tree.root().toString());
872- });
873-
874- return tx;
875- }
876-
877- public async transactWrap(
878- tokenAddress: string,
879- keypair: Keypair,
880- inputs: Utxo[],
881- outputs: Utxo[],
882- fee: BigNumberish,
883- refund: BigNumberish,
884- recipient: string,
885- relayer: string
886- ): Promise<ethers.ContractTransaction> {
887- // Default UTXO chain ID will match with the configured signer's chain ID
888- const evmId = await this.signer.getChainId();
889- const chainId = getChainIdType(evmId);
890- const randomKeypair = new Keypair();
891-
892- const identityRootInputs = this.populateIdentityRootsForProof();
893- const identityMerkleProof: MerkleProof = this.generateIdentityMerkleProof(keypair.getPubKey());
894-
895- while (inputs.length !== 2 && inputs.length < 16) {
896- inputs.push(
897- await CircomUtxo.generateUtxo({
898- curve: 'Bn254',
899- backend: 'Circom',
900- chainId: chainId.toString(),
901- originChainId: chainId.toString(),
902- amount: '0',
903- blinding: hexToU8a(randomBN(31).toHexString()),
904- keypair: randomKeypair,
905- })
906- );
795+ if (wrapUnwrapToken.length === 0) {
796+ wrapUnwrapToken = this.token;
907797 }
908798
909- if (outputs.length < 2) {
910- while (outputs.length < 2) {
911- outputs.push(
912- await CircomUtxo.generateUtxo({
913- curve: 'Bn254',
914- backend: 'Circom',
915- chainId: chainId.toString(),
916- originChainId: chainId.toString(),
917- amount: '0',
918- keypair: randomKeypair,
919- })
920- );
921- }
922- }
923- let extAmount = BigNumber.from(fee)
924- .add(outputs.reduce((sum, x) => sum.add(x.amount), BigNumber.from(0)))
925- .sub(inputs.reduce((sum, x) => sum.add(x.amount), BigNumber.from(0)));
926-
927799 const { extData, extDataHash } = await this.generateExtData(
928800 recipient,
929801 extAmount,
930802 relayer,
931803 BigNumber.from(fee),
932804 BigNumber.from(refund),
805+ wrapUnwrapToken,
933806 outputs[0].encrypt(),
934807 outputs[1].encrypt()
935808 );
@@ -954,46 +827,38 @@ export class IdentityVAnchor implements IAnchor {
954827 extDataHash.toString()
955828 );
956829
957- let tx: ContractTransaction;
958- if (extAmount.gt(0) && checkNativeAddress(tokenAddress)) {
959- let tokenWrapper = TokenWrapper__factory.connect(await this.contract.token(), this.signer);
960- let valueToSend = await tokenWrapper.getAmountToWrap(extAmount);
961-
962- tx = await this.contract.transactWrap(
963- {
964- ...publicInputs,
965- outputCommitments: [publicInputs.outputCommitments[0], publicInputs.outputCommitments[1]],
966- },
967- extData,
968- tokenAddress,
969- {
970- value: valueToSend.toHexString(),
971- gasLimit: '0x5B8D80',
972- }
973- );
974- } else {
975- tx = await this.contract.transactWrap(
976- {
977- ...publicInputs,
978- outputCommitments: [publicInputs.outputCommitments[0], publicInputs.outputCommitments[1]],
979- },
980- extData,
981- tokenAddress,
982- { gasLimit: '0x5B8D80' }
983- );
984- }
985- // const receipt = await tx.wait();
830+ let tx = await this.contract.transact(
831+ publicInputs.proof,
832+ ZERO_BYTES32,
833+ {
834+ recipient: extData.recipient,
835+ extAmount: extData.extAmount,
836+ relayer: extData.relayer,
837+ fee: extData.fee,
838+ refund: extData.refund,
839+ token: extData.token,
840+ },
841+ {
842+ roots: publicInputs.vanchorRoots,
843+ extensionRoots: publicInputs.identityRoots,
844+ inputNullifiers: publicInputs.inputNullifiers,
845+ outputCommitments: [publicInputs.outputCommitments[0], publicInputs.outputCommitments[1]],
846+ publicAmount: publicInputs.publicAmount,
847+ extDataHash: publicInputs.extDataHash,
848+ },
849+ extData,
850+ { gasLimit: '0x5B8D80' }
851+ );
852+ const receipt = await tx.wait();
986853
987854 // Add the leaves to the tree
988855 outputs.forEach((x) => {
989- // Maintain tree state after insertions
990856 this.tree.insert(u8aToHex(x.commitment));
991857 let numOfElements = this.tree.number_of_elements();
992858 this.depositHistory[numOfElements - 1] = toFixedHex(this.tree.root().toString());
993859 });
994860
995861 return tx;
996- // return receipt;
997862 }
998863}
999864
0 commit comments