UNPKG

ox

Version:

Ethereum Standard Library

549 lines (492 loc) 26.8 kB
import { Execute } from 'ox/erc7821' import { describe, expect, test } from 'vp/test' describe('encodeData', () => { test('default', () => { expect( Execute.encodeData([ { data: '0xdeadbeef', to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 1n, }, { data: '0xcafebabe', to: '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF', value: 2n, }, ]), ).toMatchInlineSnapshot( `"0xe9ae5c530100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000cafebabecafebabecafebabecafebabecafebabe000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004deadbeef00000000000000000000000000000000000000000000000000000000000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeef000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004cafebabe00000000000000000000000000000000000000000000000000000000"`, ) }) test('behavior: single call', () => { expect( Execute.encodeData([ { data: '0xdeadbeef', to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 1000000000000000000n, }, ]), ).toMatchInlineSnapshot( `"0xe9ae5c53010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000cafebabecafebabecafebabecafebabecafebabe0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004deadbeef00000000000000000000000000000000000000000000000000000000"`, ) }) test('behavior: no data', () => { expect( Execute.encodeData([ { to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 1n, }, { to: '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF', value: 2n, }, ]), ).toMatchInlineSnapshot( `"0xe9ae5c5301000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000cafebabecafebabecafebabecafebabecafebabe000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeef000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000"`, ) }) test('behavior: no value', () => { expect( Execute.encodeData([ { data: '0xdeadbeef', to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', }, { data: '0xcafebabe', to: '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF', }, ]), ).toMatchInlineSnapshot( `"0xe9ae5c530100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000cafebabecafebabecafebabecafebabecafebabe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004deadbeef00000000000000000000000000000000000000000000000000000000000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004cafebabe00000000000000000000000000000000000000000000000000000000"`, ) }) test('behavior: empty calls array', () => { expect(Execute.encodeData([])).toMatchInlineSnapshot( `"0xe9ae5c5301000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000"`, ) }) test('behavior: with opData', () => { expect( Execute.encodeData( [ { data: '0xdeadbeef', to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 1n, }, ], { opData: '0x1234567890abcdef' }, ), ).toMatchInlineSnapshot( `"0xe9ae5c530100000000007821000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000cafebabecafebabecafebabecafebabecafebabe000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004deadbeef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000081234567890abcdef000000000000000000000000000000000000000000000000"`, ) }) test('behavior: with empty opData', () => { expect( Execute.encodeData( [ { data: '0xdeadbeef', to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 1n, }, ], { opData: '0x' }, ), ).toMatchInlineSnapshot( `"0xe9ae5c530100000000007821000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000cafebabecafebabecafebabecafebabecafebabe000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004deadbeef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"`, ) }) test('behavior: mixed calls with and without data/value', () => { expect( Execute.encodeData([ { to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 100n, }, { data: '0xdeadbeef', to: '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF', }, { data: '0xcafebabe', to: '0x1234567890123456789012345678901234567890', value: 200n, }, ]), ).toMatchInlineSnapshot( `"0xe9ae5c5301000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000180000000000000000000000000cafebabecafebabecafebabecafebabecafebabe000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004deadbeef00000000000000000000000000000000000000000000000000000000000000000000000000000000123456789012345678901234567890123456789000000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004cafebabe00000000000000000000000000000000000000000000000000000000"`, ) }) }) describe('decodeData', () => { test('default', () => { const calls = [ { data: '0xdeadbeef', to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 1n, }, { data: '0xcafebabe', to: '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF', value: 2n, }, ] as const const encoded = Execute.encodeData(calls) const result = Execute.decodeData(encoded) expect(result).toEqual({ calls }) }) test('behavior: single call', () => { const calls = [ { data: '0xdeadbeef', to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 1000000000000000000n, }, ] as const const encoded = Execute.encodeData(calls) const result = Execute.decodeData(encoded) expect(result).toEqual({ calls }) }) test('behavior: empty calls', () => { const calls = [] as const const encoded = Execute.encodeData(calls) const result = Execute.decodeData(encoded) expect(result).toEqual({ calls }) }) test('behavior: with opData', () => { const calls = [ { data: '0xdeadbeef', to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 1n, }, ] as const const opData = '0x1234567890abcdef' as const const encoded = Execute.encodeData(calls, { opData }) const result = Execute.decodeData(encoded) expect(result).toEqual({ calls, opData }) }) test('behavior: with empty opData', () => { const calls = [ { data: '0xdeadbeef', to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 1n, }, ] as const const opData = '0x' as const const encoded = Execute.encodeData(calls, { opData }) const result = Execute.decodeData(encoded) expect(result).toEqual({ calls, opData: undefined, }) }) test('behavior: no data or value', () => { const calls = [ { to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 0n, data: '0x', }, ] as const const encoded = Execute.encodeData(calls) const result = Execute.decodeData(encoded) expect(result).toEqual({ calls }) }) test('behavior: round trip with mixed calls', () => { const calls = [ { to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 100n, data: '0x', }, { data: '0xdeadbeef', to: '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF', value: 0n, }, { data: '0xcafebabe', to: '0x1234567890123456789012345678901234567890', value: 200n, }, ] as const const encoded = Execute.encodeData(calls) const result = Execute.decodeData(encoded) expect(result).toEqual({ calls }) }) }) describe('encodeBatchOfBatchesData', () => { test('default', () => { expect( Execute.encodeBatchOfBatchesData([ { calls: [ { data: '0xcafebabe', to: '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF', value: 1n, }, ], }, { calls: [ { data: '0xdeadbeef', to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 2n, }, ], opData: '0x1234567890abcdef', }, ]), ).toMatchInlineSnapshot( `"0xe9ae5c5301000000000078210002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeef000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004cafebabe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000cafebabecafebabecafebabecafebabecafebabe000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004deadbeef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000081234567890abcdef000000000000000000000000000000000000000000000000"`, ) }) test('behavior: single batch', () => { expect( Execute.encodeBatchOfBatchesData([ { calls: [ { data: '0xdeadbeef', to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 1n, }, ], }, ]), ).toMatchInlineSnapshot( `"0xe9ae5c530100000000007821000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000cafebabecafebabecafebabecafebabecafebabe000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004deadbeef00000000000000000000000000000000000000000000000000000000"`, ) }) test('behavior: batch without opData', () => { expect( Execute.encodeBatchOfBatchesData([ { calls: [ { data: '0xcafebabe', to: '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF', value: 1n, }, ], }, { calls: [ { data: '0xdeadbeef', to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 2n, }, ], }, ]), ).toMatchInlineSnapshot( `"0xe9ae5c530100000000007821000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeef000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004cafebabe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000cafebabecafebabecafebabecafebabecafebabe000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004deadbeef00000000000000000000000000000000000000000000000000000000"`, ) }) test('behavior: batch with empty opData', () => { expect( Execute.encodeBatchOfBatchesData([ { calls: [ { data: '0xdeadbeef', to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 1n, }, ], opData: '0x', }, ]), ).toMatchInlineSnapshot( `"0xe9ae5c530100000000007821000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000cafebabecafebabecafebabecafebabecafebabe000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004deadbeef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"`, ) }) test('behavior: multiple calls per batch', () => { expect( Execute.encodeBatchOfBatchesData([ { calls: [ { data: '0xcafebabe', to: '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF', value: 1n, }, { data: '0xdeadbeef', to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 2n, }, ], }, ]), ).toMatchInlineSnapshot( `"0xe9ae5c5301000000000078210002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeef000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004cafebabe00000000000000000000000000000000000000000000000000000000000000000000000000000000cafebabecafebabecafebabecafebabecafebabe000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004deadbeef00000000000000000000000000000000000000000000000000000000"`, ) }) test('behavior: empty batches array', () => { expect(Execute.encodeBatchOfBatchesData([])).toMatchInlineSnapshot( `"0xe9ae5c5301000000000078210002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000"`, ) }) }) describe('decodeBatchOfBatchesData', () => { test('default', () => { const batches = [ { calls: [ { data: '0xcafebabe', to: '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF', value: 1n, }, ], }, { calls: [ { data: '0xdeadbeef', to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 2n, }, ], opData: '0x1234567890abcdef', }, ] as const const encoded = Execute.encodeBatchOfBatchesData(batches) const result = Execute.decodeBatchOfBatchesData(encoded) expect(result).toEqual(batches) }) test('behavior: single batch', () => { const batches = [ { calls: [ { data: '0xdeadbeef', to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 1n, }, ], }, ] as const const encoded = Execute.encodeBatchOfBatchesData(batches) const result = Execute.decodeBatchOfBatchesData(encoded) expect(result).toEqual(batches) }) test('behavior: batch without opData', () => { const batches = [ { calls: [ { data: '0xcafebabe', to: '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF', value: 1n, }, ], }, { calls: [ { data: '0xdeadbeef', to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 2n, }, ], }, ] as const const encoded = Execute.encodeBatchOfBatchesData(batches) const result = Execute.decodeBatchOfBatchesData(encoded) expect(result).toEqual(batches) }) test('behavior: batch with empty opData', () => { const batches = [ { calls: [ { data: '0xdeadbeef', to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 1n, }, ], }, ] as const const opData = '0x' as const const encoded = Execute.encodeBatchOfBatchesData([ { calls: batches[0].calls, opData }, ]) const result = Execute.decodeBatchOfBatchesData(encoded) expect(result).toEqual(batches) }) test('behavior: multiple calls per batch', () => { const batches = [ { calls: [ { data: '0xcafebabe', to: '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF', value: 1n, }, { data: '0xdeadbeef', to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 2n, }, ], }, ] as const const encoded = Execute.encodeBatchOfBatchesData(batches) const result = Execute.decodeBatchOfBatchesData(encoded) expect(result).toEqual(batches) }) test('behavior: empty batches', () => { const batches = [] as const const encoded = Execute.encodeBatchOfBatchesData(batches) const result = Execute.decodeBatchOfBatchesData(encoded) expect(result).toEqual(batches) }) test('behavior: mixed batches with and without opData', () => { const batches = [ { calls: [ { data: '0xcafebabe', to: '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF', value: 100n, }, ], }, { calls: [ { data: '0xdeadbeef', to: '0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe', value: 200n, }, ], opData: '0xabcdef', }, { calls: [ { to: '0x1234567890123456789012345678901234567890', value: 300n, data: '0x', }, ], }, ] as const const encoded = Execute.encodeBatchOfBatchesData(batches) const result = Execute.decodeBatchOfBatchesData(encoded) expect(result).toEqual(batches) }) })