xpi-ts 0.2.21 → 0.2.23

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,604 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ScriptProcessor = exports.PlatformConfiguration = exports.ScriptChunksOptionalRANKMap = exports.ScriptChunksRANKMap = exports.RANK_SCRIPT_REQUIRED_LENGTH = exports.ScriptChunksRNKCMap = exports.SCRIPT_CHUNK_PLATFORM = exports.RANK_SENTIMENT_OP_CODES = exports.SCRIPT_CHUNK_SENTIMENT = exports.RANK_SENTIMENT_NEGATIVE = exports.RANK_SENTIMENT_POSITIVE = exports.RANK_SENTIMENT_NEUTRAL = exports.SCRIPT_CHUNK_LOKAD = exports.LOKAD_PREFIX_RNKE = exports.LOKAD_PREFIX_RNKC = exports.LOKAD_PREFIX_RANK = void 0;
4
+ exports.isOpReturn = isOpReturn;
5
+ exports.toProfileIdBuf = toProfileIdBuf;
6
+ exports.toProfileIdUTF8 = toProfileIdUTF8;
7
+ exports.toPostIdBuf = toPostIdBuf;
8
+ exports.toPlatformBuf = toPlatformBuf;
9
+ exports.toPlatformUTF8 = toPlatformUTF8;
10
+ exports.toSentimentOpCode = toSentimentOpCode;
11
+ exports.toSentimentUTF8 = toSentimentUTF8;
12
+ exports.toCommentUTF8 = toCommentUTF8;
13
+ exports.isValidLokad = isValidLokad;
14
+ exports.fromScriptRANK = fromScriptRANK;
15
+ exports.toScriptRANK = toScriptRANK;
16
+ exports.fromScriptRNKC = fromScriptRNKC;
17
+ exports.toScriptRNKC = toScriptRNKC;
18
+ const bitcore_1 = require("./bitcore");
19
+ const constants_js_1 = require("../utils/constants.js");
20
+ const string_1 = require("../utils/string");
21
+ exports.LOKAD_PREFIX_RANK = 0x52414e4b;
22
+ exports.LOKAD_PREFIX_RNKC = 0x524e4b43;
23
+ exports.LOKAD_PREFIX_RNKE = 0x524e4b45;
24
+ exports.SCRIPT_CHUNK_LOKAD = new Map();
25
+ exports.SCRIPT_CHUNK_LOKAD.set(exports.LOKAD_PREFIX_RANK, 'RANK');
26
+ exports.SCRIPT_CHUNK_LOKAD.set(exports.LOKAD_PREFIX_RNKC, 'RNKC');
27
+ exports.SCRIPT_CHUNK_LOKAD.set(exports.LOKAD_PREFIX_RNKE, 'RNKE');
28
+ exports.RANK_SENTIMENT_NEUTRAL = bitcore_1.Opcode.OP_16;
29
+ exports.RANK_SENTIMENT_POSITIVE = bitcore_1.Opcode.OP_1;
30
+ exports.RANK_SENTIMENT_NEGATIVE = bitcore_1.Opcode.OP_0;
31
+ exports.SCRIPT_CHUNK_SENTIMENT = new Map();
32
+ exports.SCRIPT_CHUNK_SENTIMENT.set(exports.RANK_SENTIMENT_NEUTRAL, 'neutral');
33
+ exports.SCRIPT_CHUNK_SENTIMENT.set(exports.RANK_SENTIMENT_POSITIVE, 'positive');
34
+ exports.SCRIPT_CHUNK_SENTIMENT.set(exports.RANK_SENTIMENT_NEGATIVE, 'negative');
35
+ exports.RANK_SENTIMENT_OP_CODES = new Map();
36
+ exports.RANK_SENTIMENT_OP_CODES.set('neutral', 'OP_16');
37
+ exports.RANK_SENTIMENT_OP_CODES.set('positive', 'OP_1');
38
+ exports.RANK_SENTIMENT_OP_CODES.set('negative', 'OP_0');
39
+ exports.SCRIPT_CHUNK_PLATFORM = new Map();
40
+ exports.SCRIPT_CHUNK_PLATFORM.set(0x00, 'lotusia');
41
+ exports.SCRIPT_CHUNK_PLATFORM.set(0x01, 'twitter');
42
+ exports.ScriptChunksRNKCMap = new Map();
43
+ exports.ScriptChunksRNKCMap.set('platform', {
44
+ offset: 7,
45
+ len: 1,
46
+ map: exports.SCRIPT_CHUNK_PLATFORM,
47
+ });
48
+ exports.ScriptChunksRNKCMap.set('profileId', {
49
+ offset: 9,
50
+ len: null,
51
+ });
52
+ exports.ScriptChunksRNKCMap.set('postId', {
53
+ offset: null,
54
+ len: null,
55
+ });
56
+ exports.ScriptChunksRNKCMap.set('comment', {
57
+ offset: null,
58
+ len: null,
59
+ });
60
+ exports.RANK_SCRIPT_REQUIRED_LENGTH = 10;
61
+ exports.ScriptChunksRANKMap = new Map();
62
+ exports.ScriptChunksRANKMap.set('sentiment', {
63
+ offset: 6,
64
+ len: 1,
65
+ map: exports.SCRIPT_CHUNK_SENTIMENT,
66
+ });
67
+ exports.ScriptChunksRANKMap.set('platform', {
68
+ offset: 8,
69
+ len: 1,
70
+ map: exports.SCRIPT_CHUNK_PLATFORM,
71
+ });
72
+ exports.ScriptChunksRANKMap.set('profileId', {
73
+ offset: 10,
74
+ len: null,
75
+ });
76
+ exports.ScriptChunksOptionalRANKMap = new Map();
77
+ exports.ScriptChunksOptionalRANKMap.set('postId', {
78
+ offset: null,
79
+ len: null,
80
+ });
81
+ exports.ScriptChunksOptionalRANKMap.set('instanceId', {
82
+ offset: null,
83
+ len: null,
84
+ });
85
+ exports.PlatformConfiguration = new Map();
86
+ exports.PlatformConfiguration.set('lotusia', {
87
+ profileId: {
88
+ len: 33,
89
+ regex: /^[0-9a-fA-F]{40,66}$/,
90
+ },
91
+ postId: {
92
+ len: 32,
93
+ regex: /^[0-9a-f]{64}$/,
94
+ type: 'String',
95
+ },
96
+ });
97
+ exports.PlatformConfiguration.set('twitter', {
98
+ profileId: {
99
+ len: 16,
100
+ regex: /^[a-z0-9_]{1,16}$/,
101
+ },
102
+ postId: {
103
+ len: 8,
104
+ regex: /^[0-9]+$/,
105
+ type: 'BigInt',
106
+ },
107
+ });
108
+ function isOpReturn(script) {
109
+ if (typeof script === 'string') {
110
+ script = bitcore_1.BufferUtil.from(script, 'hex');
111
+ }
112
+ return script.readUInt8(0) === bitcore_1.Opcode.OP_RETURN;
113
+ }
114
+ function toProfileIdBuf(platform, profileId) {
115
+ const platformSpec = exports.PlatformConfiguration.get(platform);
116
+ if (!platformSpec) {
117
+ return null;
118
+ }
119
+ const profileIdSpec = platformSpec.profileId;
120
+ if (!profileIdSpec) {
121
+ return null;
122
+ }
123
+ if (profileIdSpec.regex && !profileIdSpec.regex.test(profileId)) {
124
+ return null;
125
+ }
126
+ switch (platform) {
127
+ case 'lotusia': {
128
+ const profileIdHex = bitcore_1.BufferUtil.from(profileId, 'hex');
129
+ const actualLen = profileIdHex.length;
130
+ if (actualLen !== 20 && actualLen !== 33) {
131
+ return null;
132
+ }
133
+ const profileBuf = bitcore_1.BufferUtil.alloc(actualLen);
134
+ profileIdHex.copy(profileBuf, 0);
135
+ return profileBuf;
136
+ }
137
+ case 'twitter': {
138
+ const profileBuf = bitcore_1.BufferUtil.alloc(profileIdSpec.len);
139
+ bitcore_1.BufferUtil.from(profileId, 'utf8').copy(profileBuf, profileIdSpec.len - profileId.length);
140
+ return profileBuf;
141
+ }
142
+ default:
143
+ return null;
144
+ }
145
+ }
146
+ function toProfileIdUTF8(profileIdBuf) {
147
+ return new TextDecoder('utf-8').decode(profileIdBuf.filter(byte => byte != 0x00));
148
+ }
149
+ function toPostIdBuf(platform, postId) {
150
+ switch (platform) {
151
+ case 'lotusia':
152
+ return bitcore_1.BufferUtil.from(postId, 'hex');
153
+ case 'twitter':
154
+ return bitcore_1.BufferUtil.from(BigInt(postId).toString(16), 'hex');
155
+ default:
156
+ return undefined;
157
+ }
158
+ }
159
+ function toPlatformBuf(platform) {
160
+ for (const [byte, platformName] of exports.SCRIPT_CHUNK_PLATFORM) {
161
+ if (platformName == platform) {
162
+ return bitcore_1.BufferUtil.from([byte]);
163
+ }
164
+ }
165
+ }
166
+ function toPlatformUTF8(platformBuf) {
167
+ return exports.SCRIPT_CHUNK_PLATFORM.get(platformBuf.readUInt8(0));
168
+ }
169
+ function toSentimentOpCode(sentiment) {
170
+ return exports.RANK_SENTIMENT_OP_CODES.get(sentiment);
171
+ }
172
+ function toSentimentUTF8(sentimentBuf) {
173
+ return exports.SCRIPT_CHUNK_SENTIMENT.get(sentimentBuf.readUInt8(0));
174
+ }
175
+ function toCommentUTF8(commentBuf) {
176
+ return new TextDecoder('utf-8').decode(commentBuf);
177
+ }
178
+ function isValidLokad(scriptChunk, lokadType) {
179
+ let result = scriptChunk.buf !== undefined &&
180
+ scriptChunk.buf.length === 4 &&
181
+ exports.SCRIPT_CHUNK_LOKAD.has(scriptChunk.buf.readUInt32BE(0));
182
+ if (lokadType) {
183
+ result =
184
+ result &&
185
+ scriptChunk.buf !== undefined &&
186
+ exports.SCRIPT_CHUNK_LOKAD.get(scriptChunk.buf?.readUInt32BE(0)) === lokadType;
187
+ }
188
+ return result;
189
+ }
190
+ function fromScriptRANK(scriptBuf) {
191
+ const script = typeof scriptBuf === 'string'
192
+ ? bitcore_1.Script.fromString(scriptBuf)
193
+ : bitcore_1.Script.fromBuffer(scriptBuf);
194
+ if (!script.isDataOut()) {
195
+ throw new Error('Script is not OP_RETURN');
196
+ }
197
+ if (!isValidLokad(script.chunks[1], 'RANK')) {
198
+ throw new Error('LOKAD chunk is either invalid or unsupported');
199
+ }
200
+ const sentiment = exports.SCRIPT_CHUNK_SENTIMENT.get(script.chunks[2].opcodenum);
201
+ if (!sentiment) {
202
+ throw new Error('Invalid sentiment chunk');
203
+ }
204
+ const platform = exports.SCRIPT_CHUNK_PLATFORM.get(script.chunks[3].buf?.readUInt8(0));
205
+ if (!platform) {
206
+ throw new Error('Invalid platform chunk');
207
+ }
208
+ const platformSpec = exports.PlatformConfiguration.get(platform);
209
+ if (!platformSpec) {
210
+ throw new Error('Invalid platform spec');
211
+ }
212
+ const profileIdChunk = script.chunks[4];
213
+ if (profileIdChunk.buf === undefined ||
214
+ profileIdChunk.buf.length !== platformSpec.profileId.len) {
215
+ throw new Error(`Invalid profileId chunk (profileId chunk missing or length does not match platform ${platform})`);
216
+ }
217
+ const profileId = toProfileIdUTF8(profileIdChunk.buf);
218
+ if (!platformSpec.profileId.regex.test(profileId)) {
219
+ throw new Error(`Invalid profileId "${profileId}" (regex does not match for platform ${platform})`);
220
+ }
221
+ const data = {
222
+ sentiment,
223
+ platform,
224
+ profileId,
225
+ };
226
+ if (script.chunks.length > 5) {
227
+ const postIdChunk = script.chunks[5];
228
+ if (postIdChunk.buf === undefined) {
229
+ throw new Error('Invalid postId chunk (postId chunk missing)');
230
+ }
231
+ if (platformSpec.postId?.type === 'BigInt') {
232
+ data.postId = postIdChunk.buf.readBigUInt64BE(0).toString();
233
+ }
234
+ else {
235
+ data.postId = postIdChunk.buf.toString('hex');
236
+ }
237
+ if (platformSpec.postId?.regex &&
238
+ !platformSpec.postId.regex.test(data.postId)) {
239
+ throw new Error(`Invalid postId "${data.postId}" (regex does not match for platform ${platform})`);
240
+ }
241
+ }
242
+ return data;
243
+ }
244
+ function toScriptRANK(sentiment, platform, profileId, postId) {
245
+ if (!sentiment || !platform || !profileId) {
246
+ throw new Error('Must specify sentiment, platform, and profileId');
247
+ }
248
+ const platformSpec = exports.PlatformConfiguration.get(platform);
249
+ if (!platformSpec || !platformSpec.profileId) {
250
+ throw new Error(`RANK outputs for platform ${platform} are not supported`);
251
+ }
252
+ const script = bitcore_1.Script.empty()
253
+ .add(bitcore_1.Opcode.OP_RETURN)
254
+ .add(bitcore_1.BufferUtil.from((0, string_1.toHex)(exports.LOKAD_PREFIX_RANK), 'hex'));
255
+ switch (sentiment) {
256
+ case 'neutral':
257
+ script.add(exports.RANK_SENTIMENT_NEUTRAL);
258
+ break;
259
+ case 'positive':
260
+ script.add(exports.RANK_SENTIMENT_POSITIVE);
261
+ break;
262
+ case 'negative':
263
+ script.add(exports.RANK_SENTIMENT_NEGATIVE);
264
+ break;
265
+ }
266
+ script.add(toPlatformBuf(platform));
267
+ const profileIdBuf = toProfileIdBuf(platform, profileId);
268
+ script.add(profileIdBuf);
269
+ if (postId) {
270
+ if (!platformSpec.postId) {
271
+ throw new Error('Post ID provided, but no platform post specification defined');
272
+ }
273
+ script.add(toPostIdBuf(platform, postId));
274
+ }
275
+ return script.toBuffer();
276
+ }
277
+ function fromScriptRNKC(scriptBuf, supplementalScriptBufs, burnedSats, options) {
278
+ const script = typeof scriptBuf === 'string'
279
+ ? bitcore_1.Script.fromString(scriptBuf)
280
+ : bitcore_1.Script.fromBuffer(scriptBuf);
281
+ if (!script.isDataOut()) {
282
+ throw new Error('Script is not OP_RETURN');
283
+ }
284
+ if (!isValidLokad(script.chunks[1], 'RNKC')) {
285
+ throw new Error('LOKAD chunk is either invalid or unsupported');
286
+ }
287
+ const supplementalScripts = supplementalScriptBufs.map(s => typeof s === 'string' ? bitcore_1.Script.fromString(s) : bitcore_1.Script.fromBuffer(s));
288
+ const platform = exports.SCRIPT_CHUNK_PLATFORM.get(script.chunks[2].buf?.readUInt8(0));
289
+ if (!platform) {
290
+ throw new Error('Invalid platform chunk');
291
+ }
292
+ const platformSpec = exports.PlatformConfiguration.get(platform);
293
+ if (!platformSpec) {
294
+ throw new Error('Platform configuration not found');
295
+ }
296
+ const profileIdChunk = script.chunks[3];
297
+ if (!profileIdChunk?.buf) {
298
+ throw new Error('Invalid profileId chunk');
299
+ }
300
+ const profileId = toProfileIdUTF8(profileIdChunk.buf);
301
+ if (!platformSpec.profileId.regex.test(profileId)) {
302
+ throw new Error('Invalid profileId format for platform');
303
+ }
304
+ let postId;
305
+ if (script.chunks.length > 4 && script.chunks[4]?.buf) {
306
+ if (!platformSpec.postId) {
307
+ throw new Error('Post ID found but platform does not support post IDs');
308
+ }
309
+ postId = script.chunks[4].buf.toString('utf8');
310
+ if (!platformSpec.postId.regex.test(postId)) {
311
+ throw new Error('Invalid postId format for platform');
312
+ }
313
+ }
314
+ let commentBuf = bitcore_1.BufferUtil.alloc(0);
315
+ for (const supplementalScript of supplementalScripts) {
316
+ if (!supplementalScript.isDataOut()) {
317
+ break;
318
+ }
319
+ const chunks = supplementalScript.chunks;
320
+ if (chunks.length < 2 || !chunks[1]?.buf) {
321
+ break;
322
+ }
323
+ commentBuf = bitcore_1.BufferUtil.concat([commentBuf, chunks[1].buf]);
324
+ }
325
+ if (commentBuf.length === 0) {
326
+ throw new Error('No comment data found in supplemental scripts');
327
+ }
328
+ const minDataLength = options?.minDataLength ?? constants_js_1.RNKC_MIN_DATA_LENGTH;
329
+ const minFeeRate = options?.minFeeRate ?? constants_js_1.RNKC_MIN_FEE_RATE;
330
+ if (commentBuf.length < minDataLength) {
331
+ throw new Error(`Comment data length ${commentBuf.length} is below minimum ${minDataLength}`);
332
+ }
333
+ const burnedSatsNum = typeof burnedSats === 'bigint' ? Number(burnedSats) : burnedSats;
334
+ if (burnedSatsNum < minFeeRate * commentBuf.length) {
335
+ throw new Error(`Fee rate too low: ${Math.floor(burnedSatsNum / commentBuf.length)} < ${minFeeRate}`);
336
+ }
337
+ const result = {
338
+ data: new Uint8Array(commentBuf),
339
+ feeRate: Math.floor(burnedSatsNum / commentBuf.length),
340
+ inReplyToPlatform: platform,
341
+ inReplyToProfileId: profileId,
342
+ inReplyToPostId: postId,
343
+ };
344
+ if (!result) {
345
+ throw new Error('Failed to process RNKC script');
346
+ }
347
+ return result;
348
+ }
349
+ function toScriptRNKC({ platform, profileId, postId, comment, }) {
350
+ if (!platform || !profileId) {
351
+ throw new Error('Must specify platform and profileId');
352
+ }
353
+ const platformSpec = exports.PlatformConfiguration.get(platform);
354
+ if (!platformSpec || !platformSpec.profileId) {
355
+ throw new Error(`RNKC outputs for platform ${platform} are not supported`);
356
+ }
357
+ if (!platformSpec.profileId.regex.test(profileId)) {
358
+ throw new Error(`Invalid profileId: ${profileId}`);
359
+ }
360
+ if (postId && !platformSpec.postId.regex.test(postId)) {
361
+ throw new Error(`Invalid postId: ${postId}`);
362
+ }
363
+ const commentBuf = bitcore_1.BufferUtil.from(comment, 'utf8');
364
+ if (commentBuf.length < 1 || commentBuf.length > constants_js_1.MAX_OP_RETURN_DATA * 2) {
365
+ throw new Error(`Comment must be between 1 and ${constants_js_1.MAX_OP_RETURN_DATA * 2} bytes`);
366
+ }
367
+ const scriptBufs = [];
368
+ const script0 = bitcore_1.Script.empty()
369
+ .add(bitcore_1.Opcode.OP_RETURN)
370
+ .add(bitcore_1.BufferUtil.from((0, string_1.toHex)(exports.LOKAD_PREFIX_RNKC), 'hex'))
371
+ .add(toPlatformBuf(platform))
372
+ .add(toProfileIdBuf(platform, profileId));
373
+ if (postId) {
374
+ script0.add(toPostIdBuf(platform, postId));
375
+ }
376
+ scriptBufs.push(script0.toBuffer());
377
+ const commentBuf1 = commentBuf.slice(0, constants_js_1.MAX_OP_RETURN_DATA);
378
+ const script1 = bitcore_1.Script.empty().add(bitcore_1.Opcode.OP_RETURN).add(commentBuf1);
379
+ scriptBufs.push(script1.toBuffer());
380
+ if (commentBuf.length > constants_js_1.MAX_OP_RETURN_DATA) {
381
+ const commentBuf2 = commentBuf.slice(constants_js_1.MAX_OP_RETURN_DATA);
382
+ const script2 = bitcore_1.Script.empty().add(bitcore_1.Opcode.OP_RETURN).add(commentBuf2);
383
+ scriptBufs.push(script2.toBuffer());
384
+ }
385
+ return scriptBufs;
386
+ }
387
+ class ScriptProcessor {
388
+ chunks = null;
389
+ script;
390
+ supplementalScripts = [];
391
+ constructor(script) {
392
+ this.script = script;
393
+ switch (this.lokadType) {
394
+ case 'RANK':
395
+ this.chunks = exports.ScriptChunksRANKMap;
396
+ break;
397
+ case 'RNKC':
398
+ this.chunks = exports.ScriptChunksRNKCMap;
399
+ break;
400
+ }
401
+ }
402
+ addScript(script) {
403
+ if (!bitcore_1.BufferUtil.isBuffer(script)) {
404
+ script = bitcore_1.BufferUtil.from(script, 'hex');
405
+ }
406
+ if (!isOpReturn(script)) {
407
+ return false;
408
+ }
409
+ this.supplementalScripts.push(script);
410
+ return true;
411
+ }
412
+ get lokadType() {
413
+ return this.processLokad();
414
+ }
415
+ processLokad() {
416
+ const lokadBuf = this.script.slice(2, 6);
417
+ const lokad = exports.SCRIPT_CHUNK_LOKAD.get(lokadBuf.readUInt32BE(0));
418
+ if (!lokad) {
419
+ return undefined;
420
+ }
421
+ return lokad;
422
+ }
423
+ processSentiment() {
424
+ const chunk = this.chunks?.get('sentiment');
425
+ if (!chunk || chunk.offset === null) {
426
+ return undefined;
427
+ }
428
+ const sentimentBuf = this.script.slice(chunk.offset, chunk.offset + chunk.len);
429
+ return exports.SCRIPT_CHUNK_SENTIMENT.get(sentimentBuf.readUInt8(0));
430
+ }
431
+ processPlatform() {
432
+ const chunk = this.chunks?.get('platform');
433
+ if (!chunk || chunk.offset === null) {
434
+ return undefined;
435
+ }
436
+ const platformBuf = this.script.slice(chunk.offset, chunk.offset + chunk.len);
437
+ const platform = exports.SCRIPT_CHUNK_PLATFORM.get(platformBuf.readUInt8(0));
438
+ if (!platform) {
439
+ return undefined;
440
+ }
441
+ return platform;
442
+ }
443
+ processProfileId(platform) {
444
+ const chunk = this.chunks?.get('profileId');
445
+ if (!chunk || chunk.offset === null) {
446
+ return undefined;
447
+ }
448
+ const platformSpec = exports.PlatformConfiguration.get(platform);
449
+ if (!platformSpec || !platformSpec.profileId) {
450
+ return undefined;
451
+ }
452
+ const pushOpOffset = chunk.offset - 1;
453
+ if (pushOpOffset < 0 || pushOpOffset >= this.script.length) {
454
+ return undefined;
455
+ }
456
+ const actualLen = this.script.readUInt8(pushOpOffset);
457
+ if (platform === 'lotusia' && actualLen !== 20 && actualLen !== 33) {
458
+ return undefined;
459
+ }
460
+ const profileIdBuf = this.script.slice(chunk.offset, chunk.offset + actualLen);
461
+ if (profileIdBuf.length !== actualLen) {
462
+ return undefined;
463
+ }
464
+ switch (platform) {
465
+ case 'lotusia':
466
+ return (0, string_1.toHex)(profileIdBuf);
467
+ case 'twitter':
468
+ return toProfileIdUTF8(profileIdBuf);
469
+ default:
470
+ return undefined;
471
+ }
472
+ }
473
+ processPostId(platform) {
474
+ if (!platform) {
475
+ return undefined;
476
+ }
477
+ const platformSpec = exports.PlatformConfiguration.get(platform);
478
+ if (!platformSpec || !platformSpec.postId || !platformSpec.profileId) {
479
+ return undefined;
480
+ }
481
+ const profileIdChunk = this.chunks?.get('profileId');
482
+ if (!profileIdChunk?.offset) {
483
+ return undefined;
484
+ }
485
+ const profileIdPushOpOffset = profileIdChunk.offset - 1;
486
+ if (profileIdPushOpOffset < 0 ||
487
+ profileIdPushOpOffset >= this.script.length) {
488
+ return undefined;
489
+ }
490
+ const actualProfileIdLen = this.script.readUInt8(profileIdPushOpOffset);
491
+ const postIdSpec = platformSpec.postId;
492
+ const postIdOffset = profileIdChunk.offset + actualProfileIdLen + 1;
493
+ if (postIdOffset + postIdSpec.len > this.script.length) {
494
+ return undefined;
495
+ }
496
+ const postIdPushOpOffset = postIdOffset - 1;
497
+ if (postIdPushOpOffset >= this.script.length) {
498
+ return undefined;
499
+ }
500
+ const postIdPushOp = this.script.readUInt8(postIdPushOpOffset);
501
+ if (postIdPushOp !== postIdSpec.len) {
502
+ return undefined;
503
+ }
504
+ const postIdBuf = this.script.slice(postIdOffset, postIdOffset + postIdSpec.len);
505
+ try {
506
+ switch (platform) {
507
+ case 'lotusia':
508
+ return postIdBuf.toString('hex');
509
+ case 'twitter':
510
+ return postIdBuf.readBigUInt64BE(0).toString();
511
+ default:
512
+ return undefined;
513
+ }
514
+ }
515
+ catch (e) {
516
+ return undefined;
517
+ }
518
+ }
519
+ processComment(scripts) {
520
+ let commentBuf = bitcore_1.BufferUtil.alloc(0);
521
+ for (let i = 0; i < scripts.length; i++) {
522
+ const script = scripts[i];
523
+ if (script.readUInt8(1) !== bitcore_1.Opcode.OP_PUSHDATA1) {
524
+ break;
525
+ }
526
+ const dataSize = script.readUInt8(2);
527
+ if (isNaN(dataSize) || dataSize > constants_js_1.MAX_OP_RETURN_DATA) {
528
+ break;
529
+ }
530
+ commentBuf = bitcore_1.BufferUtil.concat([
531
+ commentBuf,
532
+ script.slice(3, 3 + dataSize),
533
+ ]);
534
+ }
535
+ if (!commentBuf) {
536
+ return null;
537
+ }
538
+ return new Uint8Array(commentBuf);
539
+ }
540
+ processScriptRANK() {
541
+ const sentiment = this.processSentiment();
542
+ if (!sentiment) {
543
+ return null;
544
+ }
545
+ const platform = this.processPlatform();
546
+ if (!platform) {
547
+ return null;
548
+ }
549
+ const profileId = this.processProfileId(platform);
550
+ if (!profileId) {
551
+ return null;
552
+ }
553
+ const output = {
554
+ sentiment,
555
+ platform,
556
+ profileId,
557
+ };
558
+ const postId = this.processPostId(platform);
559
+ if (postId) {
560
+ output.postId = postId;
561
+ }
562
+ return output;
563
+ }
564
+ processScriptRNKC(burnedSats, options) {
565
+ if (typeof burnedSats === 'bigint') {
566
+ burnedSats = Number(burnedSats);
567
+ }
568
+ if (this.supplementalScripts.length === 0 ||
569
+ this.supplementalScripts.length > 2) {
570
+ return null;
571
+ }
572
+ const inReplyToPlatform = this.processPlatform();
573
+ if (!inReplyToPlatform) {
574
+ return null;
575
+ }
576
+ const data = this.processComment(this.supplementalScripts);
577
+ if (!data) {
578
+ return null;
579
+ }
580
+ if (data.length < (options?.minDataLength ?? constants_js_1.RNKC_MIN_DATA_LENGTH)) {
581
+ return null;
582
+ }
583
+ if (burnedSats < (options?.minFeeRate ?? constants_js_1.RNKC_MIN_FEE_RATE) * data.length) {
584
+ return null;
585
+ }
586
+ const output = {
587
+ data,
588
+ feeRate: Math.floor(burnedSats / data.length),
589
+ inReplyToPlatform,
590
+ inReplyToProfileId: undefined,
591
+ inReplyToPostId: undefined,
592
+ };
593
+ const profileId = this.processProfileId(inReplyToPlatform);
594
+ if (profileId) {
595
+ output.inReplyToProfileId = profileId;
596
+ const postId = this.processPostId(inReplyToPlatform);
597
+ if (postId) {
598
+ output.inReplyToPostId = postId;
599
+ }
600
+ }
601
+ return output;
602
+ }
603
+ }
604
+ exports.ScriptProcessor = ScriptProcessor;
package/dist/esm/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export * from './lib/rpc.js';
2
2
  export * as Bitcore from './lib/bitcore/index.js';
3
- export * as RANK from './lib/rank/index.js';
3
+ export * as LOKAD from './lib/lokad.js';
4
4
  export * from './utils/constants.js';
5
5
  export * from './utils/env.js';
6
6
  export * from './utils/string.js';
@@ -73,17 +73,13 @@ export class Schnorr {
73
73
  Point.pointToCompressed(P),
74
74
  e.toBuffer({ size: 32 }),
75
75
  ])));
76
- const s = e0.mul(d).add(k).mod(n);
76
+ const s = k.add(e0.mul(d)).mod(n);
77
77
  return { r, s, compressed: this.pubkey.compressed, isSchnorr: true };
78
78
  }
79
79
  getrBuffer(r) {
80
80
  const buf = r.toBuffer();
81
81
  return buf.length < 32 ? r.toBuffer({ size: 32 }) : buf;
82
82
  }
83
- getsBuffer(s) {
84
- const buf = s.toBuffer();
85
- return buf.length < 32 ? s.toBuffer({ size: 32 }) : buf;
86
- }
87
83
  sigError() {
88
84
  if (!BufferUtil.isBuffer(this.hashbuf) || this.hashbuf.length !== 32) {
89
85
  return true;