@lobstercove/lichen-sdk 1.0.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.
@@ -0,0 +1,628 @@
1
+ import { PublicKey } from './publickey.js';
2
+ const PREMIUM_NAME_MIN_LENGTH = 3;
3
+ const PREMIUM_NAME_MAX_LENGTH = 4;
4
+ const DIRECT_NAME_MIN_LENGTH = 5;
5
+ const MAX_NAME_LENGTH = 32;
6
+ const MAX_SKILL_NAME_BYTES = 32;
7
+ const MAX_ENDPOINT_BYTES = 255;
8
+ const MAX_METADATA_BYTES = 1024;
9
+ const RECOVERY_GUARDIAN_COUNT = 5;
10
+ const MAX_U64 = (1n << 64n) - 1n;
11
+ const SPORES_PER_LICN = 1000000000;
12
+ const PROGRAM_SYMBOL_CANDIDATES = ['YID', 'yid', 'LICHENID'];
13
+ const textEncoder = new TextEncoder();
14
+ export const LICHEN_ID_DELEGATE_PERMISSIONS = {
15
+ PROFILE: 1,
16
+ AGENT_TYPE: 2,
17
+ SKILLS: 4,
18
+ NAMING: 8,
19
+ };
20
+ const AVAILABILITY_BY_NAME = {
21
+ offline: 0,
22
+ available: 1,
23
+ busy: 2,
24
+ online: 1,
25
+ };
26
+ function normalizeAddress(value) {
27
+ return value instanceof PublicKey ? value : new PublicKey(value);
28
+ }
29
+ function normalizeNameLabel(name) {
30
+ return name.trim().toLowerCase().replace(/\.lichen$/, '');
31
+ }
32
+ function hasValidNameCharacters(label) {
33
+ return !label.startsWith('-')
34
+ && !label.endsWith('-')
35
+ && !label.includes('--')
36
+ && /^[a-z0-9-]+$/.test(label);
37
+ }
38
+ function validateLookupName(name) {
39
+ const label = normalizeNameLabel(name);
40
+ if (!label) {
41
+ throw new Error('Name cannot be empty');
42
+ }
43
+ if (label.length > MAX_NAME_LENGTH) {
44
+ throw new Error('LichenID names must be at most 32 characters');
45
+ }
46
+ if (!hasValidNameCharacters(label)) {
47
+ throw new Error('LichenID names must use lowercase a-z, 0-9, and internal hyphens only');
48
+ }
49
+ return label;
50
+ }
51
+ function validateDirectRegistrationName(name) {
52
+ const label = validateLookupName(name);
53
+ if (label.length < DIRECT_NAME_MIN_LENGTH) {
54
+ throw new Error('Direct registerName supports 5-32 character labels; 3-4 character names are auction-only');
55
+ }
56
+ return label;
57
+ }
58
+ function validateAuctionName(name) {
59
+ const label = validateLookupName(name);
60
+ if (label.length < PREMIUM_NAME_MIN_LENGTH || label.length > PREMIUM_NAME_MAX_LENGTH) {
61
+ throw new Error('Name auction helpers support 3-4 character premium labels only');
62
+ }
63
+ return label;
64
+ }
65
+ function normalizeDurationYears(value) {
66
+ return Math.max(1, Math.min(10, Math.trunc(value ?? 1) || 1));
67
+ }
68
+ function validateSkillName(name) {
69
+ const skillName = name.trim();
70
+ if (!skillName) {
71
+ throw new Error('Skill name cannot be empty');
72
+ }
73
+ if (textEncoder.encode(skillName).length > MAX_SKILL_NAME_BYTES) {
74
+ throw new Error('Skill names must be at most 32 bytes');
75
+ }
76
+ return skillName;
77
+ }
78
+ function normalizeEndpointUrl(url) {
79
+ const value = url.trim();
80
+ if (!value) {
81
+ throw new Error('Endpoint URL cannot be empty');
82
+ }
83
+ if (textEncoder.encode(value).length > MAX_ENDPOINT_BYTES) {
84
+ throw new Error('Endpoint URL must be at most 255 bytes');
85
+ }
86
+ return value;
87
+ }
88
+ function normalizeMetadata(metadata) {
89
+ const serialized = typeof metadata === 'string' ? metadata.trim() : JSON.stringify(metadata);
90
+ if (!serialized) {
91
+ throw new Error('Metadata cannot be empty');
92
+ }
93
+ if (textEncoder.encode(serialized).length > MAX_METADATA_BYTES) {
94
+ throw new Error('Metadata must be at most 1024 bytes');
95
+ }
96
+ return serialized;
97
+ }
98
+ function normalizeAvailabilityStatus(status) {
99
+ if (typeof status === 'number') {
100
+ if (status === 0 || status === 1 || status === 2) {
101
+ return status;
102
+ }
103
+ }
104
+ else {
105
+ const normalized = AVAILABILITY_BY_NAME[status.toLowerCase()];
106
+ if (normalized !== undefined) {
107
+ return normalized;
108
+ }
109
+ }
110
+ throw new Error('Availability must be one of offline, available, busy, or the numeric values 0-2');
111
+ }
112
+ function normalizeDelegatePermissions(permissions) {
113
+ if (!Number.isInteger(permissions) || permissions <= 0 || permissions > 0x0F) {
114
+ throw new Error('Delegate permissions must be a non-zero bitmask using PROFILE, AGENT_TYPE, SKILLS, and NAMING');
115
+ }
116
+ return permissions;
117
+ }
118
+ function normalizeUnsignedU64(value, fieldName) {
119
+ const normalized = typeof value === 'bigint'
120
+ ? value
121
+ : Number.isSafeInteger(value) && value >= 0
122
+ ? BigInt(value)
123
+ : null;
124
+ if (normalized === null || normalized < 0n || normalized > MAX_U64) {
125
+ throw new Error(`${fieldName} must be a u64-safe integer value`);
126
+ }
127
+ return normalized;
128
+ }
129
+ function validateAttestationLevel(level) {
130
+ const normalized = Math.trunc(level ?? 3);
131
+ if (normalized < 1 || normalized > 5) {
132
+ throw new Error('Attestation level must be between 1 and 5');
133
+ }
134
+ return normalized;
135
+ }
136
+ function normalizeRecoveryGuardians(owner, guardians) {
137
+ if (guardians.length !== RECOVERY_GUARDIAN_COUNT) {
138
+ throw new Error('Recovery helpers require exactly 5 guardian addresses');
139
+ }
140
+ const normalized = guardians.map(normalizeAddress);
141
+ const unique = new Set(normalized.map((guardian) => guardian.toBase58()));
142
+ if (unique.size !== RECOVERY_GUARDIAN_COUNT) {
143
+ throw new Error('Recovery guardians must be unique');
144
+ }
145
+ if (normalized.some((guardian) => guardian.equals(owner))) {
146
+ throw new Error('Recovery guardians cannot include the owner');
147
+ }
148
+ return normalized;
149
+ }
150
+ function padBytes(bytes, size) {
151
+ const out = new Uint8Array(size);
152
+ out.set(bytes.subarray(0, size));
153
+ return out;
154
+ }
155
+ function u8(value) {
156
+ return Uint8Array.from([value & 0xFF]);
157
+ }
158
+ function u32LE(value) {
159
+ const out = new Uint8Array(4);
160
+ new DataView(out.buffer).setUint32(0, value, true);
161
+ return out;
162
+ }
163
+ function u64LE(value, fieldName) {
164
+ const out = new Uint8Array(8);
165
+ new DataView(out.buffer).setBigUint64(0, normalizeUnsignedU64(value, fieldName), true);
166
+ return out;
167
+ }
168
+ function buildLayoutArgs(layout, chunks) {
169
+ const header = Uint8Array.from([0xAB, ...layout]);
170
+ const total = chunks.reduce((sum, chunk) => sum + chunk.length, header.length);
171
+ const out = new Uint8Array(total);
172
+ out.set(header, 0);
173
+ let offset = header.length;
174
+ for (const chunk of chunks) {
175
+ out.set(chunk, offset);
176
+ offset += chunk.length;
177
+ }
178
+ return out;
179
+ }
180
+ function encodeRegisterIdentityArgs(owner, params) {
181
+ const nameBytes = textEncoder.encode(params.name);
182
+ return buildLayoutArgs([0x20, 0x01, 0x40, 0x04], [
183
+ owner.toBytes(),
184
+ u8(params.agentType),
185
+ padBytes(nameBytes, 64),
186
+ u32LE(nameBytes.length),
187
+ ]);
188
+ }
189
+ function encodeNameDurationArgs(owner, name, durationYears) {
190
+ const nameBytes = textEncoder.encode(name);
191
+ return buildLayoutArgs([0x20, 0x20, 0x04, 0x01], [
192
+ owner.toBytes(),
193
+ padBytes(nameBytes, 32),
194
+ u32LE(nameBytes.length),
195
+ u8(durationYears),
196
+ ]);
197
+ }
198
+ function encodeAddSkillArgs(owner, params) {
199
+ const skillName = validateSkillName(params.name);
200
+ const proficiency = Math.max(0, Math.min(100, Math.trunc(params.proficiency ?? 50) || 0));
201
+ const nameBytes = textEncoder.encode(skillName);
202
+ return buildLayoutArgs([0x20, 0x20, 0x04, 0x01], [
203
+ owner.toBytes(),
204
+ padBytes(nameBytes, 32),
205
+ u32LE(nameBytes.length),
206
+ u8(proficiency),
207
+ ]);
208
+ }
209
+ function encodeVouchArgs(owner, vouchee) {
210
+ return buildLayoutArgs([0x20, 0x20], [owner.toBytes(), vouchee.toBytes()]);
211
+ }
212
+ function encodeEndpointArgs(owner, url) {
213
+ const endpoint = normalizeEndpointUrl(url);
214
+ const urlBytes = textEncoder.encode(endpoint);
215
+ const stride = Math.max(32, urlBytes.length);
216
+ return buildLayoutArgs([0x20, stride, 0x04], [
217
+ owner.toBytes(),
218
+ padBytes(urlBytes, stride),
219
+ u32LE(urlBytes.length),
220
+ ]);
221
+ }
222
+ function encodeMetadataArgs(owner, metadata) {
223
+ const serialized = normalizeMetadata(metadata);
224
+ const metadataBytes = textEncoder.encode(serialized);
225
+ const stride = Math.max(32, metadataBytes.length);
226
+ return buildLayoutArgs([0x20, stride, 0x04], [
227
+ owner.toBytes(),
228
+ padBytes(metadataBytes, stride),
229
+ u32LE(metadataBytes.length),
230
+ ]);
231
+ }
232
+ function encodeRateArgs(owner, rateSpores) {
233
+ return buildLayoutArgs([0x20, 0x08], [
234
+ owner.toBytes(),
235
+ u64LE(rateSpores, 'rateSpores'),
236
+ ]);
237
+ }
238
+ function encodeAvailabilityArgs(owner, status) {
239
+ return buildLayoutArgs([0x20, 0x01], [
240
+ owner.toBytes(),
241
+ u8(normalizeAvailabilityStatus(status)),
242
+ ]);
243
+ }
244
+ function encodeSetDelegateArgs(owner, params) {
245
+ return buildLayoutArgs([0x20, 0x20, 0x01, 0x08], [
246
+ owner.toBytes(),
247
+ normalizeAddress(params.delegate).toBytes(),
248
+ u8(normalizeDelegatePermissions(params.permissions)),
249
+ u64LE(params.expiresAtMs, 'expiresAtMs'),
250
+ ]);
251
+ }
252
+ function encodeDelegateLookupArgs(owner, delegate) {
253
+ return buildLayoutArgs([0x20, 0x20], [owner.toBytes(), delegate.toBytes()]);
254
+ }
255
+ function encodeDelegatedEndpointArgs(delegate, params) {
256
+ const owner = normalizeAddress(params.owner);
257
+ const endpoint = normalizeEndpointUrl(params.url);
258
+ const urlBytes = textEncoder.encode(endpoint);
259
+ const stride = Math.max(32, urlBytes.length);
260
+ return buildLayoutArgs([0x20, 0x20, stride, 0x04], [
261
+ delegate.toBytes(),
262
+ owner.toBytes(),
263
+ padBytes(urlBytes, stride),
264
+ u32LE(urlBytes.length),
265
+ ]);
266
+ }
267
+ function encodeDelegatedMetadataArgs(delegate, params) {
268
+ const owner = normalizeAddress(params.owner);
269
+ const serialized = normalizeMetadata(params.metadata);
270
+ const metadataBytes = textEncoder.encode(serialized);
271
+ const stride = Math.max(32, metadataBytes.length);
272
+ return buildLayoutArgs([0x20, 0x20, stride, 0x04], [
273
+ delegate.toBytes(),
274
+ owner.toBytes(),
275
+ padBytes(metadataBytes, stride),
276
+ u32LE(metadataBytes.length),
277
+ ]);
278
+ }
279
+ function encodeDelegatedAvailabilityArgs(delegate, params) {
280
+ const owner = normalizeAddress(params.owner);
281
+ return buildLayoutArgs([0x20, 0x20, 0x01], [
282
+ delegate.toBytes(),
283
+ owner.toBytes(),
284
+ u8(normalizeAvailabilityStatus(params.status)),
285
+ ]);
286
+ }
287
+ function encodeDelegatedRateArgs(delegate, params) {
288
+ const owner = normalizeAddress(params.owner);
289
+ return buildLayoutArgs([0x20, 0x20, 0x08], [
290
+ delegate.toBytes(),
291
+ owner.toBytes(),
292
+ u64LE(params.rateSpores, 'rateSpores'),
293
+ ]);
294
+ }
295
+ function encodeUpdateAgentTypeAsArgs(delegate, params) {
296
+ const owner = normalizeAddress(params.owner);
297
+ return buildLayoutArgs([0x20, 0x20, 0x01], [
298
+ delegate.toBytes(),
299
+ owner.toBytes(),
300
+ u8(params.agentType),
301
+ ]);
302
+ }
303
+ function encodeRecoveryGuardiansArgs(owner, params) {
304
+ const guardians = normalizeRecoveryGuardians(owner, params.guardians);
305
+ return buildLayoutArgs([0x20, 0x20, 0x20, 0x20, 0x20, 0x20], [
306
+ owner.toBytes(),
307
+ guardians[0].toBytes(),
308
+ guardians[1].toBytes(),
309
+ guardians[2].toBytes(),
310
+ guardians[3].toBytes(),
311
+ guardians[4].toBytes(),
312
+ ]);
313
+ }
314
+ function encodeRecoveryActionArgs(caller, params) {
315
+ return buildLayoutArgs([0x20, 0x20, 0x20], [
316
+ caller.toBytes(),
317
+ normalizeAddress(params.target).toBytes(),
318
+ normalizeAddress(params.newOwner).toBytes(),
319
+ ]);
320
+ }
321
+ function encodeAttestSkillArgs(attester, params) {
322
+ const skillName = validateSkillName(params.name);
323
+ const nameBytes = textEncoder.encode(skillName);
324
+ return buildLayoutArgs([0x20, 0x20, 0x20, 0x04, 0x01], [
325
+ attester.toBytes(),
326
+ normalizeAddress(params.identity).toBytes(),
327
+ padBytes(nameBytes, 32),
328
+ u32LE(nameBytes.length),
329
+ u8(validateAttestationLevel(params.level)),
330
+ ]);
331
+ }
332
+ function encodeGetAttestationsArgs(identity, skillName) {
333
+ const normalized = validateSkillName(skillName);
334
+ const nameBytes = textEncoder.encode(normalized);
335
+ return buildLayoutArgs([0x20, 0x20, 0x04], [
336
+ identity.toBytes(),
337
+ padBytes(nameBytes, 32),
338
+ u32LE(nameBytes.length),
339
+ ]);
340
+ }
341
+ function encodeRevokeAttestationArgs(attester, params) {
342
+ const skillName = validateSkillName(params.name);
343
+ const nameBytes = textEncoder.encode(skillName);
344
+ return buildLayoutArgs([0x20, 0x20, 0x20, 0x04], [
345
+ attester.toBytes(),
346
+ normalizeAddress(params.identity).toBytes(),
347
+ padBytes(nameBytes, 32),
348
+ u32LE(nameBytes.length),
349
+ ]);
350
+ }
351
+ function encodeCreateNameAuctionArgs(owner, params) {
352
+ const label = validateAuctionName(params.name);
353
+ const nameBytes = textEncoder.encode(label);
354
+ return buildLayoutArgs([0x20, 0x20, 0x04, 0x08, 0x08], [
355
+ owner.toBytes(),
356
+ padBytes(nameBytes, 32),
357
+ u32LE(nameBytes.length),
358
+ u64LE(params.reserveBidSpores, 'reserveBidSpores'),
359
+ u64LE(params.endSlot, 'endSlot'),
360
+ ]);
361
+ }
362
+ function encodeBidNameAuctionArgs(owner, params) {
363
+ const label = validateAuctionName(params.name);
364
+ const nameBytes = textEncoder.encode(label);
365
+ return buildLayoutArgs([0x20, 0x20, 0x04, 0x08], [
366
+ owner.toBytes(),
367
+ padBytes(nameBytes, 32),
368
+ u32LE(nameBytes.length),
369
+ u64LE(params.bidAmountSpores, 'bidAmountSpores'),
370
+ ]);
371
+ }
372
+ function decodeReturnData(returnData) {
373
+ return Uint8Array.from(Buffer.from(returnData, 'base64'));
374
+ }
375
+ function readU64(bytes, offset) {
376
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
377
+ return view.getBigUint64(offset, true);
378
+ }
379
+ function readSafeU64(bytes, offset, fieldName) {
380
+ const value = readU64(bytes, offset);
381
+ if (value > BigInt(Number.MAX_SAFE_INTEGER)) {
382
+ throw new Error(`${fieldName} exceeds JavaScript's safe integer range`);
383
+ }
384
+ return Number(value);
385
+ }
386
+ function ensureReturnCodeZero(result, functionName) {
387
+ const code = result.returnCode ?? 0;
388
+ if (code !== 0) {
389
+ throw new Error(result.error ?? `LichenID ${functionName} returned code ${code}`);
390
+ }
391
+ if (result.success === false && result.error) {
392
+ throw new Error(result.error);
393
+ }
394
+ }
395
+ function decodeDelegateRecord(owner, delegate, bytes) {
396
+ if (bytes.length < 17) {
397
+ throw new Error('Delegate record payload was shorter than expected');
398
+ }
399
+ const permissions = bytes[0];
400
+ const expiresAtMs = readSafeU64(bytes, 1, 'expiresAtMs');
401
+ const createdAtMs = readSafeU64(bytes, 9, 'createdAtMs');
402
+ return {
403
+ owner: owner.toBase58(),
404
+ delegate: delegate.toBase58(),
405
+ permissions,
406
+ expiresAtMs,
407
+ createdAtMs,
408
+ active: Date.now() < expiresAtMs,
409
+ canProfile: (permissions & LICHEN_ID_DELEGATE_PERMISSIONS.PROFILE) !== 0,
410
+ canAgentType: (permissions & LICHEN_ID_DELEGATE_PERMISSIONS.AGENT_TYPE) !== 0,
411
+ canSkills: (permissions & LICHEN_ID_DELEGATE_PERMISSIONS.SKILLS) !== 0,
412
+ canNaming: (permissions & LICHEN_ID_DELEGATE_PERMISSIONS.NAMING) !== 0,
413
+ };
414
+ }
415
+ function registrationCostPerYearLicn(name) {
416
+ const label = normalizeNameLabel(name);
417
+ if (label.length <= 3)
418
+ return 500;
419
+ if (label.length === 4)
420
+ return 100;
421
+ return 20;
422
+ }
423
+ export function estimateLichenIdNameRegistrationCost(name, durationYears = 1) {
424
+ const years = Math.max(1, Math.min(10, Math.trunc(durationYears) || 1));
425
+ return BigInt(registrationCostPerYearLicn(name)) * BigInt(years) * BigInt(SPORES_PER_LICN);
426
+ }
427
+ export class LichenIdClient {
428
+ constructor(connection, programId) {
429
+ this.connection = connection;
430
+ this.resolvedProgram = programId;
431
+ }
432
+ async callReadonly(functionName, args) {
433
+ const programId = await this.getProgramId();
434
+ return this.connection.callReadonlyContract(programId, functionName, args);
435
+ }
436
+ async getProgramId() {
437
+ if (this.resolvedProgram) {
438
+ return this.resolvedProgram;
439
+ }
440
+ for (const symbol of PROGRAM_SYMBOL_CANDIDATES) {
441
+ try {
442
+ const entry = await this.connection.getSymbolRegistry(symbol);
443
+ if (entry?.program) {
444
+ this.resolvedProgram = new PublicKey(entry.program);
445
+ return this.resolvedProgram;
446
+ }
447
+ }
448
+ catch {
449
+ // Try the next known registry alias.
450
+ }
451
+ }
452
+ throw new Error('Unable to resolve the LichenID program via getSymbolRegistry("YID")');
453
+ }
454
+ async getProfile(address) {
455
+ return this.connection.getLichenIdProfile(normalizeAddress(address));
456
+ }
457
+ async getReputation(address) {
458
+ return this.connection.getLichenIdReputation(normalizeAddress(address));
459
+ }
460
+ async getSkills(address) {
461
+ return this.connection.getLichenIdSkills(normalizeAddress(address));
462
+ }
463
+ async getVouches(address) {
464
+ return this.connection.getLichenIdVouches(normalizeAddress(address));
465
+ }
466
+ async resolveName(name) {
467
+ const label = validateLookupName(name);
468
+ return this.connection.resolveLichenName(`${label}.lichen`);
469
+ }
470
+ async getMetadata(address) {
471
+ const profile = await this.getProfile(address);
472
+ return profile?.agent?.metadata ?? null;
473
+ }
474
+ async getDelegate(owner, delegate) {
475
+ const ownerAddress = normalizeAddress(owner);
476
+ const delegateAddress = normalizeAddress(delegate);
477
+ const result = await this.callReadonly('get_delegate', encodeDelegateLookupArgs(ownerAddress, delegateAddress));
478
+ if ((result.returnCode ?? 0) === 1 || !result.returnData) {
479
+ return null;
480
+ }
481
+ ensureReturnCodeZero(result, 'get_delegate');
482
+ return decodeDelegateRecord(ownerAddress, delegateAddress, decodeReturnData(result.returnData));
483
+ }
484
+ async getAttestations(identity, skillName) {
485
+ const result = await this.callReadonly('get_attestations', encodeGetAttestationsArgs(normalizeAddress(identity), skillName));
486
+ ensureReturnCodeZero(result, 'get_attestations');
487
+ if (!result.returnData) {
488
+ throw new Error('LichenID get_attestations did not return attestation data');
489
+ }
490
+ return readSafeU64(decodeReturnData(result.returnData), 0, 'attestationCount');
491
+ }
492
+ async getNameAuction(name) {
493
+ return this.connection.getNameAuction(validateLookupName(name));
494
+ }
495
+ async getAgentDirectory(options = {}) {
496
+ return this.connection.getLichenIdAgentDirectory(options);
497
+ }
498
+ async getStats() {
499
+ return this.connection.getLichenIdStats();
500
+ }
501
+ async registerIdentity(owner, params) {
502
+ const name = params.name.trim();
503
+ if (!name) {
504
+ throw new Error('Identity name cannot be empty');
505
+ }
506
+ const args = encodeRegisterIdentityArgs(owner.pubkey(), {
507
+ agentType: params.agentType,
508
+ name,
509
+ });
510
+ const programId = await this.getProgramId();
511
+ return this.connection.callContract(owner, programId, 'register_identity', args);
512
+ }
513
+ async registerName(owner, params) {
514
+ const durationYears = normalizeDurationYears(params.durationYears);
515
+ const label = validateDirectRegistrationName(params.name);
516
+ const value = params.valueSpores ?? estimateLichenIdNameRegistrationCost(label, durationYears);
517
+ const args = encodeNameDurationArgs(owner.pubkey(), label, durationYears);
518
+ const programId = await this.getProgramId();
519
+ return this.connection.callContract(owner, programId, 'register_name', args, value);
520
+ }
521
+ async addSkill(owner, params) {
522
+ const programId = await this.getProgramId();
523
+ const args = encodeAddSkillArgs(owner.pubkey(), params);
524
+ return this.connection.callContract(owner, programId, 'add_skill', args);
525
+ }
526
+ async vouch(owner, vouchee) {
527
+ const programId = await this.getProgramId();
528
+ const args = encodeVouchArgs(owner.pubkey(), normalizeAddress(vouchee));
529
+ return this.connection.callContract(owner, programId, 'vouch', args);
530
+ }
531
+ async setEndpoint(owner, params) {
532
+ const programId = await this.getProgramId();
533
+ const args = encodeEndpointArgs(owner.pubkey(), params.url);
534
+ return this.connection.callContract(owner, programId, 'set_endpoint', args);
535
+ }
536
+ async setMetadata(owner, params) {
537
+ const programId = await this.getProgramId();
538
+ const args = encodeMetadataArgs(owner.pubkey(), params.metadata);
539
+ return this.connection.callContract(owner, programId, 'set_metadata', args);
540
+ }
541
+ async setRate(owner, params) {
542
+ const programId = await this.getProgramId();
543
+ const args = encodeRateArgs(owner.pubkey(), params.rateSpores);
544
+ return this.connection.callContract(owner, programId, 'set_rate', args);
545
+ }
546
+ async setAvailability(owner, params) {
547
+ const programId = await this.getProgramId();
548
+ const args = encodeAvailabilityArgs(owner.pubkey(), params.status);
549
+ return this.connection.callContract(owner, programId, 'set_availability', args);
550
+ }
551
+ async setDelegate(owner, params) {
552
+ const programId = await this.getProgramId();
553
+ const args = encodeSetDelegateArgs(owner.pubkey(), params);
554
+ return this.connection.callContract(owner, programId, 'set_delegate', args);
555
+ }
556
+ async revokeDelegate(owner, delegate) {
557
+ const programId = await this.getProgramId();
558
+ const args = encodeDelegateLookupArgs(owner.pubkey(), normalizeAddress(delegate));
559
+ return this.connection.callContract(owner, programId, 'revoke_delegate', args);
560
+ }
561
+ async setEndpointAs(delegate, params) {
562
+ const programId = await this.getProgramId();
563
+ const args = encodeDelegatedEndpointArgs(delegate.pubkey(), params);
564
+ return this.connection.callContract(delegate, programId, 'set_endpoint_as', args);
565
+ }
566
+ async setMetadataAs(delegate, params) {
567
+ const programId = await this.getProgramId();
568
+ const args = encodeDelegatedMetadataArgs(delegate.pubkey(), params);
569
+ return this.connection.callContract(delegate, programId, 'set_metadata_as', args);
570
+ }
571
+ async setAvailabilityAs(delegate, params) {
572
+ const programId = await this.getProgramId();
573
+ const args = encodeDelegatedAvailabilityArgs(delegate.pubkey(), params);
574
+ return this.connection.callContract(delegate, programId, 'set_availability_as', args);
575
+ }
576
+ async setRateAs(delegate, params) {
577
+ const programId = await this.getProgramId();
578
+ const args = encodeDelegatedRateArgs(delegate.pubkey(), params);
579
+ return this.connection.callContract(delegate, programId, 'set_rate_as', args);
580
+ }
581
+ async updateAgentTypeAs(delegate, params) {
582
+ const programId = await this.getProgramId();
583
+ const args = encodeUpdateAgentTypeAsArgs(delegate.pubkey(), params);
584
+ return this.connection.callContract(delegate, programId, 'update_agent_type_as', args);
585
+ }
586
+ async setRecoveryGuardians(owner, params) {
587
+ const programId = await this.getProgramId();
588
+ const args = encodeRecoveryGuardiansArgs(owner.pubkey(), params);
589
+ return this.connection.callContract(owner, programId, 'set_recovery_guardians', args);
590
+ }
591
+ async approveRecovery(guardian, params) {
592
+ const programId = await this.getProgramId();
593
+ const args = encodeRecoveryActionArgs(guardian.pubkey(), params);
594
+ return this.connection.callContract(guardian, programId, 'approve_recovery', args);
595
+ }
596
+ async executeRecovery(guardian, params) {
597
+ const programId = await this.getProgramId();
598
+ const args = encodeRecoveryActionArgs(guardian.pubkey(), params);
599
+ return this.connection.callContract(guardian, programId, 'execute_recovery', args);
600
+ }
601
+ async attestSkill(attester, params) {
602
+ const programId = await this.getProgramId();
603
+ const args = encodeAttestSkillArgs(attester.pubkey(), params);
604
+ return this.connection.callContract(attester, programId, 'attest_skill', args);
605
+ }
606
+ async revokeAttestation(attester, params) {
607
+ const programId = await this.getProgramId();
608
+ const args = encodeRevokeAttestationArgs(attester.pubkey(), params);
609
+ return this.connection.callContract(attester, programId, 'revoke_attestation', args);
610
+ }
611
+ async createNameAuction(owner, params) {
612
+ const programId = await this.getProgramId();
613
+ const args = encodeCreateNameAuctionArgs(owner.pubkey(), params);
614
+ return this.connection.callContract(owner, programId, 'create_name_auction', args);
615
+ }
616
+ async bidNameAuction(owner, params) {
617
+ const programId = await this.getProgramId();
618
+ const args = encodeBidNameAuctionArgs(owner.pubkey(), params);
619
+ return this.connection.callContract(owner, programId, 'bid_name_auction', args, params.bidAmountSpores);
620
+ }
621
+ async finalizeNameAuction(owner, params) {
622
+ const durationYears = normalizeDurationYears(params.durationYears);
623
+ const label = validateAuctionName(params.name);
624
+ const programId = await this.getProgramId();
625
+ const args = encodeNameDurationArgs(owner.pubkey(), label, durationYears);
626
+ return this.connection.callContract(owner, programId, 'finalize_name_auction', args);
627
+ }
628
+ }
@@ -0,0 +1,79 @@
1
+ import { Connection } from './connection.js';
2
+ import { Keypair } from './keypair.js';
3
+ import { PublicKey } from './publickey.js';
4
+ export interface LichenSwapPoolInfo {
5
+ reserveA: bigint;
6
+ reserveB: bigint;
7
+ totalLiquidity: bigint;
8
+ }
9
+ export interface LichenSwapVolumeTotals {
10
+ volumeA: bigint;
11
+ volumeB: bigint;
12
+ }
13
+ export interface LichenSwapProtocolFees {
14
+ feesA: bigint;
15
+ feesB: bigint;
16
+ }
17
+ export interface LichenSwapTwapCumulatives {
18
+ cumulativePriceA: bigint;
19
+ cumulativePriceB: bigint;
20
+ lastUpdatedAt: bigint;
21
+ }
22
+ export interface LichenSwapSwapStats {
23
+ swapCount: bigint;
24
+ volumeA: bigint;
25
+ volumeB: bigint;
26
+ poolCount: bigint;
27
+ totalLiquidity: bigint;
28
+ }
29
+ export interface LichenSwapStats {
30
+ swapCount: number;
31
+ volumeA: number;
32
+ volumeB: number;
33
+ paused: boolean;
34
+ }
35
+ export interface CreatePoolParams {
36
+ tokenA: PublicKey | string;
37
+ tokenB: PublicKey | string;
38
+ }
39
+ export interface AddLiquidityParams {
40
+ amountA: number | bigint;
41
+ amountB: number | bigint;
42
+ minLiquidity?: number | bigint;
43
+ valueSpores?: number | bigint;
44
+ }
45
+ export interface SwapParams {
46
+ amountIn: number | bigint;
47
+ minAmountOut?: number | bigint;
48
+ valueSpores?: number | bigint;
49
+ }
50
+ export interface SwapWithDeadlineParams extends SwapParams {
51
+ deadline: number | bigint;
52
+ }
53
+ export declare class LichenSwapClient {
54
+ private readonly connection;
55
+ private resolvedProgram?;
56
+ constructor(connection: Connection, programId?: PublicKey);
57
+ private callReadonly;
58
+ getProgramId(): Promise<PublicKey>;
59
+ getPoolInfo(): Promise<LichenSwapPoolInfo>;
60
+ getQuote(amountIn: number | bigint, aToB?: boolean): Promise<bigint>;
61
+ getLiquidityBalance(provider: PublicKey | string): Promise<bigint>;
62
+ getTotalLiquidity(): Promise<bigint>;
63
+ getFlashLoanFee(amount: number | bigint): Promise<bigint>;
64
+ getTwapCumulatives(): Promise<LichenSwapTwapCumulatives>;
65
+ getTwapSnapshotCount(): Promise<bigint>;
66
+ getProtocolFees(): Promise<LichenSwapProtocolFees>;
67
+ getPoolCount(): Promise<bigint>;
68
+ getSwapCount(): Promise<bigint>;
69
+ getTotalVolume(): Promise<LichenSwapVolumeTotals>;
70
+ getSwapStats(): Promise<LichenSwapSwapStats>;
71
+ getStats(): Promise<LichenSwapStats>;
72
+ createPool(owner: Keypair, params: CreatePoolParams): Promise<string>;
73
+ addLiquidity(provider: Keypair, params: AddLiquidityParams): Promise<string>;
74
+ swap(provider: Keypair, params: SwapParams, aToB?: boolean): Promise<string>;
75
+ swapAToB(provider: Keypair, params: SwapParams): Promise<string>;
76
+ swapBToA(provider: Keypair, params: SwapParams): Promise<string>;
77
+ swapAToBWithDeadline(provider: Keypair, params: SwapWithDeadlineParams): Promise<string>;
78
+ swapBToAWithDeadline(provider: Keypair, params: SwapWithDeadlineParams): Promise<string>;
79
+ }