@layerzerolabs/lz-sui-sdk-v2 3.0.73 → 3.0.75

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.
@@ -0,0 +1,303 @@
1
+ import { bcs } from '@mysten/sui/bcs'
2
+ import { SuiClient } from '@mysten/sui/client'
3
+ import { Transaction, TransactionResult } from '@mysten/sui/transactions'
4
+
5
+ import { Context, ObjectOptions } from '../types'
6
+ import { moveView } from '../utils'
7
+
8
+ export class Endpoint {
9
+ public packageId: string
10
+ public readonly client: SuiClient
11
+ private readonly objects: Pick<ObjectOptions, 'endpoint_v2' | 'endpoint_admin_cap'>
12
+
13
+ constructor(
14
+ packageId: string,
15
+ client: SuiClient,
16
+ objects: Pick<ObjectOptions, 'endpoint_v2' | 'endpoint_admin_cap'>,
17
+ private readonly context: Context
18
+ ) {
19
+ this.packageId = packageId
20
+ this.client = client
21
+ this.objects = objects
22
+
23
+ // Validate that required objects are not empty strings
24
+ if (this.objects.endpoint_v2.trim() === '') {
25
+ throw new Error('endpoint_v2 object cannot be empty')
26
+ }
27
+ if (this.objects.endpoint_admin_cap.trim() === '') {
28
+ throw new Error('endpoint_admin_cap object cannot be empty')
29
+ }
30
+ }
31
+
32
+ async eid(): Promise<number> {
33
+ const tx = new Transaction()
34
+ tx.moveCall({
35
+ target: `${this.packageId}::endpoint_v2::eid`,
36
+ typeArguments: [],
37
+ arguments: [tx.object(this.objects.endpoint_v2)],
38
+ })
39
+ try {
40
+ const result = await moveView(this.client, tx)
41
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
42
+ const bytes = new Uint8Array(result?.returnValues![0][0]!)
43
+ return bcs.U32.parse(bytes)
44
+ } catch (e) {
45
+ //TODO need to handle error properly
46
+ return 0
47
+ }
48
+ }
49
+
50
+ populateInitEidTransaction(eid: number): Transaction {
51
+ const tx = new Transaction()
52
+ tx.moveCall({
53
+ target: `${this.packageId}::endpoint_v2::init_eid`,
54
+ typeArguments: [],
55
+ arguments: [
56
+ tx.object(this.objects.endpoint_v2),
57
+ tx.object(this.objects.endpoint_admin_cap),
58
+ tx.pure.u32(eid),
59
+ ],
60
+ })
61
+ return tx
62
+ }
63
+
64
+ async getDefaultSendLibrary(srcEid: number): Promise<string> {
65
+ const tx = new Transaction()
66
+ tx.moveCall({
67
+ target: `${this.packageId}::endpoint_v2::get_default_send_library`,
68
+ typeArguments: [],
69
+ arguments: [tx.object(this.objects.endpoint_v2), tx.pure.u32(srcEid)],
70
+ })
71
+ try {
72
+ const result = await moveView(this.client, tx)
73
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
74
+ const bytes = new Uint8Array(result?.returnValues![0][0]!)
75
+ return bcs.Address.parse(bytes)
76
+ } catch (error) {
77
+ //TODO need to handle error properly
78
+ return '0x0'
79
+ }
80
+ }
81
+
82
+ populateSetDefaultSendLibraryTransaction(dstEid: number, newLib: string): Transaction {
83
+ const tx = new Transaction()
84
+ tx.moveCall({
85
+ target: `${this.packageId}::endpoint_v2::set_default_send_library`,
86
+ typeArguments: [],
87
+ arguments: [
88
+ tx.object(this.objects.endpoint_v2),
89
+ tx.object(this.objects.endpoint_admin_cap),
90
+ tx.pure.u32(dstEid),
91
+ tx.pure.address(newLib),
92
+ ],
93
+ })
94
+ return tx
95
+ }
96
+
97
+ async getDefaultReceiveLibrary(srcEid: number): Promise<string> {
98
+ const tx = new Transaction()
99
+ tx.moveCall({
100
+ target: `${this.packageId}::endpoint_v2::get_default_receive_library`,
101
+ typeArguments: [],
102
+ arguments: [tx.object(this.objects.endpoint_v2), tx.pure.u32(srcEid)],
103
+ })
104
+ try {
105
+ const result = await moveView(this.client, tx)
106
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
107
+ const bytes = new Uint8Array(result?.returnValues![0][0]!)
108
+ return bcs.Address.parse(bytes)
109
+ } catch (error) {
110
+ return '0x'
111
+ }
112
+ }
113
+
114
+ populateSetDefaultReceiveLibraryTransaction(srcEid: number, newLib: string, gracePeriod: number): Transaction {
115
+ const tx = new Transaction()
116
+ tx.moveCall({
117
+ target: `${this.packageId}::endpoint_v2::set_default_receive_library`,
118
+ typeArguments: [],
119
+ arguments: [
120
+ tx.object(this.objects.endpoint_v2),
121
+ tx.object(this.objects.endpoint_admin_cap),
122
+ tx.pure.u32(srcEid),
123
+ tx.pure.address(newLib),
124
+ tx.pure.u64(gracePeriod),
125
+ tx.object('0x6'), // Clock Object TODO try to get it from the client or sdk
126
+ ],
127
+ })
128
+ return tx
129
+ }
130
+
131
+ confirmQuoteMoveCall(tx: Transaction, executedCall: TransactionResult): TransactionResult {
132
+ return tx.moveCall({
133
+ target: `${this.packageId}::endpoint_v2::confirm_quote`,
134
+ typeArguments: [],
135
+ arguments: [tx.object(this.objects.endpoint_v2), executedCall],
136
+ })
137
+ }
138
+
139
+ confirmSendMoveCall(tx: Transaction, executedCall: TransactionResult): TransactionResult {
140
+ return tx.moveCall({
141
+ target: `${this.packageId}::endpoint_v2::confirm_send`,
142
+ typeArguments: [],
143
+ arguments: [tx.object(this.objects.endpoint_v2), executedCall],
144
+ })
145
+ }
146
+
147
+ // === Worker Endpoint Required Methods ===
148
+
149
+ async getSendLibrary(sender: string, dstEid: number): Promise<[string, boolean]> {
150
+ const tx = new Transaction()
151
+ tx.moveCall({
152
+ target: `${this.packageId}::endpoint_v2::get_send_library`,
153
+ typeArguments: [],
154
+ arguments: [tx.object(this.objects.endpoint_v2), tx.pure.address(sender), tx.pure.u32(dstEid)],
155
+ })
156
+ const result = await moveView(this.client, tx)
157
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
158
+ const bytes = new Uint8Array(result?.returnValues![0][0]!)
159
+ const lib = bcs.Address.parse(bytes)
160
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
161
+ const isDefaultBytes = new Uint8Array(result?.returnValues![1][0]!)
162
+ const isDefault = bcs.Bool.parse(isDefaultBytes)
163
+ return [lib, isDefault]
164
+ }
165
+
166
+ async getReceiveLibrary(receiver: string, srcEid: number): Promise<[string, boolean]> {
167
+ const tx = new Transaction()
168
+ tx.moveCall({
169
+ target: `${this.packageId}::endpoint_v2::get_receive_library`,
170
+ typeArguments: [],
171
+ arguments: [tx.object(this.objects.endpoint_v2), tx.pure.address(receiver), tx.pure.u32(srcEid)],
172
+ })
173
+ const result = await moveView(this.client, tx)
174
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
175
+ const bytes = new Uint8Array(result?.returnValues![0][0]!)
176
+ const lib = bcs.Address.parse(bytes)
177
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
178
+ const isDefaultBytes = new Uint8Array(result?.returnValues![1][0]!)
179
+ const isDefault = bcs.Bool.parse(isDefaultBytes)
180
+ return [lib, isDefault]
181
+ }
182
+
183
+ async getInboundNonce(receiver: string, srcEid: number, sender: Uint8Array): Promise<bigint> {
184
+ const tx = new Transaction()
185
+ tx.moveCall({
186
+ target: `${this.packageId}::endpoint_v2::get_inbound_nonce`,
187
+ typeArguments: [],
188
+ arguments: [
189
+ tx.object(this.objects.endpoint_v2),
190
+ tx.pure.address(receiver),
191
+ tx.pure.u32(srcEid),
192
+ tx.pure(bcs.vector(bcs.u8()).serialize(sender)),
193
+ ],
194
+ })
195
+ const result = await moveView(this.client, tx)
196
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
197
+ const bytes = new Uint8Array(result?.returnValues![0][0]!)
198
+ return BigInt(bcs.U64.parse(bytes))
199
+ }
200
+
201
+ async getLazyInboundNonce(receiver: string, srcEid: number, sender: Uint8Array): Promise<bigint> {
202
+ const tx = new Transaction()
203
+ tx.moveCall({
204
+ target: `${this.packageId}::endpoint_v2::get_lazy_inbound_nonce`,
205
+ typeArguments: [],
206
+ arguments: [
207
+ tx.object(this.objects.endpoint_v2),
208
+ tx.pure.address(receiver),
209
+ tx.pure.u32(srcEid),
210
+ tx.pure(bcs.vector(bcs.u8()).serialize(sender)),
211
+ ],
212
+ })
213
+ const result = await moveView(this.client, tx)
214
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
215
+ const bytes = new Uint8Array(result?.returnValues![0][0]!)
216
+ return BigInt(bcs.U64.parse(bytes))
217
+ }
218
+
219
+ async getOutboundNonce(sender: string, dstEid: number, receiver: Uint8Array): Promise<bigint> {
220
+ const tx = new Transaction()
221
+ tx.moveCall({
222
+ target: `${this.packageId}::endpoint_v2::get_outbound_nonce`,
223
+ typeArguments: [],
224
+ arguments: [
225
+ tx.object(this.objects.endpoint_v2),
226
+ tx.pure.address(sender),
227
+ tx.pure.u32(dstEid),
228
+ tx.pure(bcs.vector(bcs.u8()).serialize(receiver)),
229
+ ],
230
+ })
231
+ const result = await moveView(this.client, tx)
232
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
233
+ const bytes = new Uint8Array(result?.returnValues![0][0]!)
234
+ return BigInt(bcs.U64.parse(bytes))
235
+ }
236
+
237
+ async getInboundPayloadHash(
238
+ receiver: string,
239
+ srcEid: number,
240
+ sender: Uint8Array,
241
+ nonce: bigint
242
+ ): Promise<Uint8Array | null> {
243
+ const tx = new Transaction()
244
+ tx.moveCall({
245
+ target: `${this.packageId}::endpoint_v2::get_inbound_payload_hash`,
246
+ typeArguments: [],
247
+ arguments: [
248
+ tx.object(this.objects.endpoint_v2),
249
+ tx.pure.address(receiver),
250
+ tx.pure.u32(srcEid),
251
+ tx.pure(bcs.vector(bcs.u8()).serialize(sender)),
252
+ tx.pure.u64(nonce),
253
+ ],
254
+ })
255
+ try {
256
+ const result = await moveView(this.client, tx)
257
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
258
+ const bytes = new Uint8Array(result?.returnValues![0][0]!)
259
+ const parsed = bcs.vector(bcs.u8()).parse(bytes)
260
+ return Buffer.from(parsed)
261
+ } catch (error) {
262
+ //TODO need to handle error properly
263
+ return null
264
+ }
265
+ }
266
+
267
+ async getComposeMessageHash(from: string, to: string, guid: Uint8Array, index: number): Promise<Uint8Array> {
268
+ const tx = new Transaction()
269
+ tx.moveCall({
270
+ target: `${this.packageId}::endpoint_v2::get_compose_message_hash`,
271
+ typeArguments: [],
272
+ arguments: [
273
+ tx.object(this.objects.endpoint_v2),
274
+ tx.pure.address(from),
275
+ tx.pure.address(to),
276
+ tx.pure(bcs.vector(bcs.u8()).serialize(guid)),
277
+ tx.pure.u16(index),
278
+ ],
279
+ })
280
+ const result = await moveView(this.client, tx)
281
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
282
+ const bytes = new Uint8Array(result?.returnValues![0][0]!)
283
+ const parsed = bcs.vector(bcs.u8()).parse(bytes)
284
+ return Buffer.from(parsed)
285
+ }
286
+
287
+ // TODO: more view functions to be added here
288
+ populateQuoteTransaction(tx: Transaction): void {
289
+ // TODO: implement
290
+ }
291
+
292
+ populateSendTransaction(tx: Transaction): void {
293
+ // TODO: implement
294
+ }
295
+
296
+ populateGetConfigTransaction(tx: Transaction): void {
297
+ // TODO: implement
298
+ }
299
+
300
+ populateSetConfigTransaction(tx: Transaction): void {
301
+ // TODO: implement
302
+ }
303
+ }
@@ -0,0 +1,5 @@
1
+ export * from './simple-message-lib'
2
+ export * from './endpoint'
3
+ export * from './counter'
4
+ export * from './utils'
5
+ export * from './zro'
@@ -0,0 +1,240 @@
1
+ import { bcs } from '@mysten/sui/bcs'
2
+ import { SuiClient } from '@mysten/sui/client'
3
+ import { Transaction, TransactionResult } from '@mysten/sui/transactions'
4
+
5
+ import { Context, ObjectOptions } from '../types'
6
+ import { moveView } from '../utils'
7
+
8
+ export class SimpleMessageLib {
9
+ public packageId: string
10
+ public readonly client: SuiClient
11
+ private readonly objects: Pick<
12
+ ObjectOptions,
13
+ 'simple_message_lib' | 'endpoint_admin_cap' | 'endpoint_v2' | 'discovery'
14
+ >
15
+
16
+ constructor(
17
+ packageId: string,
18
+ client: SuiClient,
19
+ objects: Pick<ObjectOptions, 'simple_message_lib' | 'endpoint_admin_cap' | 'endpoint_v2' | 'discovery'>,
20
+ private readonly context: Context
21
+ ) {
22
+ this.packageId = packageId
23
+ this.client = client
24
+ this.objects = objects
25
+
26
+ // Validate that required objects are not empty strings
27
+ if (this.objects.simple_message_lib.trim() === '') {
28
+ throw new Error('simple_message_lib object cannot be empty')
29
+ }
30
+ if (this.objects.endpoint_admin_cap.trim() === '') {
31
+ throw new Error('admin_cap object cannot be empty')
32
+ }
33
+ if (this.objects.endpoint_v2.trim() === '') {
34
+ throw new Error('endpoint_v2 object cannot be empty')
35
+ }
36
+ }
37
+
38
+ populateInitializeTransaction(): Transaction {
39
+ const tx = new Transaction()
40
+
41
+ tx.moveCall({
42
+ target: `${this.packageId}::simple_message_lib::initialize`,
43
+ typeArguments: [],
44
+ arguments: [tx.object(this.objects.endpoint_admin_cap), tx.object(this.objects.endpoint_v2)],
45
+ })
46
+ return tx
47
+ }
48
+
49
+ // === View Functions ===
50
+
51
+ async getNativeFee(): Promise<string> {
52
+ const tx = new Transaction()
53
+ tx.moveCall({
54
+ target: `${this.packageId}::simple_message_lib::get_native_fee`,
55
+ typeArguments: [],
56
+ arguments: [tx.object(this.objects.simple_message_lib)],
57
+ })
58
+ const result = await moveView(this.client, tx)
59
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
60
+ const bytes = new Uint8Array(result?.returnValues![0][0]!)
61
+ return bcs.U64.parse(bytes)
62
+ }
63
+
64
+ async getZroFee(): Promise<string> {
65
+ const tx = new Transaction()
66
+ tx.moveCall({
67
+ target: `${this.packageId}::simple_message_lib::get_zro_fee`,
68
+ typeArguments: [],
69
+ arguments: [tx.object(this.objects.simple_message_lib)],
70
+ })
71
+ const result = await moveView(this.client, tx)
72
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
73
+ const bytes = new Uint8Array(result?.returnValues![0][0]!)
74
+ return bcs.U64.parse(bytes)
75
+ }
76
+
77
+ async getFeeRecipient(): Promise<string> {
78
+ const tx = new Transaction()
79
+ tx.moveCall({
80
+ target: `${this.packageId}::simple_message_lib::get_fee_recipient`,
81
+ typeArguments: [],
82
+ arguments: [tx.object(this.objects.simple_message_lib)],
83
+ })
84
+ const result = await moveView(this.client, tx)
85
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
86
+ const bytes = new Uint8Array(result?.returnValues![0][0]!)
87
+ return bcs.Address.parse(bytes)
88
+ }
89
+
90
+ async isRegistered(): Promise<boolean> {
91
+ const tx = new Transaction()
92
+ tx.moveCall({
93
+ target: `${this.packageId}::simple_message_lib::is_registered`,
94
+ typeArguments: [],
95
+ arguments: [tx.object(this.objects.simple_message_lib), tx.object(this.objects.endpoint_v2)],
96
+ })
97
+ const result = await moveView(this.client, tx)
98
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
99
+ const bytes = new Uint8Array(result?.returnValues![0][0]!)
100
+ return bcs.Bool.parse(bytes)
101
+ }
102
+
103
+ // === Admin Functions ===
104
+
105
+ populateRegisterLibraryTransaction(): Transaction {
106
+ const tx = new Transaction()
107
+ tx.moveCall({
108
+ target: `${this.packageId}::simple_message_lib::register_library`,
109
+ typeArguments: [],
110
+ arguments: [
111
+ tx.object(this.objects.simple_message_lib),
112
+ tx.object(this.objects.endpoint_admin_cap),
113
+ tx.object(this.objects.endpoint_v2),
114
+ ],
115
+ })
116
+ return tx
117
+ }
118
+
119
+ populateSetMessagingFeeTransaction(zroFee: number, nativeFee: number): Transaction {
120
+ const tx = new Transaction()
121
+ tx.moveCall({
122
+ target: `${this.packageId}::simple_message_lib::set_messaging_fee`,
123
+ typeArguments: [],
124
+ arguments: [
125
+ tx.object(this.objects.simple_message_lib),
126
+ tx.object(this.objects.endpoint_admin_cap),
127
+ tx.pure.u64(zroFee),
128
+ tx.pure.u64(nativeFee),
129
+ ],
130
+ })
131
+ return tx
132
+ }
133
+
134
+ populateSetDefaultConfigTransaction(eid: number, configType: number, config: Uint8Array): Transaction {
135
+ const tx = new Transaction()
136
+ tx.moveCall({
137
+ target: `${this.packageId}::simple_message_lib::set_default_config`,
138
+ typeArguments: [],
139
+ arguments: [
140
+ tx.object(this.objects.simple_message_lib),
141
+ tx.object(this.objects.endpoint_admin_cap),
142
+ tx.pure.u32(eid),
143
+ tx.pure.u32(configType),
144
+ tx.pure(bcs.vector(bcs.u8()).serialize(config)),
145
+ ],
146
+ })
147
+ return tx
148
+ }
149
+
150
+ populateSetFeeRecipientTransaction(feeRecipient: string): Transaction {
151
+ const tx = new Transaction()
152
+ tx.moveCall({
153
+ target: `${this.packageId}::simple_message_lib::set_fee_recipient`,
154
+ typeArguments: [],
155
+ arguments: [
156
+ tx.object(this.objects.simple_message_lib),
157
+ tx.object(this.objects.endpoint_admin_cap),
158
+ tx.pure.address(feeRecipient),
159
+ ],
160
+ })
161
+ return tx
162
+ }
163
+
164
+ // === Endpoint Validation ===
165
+
166
+ populateValidatePacketTransaction(packetHeader: Uint8Array, payloadHash: Uint8Array): Transaction {
167
+ const tx = new Transaction()
168
+ const payloadHashBytes32 = this.context.utils.fromBytesMoveCall(tx, payloadHash)
169
+ tx.moveCall({
170
+ target: `${this.packageId}::simple_message_lib::validate_packet`,
171
+ typeArguments: [],
172
+ arguments: [
173
+ tx.object(this.objects.simple_message_lib),
174
+ tx.object(this.objects.endpoint_v2),
175
+ tx.object(this.objects.endpoint_admin_cap),
176
+ tx.pure(bcs.vector(bcs.u8()).serialize(packetHeader)),
177
+ payloadHashBytes32,
178
+ tx.object('0x6'), // Clock Object TODO try to get it from the client or sdk
179
+ ],
180
+ })
181
+ return tx
182
+ }
183
+
184
+ // === Protocol Discovery ===
185
+
186
+ populateRegisterMessageLibDiscoveryTransaction(): Transaction {
187
+ const tx = new Transaction()
188
+ tx.moveCall({
189
+ target: `${this.packageId}::simple_message_lib::register_message_lib_discovery`,
190
+ typeArguments: [],
191
+ arguments: [
192
+ tx.object(this.objects.simple_message_lib),
193
+ tx.object(this.objects.endpoint_admin_cap),
194
+ tx.object(this.objects.endpoint_v2),
195
+ tx.object(this.objects.discovery),
196
+ ],
197
+ })
198
+ return tx
199
+ }
200
+
201
+ quoteMoveCall(tx: Transaction, quoteCall: TransactionResult): TransactionResult {
202
+ return tx.moveCall({
203
+ target: `${this.packageId}::simple_message_lib::quote`,
204
+ typeArguments: [],
205
+ arguments: [tx.object(this.objects.simple_message_lib), quoteCall],
206
+ })
207
+ }
208
+
209
+ sendMoveCall(tx: Transaction, sendCall: TransactionResult): TransactionResult {
210
+ return tx.moveCall({
211
+ target: `${this.packageId}::simple_message_lib::send`,
212
+ typeArguments: [],
213
+ arguments: [tx.object(this.objects.simple_message_lib), tx.object(this.objects.endpoint_v2), sendCall],
214
+ })
215
+ }
216
+
217
+ // === TODO: Core Message Lib Functions ===
218
+ // These functions are called by the endpoint and require specific parameter types
219
+ // that need to be implemented based on the endpoint_v2 module interfaces
220
+
221
+ populateQuoteTransaction(tx: Transaction): void {
222
+ // TODO: implement quote functionality
223
+ // This requires Call<QuoteParam> parameter from endpoint_v2
224
+ }
225
+
226
+ populateSendTransaction(tx: Transaction): void {
227
+ // TODO: implement send functionality
228
+ // This requires Call<SendParam> parameter from endpoint_v2
229
+ }
230
+
231
+ populateSetConfigTransaction(tx: Transaction): void {
232
+ // TODO: implement set_config functionality
233
+ // This requires Call<SetConfigParam> parameter from endpoint_v2
234
+ }
235
+
236
+ populateGetConfigTransaction(tx: Transaction): void {
237
+ // TODO: implement get_config functionality
238
+ // This requires Call<GetConfigParam> parameter from endpoint_v2
239
+ }
240
+ }