@@ -55,6 +55,14 @@ import {
5555 flushCoinsTypes ,
5656 flushForwarderTokensMethodId ,
5757 flushTokensTypes ,
58+ flushERC721ForwarderTokensMethodId ,
59+ flushERC721ForwarderTokensMethodIdV4 ,
60+ flushERC721TokensTypes ,
61+ flushERC721TokensTypesv4 ,
62+ flushERC1155ForwarderTokensMethodId ,
63+ flushERC1155ForwarderTokensMethodIdV4 ,
64+ flushERC1155TokensTypes ,
65+ flushERC1155TokensTypesv4 ,
5866 sendMultisigMethodId ,
5967 sendMultisigTokenMethodId ,
6068 sendMultiSigTokenTypes ,
@@ -209,6 +217,152 @@ export function flushCoinsData(): string {
209217 return addHexPrefix ( Buffer . concat ( [ method , args ] ) . toString ( 'hex' ) ) ;
210218}
211219
220+ /**
221+ * Get the data required to make a flush ERC721 tokens contract call
222+ * @param forwarderAddress - The forwarder address (for v0-v3)
223+ * @param tokenAddress - The ERC721 token contract address
224+ * @param tokenId - The token ID to flush
225+ * @param forwarderVersion - The forwarder version
226+ */
227+ export function flushERC721TokensData (
228+ forwarderAddress : string ,
229+ tokenAddress : string ,
230+ tokenId : string ,
231+ forwarderVersion : number
232+ ) : string {
233+ let params : ( string | Buffer ) [ ] ;
234+ let method : Uint8Array ;
235+ let args : Uint8Array ;
236+
237+ if ( forwarderVersion >= 4 ) {
238+ params = [ tokenAddress , tokenId ] ;
239+ method = EthereumAbi . methodID ( 'flushERC721Token' , flushERC721TokensTypesv4 ) ;
240+ args = EthereumAbi . rawEncode ( flushERC721TokensTypesv4 , params ) ;
241+ } else {
242+ params = [ forwarderAddress , tokenAddress , tokenId ] ;
243+ method = EthereumAbi . methodID ( 'flushERC721ForwarderTokens' , flushERC721TokensTypes ) ;
244+ args = EthereumAbi . rawEncode ( flushERC721TokensTypes , params ) ;
245+ }
246+ return addHexPrefix ( Buffer . concat ( [ method , args ] ) . toString ( 'hex' ) ) ;
247+ }
248+
249+ /**
250+ * Decode the given ABI-encoded flush ERC721 tokens data
251+ * @param data The data to decode
252+ * @param to The to address (contract address for v4+)
253+ * @returns parsed flush data with forwarderAddress, tokenAddress, tokenId and forwarderVersion
254+ */
255+ export function decodeFlushERC721TokensData (
256+ data : string ,
257+ to ?: string
258+ ) : {
259+ forwarderAddress : string ;
260+ tokenAddress : string ;
261+ tokenId : string ;
262+ forwarderVersion : number ;
263+ } {
264+ if ( data . startsWith ( flushERC721ForwarderTokensMethodIdV4 ) ) {
265+ if ( ! to ) {
266+ throw new BuildTransactionError ( `Missing to address: ${ to } ` ) ;
267+ }
268+ const [ tokenAddress , tokenId ] = getRawDecoded (
269+ flushERC721TokensTypesv4 ,
270+ getBufferedByteCode ( flushERC721ForwarderTokensMethodIdV4 , data )
271+ ) ;
272+ return {
273+ forwarderAddress : to ,
274+ tokenAddress : addHexPrefix ( tokenAddress as string ) ,
275+ tokenId : new BigNumber ( bufferToHex ( tokenId as Buffer ) ) . toFixed ( ) ,
276+ forwarderVersion : 4 ,
277+ } ;
278+ } else if ( data . startsWith ( flushERC721ForwarderTokensMethodId ) ) {
279+ const [ forwarderAddress , tokenAddress , tokenId ] = getRawDecoded (
280+ flushERC721TokensTypes ,
281+ getBufferedByteCode ( flushERC721ForwarderTokensMethodId , data )
282+ ) ;
283+ return {
284+ forwarderAddress : addHexPrefix ( forwarderAddress as string ) ,
285+ tokenAddress : addHexPrefix ( tokenAddress as string ) ,
286+ tokenId : new BigNumber ( bufferToHex ( tokenId as Buffer ) ) . toFixed ( ) ,
287+ forwarderVersion : 0 ,
288+ } ;
289+ }
290+ throw new BuildTransactionError ( `Invalid flush ERC721 bytecode: ${ data } ` ) ;
291+ }
292+
293+ /**
294+ * Get the data required to make a flush ERC1155 tokens contract call
295+ * @param forwarderAddress - The forwarder address (for v0-v3)
296+ * @param tokenAddress - The ERC1155 token contract address
297+ * @param tokenId - The token ID to flush
298+ * @param forwarderVersion - The forwarder version
299+ */
300+ export function flushERC1155TokensData (
301+ forwarderAddress : string ,
302+ tokenAddress : string ,
303+ tokenId : string ,
304+ forwarderVersion : number
305+ ) : string {
306+ let params : ( string | Buffer ) [ ] ;
307+ let method : Uint8Array ;
308+ let args : Uint8Array ;
309+
310+ if ( forwarderVersion >= 4 ) {
311+ params = [ tokenAddress , tokenId ] ;
312+ method = EthereumAbi . methodID ( 'flushERC1155Tokens' , flushERC1155TokensTypesv4 ) ;
313+ args = EthereumAbi . rawEncode ( flushERC1155TokensTypesv4 , params ) ;
314+ } else {
315+ params = [ forwarderAddress , tokenAddress , tokenId ] ;
316+ method = EthereumAbi . methodID ( 'flushERC1155ForwarderTokens' , flushERC1155TokensTypes ) ;
317+ args = EthereumAbi . rawEncode ( flushERC1155TokensTypes , params ) ;
318+ }
319+ return addHexPrefix ( Buffer . concat ( [ method , args ] ) . toString ( 'hex' ) ) ;
320+ }
321+
322+ /**
323+ * Decode the given ABI-encoded flush ERC1155 tokens data
324+ * @param data The data to decode
325+ * @param to The to address (contract address for v4+)
326+ * @returns parsed flush data with forwarderAddress, tokenAddress, tokenId and forwarderVersion
327+ */
328+ export function decodeFlushERC1155TokensData (
329+ data : string ,
330+ to ?: string
331+ ) : {
332+ forwarderAddress : string ;
333+ tokenAddress : string ;
334+ tokenId : string ;
335+ forwarderVersion : number ;
336+ } {
337+ if ( data . startsWith ( flushERC1155ForwarderTokensMethodIdV4 ) ) {
338+ if ( ! to ) {
339+ throw new BuildTransactionError ( `Missing to address: ${ to } ` ) ;
340+ }
341+ const [ tokenAddress , tokenId ] = getRawDecoded (
342+ flushERC1155TokensTypesv4 ,
343+ getBufferedByteCode ( flushERC1155ForwarderTokensMethodIdV4 , data )
344+ ) ;
345+ return {
346+ forwarderAddress : to ,
347+ tokenAddress : addHexPrefix ( tokenAddress as string ) ,
348+ tokenId : new BigNumber ( bufferToHex ( tokenId as Buffer ) ) . toFixed ( ) ,
349+ forwarderVersion : 4 ,
350+ } ;
351+ } else if ( data . startsWith ( flushERC1155ForwarderTokensMethodId ) ) {
352+ const [ forwarderAddress , tokenAddress , tokenId ] = getRawDecoded (
353+ flushERC1155TokensTypes ,
354+ getBufferedByteCode ( flushERC1155ForwarderTokensMethodId , data )
355+ ) ;
356+ return {
357+ forwarderAddress : addHexPrefix ( forwarderAddress as string ) ,
358+ tokenAddress : addHexPrefix ( tokenAddress as string ) ,
359+ tokenId : new BigNumber ( bufferToHex ( tokenId as Buffer ) ) . toFixed ( ) ,
360+ forwarderVersion : 0 ,
361+ } ;
362+ }
363+ throw new BuildTransactionError ( `Invalid flush ERC1155 bytecode: ${ data } ` ) ;
364+ }
365+
212366/**
213367 * Returns the create forwarder method calling data
214368 *
@@ -542,6 +696,10 @@ const transactionTypesMap = {
542696 [ flushForwarderTokensMethodId ] : TransactionType . FlushTokens ,
543697 [ flushForwarderTokensMethodIdV4 ] : TransactionType . FlushTokens ,
544698 [ flushCoinsMethodId ] : TransactionType . FlushCoins ,
699+ [ flushERC721ForwarderTokensMethodId ] : TransactionType . FlushERC721 ,
700+ [ flushERC721ForwarderTokensMethodIdV4 ] : TransactionType . FlushERC721 ,
701+ [ flushERC1155ForwarderTokensMethodId ] : TransactionType . FlushERC1155 ,
702+ [ flushERC1155ForwarderTokensMethodIdV4 ] : TransactionType . FlushERC1155 ,
545703 [ sendMultisigTokenMethodId ] : TransactionType . Send ,
546704 [ LockMethodId ] : TransactionType . StakingLock ,
547705 [ VoteMethodId ] : TransactionType . StakingVote ,
0 commit comments