11import { BigNumber , Contract , providers , Wallet } from 'ethers'
22import { formatEther , parseEther } from 'ethers/lib/utils'
3- import { TransactionReceipt } from '@ethersproject/providers'
43import debug from 'debug'
54
65import { getEndpointUrl , until } from '../../../src/utils'
@@ -10,7 +9,8 @@ import * as DataUnionSidechain from '../../../contracts/DataUnionSidechain.json'
109import config from '../config'
1110import authFetch from '../../../src/rest/authFetch'
1211import { createClient , createMockAddress , expectInvalidAddress } from '../../utils'
13- import { MemberStatus } from '../../../src/dataunion/DataUnion'
12+ import { AmbMessageHash , DataUnionWithdrawOptions , MemberStatus } from '../../../src/dataunion/DataUnion'
13+ import { ContractReceipt } from '@ethersproject/contracts'
1414
1515const log = debug ( 'StreamrClient::DataUnion::integration-test-withdraw' )
1616
@@ -31,8 +31,9 @@ const testWithdraw = async (
3131 memberClient : StreamrClient ,
3232 memberWallet : Wallet ,
3333 adminClient : StreamrClient
34- ) => Promise < TransactionReceipt > ,
34+ ) => Promise < ContractReceipt | AmbMessageHash | null > ,
3535 requiresMainnetETH : boolean ,
36+ options : DataUnionWithdrawOptions ,
3637) => {
3738 log ( `Connecting to Ethereum networks, config = ${ JSON . stringify ( config ) } ` )
3839 const network = await providerMainnet . getNetwork ( )
@@ -135,8 +136,17 @@ const testWithdraw = async (
135136 const balanceBefore = await getBalance ( memberWallet )
136137 log ( `Balance before: ${ balanceBefore } . Withdrawing tokens...` )
137138
138- const withdrawTr = await withdraw ( dataUnion . getAddress ( ) , memberClient , memberWallet , adminClient )
139- log ( `Tokens withdrawn, sidechain tx receipt: ${ JSON . stringify ( withdrawTr ) } ` )
139+ let ret = await withdraw ( dataUnion . getAddress ( ) , memberClient , memberWallet , adminClient )
140+ if ( ret instanceof String ) {
141+ log ( `Transporting message "${ ret } "` )
142+ ret = await dataUnion . transportMessage ( String ( ret ) )
143+ }
144+ log ( `Tokens withdrawn, return value: ${ JSON . stringify ( ret ) } ` )
145+ if ( ! options . waitUntilTransportIsComplete ) {
146+ log ( `Waiting until balance changes from ${ balanceBefore . toString ( ) } ` )
147+ await until ( async ( ) => getBalance ( memberWallet ) . then ( ( b ) => ! b . eq ( balanceBefore ) ) )
148+ }
149+
140150 const balanceAfter = await getBalance ( memberWallet )
141151 const balanceIncrease = balanceAfter . sub ( balanceBefore )
142152
@@ -158,65 +168,69 @@ describe('DataUnion withdraw', () => {
158168 providerSidechain . removeAllListeners ( )
159169 } )
160170
161- for ( const sendToMainnet of [ true , false ] ) {
171+ // TODO: add tests for just getting the hash and doing the transportMessage manually
172+ describe . each ( [
173+ [ false , true , true ] , // sidechain withdraw
174+ [ true , true , true ] , // self-service mainnet withdraw
175+ [ true , true , false ] , // self-service mainnet withdraw without checking the recipient account
176+ [ true , false , true ] , // bridge-sponsored mainnet withdraw
177+ [ true , false , false ] , // other-sponsored mainnet withdraw
178+ ] ) ( 'Withdrawing with sendToMainnet=%p, payForTransport=%p, wait=%p' , ( sendToMainnet , payForTransport , waitUntilTransportIsComplete ) => {
179+ const options = { sendToMainnet, payForTransport, waitUntilTransportIsComplete }
162180
163181 const getTokenBalance = async ( wallet : Wallet ) => {
164182 return sendToMainnet ? balanceClient . getTokenBalance ( wallet . address ) : balanceClient . getSidechainTokenBalance ( wallet . address )
165183 }
166184
167- describe ( 'Withdrawing to ' + ( sendToMainnet ? 'mainnet' : 'sidechain' ) , ( ) => {
168-
169- describe ( 'Member' , ( ) => {
170-
171- it ( 'by member itself' , ( ) => {
172- const getBalance = async ( memberWallet : Wallet ) => getTokenBalance ( memberWallet )
173- const withdraw = async ( dataUnionAddress : string , memberClient : StreamrClient ) => (
174- memberClient . getDataUnion ( dataUnionAddress ) . withdrawAll ( { sendToMainnet } )
175- )
176- return testWithdraw ( getBalance , withdraw , true )
177- } , 300000 )
178-
179- it ( 'from member to any address' , ( ) => {
180- const outsiderWallet = new Wallet ( `0x100000000000000000000000000000000000000012300000002${ Date . now ( ) } ` , providerSidechain )
181- const getBalance = async ( ) => getTokenBalance ( outsiderWallet )
182- const withdraw = ( dataUnionAddress : string , memberClient : StreamrClient ) => (
183- memberClient . getDataUnion ( dataUnionAddress ) . withdrawAllTo ( outsiderWallet . address , { sendToMainnet } )
184- )
185- return testWithdraw ( getBalance , withdraw , true )
186- } , 300000 )
187-
188- } )
189-
190- describe ( 'Admin' , ( ) => {
191-
192- it ( 'non-signed' , async ( ) => {
193- const getBalance = async ( memberWallet : Wallet ) => getTokenBalance ( memberWallet )
194- const withdraw = ( dataUnionAddress : string , _ : StreamrClient , memberWallet : Wallet , adminClient : StreamrClient ) => (
195- adminClient . getDataUnion ( dataUnionAddress ) . withdrawAllToMember ( memberWallet . address , { sendToMainnet } )
196- )
197- return testWithdraw ( getBalance , withdraw , false )
198- } , 300000 )
199-
200- it ( 'signed' , async ( ) => {
201- const member2Wallet = new Wallet ( `0x100000000000000000000000000040000000000012300000007${ Date . now ( ) } ` , providerSidechain )
202- const getBalance = async ( ) => getTokenBalance ( member2Wallet )
203- const withdraw = async (
204- dataUnionAddress : string ,
205- memberClient : StreamrClient ,
206- memberWallet : Wallet ,
207- adminClient : StreamrClient
208- ) => {
209- const signature = await memberClient . getDataUnion ( dataUnionAddress ) . signWithdrawAllTo ( member2Wallet . address )
210- const withdrawTr = await adminClient
211- . getDataUnion ( dataUnionAddress )
212- . withdrawAllToSigned ( memberWallet . address , member2Wallet . address , signature , { sendToMainnet } )
213- return withdrawTr
214- }
215- return testWithdraw ( getBalance , withdraw , false )
216- } , 300000 )
217- } )
185+ describe ( 'by member' , ( ) => {
186+
187+ it ( 'to itself' , ( ) => {
188+ const getBalance = async ( memberWallet : Wallet ) => getTokenBalance ( memberWallet )
189+ const withdraw = async ( dataUnionAddress : string , memberClient : StreamrClient ) => (
190+ memberClient . getDataUnion ( dataUnionAddress ) . withdrawAll ( options )
191+ )
192+ return testWithdraw ( getBalance , withdraw , true , options )
193+ } , 300000 )
194+
195+ it ( 'to any address' , ( ) => {
196+ const outsiderWallet = new Wallet ( `0x100000000000000000000000000000000000000012300000002${ Date . now ( ) } ` , providerSidechain )
197+ const getBalance = async ( ) => getTokenBalance ( outsiderWallet )
198+ const withdraw = ( dataUnionAddress : string , memberClient : StreamrClient ) => (
199+ memberClient . getDataUnion ( dataUnionAddress ) . withdrawAllTo ( outsiderWallet . address , options )
200+ )
201+ return testWithdraw ( getBalance , withdraw , true , options )
202+ } , 300000 )
203+
218204 } )
219- }
205+
206+ describe ( 'by admin' , ( ) => {
207+
208+ it ( 'to member without signature' , async ( ) => {
209+ const getBalance = async ( memberWallet : Wallet ) => getTokenBalance ( memberWallet )
210+ const withdraw = ( dataUnionAddress : string , _ : StreamrClient , memberWallet : Wallet , adminClient : StreamrClient ) => (
211+ adminClient . getDataUnion ( dataUnionAddress ) . withdrawAllToMember ( memberWallet . address , options )
212+ )
213+ return testWithdraw ( getBalance , withdraw , false , options )
214+ } , 300000 )
215+
216+ it ( "to anyone with member's signature" , async ( ) => {
217+ const member2Wallet = new Wallet ( `0x100000000000000000000000000040000000000012300000007${ Date . now ( ) } ` , providerSidechain )
218+ const getBalance = async ( ) => getTokenBalance ( member2Wallet )
219+ const withdraw = async (
220+ dataUnionAddress : string ,
221+ memberClient : StreamrClient ,
222+ memberWallet : Wallet ,
223+ adminClient : StreamrClient
224+ ) => {
225+ const signature = await memberClient . getDataUnion ( dataUnionAddress ) . signWithdrawAllTo ( member2Wallet . address )
226+ return adminClient
227+ . getDataUnion ( dataUnionAddress )
228+ . withdrawAllToSigned ( memberWallet . address , member2Wallet . address , signature , options )
229+ }
230+ return testWithdraw ( getBalance , withdraw , false , options )
231+ } , 300000 )
232+ } )
233+ } )
220234
221235 it ( 'Validate address' , async ( ) => {
222236 const client = createClient ( providerSidechain )
0 commit comments