@layerzerolabs/lz-solana-sdk-v2 3.0.104 → 3.0.105

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@layerzerolabs/lz-solana-sdk-v2",
3
- "version": "3.0.104",
3
+ "version": "3.0.105",
4
4
  "license": "BUSL-1.1",
5
5
  "exports": {
6
6
  ".": {
@@ -39,14 +39,15 @@
39
39
  "test-uln": "TEST_SCOPES=uln anchor test --skip-build"
40
40
  },
41
41
  "dependencies": {
42
- "@layerzerolabs/lz-corekit-solana": "^3.0.104",
43
- "@layerzerolabs/lz-definitions": "^3.0.104",
44
- "@layerzerolabs/lz-foundation": "^3.0.104",
45
- "@layerzerolabs/lz-serdes": "^3.0.104",
46
- "@layerzerolabs/lz-utilities": "^3.0.104",
47
- "@layerzerolabs/lz-v2-utilities": "^3.0.104",
42
+ "@layerzerolabs/lz-corekit-solana": "^3.0.105",
43
+ "@layerzerolabs/lz-definitions": "^3.0.105",
44
+ "@layerzerolabs/lz-foundation": "^3.0.105",
45
+ "@layerzerolabs/lz-serdes": "^3.0.105",
46
+ "@layerzerolabs/lz-utilities": "^3.0.105",
47
+ "@layerzerolabs/lz-v2-utilities": "^3.0.105",
48
48
  "@metaplex-foundation/beet": "^0.7.1",
49
49
  "@metaplex-foundation/beet-solana": "^0.4.0",
50
+ "@metaplex-foundation/mpl-toolbox": "^0.9.2",
50
51
  "@metaplex-foundation/umi": "^0.9.2",
51
52
  "@metaplex-foundation/umi-eddsa-web3js": "^0.9.2",
52
53
  "@metaplex-foundation/umi-program-repository": "^0.9.2",
@@ -66,8 +67,8 @@
66
67
  "@kinobi-so/renderers": "^0.21.3",
67
68
  "@kinobi-so/renderers-js-umi": "^0.21.6",
68
69
  "@layerzerolabs/layerzero-v2-solana": "^0.0.0",
69
- "@layerzerolabs/tsup-config-next": "^3.0.104",
70
- "@layerzerolabs/typescript-config-next": "^3.0.104",
70
+ "@layerzerolabs/tsup-config-next": "^3.0.105",
71
+ "@layerzerolabs/typescript-config-next": "^3.0.105",
71
72
  "@metaplex-foundation/umi-bundle-defaults": "^0.9.2",
72
73
  "@types/bn.js": "^5.1.5",
73
74
  "@types/chai": "^4.3.11",
package/src/executor.ts CHANGED
@@ -3,6 +3,7 @@ import {
3
3
  Cluster,
4
4
  ClusterFilter,
5
5
  Commitment,
6
+ Instruction,
6
7
  Program,
7
8
  ProgramError,
8
9
  ProgramRepositoryInterface,
@@ -17,8 +18,7 @@ import {
17
18
  import { createDefaultProgramRepository } from '@metaplex-foundation/umi-program-repository'
18
19
  import invariant from 'tiny-invariant'
19
20
 
20
- import { arrayify } from '@layerzerolabs/lz-utilities'
21
- import { Packet, addressToBytes32 } from '@layerzerolabs/lz-v2-utilities'
21
+ import { Packet } from '@layerzerolabs/lz-v2-utilities'
22
22
 
23
23
  import { ENDPOINT_PROGRAM_ID } from './endpoint'
24
24
  import { ComposeSentEvent } from './generated/kinobi/endpoint/events'
@@ -30,7 +30,7 @@ import { NativeDropInstructionDataArgs, QuoteExecutorInstructionArgs } from './g
30
30
  import { EXECUTOR_PROGRAM_ID } from './generated/kinobi/executor/programs'
31
31
  import * as types from './generated/kinobi/executor/types'
32
32
  import { EventPDA, ExecutorPDA, MessageLibPDA, PriceFeedPDA } from './pda'
33
- import { getLzComposeAccountMeta, getLzReceiveAccounts } from './receive'
33
+ import { getLzComposeAccountMeta, lzReceive } from './receive'
34
34
 
35
35
  export { EXECUTOR_PROGRAM_ID } from './generated/kinobi/executor/programs'
36
36
  export { accounts, instructions, types, events, errors }
@@ -320,63 +320,25 @@ export class Executor {
320
320
  endpointProgram?: PublicKey
321
321
  },
322
322
  commitment: Commitment = 'confirmed'
323
- ): Promise<WrappedInstruction> {
324
- const { packet, extraData, value = 0n, computeUnits = 200000, endpointProgram = ENDPOINT_PROGRAM_ID } = param
325
- const endpointEventPDA = new EventPDA(endpointProgram)
326
- const executorEventPDA = new EventPDA(this.programId)
327
- const { message: message_, sender: sender, srcEid, guid, receiver: receiver_, nonce } = packet
328
- const receiver = publicKey(addressToBytes32(receiver_))
329
- const receiverInfo = await rpc.getAccount(receiver, { commitment })
330
- invariant(receiverInfo.exists, `Receiver account not found: ${receiver}`)
331
- const receiverProgram = publicKey(receiverInfo.owner)
332
- const message = arrayify(message_)
333
- const accounts = await getLzReceiveAccounts(
334
- rpc,
335
- executor.publicKey,
336
- receiver,
337
- receiverProgram,
338
- {
339
- srcEid: srcEid,
340
- sender: arrayify(sender),
341
- guid: arrayify(guid),
342
- message,
343
- callerParams: extraData,
344
- nonce: BigInt(packet.nonce),
345
- },
346
- commitment
347
- )
323
+ ): Promise<{ signers: Signer[]; instructions: Instruction[] }> {
324
+ const { packet, extraData, value = 0n } = param
325
+ const payer = executor.publicKey
326
+ const lzReceiveResult = await lzReceive(rpc, payer, packet, extraData, this.programId, commitment)
327
+ const { contextVersion } = lzReceiveResult
328
+ const instructions: Instruction[] = [this.preExecute(executor, contextVersion, value).instruction]
329
+ const signers: Signer[] = []
348
330
 
349
- const txBuilder = instructions.execute(
350
- { programs: this.programRepo },
351
- {
352
- executor,
353
- config: this.pda.config(),
354
- endpointProgram: endpointProgram,
355
- endpointEventAuthority: endpointEventPDA.eventAuthority()[0],
356
- program: this.programId,
357
- eventAuthority: executorEventPDA.eventAuthority()[0],
358
- // param
359
- receiver,
360
- lzReceive: {
361
- srcEid,
362
- sender: arrayify(sender),
363
- nonce: parseInt(nonce),
364
- guid: arrayify(guid),
365
- message,
366
- extraData,
367
- },
368
- value,
369
- computeUnits,
370
- }
371
- )
372
- return txBuilder.addRemainingAccounts([
373
- {
374
- pubkey: receiverProgram,
375
- isWritable: false,
376
- isSigner: false,
377
- },
378
- ...accounts,
379
- ]).items[0]
331
+ // Handle both V1 (Instruction) and V2 ({signers, instructions})
332
+ if ('instruction' in lzReceiveResult) {
333
+ // V1: single instruction
334
+ instructions.push(lzReceiveResult.instruction)
335
+ } else {
336
+ // V2: multi-instruction
337
+ instructions.push(...lzReceiveResult.instructions)
338
+ signers.push(...lzReceiveResult.signers)
339
+ }
340
+ instructions.push(this.postExecute(executor, contextVersion).instruction)
341
+ return { signers, instructions }
380
342
  }
381
343
 
382
344
  async compose(
@@ -447,4 +409,18 @@ export class Executor {
447
409
  ...accounts,
448
410
  ]).items[0]
449
411
  }
412
+
413
+ preExecute(executor: Signer, version: number, feeLimit: bigint): WrappedInstruction {
414
+ const context = this.pda.context(executor.publicKey, version)
415
+ return instructions.preExecute(
416
+ { programs: this.programRepo },
417
+ { executor, context, feeLimit, contextVersion: version }
418
+ ).items[0]
419
+ }
420
+
421
+ postExecute(executor: Signer, version: number): WrappedInstruction {
422
+ const context = this.pda.context(executor.publicKey, version)
423
+ return instructions.postExecute({ programs: this.programRepo }, { context, executor, contextVersion: version })
424
+ .items[0]
425
+ }
450
426
  }
@@ -0,0 +1,173 @@
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
+ Account,
11
+ Context,
12
+ Pda,
13
+ PublicKey,
14
+ RpcAccount,
15
+ RpcGetAccountOptions,
16
+ RpcGetAccountsOptions,
17
+ assertAccountExists,
18
+ deserializeAccount,
19
+ gpaBuilder,
20
+ publicKey as toPublicKey,
21
+ } from '@metaplex-foundation/umi';
22
+ import {
23
+ Serializer,
24
+ bytes,
25
+ mapSerializer,
26
+ struct,
27
+ u64,
28
+ } from '@metaplex-foundation/umi/serializers';
29
+
30
+ export type ExecutionContextV1 = Account<ExecutionContextV1AccountData>;
31
+
32
+ export type ExecutionContextV1AccountData = {
33
+ discriminator: Uint8Array;
34
+ initialPayerBalance: bigint;
35
+ /**
36
+ * The maximum total lamports allowed to be used by all instructions in this execution.
37
+ * This is a hard cap for the sum of lamports consumed by all instructions in the execution batch.
38
+ */
39
+ feeLimit: bigint;
40
+ };
41
+
42
+ export type ExecutionContextV1AccountDataArgs = {
43
+ initialPayerBalance: number | bigint;
44
+ /**
45
+ * The maximum total lamports allowed to be used by all instructions in this execution.
46
+ * This is a hard cap for the sum of lamports consumed by all instructions in the execution batch.
47
+ */
48
+ feeLimit: number | bigint;
49
+ };
50
+
51
+ export function getExecutionContextV1AccountDataSerializer(): Serializer<
52
+ ExecutionContextV1AccountDataArgs,
53
+ ExecutionContextV1AccountData
54
+ > {
55
+ return mapSerializer<
56
+ ExecutionContextV1AccountDataArgs,
57
+ any,
58
+ ExecutionContextV1AccountData
59
+ >(
60
+ struct<ExecutionContextV1AccountData>(
61
+ [
62
+ ['discriminator', bytes({ size: 8 })],
63
+ ['initialPayerBalance', u64()],
64
+ ['feeLimit', u64()],
65
+ ],
66
+ { description: 'ExecutionContextV1AccountData' }
67
+ ),
68
+ (value) => ({
69
+ ...value,
70
+ discriminator: new Uint8Array([132, 92, 176, 59, 141, 186, 141, 137]),
71
+ })
72
+ ) as Serializer<
73
+ ExecutionContextV1AccountDataArgs,
74
+ ExecutionContextV1AccountData
75
+ >;
76
+ }
77
+
78
+ export function deserializeExecutionContextV1(
79
+ rawAccount: RpcAccount
80
+ ): ExecutionContextV1 {
81
+ return deserializeAccount(
82
+ rawAccount,
83
+ getExecutionContextV1AccountDataSerializer()
84
+ );
85
+ }
86
+
87
+ export async function fetchExecutionContextV1(
88
+ context: Pick<Context, 'rpc'>,
89
+ publicKey: PublicKey | Pda,
90
+ options?: RpcGetAccountOptions
91
+ ): Promise<ExecutionContextV1> {
92
+ const maybeAccount = await context.rpc.getAccount(
93
+ toPublicKey(publicKey, false),
94
+ options
95
+ );
96
+ assertAccountExists(maybeAccount, 'ExecutionContextV1');
97
+ return deserializeExecutionContextV1(maybeAccount);
98
+ }
99
+
100
+ export async function safeFetchExecutionContextV1(
101
+ context: Pick<Context, 'rpc'>,
102
+ publicKey: PublicKey | Pda,
103
+ options?: RpcGetAccountOptions
104
+ ): Promise<ExecutionContextV1 | null> {
105
+ const maybeAccount = await context.rpc.getAccount(
106
+ toPublicKey(publicKey, false),
107
+ options
108
+ );
109
+ return maybeAccount.exists
110
+ ? deserializeExecutionContextV1(maybeAccount)
111
+ : null;
112
+ }
113
+
114
+ export async function fetchAllExecutionContextV1(
115
+ context: Pick<Context, 'rpc'>,
116
+ publicKeys: Array<PublicKey | Pda>,
117
+ options?: RpcGetAccountsOptions
118
+ ): Promise<ExecutionContextV1[]> {
119
+ const maybeAccounts = await context.rpc.getAccounts(
120
+ publicKeys.map((key) => toPublicKey(key, false)),
121
+ options
122
+ );
123
+ return maybeAccounts.map((maybeAccount) => {
124
+ assertAccountExists(maybeAccount, 'ExecutionContextV1');
125
+ return deserializeExecutionContextV1(maybeAccount);
126
+ });
127
+ }
128
+
129
+ export async function safeFetchAllExecutionContextV1(
130
+ context: Pick<Context, 'rpc'>,
131
+ publicKeys: Array<PublicKey | Pda>,
132
+ options?: RpcGetAccountsOptions
133
+ ): Promise<ExecutionContextV1[]> {
134
+ const maybeAccounts = await context.rpc.getAccounts(
135
+ publicKeys.map((key) => toPublicKey(key, false)),
136
+ options
137
+ );
138
+ return maybeAccounts
139
+ .filter((maybeAccount) => maybeAccount.exists)
140
+ .map((maybeAccount) =>
141
+ deserializeExecutionContextV1(maybeAccount as RpcAccount)
142
+ );
143
+ }
144
+
145
+ export function getExecutionContextV1GpaBuilder(
146
+ context: Pick<Context, 'rpc' | 'programs'>
147
+ ) {
148
+ const programId = context.programs.getPublicKey(
149
+ 'executor',
150
+ '6doghB248px58JSSwG4qejQ46kFMW4AMj7vzJnWZHNZn'
151
+ );
152
+ return gpaBuilder(context, programId)
153
+ .registerFields<{
154
+ discriminator: Uint8Array;
155
+ initialPayerBalance: number | bigint;
156
+ feeLimit: number | bigint;
157
+ }>({
158
+ discriminator: [0, bytes({ size: 8 })],
159
+ initialPayerBalance: [8, u64()],
160
+ feeLimit: [16, u64()],
161
+ })
162
+ .deserializeUsing<ExecutionContextV1>((account) =>
163
+ deserializeExecutionContextV1(account)
164
+ )
165
+ .whereField(
166
+ 'discriminator',
167
+ new Uint8Array([132, 92, 176, 59, 141, 186, 141, 137])
168
+ );
169
+ }
170
+
171
+ export function getExecutionContextV1Size(): number {
172
+ return 24;
173
+ }
@@ -6,5 +6,6 @@
6
6
  * @see https://github.com/kinobi-so/kinobi
7
7
  */
8
8
 
9
+ export * from './executionContextV1';
9
10
  export * from './executorConfig';
10
11
  export * from './nonce';
@@ -252,6 +252,38 @@ export class InvalidOwnerError extends ProgramError {
252
252
  codeToErrorMap.set(0x1781, InvalidOwnerError);
253
253
  nameToErrorMap.set('InvalidOwner', InvalidOwnerError);
254
254
 
255
+ /** InvalidInstructionSequence */
256
+ export class InvalidInstructionSequenceError extends ProgramError {
257
+ override readonly name: string = 'InvalidInstructionSequence';
258
+
259
+ readonly code: number = 0x1782; // 6018
260
+
261
+ constructor(program: Program, cause?: Error) {
262
+ super('', program, cause);
263
+ }
264
+ }
265
+ codeToErrorMap.set(0x1782, InvalidInstructionSequenceError);
266
+ nameToErrorMap.set(
267
+ 'InvalidInstructionSequence',
268
+ InvalidInstructionSequenceError
269
+ );
270
+
271
+ /** ContextAccountAlreadyInitialized */
272
+ export class ContextAccountAlreadyInitializedError extends ProgramError {
273
+ override readonly name: string = 'ContextAccountAlreadyInitialized';
274
+
275
+ readonly code: number = 0x1783; // 6019
276
+
277
+ constructor(program: Program, cause?: Error) {
278
+ super('', program, cause);
279
+ }
280
+ }
281
+ codeToErrorMap.set(0x1783, ContextAccountAlreadyInitializedError);
282
+ nameToErrorMap.set(
283
+ 'ContextAccountAlreadyInitialized',
284
+ ContextAccountAlreadyInitializedError
285
+ );
286
+
255
287
  /**
256
288
  * Attempts to resolve a custom program error from the provided error code.
257
289
  * @category Errors
@@ -9,9 +9,10 @@
9
9
  export * from './adminSetConfig';
10
10
  export * from './compose';
11
11
  export * from './executable';
12
- export * from './execute';
13
12
  export * from './extendExecutorConfig';
14
13
  export * from './initExecutor';
15
14
  export * from './nativeDrop';
16
15
  export * from './ownerSetConfig';
16
+ export * from './postExecute';
17
+ export * from './preExecute';
17
18
  export * from './quoteExecutor';
@@ -0,0 +1,141 @@
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
+ publicKey,
16
+ transactionBuilder,
17
+ } from '@metaplex-foundation/umi';
18
+ import {
19
+ Serializer,
20
+ bytes,
21
+ mapSerializer,
22
+ struct,
23
+ u8,
24
+ } from '@metaplex-foundation/umi/serializers';
25
+ import {
26
+ ResolvedAccount,
27
+ ResolvedAccountsWithIndices,
28
+ getAccountMetasAndSigners,
29
+ } from '../shared';
30
+
31
+ // Accounts.
32
+ export type PostExecuteInstructionAccounts = {
33
+ executor: Signer;
34
+ /** Execution context account containing state from pre-execution */
35
+ context: PublicKey | Pda;
36
+ /** Instruction sysvar account for introspection */
37
+ instructionSysvar?: PublicKey | Pda;
38
+ };
39
+
40
+ // Data.
41
+ export type PostExecuteInstructionData = {
42
+ discriminator: Uint8Array;
43
+ /** Version of the execution context to use */
44
+ contextVersion: number;
45
+ };
46
+
47
+ export type PostExecuteInstructionDataArgs = {
48
+ /** Version of the execution context to use */
49
+ contextVersion: number;
50
+ };
51
+
52
+ export function getPostExecuteInstructionDataSerializer(): Serializer<
53
+ PostExecuteInstructionDataArgs,
54
+ PostExecuteInstructionData
55
+ > {
56
+ return mapSerializer<
57
+ PostExecuteInstructionDataArgs,
58
+ any,
59
+ PostExecuteInstructionData
60
+ >(
61
+ struct<PostExecuteInstructionData>(
62
+ [
63
+ ['discriminator', bytes({ size: 8 })],
64
+ ['contextVersion', u8()],
65
+ ],
66
+ { description: 'PostExecuteInstructionData' }
67
+ ),
68
+ (value) => ({
69
+ ...value,
70
+ discriminator: new Uint8Array([74, 168, 167, 167, 76, 220, 95, 56]),
71
+ })
72
+ ) as Serializer<PostExecuteInstructionDataArgs, PostExecuteInstructionData>;
73
+ }
74
+
75
+ // Args.
76
+ export type PostExecuteInstructionArgs = PostExecuteInstructionDataArgs;
77
+
78
+ // Instruction.
79
+ export function postExecute(
80
+ context: Pick<Context, 'programs'>,
81
+ input: PostExecuteInstructionAccounts & PostExecuteInstructionArgs
82
+ ): TransactionBuilder {
83
+ // Program ID.
84
+ const programId = context.programs.getPublicKey(
85
+ 'executor',
86
+ '6doghB248px58JSSwG4qejQ46kFMW4AMj7vzJnWZHNZn'
87
+ );
88
+
89
+ // Accounts.
90
+ const resolvedAccounts = {
91
+ executor: {
92
+ index: 0,
93
+ isWritable: false as boolean,
94
+ value: input.executor ?? null,
95
+ },
96
+ context: {
97
+ index: 1,
98
+ isWritable: true as boolean,
99
+ value: input.context ?? null,
100
+ },
101
+ instructionSysvar: {
102
+ index: 2,
103
+ isWritable: false as boolean,
104
+ value: input.instructionSysvar ?? null,
105
+ },
106
+ } satisfies ResolvedAccountsWithIndices;
107
+
108
+ // Arguments.
109
+ const resolvedArgs: PostExecuteInstructionArgs = { ...input };
110
+
111
+ // Default values.
112
+ if (!resolvedAccounts.instructionSysvar.value) {
113
+ resolvedAccounts.instructionSysvar.value = publicKey(
114
+ 'Sysvar1nstructions1111111111111111111111111'
115
+ );
116
+ }
117
+
118
+ // Accounts in order.
119
+ const orderedAccounts: ResolvedAccount[] = Object.values(
120
+ resolvedAccounts
121
+ ).sort((a, b) => a.index - b.index);
122
+
123
+ // Keys and Signers.
124
+ const [keys, signers] = getAccountMetasAndSigners(
125
+ orderedAccounts,
126
+ 'programId',
127
+ programId
128
+ );
129
+
130
+ // Data.
131
+ const data = getPostExecuteInstructionDataSerializer().serialize(
132
+ resolvedArgs as PostExecuteInstructionDataArgs
133
+ );
134
+
135
+ // Bytes Created On Chain.
136
+ const bytesCreatedOnChain = 0;
137
+
138
+ return transactionBuilder([
139
+ { instruction: { keys, programId, data }, signers, bytesCreatedOnChain },
140
+ ]);
141
+ }