import { Address, getAddressComparator } from '@solana/addresses'; import { AccountLookupMeta, AccountRole, Instruction } from '@solana/instructions'; import { ADDRESS_MAP_TYPE_PROPERTY as TYPE, AddressMapEntryType, getAddressMapFromInstructions, getOrderedAccountsFromAddressMap, } from '../accounts'; type AccountRoleEnumName = keyof typeof AccountRole; type TestCase = { aRole: AccountRoleEnumName; bRole: AccountRoleEnumName; expectedEntry: | typeof FEE_PAYER_ENTRY | typeof LUT_ENTRY_READONLY | typeof LUT_ENTRY_WRITABLE | typeof STATIC_ENTRY_READONLY | typeof STATIC_ENTRY_READONLY_SIGNER | typeof STATIC_ENTRY_WRITABLE | typeof STATIC_ENTRY_WRITABLE_SIGNER; instructionOrder: [string, (i: Instruction[]) => Instruction[]]; lutRole: AccountRoleEnumName; role: AccountRoleEnumName; staticRole: AccountRoleEnumName; }; const MOCK_ADDRESSES: ReadonlyArray
= [ 'BRwZRKsvKkG45g59269qZ5e8UaECFim5Qfxex44UKwDG', 'AZE3mXbzNp8SfZYBfL4L67ejQ8zmatAKKezUdCarKnUL', 'Awft9caFzun5FcVTaXJAkAYDBgbEDF5QALeaqeY3M3Va', 'ARc8zz6T14LZQTpjryhBGDuNZb3YmNT9PtEuBSuVM5xo', '6Tu9wk1r9yGwzd3xdrVzDttmkTN98iiffq7L25JKTvwh', '4R6dgeBbwPjnTSN78KGxhB78oFsxaobiwBsCBLAyauqA', ] as Address[]; let _nextMockAddress = 0; function getMockAddress() { return `${_nextMockAddress++}` as Address; } function forwardOrder(i: Instruction[]) { return i; } function reverseOrder(i: Instruction[]) { return i.reverse(); } const FEE_PAYER_ENTRY = { [TYPE]: AddressMapEntryType.FEE_PAYER, role: AccountRole.WRITABLE_SIGNER } as const; const LUT_ENTRY_READONLY = { [TYPE]: AddressMapEntryType.LOOKUP_TABLE, role: AccountRole.READONLY } as const; const LUT_ENTRY_WRITABLE = { [TYPE]: AddressMapEntryType.LOOKUP_TABLE, role: AccountRole.WRITABLE } as const; const STATIC_ENTRY_READONLY = { [TYPE]: AddressMapEntryType.STATIC, role: AccountRole.READONLY } as const; const STATIC_ENTRY_READONLY_SIGNER = { [TYPE]: AddressMapEntryType.STATIC, role: AccountRole.READONLY_SIGNER } as const; const STATIC_ENTRY_WRITABLE = { [TYPE]: AddressMapEntryType.STATIC, role: AccountRole.WRITABLE } as const; const STATIC_ENTRY_WRITABLE_SIGNER = { [TYPE]: AddressMapEntryType.STATIC, role: AccountRole.WRITABLE_SIGNER } as const; describe('getAddressMapFromInstructions', () => { it('creates a fee-payer entry for the fee payer', () => { const feePayerAddress = getMockAddress(); const addressMap = getAddressMapFromInstructions(feePayerAddress, []); expect(addressMap).toHaveProperty(feePayerAddress, FEE_PAYER_ENTRY); }); it('creates a READONLY static entry for a program address', () => { const programAddress = getMockAddress(); const addressMap = getAddressMapFromInstructions(/* fee payer */ getMockAddress(), [{ programAddress }]); expect(addressMap).toHaveProperty(programAddress, STATIC_ENTRY_READONLY); }); it('creates a READONLY static entry for a static account address', () => { const staticAccountAddress = getMockAddress(); const addressMap = getAddressMapFromInstructions(/* fee payer */ getMockAddress(), [ { accounts: [{ address: staticAccountAddress, role: AccountRole.READONLY }], programAddress: getMockAddress(), }, ]); expect(addressMap).toHaveProperty(staticAccountAddress, STATIC_ENTRY_READONLY); }); it.each` role | expectedEntry ${'READONLY'} | ${STATIC_ENTRY_READONLY} ${'WRITABLE'} | ${STATIC_ENTRY_WRITABLE} ${'READONLY_SIGNER'} | ${STATIC_ENTRY_READONLY_SIGNER} ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} `('creates a $role static entry for a $role static account address', ({ expectedEntry, role }: TestCase) => { const staticAccountAddress = getMockAddress(); const addressMap = getAddressMapFromInstructions(/* fee payer */ getMockAddress(), [ { accounts: [{ address: staticAccountAddress, role: AccountRole[role] }], programAddress: getMockAddress(), }, ]); expect(addressMap).toHaveProperty(staticAccountAddress, expectedEntry); }); it.each` role | expectedEntry ${'READONLY'} | ${LUT_ENTRY_READONLY} ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} `('creates a $role lut entry for a $role lookup table address', ({ expectedEntry, role }: TestCase) => { const lutAccountAddress = getMockAddress(); const lutMeta = { addressIndex: 0, lookupTableAddress: getMockAddress(), role: AccountRole[role], }; const addressMap = getAddressMapFromInstructions(/* fee payer */ getMockAddress(), [ { accounts: [{ address: lutAccountAddress, ...lutMeta }], programAddress: getMockAddress(), }, ]); expect(addressMap).toHaveProperty(lutAccountAddress, { ...expectedEntry, ...lutMeta }); }); it('fatals given a matching fee payer and program address', () => { const commonAddress = getMockAddress(); expect(() => { getAddressMapFromInstructions(/* fee payer */ commonAddress, [{ programAddress: commonAddress }]); }).toThrow(); }); it.each(['READONLY', 'WRITABLE', 'READONLY_SIGNER', 'WRITABLE_SIGNER'] as AccountRoleEnumName[])( 'creates a fee-payer entry given a matching fee payer and %s static account address', role => { const commonAddress = getMockAddress(); const addressMap = getAddressMapFromInstructions(/* fee payer */ commonAddress, [ { accounts: [{ address: commonAddress, role: AccountRole[role] }], programAddress: getMockAddress(), }, ]); expect(addressMap).toHaveProperty(commonAddress, FEE_PAYER_ENTRY); }, ); it.each(['READONLY', 'WRITABLE'] as AccountRoleEnumName[])( 'creates a fee-payer entry given a matching fee payer and %s lookup table address', role => { const commonAddress = getMockAddress(); const addressMap = getAddressMapFromInstructions(/* fee payer */ commonAddress, [ { accounts: [ { address: commonAddress, addressIndex: 0, lookupTableAddress: getMockAddress(), role: AccountRole[role], } as AccountLookupMeta, ], programAddress: getMockAddress(), }, ]); expect(addressMap).toHaveProperty(commonAddress, FEE_PAYER_ENTRY); }, ); it('creates one READONLY static entry given two matching program addresses', () => { const commonAddress = getMockAddress(); const addressMap = getAddressMapFromInstructions(/* fee payer */ getMockAddress(), [ { programAddress: commonAddress }, { programAddress: commonAddress }, ]); expect(addressMap).toHaveProperty(commonAddress, STATIC_ENTRY_READONLY); }); it.each` role | instructionOrder ${'READONLY'} | ${['static address comes first', forwardOrder]} ${'READONLY_SIGNER'} | ${['static address comes first', forwardOrder]} ${'READONLY'} | ${['program address comes first', reverseOrder]} ${'READONLY_SIGNER'} | ${['program address comes first', reverseOrder]} `( 'creates a $role static entry given a matching program and $role static account address when the $instructionOrder.0', ({ instructionOrder: [_, orderInstructions], role }: TestCase) => { const commonAddress = getMockAddress(); const addressMap = getAddressMapFromInstructions( /* fee payer */ getMockAddress(), orderInstructions([ { accounts: [{ address: commonAddress, role: AccountRole[role] }], programAddress: getMockAddress(), }, { programAddress: commonAddress, }, ]), ); expect(addressMap).toHaveProperty(commonAddress, { [TYPE]: AddressMapEntryType.STATIC, role: AccountRole[role], }); }, ); it.each` role | instructionOrder ${'WRITABLE'} | ${['static address comes first', forwardOrder]} ${'WRITABLE_SIGNER'} | ${['static address comes first', forwardOrder]} ${'WRITABLE'} | ${['program address comes first', reverseOrder]} ${'WRITABLE_SIGNER'} | ${['program address comes first', reverseOrder]} `( 'fatals given a matching program and $role static account address when the $instructionOrder.0', ({ instructionOrder: [_, orderInstructions], role }: TestCase) => { const commonAddress = getMockAddress(); expect(() => getAddressMapFromInstructions( /* fee payer */ getMockAddress(), orderInstructions([ { accounts: [{ address: commonAddress, role: AccountRole[role] }], programAddress: getMockAddress(), }, { programAddress: commonAddress }, ]), ), ).toThrow(); }, ); it.each` instructionOrder ${['lut address comes first', forwardOrder]} ${['program address comes first', reverseOrder]} `( 'creates a READONLY static entry given a matching program and READONLY lookup table address when the $instructionOrder.0', ({ instructionOrder: [_, orderInstructions] }: TestCase) => { const commonAddress = getMockAddress(); const addressMap = getAddressMapFromInstructions( /* fee payer */ getMockAddress(), orderInstructions([ { accounts: [ { address: commonAddress, addressIndex: 0, lookupTableAddress: getMockAddress(), role: AccountRole.READONLY, }, ], programAddress: getMockAddress(), }, { programAddress: commonAddress }, ]), ); expect(addressMap).toHaveProperty(commonAddress, STATIC_ENTRY_READONLY); }, ); it.each` instructionOrder ${['lut address comes first', forwardOrder]} ${['program address comes first', reverseOrder]} `( 'fatals given a matching program and WRITABLE lookup table address when the $instructionOrder.0', ({ instructionOrder: [_, orderInstructions] }: TestCase) => { const commonAddress = getMockAddress(); expect(() => getAddressMapFromInstructions( /* fee payer */ getMockAddress(), orderInstructions([ { accounts: [ { address: commonAddress, addressIndex: 0, lookupTableAddress: getMockAddress(), role: AccountRole.WRITABLE, }, ], programAddress: getMockAddress(), }, { programAddress: commonAddress }, ]), ), ).toThrow(); }, ); it.each` aRole | bRole | endRole | expectedEntry ${'READONLY'} | ${'READONLY'} | ${'READONLY'} | ${STATIC_ENTRY_READONLY} ${'READONLY'} | ${'WRITABLE'} | ${'WRITABLE'} | ${STATIC_ENTRY_WRITABLE} ${'READONLY'} | ${'READONLY_SIGNER'} | ${'READONLY_SIGNER'} | ${STATIC_ENTRY_READONLY_SIGNER} ${'READONLY'} | ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} ${'WRITABLE'} | ${'READONLY'} | ${'WRITABLE'} | ${STATIC_ENTRY_WRITABLE} ${'WRITABLE'} | ${'WRITABLE'} | ${'WRITABLE'} | ${STATIC_ENTRY_WRITABLE} ${'WRITABLE'} | ${'READONLY_SIGNER'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} ${'WRITABLE'} | ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} ${'READONLY_SIGNER'} | ${'READONLY'} | ${'READONLY_SIGNER'} | ${STATIC_ENTRY_READONLY_SIGNER} ${'READONLY_SIGNER'} | ${'WRITABLE'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} ${'READONLY_SIGNER'} | ${'READONLY_SIGNER'} | ${'READONLY_SIGNER'} | ${STATIC_ENTRY_READONLY_SIGNER} ${'READONLY_SIGNER'} | ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} ${'WRITABLE_SIGNER'} | ${'READONLY'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} ${'WRITABLE_SIGNER'} | ${'WRITABLE'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} ${'WRITABLE_SIGNER'} | ${'READONLY_SIGNER'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} `( 'creates one $endRole static entry given matching $aRole and $bRole static accounts', ({ aRole, bRole, expectedEntry }: TestCase) => { const commonAddress = getMockAddress(); const addressMap = getAddressMapFromInstructions(/* fee payer */ getMockAddress(), [ { accounts: [{ address: commonAddress, role: AccountRole[aRole] }], programAddress: getMockAddress(), }, { accounts: [{ address: commonAddress, role: AccountRole[bRole] }], programAddress: getMockAddress(), }, ]); expect(addressMap).toHaveProperty(commonAddress, expectedEntry); }, ); it.each` staticRole | lutRole | endRole | expectedEntry | instructionOrder ${'READONLY'} | ${'READONLY'} | ${'READONLY'} | ${LUT_ENTRY_READONLY} | ${['lut address comes first', forwardOrder]} ${'READONLY'} | ${'WRITABLE'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['lut address comes first', forwardOrder]} ${'WRITABLE'} | ${'READONLY'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['lut address comes first', forwardOrder]} ${'WRITABLE'} | ${'WRITABLE'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['lut address comes first', forwardOrder]} ${'READONLY'} | ${'READONLY'} | ${'READONLY'} | ${LUT_ENTRY_READONLY} | ${['static address comes first', reverseOrder]} ${'READONLY'} | ${'WRITABLE'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['static address comes first', reverseOrder]} ${'WRITABLE'} | ${'READONLY'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['static address comes first', reverseOrder]} ${'WRITABLE'} | ${'WRITABLE'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['static address comes first', reverseOrder]} `( 'creates a $endRole lut entry given a matching $staticRole static and $lutRole lookup table address when the $instructionOrder.0 because the static address is not a signer', ({ expectedEntry, instructionOrder: [_, orderInstructions], lutRole, staticRole }: TestCase) => { const commonAddress = getMockAddress(); const lutMeta = { addressIndex: 0, lookupTableAddress: getMockAddress(), }; const addressMap = getAddressMapFromInstructions( /* fee payer */ getMockAddress(), orderInstructions([ { accounts: [{ address: commonAddress, ...lutMeta, role: AccountRole[lutRole] }], programAddress: getMockAddress(), }, { accounts: [{ address: commonAddress, role: AccountRole[staticRole] }], programAddress: getMockAddress(), }, ]), ); expect(addressMap).toHaveProperty(commonAddress, { ...expectedEntry, ...lutMeta }); }, ); it.each` staticRole | lutRole | endRole | expectedEntry | instructionOrder ${'READONLY_SIGNER'} | ${'READONLY'} | ${'READONLY_SIGNER'} | ${STATIC_ENTRY_READONLY_SIGNER} | ${['lut address comes first', forwardOrder]} ${'READONLY_SIGNER'} | ${'WRITABLE'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${['lut address comes first', forwardOrder]} ${'WRITABLE_SIGNER'} | ${'READONLY'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${['lut address comes first', forwardOrder]} ${'WRITABLE_SIGNER'} | ${'WRITABLE'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${['lut address comes first', forwardOrder]} ${'READONLY_SIGNER'} | ${'READONLY'} | ${'READONLY_SIGNER'} | ${STATIC_ENTRY_READONLY_SIGNER} | ${['static address comes first', reverseOrder]} ${'READONLY_SIGNER'} | ${'WRITABLE'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${['static address comes first', reverseOrder]} ${'WRITABLE_SIGNER'} | ${'READONLY'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${['static address comes first', reverseOrder]} ${'WRITABLE_SIGNER'} | ${'WRITABLE'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${['static address comes first', reverseOrder]} `( 'creates a $endRole static entry given a matching $staticRole static and $lutRole lookup table address when the $instructionOrder.0 because the static address is a signer', ({ expectedEntry, instructionOrder: [_, orderInstructions], lutRole, staticRole }) => { const commonAddress = getMockAddress(); const lutMeta = { addressIndex: 0, lookupTableAddress: getMockAddress(), }; const addressMap = getAddressMapFromInstructions( /* fee payer */ getMockAddress(), orderInstructions([ { accounts: [{ address: commonAddress, ...lutMeta, role: AccountRole[lutRole] }], programAddress: getMockAddress(), }, { accounts: [{ address: commonAddress, role: AccountRole[staticRole] }], programAddress: getMockAddress(), }, ]), ); expect(addressMap).toHaveProperty(commonAddress, expectedEntry); }, ); it.each` aRole | bRole | endRole | expectedEntry ${'READONLY'} | ${'READONLY'} | ${'READONLY'} | ${LUT_ENTRY_READONLY} ${'READONLY'} | ${'WRITABLE'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} ${'WRITABLE'} | ${'READONLY'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} ${'WRITABLE'} | ${'WRITABLE'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} `( 'creates one $endRole lut entry given matching $aRole and $bRole lut addresses', ({ aRole, bRole, expectedEntry }: TestCase) => { const commonAddress = getMockAddress(); const lutMeta = { addressIndex: 0, lookupTableAddress: getMockAddress(), }; const addressMap = getAddressMapFromInstructions(/* fee payer */ getMockAddress(), [ { accounts: [{ address: commonAddress, ...lutMeta, role: AccountRole[aRole] }], programAddress: getMockAddress(), }, { accounts: [{ address: commonAddress, ...lutMeta, role: AccountRole[bRole] }], programAddress: getMockAddress(), }, ]); expect(addressMap).toHaveProperty(commonAddress, { ...expectedEntry, ...lutMeta }); }, ); it.each` aRole | bRole | endRole | expectedEntry | instructionOrder ${'READONLY'} | ${'READONLY'} | ${'READONLY'} | ${LUT_ENTRY_READONLY} | ${['comes first', forwardOrder]} ${'READONLY'} | ${'WRITABLE'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['comes first', forwardOrder]} ${'WRITABLE'} | ${'READONLY'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['comes first', forwardOrder]} ${'WRITABLE'} | ${'WRITABLE'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['comes first', forwardOrder]} ${'READONLY'} | ${'READONLY'} | ${'READONLY'} | ${LUT_ENTRY_READONLY} | ${['comes last', reverseOrder]} ${'READONLY'} | ${'WRITABLE'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['comes last', reverseOrder]} ${'WRITABLE'} | ${'READONLY'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['comes last', reverseOrder]} ${'WRITABLE'} | ${'WRITABLE'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['comes last', reverseOrder]} `( 'creates one $endRole lut entry given matching $aRole and $bRole lut addresses from different lookup tables, preferring the table with the lower address when it $instructionOrder.0', ({ aRole, bRole, expectedEntry, instructionOrder: [_, orderInstructions] }) => { const commonAddress = getMockAddress(); const sortedAddresses = MOCK_ADDRESSES.slice(0, 2).sort(getAddressComparator()); const lowerLutMeta = { addressIndex: 9, lookupTableAddress: sortedAddresses[0], // Address which sorts lower. }; const higherLutMeta = { addressIndex: 6, lookupTableAddress: sortedAddresses[1], // Address which sorts higher. }; const addressMap = getAddressMapFromInstructions( /* fee payer */ getMockAddress(), orderInstructions([ { accounts: [{ address: commonAddress, role: AccountRole[aRole], ...lowerLutMeta }], programAddress: getMockAddress(), }, { accounts: [{ address: commonAddress, role: AccountRole[bRole], ...higherLutMeta }], programAddress: getMockAddress(), }, ]), ); expect(addressMap).toHaveProperty(commonAddress, { ...expectedEntry, ...lowerLutMeta }); }, ); }); describe('getOrderedAccountsFromAddressMap', () => { let sortedAddresses: Address[]; beforeEach(() => { sortedAddresses = [...MOCK_ADDRESSES].sort(getAddressComparator()); }); it.each(['READONLY', 'WRITABLE', 'READONLY_SIGNER', 'WRITABLE_SIGNER'] as AccountRoleEnumName[])( 'puts the fee payer before %s static addresses', role => { const orderedAccounts = getOrderedAccountsFromAddressMap({ [sortedAddresses[0]]: { [TYPE]: AddressMapEntryType.STATIC, role: AccountRole[role] }, [sortedAddresses[1]]: { [TYPE]: AddressMapEntryType.FEE_PAYER, role: AccountRole.WRITABLE_SIGNER }, }); expect(orderedAccounts).toHaveProperty('0', { [TYPE]: AddressMapEntryType.FEE_PAYER, address: sortedAddresses[1], role: AccountRole.WRITABLE_SIGNER, }); }, ); it.each(['READONLY', 'WRITABLE'] as AccountRoleEnumName[])( 'puts the fee payer before %s lookup table addresses', role => { const orderedAccounts = getOrderedAccountsFromAddressMap({ [sortedAddresses[0]]: { [TYPE]: AddressMapEntryType.LOOKUP_TABLE, addressIndex: 0, lookupTableAddress: getMockAddress(), role: AccountRole[role] as Exclude< AccountRole, AccountRole.READONLY_SIGNER | AccountRole.WRITABLE_SIGNER >, }, [sortedAddresses[1]]: { [TYPE]: AddressMapEntryType.FEE_PAYER, role: AccountRole.WRITABLE_SIGNER }, }); expect(orderedAccounts).toHaveProperty('0', { [TYPE]: AddressMapEntryType.FEE_PAYER, address: sortedAddresses[1], role: AccountRole.WRITABLE_SIGNER, }); }, ); it.each(['READONLY', 'WRITABLE', 'READONLY_SIGNER', 'WRITABLE_SIGNER'] as AccountRoleEnumName[])( 'orders %s static account addresses in lexical order', role => { const roleMeta = { role: AccountRole[role] }; const orderedAccounts = getOrderedAccountsFromAddressMap({ [sortedAddresses[1]]: { [TYPE]: AddressMapEntryType.STATIC, ...roleMeta }, [sortedAddresses[0]]: { [TYPE]: AddressMapEntryType.STATIC, ...roleMeta }, }); expect(orderedAccounts).toEqual([ { [TYPE]: AddressMapEntryType.STATIC, address: sortedAddresses[0], ...roleMeta }, { [TYPE]: AddressMapEntryType.STATIC, address: sortedAddresses[1], ...roleMeta }, ]); }, ); it.each(['READONLY', 'WRITABLE'] as AccountRoleEnumName[])( 'orders %s lookup table addresses by the lexical order of the address of their lookup table first, then by the addresses themselves', role => { const firstLutMeta = { addressIndex: 0, lookupTableAddress: sortedAddresses[0], }; const secondLutMeta = { addressIndex: 0, lookupTableAddress: sortedAddresses[1], }; const roleMeta = { role: AccountRole[role] as Exclude< AccountRole, AccountRole.READONLY_SIGNER | AccountRole.WRITABLE_SIGNER >, }; const orderedAccounts = getOrderedAccountsFromAddressMap({ [sortedAddresses[3]]: { [TYPE]: AddressMapEntryType.LOOKUP_TABLE, ...secondLutMeta, ...roleMeta }, [sortedAddresses[2]]: { [TYPE]: AddressMapEntryType.LOOKUP_TABLE, ...secondLutMeta, ...roleMeta }, [sortedAddresses[5]]: { [TYPE]: AddressMapEntryType.LOOKUP_TABLE, ...firstLutMeta, ...roleMeta }, [sortedAddresses[4]]: { [TYPE]: AddressMapEntryType.LOOKUP_TABLE, ...firstLutMeta, ...roleMeta }, }); expect(orderedAccounts).toEqual([ { [TYPE]: AddressMapEntryType.LOOKUP_TABLE, address: sortedAddresses[4], ...firstLutMeta, ...roleMeta }, { [TYPE]: AddressMapEntryType.LOOKUP_TABLE, address: sortedAddresses[5], ...firstLutMeta, ...roleMeta }, { [TYPE]: AddressMapEntryType.LOOKUP_TABLE, address: sortedAddresses[2], ...secondLutMeta, ...roleMeta, }, { [TYPE]: AddressMapEntryType.LOOKUP_TABLE, address: sortedAddresses[3], ...secondLutMeta, ...roleMeta, }, ]); }, ); it.each` beforeKind | beforeEntry | afterKind | afterEntry ${'WRITABLE lookup table'} | ${LUT_ENTRY_WRITABLE} | ${'READONLY lookup table'} | ${LUT_ENTRY_READONLY} ${'READONLY static'} | ${STATIC_ENTRY_READONLY} | ${'READONLY lookup table'} | ${LUT_ENTRY_READONLY} ${'READONLY static'} | ${STATIC_ENTRY_READONLY} | ${'WRITABLE lookup table'} | ${LUT_ENTRY_WRITABLE} ${'WRITABLE static'} | ${STATIC_ENTRY_WRITABLE} | ${'READONLY lookup table'} | ${LUT_ENTRY_READONLY} ${'WRITABLE static'} | ${STATIC_ENTRY_WRITABLE} | ${'WRITABLE lookup table'} | ${LUT_ENTRY_WRITABLE} ${'WRITABLE static'} | ${STATIC_ENTRY_WRITABLE} | ${'READONLY static'} | ${STATIC_ENTRY_READONLY} ${'READONLY_SIGNER static'} | ${STATIC_ENTRY_READONLY_SIGNER} | ${'READONLY lookup table'} | ${LUT_ENTRY_READONLY} ${'READONLY_SIGNER static'} | ${STATIC_ENTRY_READONLY_SIGNER} | ${'WRITABLE lookup table'} | ${LUT_ENTRY_WRITABLE} ${'READONLY_SIGNER static'} | ${STATIC_ENTRY_READONLY_SIGNER} | ${'READONLY static'} | ${STATIC_ENTRY_READONLY} ${'READONLY_SIGNER static'} | ${STATIC_ENTRY_READONLY_SIGNER} | ${'WRITABLE static'} | ${STATIC_ENTRY_WRITABLE} ${'WRITABLE_SIGNER static'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${'READONLY lookup table'} | ${LUT_ENTRY_READONLY} ${'WRITABLE_SIGNER static'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${'WRITABLE lookup table'} | ${LUT_ENTRY_WRITABLE} ${'WRITABLE_SIGNER static'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${'READONLY static'} | ${STATIC_ENTRY_READONLY} ${'WRITABLE_SIGNER static'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${'WRITABLE static'} | ${STATIC_ENTRY_WRITABLE} ${'WRITABLE_SIGNER static'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${'READONLY_SIGNER static'} | ${STATIC_ENTRY_READONLY_SIGNER} `('orders $beforeKind addresses before $afterKind addresses', ({ afterEntry, beforeEntry }) => { const orderedAccounts = getOrderedAccountsFromAddressMap({ [sortedAddresses[0]]: afterEntry, [sortedAddresses[1]]: beforeEntry, }); expect(orderedAccounts).toEqual([ { address: sortedAddresses[1], ...beforeEntry }, { address: sortedAddresses[0], ...afterEntry }, ]); }); });