@layerzerolabs/lz-solana-sdk-v2 3.0.104 → 3.0.105-mpt.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/receive.ts CHANGED
@@ -16,9 +16,13 @@ import { Packet, addressToBytes32 } from '@layerzerolabs/lz-v2-utilities'
16
16
 
17
17
  import { OmniAppPDA } from '.'
18
18
  import { ComposeSentEvent } from './generated/kinobi/endpoint/events'
19
+ import { EXECUTOR_PROGRAM_ID } from './generated/kinobi/executor/programs'
20
+ import { getLzReceiveAccountsFromTypesV1 } from './receive-types-v1'
21
+ import { buildLzReceiveExecutionPlan, getLzReceiveTypesInfo } from './receive-types-v2'
19
22
  import {
20
23
  LzComposeParams,
21
24
  LzReceiveParams,
25
+ LzReceiveTypesV2Accounts,
22
26
  getLzComposeParamsSerializer,
23
27
  getLzReceiveAccountSerializer,
24
28
  getLzReceiveParamsSerializer,
@@ -26,50 +30,86 @@ import {
26
30
  import { instructionDiscriminator, simulateWeb3JsTransaction } from './utility'
27
31
 
28
32
  /**
29
- * Receives a LayerZero message.
33
+ * Unified entry point for receiving a LayerZero message on Solana.
34
+ * This function automatically detects the lz_receive_types version and dispatches to the correct logic.
30
35
  *
31
- * @param {Connection} connection - The Solana connection object.
32
- * @param {PublicKey} payer - The public key of the payer.
33
- * @param {Packet} packet - The packet containing the message.
34
- * @param {Uint8Array} [callerParams] - Optional caller parameters.
35
- * @param {Commitment | GetAccountInfoConfig} [commitmentOrConfig] - Optional commitment or configuration.
36
- *
37
- * @returns {Promise<TransactionInstruction>} The transaction instruction.
36
+ * For V1: returns a single Instruction (legacy behavior).
37
+ * For V2: returns { signers, instructions } for multi-instruction atomic execution.
38
38
  */
39
39
  export async function lzReceive(
40
40
  rpc: RpcInterface,
41
41
  payer: PublicKey,
42
42
  packet: Pick<Packet, 'message' | 'sender' | 'srcEid' | 'guid' | 'receiver' | 'nonce'>,
43
43
  callerParams: Uint8Array = Uint8Array.from([0, 0]),
44
+ executorProgram: PublicKey = EXECUTOR_PROGRAM_ID,
44
45
  commitment: Commitment = 'confirmed'
45
- ): Promise<Instruction> {
46
- const { message: message_, sender: sender, srcEid, guid, receiver: receiver_ } = packet
47
- const receiver = publicKey(addressToBytes32(receiver_))
46
+ ): Promise<{ instruction: Instruction; contextVersion: number } | ReturnType<typeof buildLzReceiveExecutionPlan>> {
47
+ const { message: message_, sender: sender_, srcEid, guid, receiver: receiver_, nonce } = packet
48
+ const sender = arrayify(sender_)
49
+ const receiverBytes = addressToBytes32(receiver_)
48
50
  const message = arrayify(message_)
49
51
  const params: LzReceiveParams = {
50
52
  srcEid: srcEid,
51
- sender: arrayify(sender),
53
+ sender,
52
54
  guid: arrayify(guid),
53
55
  message,
54
56
  callerParams,
55
- nonce: BigInt(packet.nonce),
57
+ nonce: BigInt(nonce),
56
58
  }
57
- const receiverInfo = await rpc.getAccount(receiver, { commitment })
58
- invariant(receiverInfo.exists, `Receiver account not found: ${receiver}`)
59
+ const receiverPubkey = publicKey(receiverBytes)
60
+ const receiverInfo = await rpc.getAccount(receiverPubkey, { commitment })
61
+ invariant(receiverInfo.exists, `Receiver account not found: ${receiverPubkey}`)
59
62
  const receiverProgram = publicKey(receiverInfo.owner)
60
- const accounts = await getLzReceiveAccounts(rpc, payer, receiver, receiverProgram, params, commitment)
61
63
 
62
- const MSG_TYPE_OFFSET = 0
63
- // const msgType: string = message[MSG_TYPE_OFFSET].toString()
64
- // if (msgType !== MessageType.COMPOSED_TYPE.toString() && msgType !== MessageType.VANILLA.toString()) {
65
- // throw new Error(`Invalid message type ${msgType}`)
66
- // }
64
+ // Try to detect version by calling lz_receive_types_info
65
+ let version = 1
66
+ let receiveTypesAccounts: LzReceiveTypesV2Accounts | undefined
67
+ try {
68
+ // V2: lz_receive_types_info returns version 2
69
+ receiveTypesAccounts = await getLzReceiveTypesInfo(
70
+ rpc,
71
+ payer,
72
+ receiverPubkey,
73
+ receiverProgram,
74
+ params,
75
+ commitment
76
+ )
77
+ version = 2
78
+ } catch (e) {
79
+ // If info call fails or version !== 2, fallback to V1
80
+ version = 1
81
+ }
67
82
 
68
- const data = getLzReceiveParamsSerializer().serialize(params)
69
- return {
70
- programId: receiverProgram,
71
- keys: accounts,
72
- data: Buffer.concat([instructionDiscriminator('lz_receive'), data]),
83
+ if (version === 2) {
84
+ return buildLzReceiveExecutionPlan(
85
+ rpc,
86
+ executorProgram,
87
+ payer,
88
+ receiverPubkey,
89
+ receiverProgram,
90
+ params,
91
+ receiveTypesAccounts,
92
+ commitment
93
+ )
94
+ } else {
95
+ // V1: return a single Instruction (legacy behavior)
96
+ const accounts = await getLzReceiveAccountsFromTypesV1(
97
+ rpc,
98
+ payer,
99
+ receiverPubkey,
100
+ receiverProgram,
101
+ params,
102
+ commitment
103
+ )
104
+ const data = getLzReceiveParamsSerializer().serialize(params)
105
+ return {
106
+ instruction: {
107
+ programId: receiverProgram,
108
+ keys: accounts,
109
+ data: Buffer.concat([instructionDiscriminator('lz_receive'), data]),
110
+ },
111
+ contextVersion: 1,
112
+ }
73
113
  }
74
114
  }
75
115
 
@@ -115,82 +155,6 @@ export async function lzCompose(
115
155
  }
116
156
  }
117
157
 
118
- /// LzReceiveTypes instruction provides a list of accounts that are used in the LzReceive
119
- /// instruction. The list of accounts required by this LzReceiveTypes instruction can be found
120
- /// from the specific PDA account that is generated by the LZ_RECEIVE_TYPES_SEED.
121
- /**
122
- * Retrieves the accounts required for the LzReceive instruction.
123
- *
124
- * @param {Connection} connection - The Solana connection object.
125
- * @param {PublicKey} payer - The public key of the payer.
126
- * @param {PublicKey} receiver - The public key of the receiver.
127
- * @param {PublicKey} receiverProgram - The public key of the receiver program.
128
- * @param {LzReceiveParams} params - The parameters for the LzReceive instruction.
129
- * @param {Commitment | GetAccountInfoConfig} [commitmentOrConfig] - Optional commitment or configuration.
130
- *
131
- * @returns {Promise<AccountMeta[]>} The list of account metadata.
132
- */
133
- export async function getLzReceiveAccounts(
134
- rpc: RpcInterface,
135
- payer: PublicKey,
136
- receiver: PublicKey,
137
- receiverProgram: PublicKey,
138
- params: LzReceiveParams,
139
- commitment: Commitment = 'confirmed'
140
- ): Promise<AccountMeta[]> {
141
- const lzReceiveTypesAccounts = await (async (): Promise<AccountMeta[]> => {
142
- const oappPDA = new OmniAppPDA(receiverProgram)
143
- const [lzReceiveTypesAccountsPDA] = oappPDA.lzReceiveTypesAccounts(receiver)
144
- // const [lzReceiveTypesAccountsPDA] = deriveLzReceiveTypesAccountsPDA(receiverProgram, receiver)
145
- // Get the lzReceiveTypesAccounts. Deserialize the AccountInfo.data to get the lzReceiveTypesAccounts.
146
- const info = await rpc.getAccount(lzReceiveTypesAccountsPDA, { commitment })
147
- const accounts = []
148
- if (info.exists) {
149
- const buffer = Buffer.from(info.data)
150
- const len = buffer.length - 8
151
- if (len % 32 !== 0) {
152
- throw new Error(
153
- `Invalid length of AccountInfo.data. The length must be a multiple of 32 plus 8.(n*32+8). Current length is ${buffer.length}`
154
- )
155
- }
156
- // const serializer = array(publicKeySerializer())
157
- // const [addresses] = serializer.deserialize(buffer, 8)
158
- // for (const address of addresses) {
159
- // accounts.push({
160
- // pubkey: address,
161
- // isSigner: false,
162
- // isWritable: false,
163
- // })
164
- // }
165
- for (let i = 8; i < len; i += 32) {
166
- const [address] = publicKeySerializer().deserialize(buffer, i)
167
- accounts.push({
168
- pubkey: address,
169
- isSigner: false,
170
- isWritable: false,
171
- })
172
- }
173
- }
174
- return accounts
175
- })()
176
-
177
- const data = getLzReceiveParamsSerializer().serialize(params)
178
- const lzReceiveTypesIx: Instruction = {
179
- programId: receiverProgram,
180
- keys: lzReceiveTypesAccounts,
181
- data: Buffer.concat([instructionDiscriminator('lz_receive_types'), data]),
182
- }
183
- const keys = await simulateWeb3JsTransaction(
184
- rpc.getEndpoint(),
185
- [toWeb3JsInstruction(lzReceiveTypesIx)],
186
- toWeb3JsPublicKey(receiverProgram),
187
- toWeb3JsPublicKey(payer),
188
- array(getLzReceiveAccountSerializer()),
189
- 'confirmed'
190
- )
191
- return updateAccountFromSimulatedResp(keys, payer)
192
- }
193
-
194
158
  /**
195
159
  * Retrieves the accounts required for the LzCompose instruction.
196
160
  *
@@ -226,15 +190,6 @@ export async function getLzComposeAccountMeta(
226
190
  `Invalid length of AccountInfo.data. The length must be a multiple of 32 plus 8.(n*32+8). Current length is ${buffer.length}`
227
191
  )
228
192
  }
229
- // const serializer = array(publicKeySerializer())
230
- // const [addresses] = serializer.deserialize(buffer, 8)
231
- // for (const address of addresses) {
232
- // accounts.push({
233
- // pubkey: address,
234
- // isSigner: false,
235
- // isWritable: false,
236
- // })
237
- // }
238
193
  for (let i = 8; i < len; i += 32) {
239
194
  const [address] = publicKeySerializer().deserialize(buffer, i)
240
195
  accounts.push({
@@ -9,11 +9,8 @@ import {
9
9
  } from '@solana/web3.js'
10
10
  import BN from 'bn.js'
11
11
 
12
- import { arrayify } from '@layerzerolabs/lz-utilities'
13
- import { Packet, addressToBytes32 } from '@layerzerolabs/lz-v2-utilities'
14
-
15
12
  import { EventPDADeriver, ExecutorPDADeriver, MessageLibPDADeriver, PriceFeedPDADeriver } from './pda-deriver'
16
- import { getLzComposeAccountMeta, getLzReceiveAccounts } from './recevie'
13
+ import { getLzComposeAccountMeta } from './recevie'
17
14
  import { ComposeSentEvent } from '../generated/solita/endpoint/events'
18
15
  import * as accounts from '../generated/solita/executor/accounts'
19
16
  import * as events from '../generated/solita/executor/events'
@@ -409,90 +406,6 @@ export class Executor {
409
406
  ].concat(ixAccounts)
410
407
  }
411
408
 
412
- /**
413
- * Executes a transaction.
414
- *
415
- * @param {Connection} connection - The connection.
416
- * @param {PublicKey} executor - The executor public key.
417
- * @param {PublicKey} endpointProgram - The endpoint program public key.
418
- * @param {Packet} packet - The packet.
419
- * @param {Uint8Array} extraData - The extra data.
420
- * @param {BN} [value] - The value.
421
- * @param {number} [computeUnits] - The compute units.
422
- * @param {Commitment} [commitmentOrConfig] - The commitment or configuration.
423
- *
424
- * @returns {Promise<TransactionInstruction>} A promise that resolves to the transaction instruction.
425
- */
426
- async execute(
427
- connection: Connection,
428
- executor: PublicKey,
429
- endpointProgram: PublicKey,
430
- packet: Packet,
431
- extraData: Uint8Array,
432
- value: BN = new BN(0),
433
- computeUnits = 200000,
434
- commitmentOrConfig?: Commitment
435
- ): Promise<TransactionInstruction> {
436
- const [config] = this.deriver.config()
437
- const endpointEventDeriver = new EventPDADeriver(endpointProgram)
438
- const executorEventDeriver = new EventPDADeriver(this.program)
439
- const { message: message_, sender: sender, srcEid, guid, receiver: receiver_, nonce } = packet
440
- const receiver = new PublicKey(addressToBytes32(receiver_))
441
- const receiverInfo = await connection.getParsedAccountInfo(receiver, commitmentOrConfig)
442
- const receiverProgram = new PublicKey((receiverInfo.value as AccountInfo<Buffer>).owner)
443
- const message = arrayify(message_)
444
- const accounts = await getLzReceiveAccounts(
445
- connection,
446
- executor,
447
- receiver,
448
- receiverProgram,
449
- {
450
- srcEid: srcEid,
451
- sender: Array.from(arrayify(sender)),
452
- guid: Array.from(arrayify(guid)),
453
- message,
454
- callerParams: extraData,
455
- nonce: parseInt(packet.nonce),
456
- },
457
- commitmentOrConfig
458
- )
459
-
460
- return instructions.createExecuteInstruction(
461
- {
462
- executor,
463
- config,
464
- endpointProgram,
465
- endpointEventAuthority: endpointEventDeriver.eventAuthority()[0],
466
- program: this.program,
467
- eventAuthority: executorEventDeriver.eventAuthority()[0],
468
- anchorRemainingAccounts: [
469
- {
470
- pubkey: receiverProgram,
471
- isWritable: false,
472
- isSigner: false,
473
- },
474
- ...accounts,
475
- ],
476
- } satisfies instructions.ExecuteInstructionAccounts,
477
- {
478
- params: {
479
- receiver,
480
- lzReceive: {
481
- srcEid,
482
- sender: Array.from(arrayify(sender)),
483
- nonce: parseInt(nonce),
484
- guid: Array.from(arrayify(guid)),
485
- message,
486
- extraData,
487
- },
488
- value,
489
- computeUnits,
490
- } satisfies types.ExecuteParams,
491
- } satisfies instructions.ExecuteInstructionArgs,
492
- this.program
493
- )
494
- }
495
-
496
409
  /**
497
410
  * Composes a transaction.
498
411
  *
package/src/types.ts CHANGED
@@ -1,13 +1,20 @@
1
1
  import { PublicKey } from '@metaplex-foundation/umi'
2
2
  import {
3
+ GetDataEnumKind,
4
+ GetDataEnumKindContent,
3
5
  Serializer,
6
+ array,
4
7
  bool,
5
8
  bytes,
9
+ dataEnum,
6
10
  publicKey as publicKeySerializer,
7
11
  struct,
12
+ tuple,
8
13
  u16,
9
14
  u32,
10
15
  u64,
16
+ u8,
17
+ unit,
11
18
  } from '@metaplex-foundation/umi/serializers'
12
19
 
13
20
  export interface SolanaPacketPath {
@@ -34,6 +41,11 @@ export enum MessageType {
34
41
  * Composed message type.
35
42
  */
36
43
  COMPOSED_TYPE = 2,
44
+
45
+ /**
46
+ * ABA message type.
47
+ */
48
+ ABA = 3,
37
49
  }
38
50
 
39
51
  /**
@@ -214,3 +226,131 @@ export enum ExecutorOptionType {
214
226
  * Maximum length for executor option types.
215
227
  */
216
228
  export const MaxExecutorOptionTypeLength = 10
229
+
230
+ export interface LzReceiveTypesV2Accounts {
231
+ accounts: PublicKey[]
232
+ }
233
+
234
+ export type AddressLocator =
235
+ | { __kind: 'Address'; fields: [PublicKey] }
236
+ | { __kind: 'AltIndex'; fields: [number, number] }
237
+ | { __kind: 'Payer' }
238
+ | { __kind: 'Signer'; fields: [number] }
239
+ | { __kind: 'Context' }
240
+
241
+ export interface AccountMetaRef {
242
+ pubkey: AddressLocator
243
+ isWritable: boolean
244
+ }
245
+
246
+ export type Instruction =
247
+ | { __kind: 'LzReceive'; accounts: AccountMetaRef[] }
248
+ | { __kind: 'Standard'; programId: PublicKey; accounts: AccountMetaRef[]; data: Uint8Array }
249
+
250
+ export interface LzReceiveTypesV2Result {
251
+ contextVersion: number
252
+ alts: PublicKey[]
253
+ instructions: Instruction[]
254
+ }
255
+
256
+ export function getAddressLocatorSerializer(): Serializer<AddressLocator, AddressLocator> {
257
+ return dataEnum<AddressLocator>(
258
+ [
259
+ [
260
+ 'Address',
261
+ struct<GetDataEnumKindContent<AddressLocator, 'Address'>>([['fields', tuple([publicKeySerializer()])]]),
262
+ ],
263
+ ['AltIndex', struct<GetDataEnumKindContent<AddressLocator, 'AltIndex'>>([['fields', tuple([u8(), u8()])]])],
264
+ ['Payer', unit()],
265
+ ['Signer', struct<GetDataEnumKindContent<AddressLocator, 'Signer'>>([['fields', tuple([u8()])]])],
266
+ ['Context', unit()],
267
+ ],
268
+ { description: 'AddressLocator' }
269
+ )
270
+ }
271
+
272
+ export function getLzReceiveTypesV2AccountsSerializer(): Serializer<
273
+ LzReceiveTypesV2Accounts,
274
+ LzReceiveTypesV2Accounts
275
+ > {
276
+ return struct<LzReceiveTypesV2Accounts>([['accounts', array(publicKeySerializer())]], {
277
+ description: 'LzReceiveTypesV2Result',
278
+ })
279
+ }
280
+
281
+ export function getAccountMetaRefSerializer(): Serializer<AccountMetaRef, AccountMetaRef> {
282
+ return struct<AccountMetaRef>(
283
+ [
284
+ ['pubkey', getAddressLocatorSerializer()],
285
+ ['isWritable', bool()],
286
+ ],
287
+ { description: 'AccountMetaRef' }
288
+ )
289
+ }
290
+
291
+ export function getInstructionSerializer(): Serializer<Instruction, Instruction> {
292
+ return dataEnum<Instruction>(
293
+ [
294
+ [
295
+ 'LzReceive',
296
+ struct<GetDataEnumKindContent<Instruction, 'LzReceive'>>([
297
+ ['accounts', array(getAccountMetaRefSerializer())],
298
+ ]),
299
+ ],
300
+ [
301
+ 'Standard',
302
+ struct<GetDataEnumKindContent<Instruction, 'Standard'>>([
303
+ ['programId', publicKeySerializer()],
304
+ ['accounts', array(getAccountMetaRefSerializer())],
305
+ ['data', bytes({ size: u32() })],
306
+ ]),
307
+ ],
308
+ ],
309
+ { description: 'Instruction' }
310
+ )
311
+ }
312
+
313
+ export function getLzReceiveTypesV2ResultSerializer(): Serializer<LzReceiveTypesV2Result, LzReceiveTypesV2Result> {
314
+ return struct<LzReceiveTypesV2Result>(
315
+ [
316
+ ['contextVersion', u8()],
317
+ ['alts', array(publicKeySerializer())],
318
+ ['instructions', array(getInstructionSerializer())],
319
+ ],
320
+ { description: 'LzReceiveTypesV2Result' }
321
+ )
322
+ }
323
+
324
+ // Data Enum Helpers.
325
+ export function addressLocator(kind: 'Payer'): GetDataEnumKind<AddressLocator, 'Payer'>
326
+
327
+ export function addressLocator(
328
+ kind: 'Signer',
329
+ data: GetDataEnumKindContent<AddressLocator, 'Signer'>['fields']
330
+ ): GetDataEnumKind<AddressLocator, 'Signer'>
331
+
332
+ export function addressLocator(
333
+ kind: 'Address',
334
+ data: GetDataEnumKindContent<AddressLocator, 'Address'>['fields']
335
+ ): GetDataEnumKind<AddressLocator, 'Address'>
336
+
337
+ export function addressLocator(
338
+ kind: 'AltIndex',
339
+ data: GetDataEnumKindContent<AddressLocator, 'AltIndex'>['fields']
340
+ ): GetDataEnumKind<AddressLocator, 'AltIndex'>
341
+
342
+ export function addressLocator<K extends AddressLocator['__kind']>(
343
+ kind: K,
344
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
345
+ data?: any
346
+ ): Extract<AddressLocator, { __kind: K }> {
347
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
348
+ return Array.isArray(data) ? { __kind: kind, fields: data } : { __kind: kind, ...(data ?? {}) }
349
+ }
350
+
351
+ export function isAddressLocator<K extends AddressLocator['__kind']>(
352
+ kind: K,
353
+ value: AddressLocator
354
+ ): value is AddressLocator & { __kind: K } {
355
+ return value.__kind === kind
356
+ }
@@ -1,159 +0,0 @@
1
- /**
2
- * This code was AUTOGENERATED using the kinobi library.
3
- * Please DO NOT EDIT THIS FILE, instead use visitors
4
- * to add features, then rerun kinobi to update it.
5
- *
6
- * @see https://github.com/kinobi-so/kinobi
7
- */
8
-
9
- import {
10
- Context,
11
- Pda,
12
- PublicKey,
13
- Signer,
14
- TransactionBuilder,
15
- transactionBuilder,
16
- } from '@metaplex-foundation/umi';
17
- import {
18
- Serializer,
19
- bytes,
20
- mapSerializer,
21
- publicKey as publicKeySerializer,
22
- struct,
23
- u64,
24
- } from '@metaplex-foundation/umi/serializers';
25
- import {
26
- ResolvedAccount,
27
- ResolvedAccountsWithIndices,
28
- getAccountMetasAndSigners,
29
- } from '../shared';
30
- import {
31
- LzReceiveParams,
32
- LzReceiveParamsArgs,
33
- getLzReceiveParamsSerializer,
34
- } from '../types';
35
-
36
- // Accounts.
37
- export type ExecuteInstructionAccounts = {
38
- executor: Signer;
39
- config: PublicKey | Pda;
40
- endpointProgram: PublicKey | Pda;
41
- /** The authority for the endpoint program to emit events */
42
- endpointEventAuthority: PublicKey | Pda;
43
- eventAuthority: PublicKey | Pda;
44
- program: PublicKey | Pda;
45
- };
46
-
47
- // Data.
48
- export type ExecuteInstructionData = {
49
- discriminator: Uint8Array;
50
- receiver: PublicKey;
51
- lzReceive: LzReceiveParams;
52
- value: bigint;
53
- computeUnits: bigint;
54
- };
55
-
56
- export type ExecuteInstructionDataArgs = {
57
- receiver: PublicKey;
58
- lzReceive: LzReceiveParamsArgs;
59
- value: number | bigint;
60
- computeUnits: number | bigint;
61
- };
62
-
63
- export function getExecuteInstructionDataSerializer(): Serializer<
64
- ExecuteInstructionDataArgs,
65
- ExecuteInstructionData
66
- > {
67
- return mapSerializer<ExecuteInstructionDataArgs, any, ExecuteInstructionData>(
68
- struct<ExecuteInstructionData>(
69
- [
70
- ['discriminator', bytes({ size: 8 })],
71
- ['receiver', publicKeySerializer()],
72
- ['lzReceive', getLzReceiveParamsSerializer()],
73
- ['value', u64()],
74
- ['computeUnits', u64()],
75
- ],
76
- { description: 'ExecuteInstructionData' }
77
- ),
78
- (value) => ({
79
- ...value,
80
- discriminator: new Uint8Array([130, 221, 242, 154, 13, 193, 189, 29]),
81
- })
82
- ) as Serializer<ExecuteInstructionDataArgs, ExecuteInstructionData>;
83
- }
84
-
85
- // Args.
86
- export type ExecuteInstructionArgs = ExecuteInstructionDataArgs;
87
-
88
- // Instruction.
89
- export function execute(
90
- context: Pick<Context, 'programs'>,
91
- input: ExecuteInstructionAccounts & ExecuteInstructionArgs
92
- ): TransactionBuilder {
93
- // Program ID.
94
- const programId = context.programs.getPublicKey(
95
- 'executor',
96
- '6doghB248px58JSSwG4qejQ46kFMW4AMj7vzJnWZHNZn'
97
- );
98
-
99
- // Accounts.
100
- const resolvedAccounts = {
101
- executor: {
102
- index: 0,
103
- isWritable: true as boolean,
104
- value: input.executor ?? null,
105
- },
106
- config: {
107
- index: 1,
108
- isWritable: false as boolean,
109
- value: input.config ?? null,
110
- },
111
- endpointProgram: {
112
- index: 2,
113
- isWritable: false as boolean,
114
- value: input.endpointProgram ?? null,
115
- },
116
- endpointEventAuthority: {
117
- index: 3,
118
- isWritable: false as boolean,
119
- value: input.endpointEventAuthority ?? null,
120
- },
121
- eventAuthority: {
122
- index: 4,
123
- isWritable: false as boolean,
124
- value: input.eventAuthority ?? null,
125
- },
126
- program: {
127
- index: 5,
128
- isWritable: false as boolean,
129
- value: input.program ?? null,
130
- },
131
- } satisfies ResolvedAccountsWithIndices;
132
-
133
- // Arguments.
134
- const resolvedArgs: ExecuteInstructionArgs = { ...input };
135
-
136
- // Accounts in order.
137
- const orderedAccounts: ResolvedAccount[] = Object.values(
138
- resolvedAccounts
139
- ).sort((a, b) => a.index - b.index);
140
-
141
- // Keys and Signers.
142
- const [keys, signers] = getAccountMetasAndSigners(
143
- orderedAccounts,
144
- 'programId',
145
- programId
146
- );
147
-
148
- // Data.
149
- const data = getExecuteInstructionDataSerializer().serialize(
150
- resolvedArgs as ExecuteInstructionDataArgs
151
- );
152
-
153
- // Bytes Created On Chain.
154
- const bytesCreatedOnChain = 0;
155
-
156
- return transactionBuilder([
157
- { instruction: { keys, programId, data }, signers, bytesCreatedOnChain },
158
- ]);
159
- }