@rialo/ts-cdk 0.1.2 → 0.1.3

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/dist/index.mjs CHANGED
@@ -453,13 +453,32 @@ var URL_MAINNET = "https://mainnet.rialo.io:4100";
453
453
  var URL_TESTNET = "https://testnet.rialo.io:4100";
454
454
  var URL_DEVNET = "https://devnet.rialo.io:4101";
455
455
  var URL_LOCALNET = "http://localhost:4100";
456
+ var RIALO_MAINNET_CHAIN = {
457
+ id: "rialo:mainnet",
458
+ name: "Mainnet",
459
+ rpcUrl: URL_MAINNET
460
+ };
461
+ var RIALO_TESTNET_CHAIN = {
462
+ id: "rialo:testnet",
463
+ name: "Testnet",
464
+ rpcUrl: URL_TESTNET
465
+ };
466
+ var RIALO_DEVNET_CHAIN = {
467
+ id: "rialo:devnet",
468
+ name: "Devnet",
469
+ rpcUrl: URL_DEVNET
470
+ };
471
+ var RIALO_LOCALNET_CHAIN = {
472
+ id: "rialo:localnet",
473
+ name: "Localhost",
474
+ rpcUrl: URL_LOCALNET
475
+ };
456
476
  var SYSTEM_PROGRAM_ID = "11111111111111111111111111111111";
457
477
  var BASE_DERIVATION_PATH = "m/44'/756'/";
458
478
  var KELVIN_PER_RLO = 1e9;
459
479
  var PUBLIC_KEY_LENGTH = 32;
460
480
  var SECRET_KEY_LENGTH = 32;
461
481
  var SIGNATURE_LENGTH = 64;
462
- var BLOCKHASH_LENGTH = 32;
463
482
 
464
483
  // src/transaction/account-meta-table.ts
465
484
  var AccountMetaTable = class {
@@ -1221,395 +1240,43 @@ function encodeBorshData(_schema) {
1221
1240
  throw new Error("Use class-based Borsh serialization with decorators");
1222
1241
  }
1223
1242
 
1224
- // node_modules/@scure/base/index.js
1225
- function isBytes(a) {
1226
- return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
1227
- }
1228
- function isArrayOf(isString, arr) {
1229
- if (!Array.isArray(arr))
1230
- return false;
1231
- if (arr.length === 0)
1232
- return true;
1233
- if (isString) {
1234
- return arr.every((item) => typeof item === "string");
1235
- } else {
1236
- return arr.every((item) => Number.isSafeInteger(item));
1243
+ // src/crypto/errors.ts
1244
+ var CryptoErrorCode = /* @__PURE__ */ ((CryptoErrorCode2) => {
1245
+ CryptoErrorCode2["INVALID_KEY_LENGTH"] = "INVALID_KEY_LENGTH";
1246
+ CryptoErrorCode2["INVALID_SIGNATURE"] = "INVALID_SIGNATURE";
1247
+ CryptoErrorCode2["INVALID_PUBLIC_KEY"] = "INVALID_PUBLIC_KEY";
1248
+ CryptoErrorCode2["INVALID_BLOCKHASH"] = "INVALID_BLOCKHASH";
1249
+ CryptoErrorCode2["INVALID_MNEMONIC"] = "INVALID_MNEMONIC";
1250
+ CryptoErrorCode2["KEY_DERIVATION_FAILED"] = "KEY_DERIVATION_FAILED";
1251
+ CryptoErrorCode2["KEYPAIR_DISPOSED"] = "KEYPAIR_DISPOSED";
1252
+ return CryptoErrorCode2;
1253
+ })(CryptoErrorCode || {});
1254
+ var CryptoError = class _CryptoError extends Error {
1255
+ code;
1256
+ details;
1257
+ constructor(code, message, details) {
1258
+ super(message);
1259
+ this.name = "CryptoError";
1260
+ this.code = code;
1261
+ this.details = details;
1237
1262
  }
1238
- }
1239
- function afn(input) {
1240
- if (typeof input !== "function")
1241
- throw new Error("function expected");
1242
- return true;
1243
- }
1244
- function astr(label, input) {
1245
- if (typeof input !== "string")
1246
- throw new Error(`${label}: string expected`);
1247
- return true;
1248
- }
1249
- function anumber(n) {
1250
- if (!Number.isSafeInteger(n))
1251
- throw new Error(`invalid integer: ${n}`);
1252
- }
1253
- function aArr(input) {
1254
- if (!Array.isArray(input))
1255
- throw new Error("array expected");
1256
- }
1257
- function astrArr(label, input) {
1258
- if (!isArrayOf(true, input))
1259
- throw new Error(`${label}: array of strings expected`);
1260
- }
1261
- function anumArr(label, input) {
1262
- if (!isArrayOf(false, input))
1263
- throw new Error(`${label}: array of numbers expected`);
1264
- }
1265
- // @__NO_SIDE_EFFECTS__
1266
- function chain(...args) {
1267
- const id = (a) => a;
1268
- const wrap = (a, b) => (c) => a(b(c));
1269
- const encode = args.map((x) => x.encode).reduceRight(wrap, id);
1270
- const decode = args.map((x) => x.decode).reduce(wrap, id);
1271
- return { encode, decode };
1272
- }
1273
- // @__NO_SIDE_EFFECTS__
1274
- function alphabet(letters) {
1275
- const lettersA = typeof letters === "string" ? letters.split("") : letters;
1276
- const len = lettersA.length;
1277
- astrArr("alphabet", lettersA);
1278
- const indexes = new Map(lettersA.map((l, i) => [l, i]));
1279
- return {
1280
- encode: (digits) => {
1281
- aArr(digits);
1282
- return digits.map((i) => {
1283
- if (!Number.isSafeInteger(i) || i < 0 || i >= len)
1284
- throw new Error(`alphabet.encode: digit index outside alphabet "${i}". Allowed: ${letters}`);
1285
- return lettersA[i];
1286
- });
1287
- },
1288
- decode: (input) => {
1289
- aArr(input);
1290
- return input.map((letter) => {
1291
- astr("alphabet.decode", letter);
1292
- const i = indexes.get(letter);
1293
- if (i === void 0)
1294
- throw new Error(`Unknown letter: "${letter}". Allowed: ${letters}`);
1295
- return i;
1296
- });
1297
- }
1298
- };
1299
- }
1300
- // @__NO_SIDE_EFFECTS__
1301
- function join(separator = "") {
1302
- astr("join", separator);
1303
- return {
1304
- encode: (from) => {
1305
- astrArr("join.decode", from);
1306
- return from.join(separator);
1307
- },
1308
- decode: (to) => {
1309
- astr("join.decode", to);
1310
- return to.split(separator);
1311
- }
1312
- };
1313
- }
1314
- // @__NO_SIDE_EFFECTS__
1315
- function padding(bits, chr = "=") {
1316
- anumber(bits);
1317
- astr("padding", chr);
1318
- return {
1319
- encode(data) {
1320
- astrArr("padding.encode", data);
1321
- while (data.length * bits % 8)
1322
- data.push(chr);
1323
- return data;
1324
- },
1325
- decode(input) {
1326
- astrArr("padding.decode", input);
1327
- let end = input.length;
1328
- if (end * bits % 8)
1329
- throw new Error("padding: invalid, string should have whole number of bytes");
1330
- for (; end > 0 && input[end - 1] === chr; end--) {
1331
- const last = end - 1;
1332
- const byte = last * bits;
1333
- if (byte % 8 === 0)
1334
- throw new Error("padding: invalid, string has too much padding");
1335
- }
1336
- return input.slice(0, end);
1337
- }
1338
- };
1339
- }
1340
- function convertRadix(data, from, to) {
1341
- if (from < 2)
1342
- throw new Error(`convertRadix: invalid from=${from}, base cannot be less than 2`);
1343
- if (to < 2)
1344
- throw new Error(`convertRadix: invalid to=${to}, base cannot be less than 2`);
1345
- aArr(data);
1346
- if (!data.length)
1347
- return [];
1348
- let pos = 0;
1349
- const res = [];
1350
- const digits = Array.from(data, (d) => {
1351
- anumber(d);
1352
- if (d < 0 || d >= from)
1353
- throw new Error(`invalid integer: ${d}`);
1354
- return d;
1355
- });
1356
- const dlen = digits.length;
1357
- while (true) {
1358
- let carry = 0;
1359
- let done = true;
1360
- for (let i = pos; i < dlen; i++) {
1361
- const digit = digits[i];
1362
- const fromCarry = from * carry;
1363
- const digitBase = fromCarry + digit;
1364
- if (!Number.isSafeInteger(digitBase) || fromCarry / from !== carry || digitBase - digit !== fromCarry) {
1365
- throw new Error("convertRadix: carry overflow");
1366
- }
1367
- const div = digitBase / to;
1368
- carry = digitBase % to;
1369
- const rounded = Math.floor(div);
1370
- digits[i] = rounded;
1371
- if (!Number.isSafeInteger(rounded) || rounded * to + carry !== digitBase)
1372
- throw new Error("convertRadix: carry overflow");
1373
- if (!done)
1374
- continue;
1375
- else if (!rounded)
1376
- pos = i;
1377
- else
1378
- done = false;
1379
- }
1380
- res.push(carry);
1381
- if (done)
1382
- break;
1263
+ static invalidKeyLength(expected, actual) {
1264
+ return new _CryptoError(
1265
+ "INVALID_KEY_LENGTH" /* INVALID_KEY_LENGTH */,
1266
+ `Invalid key length: expected ${expected} bytes, got ${actual} bytes`,
1267
+ { expected, actual }
1268
+ );
1383
1269
  }
1384
- for (let i = 0; i < data.length - 1 && data[i] === 0; i++)
1385
- res.push(0);
1386
- return res.reverse();
1387
- }
1388
- var gcd = (a, b) => b === 0 ? a : gcd(b, a % b);
1389
- var radix2carry = /* @__NO_SIDE_EFFECTS__ */ (from, to) => from + (to - gcd(from, to));
1390
- var powers = /* @__PURE__ */ (() => {
1391
- let res = [];
1392
- for (let i = 0; i < 40; i++)
1393
- res.push(2 ** i);
1394
- return res;
1395
- })();
1396
- function convertRadix2(data, from, to, padding2) {
1397
- aArr(data);
1398
- if (from <= 0 || from > 32)
1399
- throw new Error(`convertRadix2: wrong from=${from}`);
1400
- if (to <= 0 || to > 32)
1401
- throw new Error(`convertRadix2: wrong to=${to}`);
1402
- if (/* @__PURE__ */ radix2carry(from, to) > 32) {
1403
- throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${/* @__PURE__ */ radix2carry(from, to)}`);
1270
+ static invalidMnemonic(reason) {
1271
+ const message = reason ? `Invalid mnemonic: ${reason}` : "Invalid mnemonic phrase. Check that all words are valid and in the correct order.";
1272
+ return new _CryptoError("INVALID_MNEMONIC" /* INVALID_MNEMONIC */, message);
1404
1273
  }
1405
- let carry = 0;
1406
- let pos = 0;
1407
- const max = powers[from];
1408
- const mask = powers[to] - 1;
1409
- const res = [];
1410
- for (const n of data) {
1411
- anumber(n);
1412
- if (n >= max)
1413
- throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);
1414
- carry = carry << from | n;
1415
- if (pos + from > 32)
1416
- throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);
1417
- pos += from;
1418
- for (; pos >= to; pos -= to)
1419
- res.push((carry >> pos - to & mask) >>> 0);
1420
- const pow = powers[pos];
1421
- if (pow === void 0)
1422
- throw new Error("invalid carry");
1423
- carry &= pow - 1;
1424
- }
1425
- carry = carry << to - pos & mask;
1426
- if (!padding2 && pos >= from)
1427
- throw new Error("Excess padding");
1428
- if (!padding2 && carry > 0)
1429
- throw new Error(`Non-zero padding: ${carry}`);
1430
- if (padding2 && pos > 0)
1431
- res.push(carry >>> 0);
1432
- return res;
1433
- }
1434
- // @__NO_SIDE_EFFECTS__
1435
- function radix(num) {
1436
- anumber(num);
1437
- const _256 = 2 ** 8;
1438
- return {
1439
- encode: (bytes) => {
1440
- if (!isBytes(bytes))
1441
- throw new Error("radix.encode input should be Uint8Array");
1442
- return convertRadix(Array.from(bytes), _256, num);
1443
- },
1444
- decode: (digits) => {
1445
- anumArr("radix.decode", digits);
1446
- return Uint8Array.from(convertRadix(digits, num, _256));
1447
- }
1448
- };
1449
- }
1450
- // @__NO_SIDE_EFFECTS__
1451
- function radix2(bits, revPadding = false) {
1452
- anumber(bits);
1453
- if (bits <= 0 || bits > 32)
1454
- throw new Error("radix2: bits should be in (0..32]");
1455
- if (/* @__PURE__ */ radix2carry(8, bits) > 32 || /* @__PURE__ */ radix2carry(bits, 8) > 32)
1456
- throw new Error("radix2: carry overflow");
1457
- return {
1458
- encode: (bytes) => {
1459
- if (!isBytes(bytes))
1460
- throw new Error("radix2.encode input should be Uint8Array");
1461
- return convertRadix2(Array.from(bytes), 8, bits, !revPadding);
1462
- },
1463
- decode: (digits) => {
1464
- anumArr("radix2.decode", digits);
1465
- return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));
1466
- }
1467
- };
1468
- }
1469
- function checksum(len, fn) {
1470
- anumber(len);
1471
- afn(fn);
1472
- return {
1473
- encode(data) {
1474
- if (!isBytes(data))
1475
- throw new Error("checksum.encode: input should be Uint8Array");
1476
- const sum = fn(data).slice(0, len);
1477
- const res = new Uint8Array(data.length + len);
1478
- res.set(data);
1479
- res.set(sum, data.length);
1480
- return res;
1481
- },
1482
- decode(data) {
1483
- if (!isBytes(data))
1484
- throw new Error("checksum.decode: input should be Uint8Array");
1485
- const payload = data.slice(0, -len);
1486
- const oldChecksum = data.slice(-len);
1487
- const newChecksum = fn(payload).slice(0, len);
1488
- for (let i = 0; i < len; i++)
1489
- if (newChecksum[i] !== oldChecksum[i])
1490
- throw new Error("Invalid checksum");
1491
- return payload;
1492
- }
1493
- };
1494
- }
1495
- var utils = {
1496
- alphabet,
1497
- chain,
1498
- checksum,
1499
- convertRadix,
1500
- convertRadix2,
1501
- radix,
1502
- radix2,
1503
- join,
1504
- padding
1505
- };
1506
- var genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain(/* @__PURE__ */ radix(58), /* @__PURE__ */ alphabet(abc), /* @__PURE__ */ join(""));
1507
- var base58 = /* @__PURE__ */ genBase58("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
1508
-
1509
- // src/crypto/blockhash.ts
1510
- var Blockhash = class _Blockhash {
1511
- bytes;
1512
- constructor(bytes) {
1513
- if (bytes.length !== BLOCKHASH_LENGTH) {
1514
- throw CryptoError.invalidKeyLength(BLOCKHASH_LENGTH, bytes.length);
1515
- }
1516
- this.bytes = new Uint8Array(bytes);
1517
- }
1518
- /**
1519
- * Creates a Blockhash from raw bytes.
1520
- *
1521
- * @param bytes - 32-byte blockhash
1522
- * @throws {CryptoError} If bytes length is not 32
1523
- */
1524
- static fromBytes(bytes) {
1525
- return new _Blockhash(bytes);
1526
- }
1527
- /**
1528
- * Creates a Blockhash from a base58-encoded string.
1529
- *
1530
- * @param str - Base58-encoded blockhash
1531
- * @throws {CryptoError} If string is invalid or decodes to wrong length
1532
- */
1533
- static fromString(str) {
1534
- try {
1535
- const bytes = base58.decode(str);
1536
- return new _Blockhash(bytes);
1537
- } catch (error) {
1538
- throw new CryptoError(
1539
- "INVALID_BLOCKHASH" /* INVALID_BLOCKHASH */,
1540
- `Invalid base58 blockhash: ${error instanceof Error ? error.message : "unknown error"}`,
1541
- { input: str }
1542
- );
1543
- }
1544
- }
1545
- /**
1546
- * Returns a copy of the raw bytes.
1547
- */
1548
- toBytes() {
1549
- return new Uint8Array(this.bytes);
1550
- }
1551
- /**
1552
- * Returns the base58-encoded string representation.
1553
- */
1554
- toString() {
1555
- return base58.encode(this.bytes);
1556
- }
1557
- /**
1558
- * Checks equality with another blockhash using constant-time comparison.
1559
- */
1560
- equals(other) {
1561
- if (!other) return false;
1562
- if (this.bytes.length !== other.bytes.length) return false;
1563
- for (let i = 0; i < this.bytes.length; i++) {
1564
- if (this.bytes[i] !== other.bytes[i]) return false;
1565
- }
1566
- return true;
1567
- }
1568
- /**
1569
- * JSON serialization (returns base58 string).
1570
- */
1571
- toJSON() {
1572
- return this.toString();
1573
- }
1574
- };
1575
-
1576
- // src/crypto/errors.ts
1577
- var CryptoErrorCode = /* @__PURE__ */ ((CryptoErrorCode2) => {
1578
- CryptoErrorCode2["INVALID_KEY_LENGTH"] = "INVALID_KEY_LENGTH";
1579
- CryptoErrorCode2["INVALID_SIGNATURE"] = "INVALID_SIGNATURE";
1580
- CryptoErrorCode2["INVALID_PUBLIC_KEY"] = "INVALID_PUBLIC_KEY";
1581
- CryptoErrorCode2["INVALID_BLOCKHASH"] = "INVALID_BLOCKHASH";
1582
- CryptoErrorCode2["INVALID_MNEMONIC"] = "INVALID_MNEMONIC";
1583
- CryptoErrorCode2["KEY_DERIVATION_FAILED"] = "KEY_DERIVATION_FAILED";
1584
- CryptoErrorCode2["KEYPAIR_DISPOSED"] = "KEYPAIR_DISPOSED";
1585
- return CryptoErrorCode2;
1586
- })(CryptoErrorCode || {});
1587
- var CryptoError = class _CryptoError extends Error {
1588
- code;
1589
- details;
1590
- constructor(code, message, details) {
1591
- super(message);
1592
- this.name = "CryptoError";
1593
- this.code = code;
1594
- this.details = details;
1595
- }
1596
- static invalidKeyLength(expected, actual) {
1597
- return new _CryptoError(
1598
- "INVALID_KEY_LENGTH" /* INVALID_KEY_LENGTH */,
1599
- `Invalid key length: expected ${expected} bytes, got ${actual} bytes`,
1600
- { expected, actual }
1601
- );
1602
- }
1603
- static invalidMnemonic(reason) {
1604
- const message = reason ? `Invalid mnemonic: ${reason}` : "Invalid mnemonic phrase. Check that all words are valid and in the correct order.";
1605
- return new _CryptoError("INVALID_MNEMONIC" /* INVALID_MNEMONIC */, message);
1606
- }
1607
- static keyDerivationFailed(path, cause) {
1608
- return new _CryptoError(
1609
- "KEY_DERIVATION_FAILED" /* KEY_DERIVATION_FAILED */,
1610
- `Failed to derive key at path: ${path}`,
1611
- { path, cause: cause?.message }
1612
- );
1274
+ static keyDerivationFailed(path, cause) {
1275
+ return new _CryptoError(
1276
+ "KEY_DERIVATION_FAILED" /* KEY_DERIVATION_FAILED */,
1277
+ `Failed to derive key at path: ${path}`,
1278
+ { path, cause: cause?.message }
1279
+ );
1613
1280
  }
1614
1281
  static keypairDisposed() {
1615
1282
  return new _CryptoError(
@@ -1644,9 +1311,9 @@ var err = (message = "") => {
1644
1311
  };
1645
1312
  var isBig = (n) => typeof n === "bigint";
1646
1313
  var isStr = (s) => typeof s === "string";
1647
- var isBytes2 = (a) => a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
1314
+ var isBytes = (a) => a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
1648
1315
  var abytes = (value, length, title = "") => {
1649
- const bytes = isBytes2(value);
1316
+ const bytes = isBytes(value);
1650
1317
  const len = value?.length;
1651
1318
  const needsLen = length !== void 0;
1652
1319
  if (!bytes || needsLen && len !== length) {
@@ -2100,17 +1767,17 @@ var wNAF = (n) => {
2100
1767
  };
2101
1768
 
2102
1769
  // node_modules/@noble/hashes/utils.js
2103
- function isBytes3(a) {
1770
+ function isBytes2(a) {
2104
1771
  return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
2105
1772
  }
2106
- function anumber2(n, title = "") {
1773
+ function anumber(n, title = "") {
2107
1774
  if (!Number.isSafeInteger(n) || n < 0) {
2108
1775
  const prefix = title && `"${title}" `;
2109
1776
  throw new Error(`${prefix}expected integer >0, got ${n}`);
2110
1777
  }
2111
1778
  }
2112
1779
  function abytes2(value, length, title = "") {
2113
- const bytes = isBytes3(value);
1780
+ const bytes = isBytes2(value);
2114
1781
  const len = value?.length;
2115
1782
  const needsLen = length !== void 0;
2116
1783
  if (!bytes || needsLen && len !== length) {
@@ -2124,8 +1791,8 @@ function abytes2(value, length, title = "") {
2124
1791
  function ahash(h2) {
2125
1792
  if (typeof h2 !== "function" || typeof h2.create !== "function")
2126
1793
  throw new Error("Hash must wrapped by utils.createHasher");
2127
- anumber2(h2.outputLen);
2128
- anumber2(h2.blockLen);
1794
+ anumber(h2.outputLen);
1795
+ anumber(h2.blockLen);
2129
1796
  }
2130
1797
  function aexists(instance, checkFinished = true) {
2131
1798
  if (instance.destroyed)
@@ -2525,106 +2192,391 @@ var sha512 = /* @__PURE__ */ createHasher(
2525
2192
  /* @__PURE__ */ oidNist(3)
2526
2193
  );
2527
2194
 
2528
- // src/crypto/public-key.ts
2529
- var PublicKey = class _PublicKey {
2530
- bytes;
2531
- constructor(bytes) {
2532
- if (bytes.length !== PUBLIC_KEY_LENGTH) {
2533
- throw CryptoError.invalidKeyLength(PUBLIC_KEY_LENGTH, bytes.length);
2534
- }
2535
- this.bytes = new Uint8Array(bytes);
2536
- }
2537
- /**
2538
- * Creates a PublicKey from raw bytes.
2539
- *
2540
- * @param bytes - 32-byte Ed25519 public key
2541
- * @throws {CryptoError} If bytes length is not 32
2542
- */
2543
- static fromBytes(bytes) {
2544
- return new _PublicKey(bytes);
2545
- }
2546
- /**
2547
- * Creates a PublicKey from a base58-encoded string.
2548
- *
2549
- * @param str - Base58-encoded public key
2550
- * @throws {CryptoError} If string is invalid or decodes to wrong length
2551
- */
2552
- static fromString(str) {
2553
- try {
2554
- const bytes = base58.decode(str);
2555
- return new _PublicKey(bytes);
2556
- } catch (error) {
2557
- throw new CryptoError(
2558
- "INVALID_PUBLIC_KEY" /* INVALID_PUBLIC_KEY */,
2559
- `Invalid base58 public key: ${error instanceof Error ? error.message : "unknown error"}`,
2560
- { input: str }
2561
- );
2562
- }
2563
- }
2564
- /**
2565
- * Returns a copy of the raw bytes.
2566
- */
2567
- toBytes() {
2568
- return new Uint8Array(this.bytes);
2569
- }
2570
- /**
2571
- * Returns the base58-encoded string representation.
2572
- */
2573
- toString() {
2574
- return base58.encode(this.bytes);
2575
- }
2576
- /**
2577
- * Checks equality with another public key using constant-time comparison.
2578
- */
2579
- equals(other) {
2580
- if (!other) return false;
2581
- if (this.bytes.length !== other.bytes.length) return false;
2582
- for (let i = 0; i < this.bytes.length; i++) {
2583
- if (this.bytes[i] !== other.bytes[i]) return false;
2584
- }
2195
+ // node_modules/@scure/base/index.js
2196
+ function isBytes3(a) {
2197
+ return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
2198
+ }
2199
+ function isArrayOf(isString, arr) {
2200
+ if (!Array.isArray(arr))
2201
+ return false;
2202
+ if (arr.length === 0)
2585
2203
  return true;
2204
+ if (isString) {
2205
+ return arr.every((item) => typeof item === "string");
2206
+ } else {
2207
+ return arr.every((item) => Number.isSafeInteger(item));
2586
2208
  }
2587
- /**
2588
- * Verifies an Ed25519 signature over a message.
2589
- *
2590
- * @param message - Message bytes that were signed
2591
- * @param signature - Signature to verify
2592
- * @returns True if signature is valid, false otherwise
2593
- *
2594
- * @example
2595
- * ```typescript
2596
- * const message = new Uint8Array([1, 2, 3]);
2597
- * const signature = keypair.sign(message);
2598
- * const isValid = keypair.publicKey.verify(message, signature);
2599
- * ```
2600
- */
2601
- verify(message, signature) {
2602
- return verify(
2603
- signature.toBytes(),
2604
- message,
2605
- this.bytes
2606
- );
2607
- }
2608
- /**
2609
- * JSON serialization (returns base58 string).
2610
- */
2611
- toJSON() {
2612
- return this.toString();
2613
- }
2614
- };
2615
-
2616
- // src/crypto/signature.ts
2617
- var Signature = class _Signature {
2618
- bytes;
2619
- constructor(bytes) {
2620
- if (bytes.length !== SIGNATURE_LENGTH) {
2621
- throw CryptoError.invalidKeyLength(SIGNATURE_LENGTH, bytes.length);
2622
- }
2623
- this.bytes = new Uint8Array(bytes);
2624
- }
2625
- /**
2626
- * Creates a Signature from raw bytes.
2627
- *
2209
+ }
2210
+ function afn(input) {
2211
+ if (typeof input !== "function")
2212
+ throw new Error("function expected");
2213
+ return true;
2214
+ }
2215
+ function astr(label, input) {
2216
+ if (typeof input !== "string")
2217
+ throw new Error(`${label}: string expected`);
2218
+ return true;
2219
+ }
2220
+ function anumber2(n) {
2221
+ if (!Number.isSafeInteger(n))
2222
+ throw new Error(`invalid integer: ${n}`);
2223
+ }
2224
+ function aArr(input) {
2225
+ if (!Array.isArray(input))
2226
+ throw new Error("array expected");
2227
+ }
2228
+ function astrArr(label, input) {
2229
+ if (!isArrayOf(true, input))
2230
+ throw new Error(`${label}: array of strings expected`);
2231
+ }
2232
+ function anumArr(label, input) {
2233
+ if (!isArrayOf(false, input))
2234
+ throw new Error(`${label}: array of numbers expected`);
2235
+ }
2236
+ // @__NO_SIDE_EFFECTS__
2237
+ function chain(...args) {
2238
+ const id = (a) => a;
2239
+ const wrap = (a, b) => (c) => a(b(c));
2240
+ const encode = args.map((x) => x.encode).reduceRight(wrap, id);
2241
+ const decode = args.map((x) => x.decode).reduce(wrap, id);
2242
+ return { encode, decode };
2243
+ }
2244
+ // @__NO_SIDE_EFFECTS__
2245
+ function alphabet(letters) {
2246
+ const lettersA = typeof letters === "string" ? letters.split("") : letters;
2247
+ const len = lettersA.length;
2248
+ astrArr("alphabet", lettersA);
2249
+ const indexes = new Map(lettersA.map((l, i) => [l, i]));
2250
+ return {
2251
+ encode: (digits) => {
2252
+ aArr(digits);
2253
+ return digits.map((i) => {
2254
+ if (!Number.isSafeInteger(i) || i < 0 || i >= len)
2255
+ throw new Error(`alphabet.encode: digit index outside alphabet "${i}". Allowed: ${letters}`);
2256
+ return lettersA[i];
2257
+ });
2258
+ },
2259
+ decode: (input) => {
2260
+ aArr(input);
2261
+ return input.map((letter) => {
2262
+ astr("alphabet.decode", letter);
2263
+ const i = indexes.get(letter);
2264
+ if (i === void 0)
2265
+ throw new Error(`Unknown letter: "${letter}". Allowed: ${letters}`);
2266
+ return i;
2267
+ });
2268
+ }
2269
+ };
2270
+ }
2271
+ // @__NO_SIDE_EFFECTS__
2272
+ function join(separator = "") {
2273
+ astr("join", separator);
2274
+ return {
2275
+ encode: (from) => {
2276
+ astrArr("join.decode", from);
2277
+ return from.join(separator);
2278
+ },
2279
+ decode: (to) => {
2280
+ astr("join.decode", to);
2281
+ return to.split(separator);
2282
+ }
2283
+ };
2284
+ }
2285
+ // @__NO_SIDE_EFFECTS__
2286
+ function padding(bits, chr = "=") {
2287
+ anumber2(bits);
2288
+ astr("padding", chr);
2289
+ return {
2290
+ encode(data) {
2291
+ astrArr("padding.encode", data);
2292
+ while (data.length * bits % 8)
2293
+ data.push(chr);
2294
+ return data;
2295
+ },
2296
+ decode(input) {
2297
+ astrArr("padding.decode", input);
2298
+ let end = input.length;
2299
+ if (end * bits % 8)
2300
+ throw new Error("padding: invalid, string should have whole number of bytes");
2301
+ for (; end > 0 && input[end - 1] === chr; end--) {
2302
+ const last = end - 1;
2303
+ const byte = last * bits;
2304
+ if (byte % 8 === 0)
2305
+ throw new Error("padding: invalid, string has too much padding");
2306
+ }
2307
+ return input.slice(0, end);
2308
+ }
2309
+ };
2310
+ }
2311
+ function convertRadix(data, from, to) {
2312
+ if (from < 2)
2313
+ throw new Error(`convertRadix: invalid from=${from}, base cannot be less than 2`);
2314
+ if (to < 2)
2315
+ throw new Error(`convertRadix: invalid to=${to}, base cannot be less than 2`);
2316
+ aArr(data);
2317
+ if (!data.length)
2318
+ return [];
2319
+ let pos = 0;
2320
+ const res = [];
2321
+ const digits = Array.from(data, (d) => {
2322
+ anumber2(d);
2323
+ if (d < 0 || d >= from)
2324
+ throw new Error(`invalid integer: ${d}`);
2325
+ return d;
2326
+ });
2327
+ const dlen = digits.length;
2328
+ while (true) {
2329
+ let carry = 0;
2330
+ let done = true;
2331
+ for (let i = pos; i < dlen; i++) {
2332
+ const digit = digits[i];
2333
+ const fromCarry = from * carry;
2334
+ const digitBase = fromCarry + digit;
2335
+ if (!Number.isSafeInteger(digitBase) || fromCarry / from !== carry || digitBase - digit !== fromCarry) {
2336
+ throw new Error("convertRadix: carry overflow");
2337
+ }
2338
+ const div = digitBase / to;
2339
+ carry = digitBase % to;
2340
+ const rounded = Math.floor(div);
2341
+ digits[i] = rounded;
2342
+ if (!Number.isSafeInteger(rounded) || rounded * to + carry !== digitBase)
2343
+ throw new Error("convertRadix: carry overflow");
2344
+ if (!done)
2345
+ continue;
2346
+ else if (!rounded)
2347
+ pos = i;
2348
+ else
2349
+ done = false;
2350
+ }
2351
+ res.push(carry);
2352
+ if (done)
2353
+ break;
2354
+ }
2355
+ for (let i = 0; i < data.length - 1 && data[i] === 0; i++)
2356
+ res.push(0);
2357
+ return res.reverse();
2358
+ }
2359
+ var gcd = (a, b) => b === 0 ? a : gcd(b, a % b);
2360
+ var radix2carry = /* @__NO_SIDE_EFFECTS__ */ (from, to) => from + (to - gcd(from, to));
2361
+ var powers = /* @__PURE__ */ (() => {
2362
+ let res = [];
2363
+ for (let i = 0; i < 40; i++)
2364
+ res.push(2 ** i);
2365
+ return res;
2366
+ })();
2367
+ function convertRadix2(data, from, to, padding2) {
2368
+ aArr(data);
2369
+ if (from <= 0 || from > 32)
2370
+ throw new Error(`convertRadix2: wrong from=${from}`);
2371
+ if (to <= 0 || to > 32)
2372
+ throw new Error(`convertRadix2: wrong to=${to}`);
2373
+ if (/* @__PURE__ */ radix2carry(from, to) > 32) {
2374
+ throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${/* @__PURE__ */ radix2carry(from, to)}`);
2375
+ }
2376
+ let carry = 0;
2377
+ let pos = 0;
2378
+ const max = powers[from];
2379
+ const mask = powers[to] - 1;
2380
+ const res = [];
2381
+ for (const n of data) {
2382
+ anumber2(n);
2383
+ if (n >= max)
2384
+ throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);
2385
+ carry = carry << from | n;
2386
+ if (pos + from > 32)
2387
+ throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);
2388
+ pos += from;
2389
+ for (; pos >= to; pos -= to)
2390
+ res.push((carry >> pos - to & mask) >>> 0);
2391
+ const pow = powers[pos];
2392
+ if (pow === void 0)
2393
+ throw new Error("invalid carry");
2394
+ carry &= pow - 1;
2395
+ }
2396
+ carry = carry << to - pos & mask;
2397
+ if (!padding2 && pos >= from)
2398
+ throw new Error("Excess padding");
2399
+ if (!padding2 && carry > 0)
2400
+ throw new Error(`Non-zero padding: ${carry}`);
2401
+ if (padding2 && pos > 0)
2402
+ res.push(carry >>> 0);
2403
+ return res;
2404
+ }
2405
+ // @__NO_SIDE_EFFECTS__
2406
+ function radix(num) {
2407
+ anumber2(num);
2408
+ const _256 = 2 ** 8;
2409
+ return {
2410
+ encode: (bytes) => {
2411
+ if (!isBytes3(bytes))
2412
+ throw new Error("radix.encode input should be Uint8Array");
2413
+ return convertRadix(Array.from(bytes), _256, num);
2414
+ },
2415
+ decode: (digits) => {
2416
+ anumArr("radix.decode", digits);
2417
+ return Uint8Array.from(convertRadix(digits, num, _256));
2418
+ }
2419
+ };
2420
+ }
2421
+ // @__NO_SIDE_EFFECTS__
2422
+ function radix2(bits, revPadding = false) {
2423
+ anumber2(bits);
2424
+ if (bits <= 0 || bits > 32)
2425
+ throw new Error("radix2: bits should be in (0..32]");
2426
+ if (/* @__PURE__ */ radix2carry(8, bits) > 32 || /* @__PURE__ */ radix2carry(bits, 8) > 32)
2427
+ throw new Error("radix2: carry overflow");
2428
+ return {
2429
+ encode: (bytes) => {
2430
+ if (!isBytes3(bytes))
2431
+ throw new Error("radix2.encode input should be Uint8Array");
2432
+ return convertRadix2(Array.from(bytes), 8, bits, !revPadding);
2433
+ },
2434
+ decode: (digits) => {
2435
+ anumArr("radix2.decode", digits);
2436
+ return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));
2437
+ }
2438
+ };
2439
+ }
2440
+ function checksum(len, fn) {
2441
+ anumber2(len);
2442
+ afn(fn);
2443
+ return {
2444
+ encode(data) {
2445
+ if (!isBytes3(data))
2446
+ throw new Error("checksum.encode: input should be Uint8Array");
2447
+ const sum = fn(data).slice(0, len);
2448
+ const res = new Uint8Array(data.length + len);
2449
+ res.set(data);
2450
+ res.set(sum, data.length);
2451
+ return res;
2452
+ },
2453
+ decode(data) {
2454
+ if (!isBytes3(data))
2455
+ throw new Error("checksum.decode: input should be Uint8Array");
2456
+ const payload = data.slice(0, -len);
2457
+ const oldChecksum = data.slice(-len);
2458
+ const newChecksum = fn(payload).slice(0, len);
2459
+ for (let i = 0; i < len; i++)
2460
+ if (newChecksum[i] !== oldChecksum[i])
2461
+ throw new Error("Invalid checksum");
2462
+ return payload;
2463
+ }
2464
+ };
2465
+ }
2466
+ var utils = {
2467
+ alphabet,
2468
+ chain,
2469
+ checksum,
2470
+ convertRadix,
2471
+ convertRadix2,
2472
+ radix,
2473
+ radix2,
2474
+ join,
2475
+ padding
2476
+ };
2477
+ var genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain(/* @__PURE__ */ radix(58), /* @__PURE__ */ alphabet(abc), /* @__PURE__ */ join(""));
2478
+ var base58 = /* @__PURE__ */ genBase58("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
2479
+
2480
+ // src/crypto/public-key.ts
2481
+ var PublicKey = class _PublicKey {
2482
+ bytes;
2483
+ constructor(bytes) {
2484
+ if (bytes.length !== PUBLIC_KEY_LENGTH) {
2485
+ throw CryptoError.invalidKeyLength(PUBLIC_KEY_LENGTH, bytes.length);
2486
+ }
2487
+ this.bytes = new Uint8Array(bytes);
2488
+ }
2489
+ /**
2490
+ * Creates a PublicKey from raw bytes.
2491
+ *
2492
+ * @param bytes - 32-byte Ed25519 public key
2493
+ * @throws {CryptoError} If bytes length is not 32
2494
+ */
2495
+ static fromBytes(bytes) {
2496
+ return new _PublicKey(bytes);
2497
+ }
2498
+ /**
2499
+ * Creates a PublicKey from a base58-encoded string.
2500
+ *
2501
+ * @param str - Base58-encoded public key
2502
+ * @throws {CryptoError} If string is invalid or decodes to wrong length
2503
+ */
2504
+ static fromString(str) {
2505
+ try {
2506
+ const bytes = base58.decode(str);
2507
+ return new _PublicKey(bytes);
2508
+ } catch (error) {
2509
+ throw new CryptoError(
2510
+ "INVALID_PUBLIC_KEY" /* INVALID_PUBLIC_KEY */,
2511
+ `Invalid base58 public key: ${error instanceof Error ? error.message : "unknown error"}`,
2512
+ { input: str }
2513
+ );
2514
+ }
2515
+ }
2516
+ /**
2517
+ * Returns a copy of the raw bytes.
2518
+ */
2519
+ toBytes() {
2520
+ return new Uint8Array(this.bytes);
2521
+ }
2522
+ /**
2523
+ * Returns the base58-encoded string representation.
2524
+ */
2525
+ toString() {
2526
+ return base58.encode(this.bytes);
2527
+ }
2528
+ /**
2529
+ * Checks equality with another public key using constant-time comparison.
2530
+ */
2531
+ equals(other) {
2532
+ if (!other) return false;
2533
+ if (this.bytes.length !== other.bytes.length) return false;
2534
+ for (let i = 0; i < this.bytes.length; i++) {
2535
+ if (this.bytes[i] !== other.bytes[i]) return false;
2536
+ }
2537
+ return true;
2538
+ }
2539
+ /**
2540
+ * Verifies an Ed25519 signature over a message.
2541
+ *
2542
+ * @param message - Message bytes that were signed
2543
+ * @param signature - Signature to verify
2544
+ * @returns True if signature is valid, false otherwise
2545
+ *
2546
+ * @example
2547
+ * ```typescript
2548
+ * const message = new Uint8Array([1, 2, 3]);
2549
+ * const signature = keypair.sign(message);
2550
+ * const isValid = keypair.publicKey.verify(message, signature);
2551
+ * ```
2552
+ */
2553
+ verify(message, signature) {
2554
+ return verify(
2555
+ signature.toBytes(),
2556
+ message,
2557
+ this.bytes
2558
+ );
2559
+ }
2560
+ /**
2561
+ * JSON serialization (returns base58 string).
2562
+ */
2563
+ toJSON() {
2564
+ return this.toString();
2565
+ }
2566
+ };
2567
+
2568
+ // src/crypto/signature.ts
2569
+ var Signature = class _Signature {
2570
+ bytes;
2571
+ constructor(bytes) {
2572
+ if (bytes.length !== SIGNATURE_LENGTH) {
2573
+ throw CryptoError.invalidKeyLength(SIGNATURE_LENGTH, bytes.length);
2574
+ }
2575
+ this.bytes = new Uint8Array(bytes);
2576
+ }
2577
+ /**
2578
+ * Creates a Signature from raw bytes.
2579
+ *
2628
2580
  * @param bytes - 64-byte Ed25519 signature
2629
2581
  * @throws {CryptoError} If bytes length is not 64
2630
2582
  */
@@ -5989,1286 +5941,1261 @@ function createAccount(from, newAccount, lamports, space, owner) {
5989
5941
  };
5990
5942
  }
5991
5943
 
5992
- // src/rpc/errors.ts
5993
- var RpcErrorCode = /* @__PURE__ */ ((RpcErrorCode2) => {
5994
- RpcErrorCode2["REQUEST_TIMEOUT"] = "REQUEST_TIMEOUT";
5995
- RpcErrorCode2["NETWORK_ERROR"] = "NETWORK_ERROR";
5996
- RpcErrorCode2["CONNECTION_REFUSED"] = "CONNECTION_REFUSED";
5997
- RpcErrorCode2["INVALID_RESPONSE"] = "INVALID_RESPONSE";
5998
- RpcErrorCode2["PARSE_ERROR"] = "PARSE_ERROR";
5999
- RpcErrorCode2["INVALID_REQUEST"] = "INVALID_REQUEST";
6000
- RpcErrorCode2["METHOD_NOT_FOUND"] = "METHOD_NOT_FOUND";
6001
- RpcErrorCode2["INVALID_PARAMS"] = "INVALID_PARAMS";
6002
- RpcErrorCode2["INTERNAL_ERROR"] = "INTERNAL_ERROR";
6003
- RpcErrorCode2["TRANSACTION_REJECTED"] = "TRANSACTION_REJECTED";
6004
- RpcErrorCode2["INSUFFICIENT_FUNDS"] = "INSUFFICIENT_FUNDS";
6005
- RpcErrorCode2["ACCOUNT_NOT_FOUND"] = "ACCOUNT_NOT_FOUND";
6006
- RpcErrorCode2["BLOCKHASH_NOT_FOUND"] = "BLOCKHASH_NOT_FOUND";
6007
- RpcErrorCode2["RATE_LIMIT_EXCEEDED"] = "RATE_LIMIT_EXCEEDED";
6008
- RpcErrorCode2["NODE_UNHEALTHY"] = "NODE_UNHEALTHY";
6009
- return RpcErrorCode2;
6010
- })(RpcErrorCode || {});
6011
- var RpcError = class _RpcError extends Error {
6012
- code;
6013
- details;
6014
- retryable;
6015
- constructor(code, message, details = {}, retryable = false) {
6016
- super(message);
6017
- this.name = "RpcError";
6018
- this.code = code;
6019
- this.details = details;
6020
- this.retryable = retryable;
6021
- }
6022
- static requestTimeout(timeoutMs, details) {
6023
- return new _RpcError(
6024
- "REQUEST_TIMEOUT" /* REQUEST_TIMEOUT */,
6025
- `RPC request timed out after ${timeoutMs}ms. The node may be slow or unreachable.`,
6026
- { ...details, timeout: timeoutMs },
6027
- true
6028
- // Retryable
6029
- );
6030
- }
6031
- static networkError(message, details) {
6032
- return new _RpcError(
6033
- "NETWORK_ERROR" /* NETWORK_ERROR */,
6034
- `Network error: ${message}. Check your internet connection and node URL.`,
6035
- details,
6036
- true
6037
- // Retryable
6038
- );
6039
- }
6040
- static invalidResponse(details) {
6041
- return new _RpcError(
6042
- "INVALID_RESPONSE" /* INVALID_RESPONSE */,
6043
- "Received invalid response from RPC node. The response format is unexpected.",
6044
- details,
6045
- false
6046
- );
6047
- }
6048
- static accountNotFound(pubkey) {
6049
- return new _RpcError(
6050
- "ACCOUNT_NOT_FOUND" /* ACCOUNT_NOT_FOUND */,
6051
- `Account ${pubkey} not found on chain. It may not exist or has zero balance.`,
6052
- { pubkey },
6053
- false
6054
- );
6055
- }
6056
- static rateLimitExceeded(details) {
6057
- return new _RpcError(
6058
- "RATE_LIMIT_EXCEEDED" /* RATE_LIMIT_EXCEEDED */,
6059
- "Rate limit exceeded. Too many requests to the RPC endpoint. Try again later or use a different endpoint.",
6060
- details,
6061
- true
6062
- // Can retry after delay
5944
+ // src/transaction/message.ts
5945
+ var Message = class _Message {
5946
+ /** Message header with signature requirements */
5947
+ header;
5948
+ /** All account public keys referenced in the transaction */
5949
+ accountKeys;
5950
+ /** Transaction valid from (milliseconds since Unix epoch) */
5951
+ validFrom;
5952
+ /** Compiled instructions with account indices */
5953
+ instructions;
5954
+ /** Cached serialized bytes */
5955
+ serializedCache;
5956
+ constructor(header, accountKeys, validFrom, instructions) {
5957
+ this.header = Object.freeze({ ...header });
5958
+ this.accountKeys = Object.freeze([...accountKeys]);
5959
+ this.validFrom = validFrom;
5960
+ this.instructions = Object.freeze(
5961
+ instructions.map((ix) => Object.freeze({ ...ix }))
6063
5962
  );
6064
5963
  }
6065
- static fromRpcCode(rpcCode, message, details) {
6066
- const codeMap = {
6067
- [-32700]: "PARSE_ERROR" /* PARSE_ERROR */,
6068
- [-32600]: "INVALID_REQUEST" /* INVALID_REQUEST */,
6069
- [-32601]: "METHOD_NOT_FOUND" /* METHOD_NOT_FOUND */,
6070
- [-32602]: "INVALID_PARAMS" /* INVALID_PARAMS */,
6071
- [-32603]: "INTERNAL_ERROR" /* INTERNAL_ERROR */,
6072
- [429]: "RATE_LIMIT_EXCEEDED" /* RATE_LIMIT_EXCEEDED */
6073
- };
6074
- const code = codeMap[rpcCode] || "INTERNAL_ERROR" /* INTERNAL_ERROR */;
6075
- const retryable = rpcCode === 429 || rpcCode === -32603;
6076
- return new _RpcError(code, message, { ...details, rpcCode }, retryable);
6077
- }
6078
- toJSON() {
6079
- return {
6080
- code: this.code,
6081
- message: this.message,
6082
- details: this.details,
6083
- retryable: this.retryable
6084
- };
6085
- }
6086
- };
6087
-
6088
- // src/rpc/clients/base-client.ts
6089
- var BaseRpcClient = class {
6090
- transport;
6091
- requestId = 1;
6092
- constructor(transport) {
6093
- this.transport = transport;
5964
+ /**
5965
+ * Serialize message to bytes for signing.
5966
+ * Result is cached for performance.
5967
+ */
5968
+ serialize() {
5969
+ if (!this.serializedCache) {
5970
+ this.serializedCache = this.serializeInternal();
5971
+ }
5972
+ return new Uint8Array(this.serializedCache);
6094
5973
  }
6095
5974
  /**
6096
- * Makes a JSON-RPC 2.0 method call with type safety.
5975
+ * Deserialize a message from wire format.
6097
5976
  *
6098
- * Handles request serialization, response validation, and error mapping.
5977
+ * @param data - Serialized message bytes
5978
+ * @returns Deserialized Message
6099
5979
  */
6100
- async call(method, params = []) {
6101
- const requestId = this.requestId++;
6102
- const request = {
6103
- jsonrpc: "2.0",
6104
- id: requestId,
6105
- method,
6106
- params
5980
+ static deserialize(data) {
5981
+ if (data.length < 3) {
5982
+ throw new TransactionError(
5983
+ "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
5984
+ "Insufficient data for message header"
5985
+ );
5986
+ }
5987
+ let cursor = 0;
5988
+ const header = {
5989
+ numRequiredSignatures: data[cursor++],
5990
+ numReadonlySignedAccounts: data[cursor++],
5991
+ numReadonlyUnsignedAccounts: data[cursor++]
6107
5992
  };
6108
- const requestBody = JSON.stringify(request);
6109
- const requestDetails = { method, params, requestId };
6110
- const data = await this.transport.request(requestBody, requestDetails);
6111
- if (!this.isValidJsonRpcResponse(data)) {
6112
- throw RpcError.invalidResponse({
6113
- ...requestDetails,
6114
- response: data
6115
- });
5993
+ const [accountKeysLength, newCursor1] = deserializeCompactU162(data, cursor);
5994
+ cursor = newCursor1;
5995
+ const accountKeys = [];
5996
+ for (let i = 0; i < accountKeysLength; i++) {
5997
+ if (data.length < cursor + 32) {
5998
+ throw new TransactionError(
5999
+ "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6000
+ `Insufficient data for account key ${i}`
6001
+ );
6002
+ }
6003
+ const keyBytes = data.slice(cursor, cursor + 32);
6004
+ accountKeys.push(PublicKey.fromBytes(keyBytes));
6005
+ cursor += 32;
6006
+ }
6007
+ if (data.length < cursor + 8) {
6008
+ throw new TransactionError(
6009
+ "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6010
+ "Insufficient data for validFrom"
6011
+ );
6116
6012
  }
6117
- const response = data;
6118
- if (response.error) {
6119
- throw RpcError.fromRpcCode(response.error.code, response.error.message, {
6120
- ...requestDetails,
6121
- rpcData: response.error.data
6013
+ const validFromBytes = data.slice(cursor, cursor + 8);
6014
+ const validFrom = BigInt.asUintN(64, new DataView(validFromBytes.buffer).getBigUint64(0));
6015
+ cursor += 8;
6016
+ const [instructionsLength, newCursor2] = deserializeCompactU162(
6017
+ data,
6018
+ cursor
6019
+ );
6020
+ cursor = newCursor2;
6021
+ const instructions = [];
6022
+ for (let i = 0; i < instructionsLength; i++) {
6023
+ if (data.length < cursor + 1) {
6024
+ throw new TransactionError(
6025
+ "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6026
+ `Insufficient data for instruction ${i} program index`
6027
+ );
6028
+ }
6029
+ const programIdIndex = data[cursor++];
6030
+ const [accountIndexesLength, newCursor3] = deserializeCompactU162(
6031
+ data,
6032
+ cursor
6033
+ );
6034
+ cursor = newCursor3;
6035
+ const accountKeyIndexes = [];
6036
+ for (let j = 0; j < accountIndexesLength; j++) {
6037
+ if (data.length < cursor + 1) {
6038
+ throw new TransactionError(
6039
+ "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6040
+ `Insufficient data for instruction ${i} account index ${j}`
6041
+ );
6042
+ }
6043
+ accountKeyIndexes.push(data[cursor++]);
6044
+ }
6045
+ const [dataLength, newCursor4] = deserializeCompactU162(data, cursor);
6046
+ cursor = newCursor4;
6047
+ if (data.length < cursor + dataLength) {
6048
+ throw new TransactionError(
6049
+ "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6050
+ `Insufficient data for instruction ${i} data`
6051
+ );
6052
+ }
6053
+ const instructionData = data.slice(cursor, cursor + dataLength);
6054
+ cursor += dataLength;
6055
+ instructions.push({
6056
+ programIdIndex,
6057
+ accountKeyIndexes: Object.freeze(accountKeyIndexes),
6058
+ data: instructionData
6122
6059
  });
6123
6060
  }
6124
- if (!("result" in response)) {
6125
- throw RpcError.invalidResponse({
6126
- ...requestDetails,
6127
- response
6061
+ return new _Message(header, accountKeys, validFrom, instructions);
6062
+ }
6063
+ serializeInternal() {
6064
+ const buffer = [];
6065
+ buffer.push(this.header.numRequiredSignatures);
6066
+ buffer.push(this.header.numReadonlySignedAccounts);
6067
+ buffer.push(this.header.numReadonlyUnsignedAccounts);
6068
+ this.serializeCompactArray(buffer, this.accountKeys, (buf, key) => {
6069
+ buf.push(...key.toBytes());
6070
+ });
6071
+ const validFromBuffer = new ArrayBuffer(8);
6072
+ new DataView(validFromBuffer).setBigUint64(0, this.validFrom ?? BigInt(0));
6073
+ buffer.push(...new Uint8Array(validFromBuffer));
6074
+ this.serializeCompactArray(buffer, this.instructions, (buf, ix) => {
6075
+ buf.push(ix.programIdIndex);
6076
+ this.serializeCompactArray(buf, ix.accountKeyIndexes, (b, idx) => {
6077
+ b.push(idx);
6128
6078
  });
6129
- }
6130
- return response.result;
6079
+ this.serializeCompactArray(buf, Array.from(ix.data), (b, byte) => {
6080
+ b.push(byte);
6081
+ });
6082
+ });
6083
+ return new Uint8Array(buffer);
6131
6084
  }
6132
- /**
6133
- * Validate JSON-RPC response structure
6134
- */
6135
- isValidJsonRpcResponse(data) {
6136
- if (typeof data !== "object" || data === null) {
6137
- return false;
6085
+ serializeCompactArray(buffer, items, serializeItem) {
6086
+ this.serializeCompactU16(buffer, items.length);
6087
+ for (const item of items) {
6088
+ serializeItem(buffer, item);
6138
6089
  }
6139
- const response = data;
6140
- return response.jsonrpc === "2.0" && typeof response.id === "number" && ("result" in response || "error" in response);
6141
- }
6142
- /**
6143
- * Returns the configured RPC endpoint URL.
6144
- */
6145
- getUrl() {
6146
- return this.transport.getUrl();
6147
6090
  }
6148
- };
6149
-
6150
- // src/utils.ts
6151
- function toBase64(bytes) {
6152
- if (typeof btoa !== "undefined") {
6153
- const chunkSize = 8192;
6154
- let result = "";
6155
- for (let i = 0; i < bytes.length; i += chunkSize) {
6156
- const chunk = bytes.slice(i, i + chunkSize);
6157
- result += String.fromCharCode(...chunk);
6091
+ serializeCompactU16(buffer, value) {
6092
+ if (value < 0 || value > 65535) {
6093
+ throw new Error(`Value out of range for compact-u16: ${value}`);
6158
6094
  }
6159
- return btoa(result);
6160
- }
6161
- if (typeof Buffer !== "undefined") {
6162
- return Buffer.from(bytes).toString("base64");
6163
- }
6164
- throw new Error("No base64 encoding available in this environment");
6165
- }
6166
- function fromBase64(base64) {
6167
- if (typeof atob !== "undefined") {
6168
- const binary = atob(base64);
6169
- const bytes = new Uint8Array(binary.length);
6170
- for (let i = 0; i < binary.length; i++) {
6171
- bytes[i] = binary.charCodeAt(i);
6095
+ if (value <= 127) {
6096
+ buffer.push(value);
6097
+ return;
6172
6098
  }
6173
- return bytes;
6174
- }
6175
- if (typeof Buffer !== "undefined") {
6176
- return new Uint8Array(Buffer.from(base64, "base64"));
6099
+ if (value <= 16383) {
6100
+ buffer.push(value & 127 | 128);
6101
+ buffer.push(value >> 7 & 127);
6102
+ return;
6103
+ }
6104
+ buffer.push(value & 127 | 128);
6105
+ buffer.push(value >> 7 & 127 | 128);
6106
+ buffer.push(value >> 14 & 255);
6177
6107
  }
6178
- throw new Error("No base64 decoding available in this environment");
6179
- }
6180
- function sleep(ms) {
6181
- return new Promise((resolve) => setTimeout(resolve, ms));
6182
- }
6183
- function calculateBackoff(attempt, baseMs = 1e3, maxMs = 3e4) {
6184
- const exponentialDelay = baseMs * 2 ** attempt;
6185
- const jitter = Math.random() * 0.3 * exponentialDelay;
6186
- return Math.min(exponentialDelay + jitter, maxMs);
6187
- }
6188
- function getDevnetUrl() {
6189
- return URL_DEVNET;
6190
- }
6191
- function getTestnetUrl() {
6192
- return URL_TESTNET;
6193
- }
6194
- function getMainnetUrl() {
6195
- return URL_MAINNET;
6196
- }
6197
- function getLocalnetUrl() {
6198
- return URL_LOCALNET;
6199
- }
6200
-
6201
- // src/rpc/clients/query-client.ts
6202
- var QueryRpcClient = class extends BaseRpcClient {
6203
6108
  /**
6204
- * Get the latest blockhash from the blockchain
6109
+ * Get all signers required for this message.
6205
6110
  */
6206
- async getLatestBlockhash() {
6207
- const result = await this.call(
6208
- "getLatestBlockhash",
6209
- []
6210
- );
6211
- return Blockhash.fromString(result.value.blockhash);
6111
+ getSigners() {
6112
+ return this.accountKeys.slice(0, this.header.numRequiredSignatures);
6212
6113
  }
6213
6114
  /**
6214
- * Get the balance of an account
6115
+ * Check if a public key is a required signer.
6215
6116
  */
6216
- async getBalance(pubkey) {
6217
- const result = await this.call("getBalance", [
6218
- { address: pubkey.toString() }
6219
- ]);
6220
- return BigInt(result.value);
6117
+ isSignerRequired(pubkey) {
6118
+ return this.getSigners().some((signer) => signer.equals(pubkey));
6221
6119
  }
6222
6120
  /**
6223
- * Get detailed information about an account
6121
+ * Get the index of a signer in the signers array.
6122
+ * Returns -1 if not a signer.
6224
6123
  */
6225
- async getAccountInfo(pubkey) {
6226
- const result = await this.call("getAccountInfo", [{ address: pubkey.toString(), encoding: "base64" }]);
6227
- if (!result.value) {
6228
- return null;
6229
- }
6230
- return {
6231
- balance: BigInt(result.value.balance),
6232
- owner: PublicKey.fromString(result.value.owner),
6233
- data: fromBase64(result.value.data),
6234
- executable: result.value.executable,
6235
- rentEpoch: BigInt(result.value.rentEpoch)
6236
- };
6124
+ getSignerIndex(pubkey) {
6125
+ return this.getSigners().findIndex((signer) => signer.equals(pubkey));
6237
6126
  }
6238
- /**
6239
- * Get the current block height
6240
- */
6241
- async getBlockHeight() {
6242
- const result = await this.call("getBlockHeight", []);
6243
- return BigInt(result);
6127
+ };
6128
+ function deserializeCompactU162(data, currentCursor) {
6129
+ let cursor = currentCursor;
6130
+ if (cursor >= data.length) {
6131
+ throw new TransactionError(
6132
+ "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6133
+ "Insufficient data for compact-u16"
6134
+ );
6244
6135
  }
6245
- /**
6246
- * Get detailed information about a transaction
6247
- */
6248
- async getTransaction(signature) {
6249
- const result = await this.call("getTransaction", [signature]);
6250
- if (!result) {
6251
- return null;
6136
+ const firstByte = data[cursor++];
6137
+ if ((firstByte & 128) === 0) {
6138
+ return [firstByte, cursor];
6139
+ }
6140
+ if (cursor >= data.length) {
6141
+ throw new TransactionError(
6142
+ "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6143
+ "Incomplete compact-u16 encoding"
6144
+ );
6145
+ }
6146
+ const secondByte = data[cursor++];
6147
+ if ((secondByte & 128) === 0) {
6148
+ return [firstByte & 127 | secondByte << 7, cursor];
6149
+ }
6150
+ if (cursor >= data.length) {
6151
+ throw new TransactionError(
6152
+ "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6153
+ "Incomplete compact-u16 encoding"
6154
+ );
6155
+ }
6156
+ const thirdByte = data[cursor++];
6157
+ const value = firstByte & 127 | (secondByte & 127) << 7 | thirdByte << 14;
6158
+ return [value, cursor];
6159
+ }
6160
+
6161
+ // src/transaction/transaction.ts
6162
+ var Transaction = class _Transaction {
6163
+ /** The unsigned message */
6164
+ message;
6165
+ /** Signatures (64 bytes each), aligned with message.header.numRequiredSignatures */
6166
+ signatures;
6167
+ // Private constructor - use static factories
6168
+ constructor(message, signatures) {
6169
+ this.message = message;
6170
+ this.signatures = signatures.map((sig) => new Uint8Array(sig));
6171
+ if (signatures.length !== message.header.numRequiredSignatures) {
6172
+ throw new TransactionError(
6173
+ "INVALID_SIGNATURE" /* INVALID_SIGNATURE */,
6174
+ `Signature count (${signatures.length}) doesn't match required signers (${message.header.numRequiredSignatures})`
6175
+ );
6252
6176
  }
6253
- return {
6254
- signature,
6255
- slot: BigInt(result.slot),
6256
- blockTime: result.blockTime ? BigInt(result.blockTime) : void 0,
6257
- err: result.err
6258
- };
6259
6177
  }
6260
6178
  /**
6261
- * Get the total number of transactions processed since genesis
6179
+ * Create an unsigned transaction from a message.
6180
+ * All signature slots are initialized to zero.
6181
+ *
6182
+ * @internal - Users should use TransactionBuilder instead
6262
6183
  */
6263
- async getTransactionCount() {
6264
- const result = await this.call("getTransactionCount", []);
6265
- return BigInt(result);
6184
+ static fromMessage(message) {
6185
+ const numSignatures = message.header.numRequiredSignatures;
6186
+ const signatures = Array.from(
6187
+ { length: numSignatures },
6188
+ () => new Uint8Array(SIGNATURE_LENGTH)
6189
+ );
6190
+ return new _Transaction(message, signatures);
6266
6191
  }
6267
6192
  /**
6268
- * Get the status of multiple transaction signatures
6193
+ * Create transaction from message and existing signatures.
6194
+ * @internal
6269
6195
  */
6270
- async getSignatureStatuses(signatures) {
6271
- const result = await this.call("getSignatureStatuses", [signatures]);
6272
- return result.value.map((status) => {
6273
- if (!status) {
6274
- return null;
6196
+ static fromMessageAndSignatures(message, signatures) {
6197
+ return new _Transaction(message, signatures);
6198
+ }
6199
+ /**
6200
+ * Deserialize a transaction from wire format.
6201
+ */
6202
+ static deserialize(data) {
6203
+ if (data.length === 0) {
6204
+ throw new TransactionError(
6205
+ "SERIALIZATION_FAILED" /* SERIALIZATION_FAILED */,
6206
+ "Cannot deserialize empty transaction data"
6207
+ );
6208
+ }
6209
+ let cursor = 0;
6210
+ const [signaturesLength, newCursor] = deserializeCompactU16(data, cursor);
6211
+ cursor = newCursor;
6212
+ const signatures = [];
6213
+ for (let i = 0; i < signaturesLength; i++) {
6214
+ if (data.length < cursor + SIGNATURE_LENGTH) {
6215
+ throw new TransactionError(
6216
+ "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6217
+ `Insufficient data for signature ${i}: need ${SIGNATURE_LENGTH} bytes at offset ${cursor}`
6218
+ );
6275
6219
  }
6276
- return {
6277
- slot: BigInt(status.slot),
6278
- confirmations: status.confirmations,
6279
- err: status.err
6280
- };
6281
- });
6220
+ const signature = data.slice(cursor, cursor + SIGNATURE_LENGTH);
6221
+ signatures.push(signature);
6222
+ cursor += SIGNATURE_LENGTH;
6223
+ }
6224
+ if (cursor >= data.length) {
6225
+ throw new TransactionError(
6226
+ "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6227
+ "No message data found after signatures"
6228
+ );
6229
+ }
6230
+ const messageBytes = data.slice(cursor);
6231
+ const message = Message.deserialize(messageBytes);
6232
+ return new _Transaction(message, signatures);
6233
+ }
6234
+ getMessage() {
6235
+ return this.message;
6282
6236
  }
6283
6237
  /**
6284
- * Get epoch information
6238
+ * Sign the transaction with a keypair.
6239
+ * Returns a NEW Transaction instance.
6240
+ *
6241
+ * @param keypair - Keypair to sign with
6242
+ * @returns New Transaction instance with signature added
6243
+ *
6244
+ * @example
6245
+ * ```typescript
6246
+ * const signedTx = tx.sign(keypair);
6247
+ * await client.sendTransaction(signedTx.serialize());
6248
+ * ```
6285
6249
  */
6286
- async getEpochInfo() {
6287
- const result = await this.call("getEpochInfo", []);
6288
- return {
6289
- epoch: BigInt(result.epoch),
6290
- slotIndex: BigInt(result.slotIndex),
6291
- slotsInEpoch: BigInt(result.slotsInEpoch),
6292
- absoluteSlot: BigInt(result.absoluteSlot),
6293
- blockHeight: BigInt(result.blockHeight),
6294
- transactionCount: result.transactionCount ? BigInt(result.transactionCount) : void 0
6295
- };
6250
+ sign(keypair) {
6251
+ const messageBytes = this.message.serialize();
6252
+ const signature = keypair.sign(messageBytes);
6253
+ return this.addSignatureForPubkey(keypair.publicKey, signature);
6296
6254
  }
6297
6255
  /**
6298
- * Get the health status of the node
6256
+ * Sign with multiple keypairs at once.
6257
+ * Returns a NEW Transaction instance.
6258
+ *
6259
+ * @example
6260
+ * ```typescript
6261
+ * const signed = tx.signAll([keypair1, keypair2, keypair3]);
6262
+ * ```
6299
6263
  */
6300
- async getHealth() {
6301
- const result = await this.call("getHealth", []);
6264
+ signAll(keypairs) {
6265
+ let result = this;
6266
+ for (const keypair of keypairs) {
6267
+ result = result.sign(keypair);
6268
+ }
6302
6269
  return result;
6303
6270
  }
6304
- };
6305
-
6306
- // src/rpc/clients/transaction-client.ts
6307
- var TransactionRpcClient = class extends BaseRpcClient {
6308
6271
  /**
6309
- * Submit a signed transaction to the blockchain
6272
+ * Sign the transaction with a Signer interface (async).
6273
+ * Returns a NEW Transaction instance.
6274
+ *
6275
+ * @example
6276
+ * ```typescript
6277
+ * const signedTx = await tx.signWith(browserWallet);
6278
+ * ```
6310
6279
  */
6311
- async sendTransaction(transaction, options) {
6312
- const base64Tx = toBase64(transaction);
6313
- const config = {
6314
- encoding: "base64",
6315
- skipPreflight: options?.skipPreflight ?? false,
6316
- maxRetries: options?.maxRetries ?? 5
6317
- };
6318
- const signature = await this.call("sendTransaction", [
6319
- base64Tx,
6320
- config
6321
- ]);
6322
- return signature;
6280
+ async signWith(signer) {
6281
+ const pubkey = await signer.getPublicKey();
6282
+ const messageBytes = this.message.serialize();
6283
+ const signature = await signer.signMessage(messageBytes);
6284
+ return this.addSignatureForPubkey(pubkey, signature);
6323
6285
  }
6324
6286
  /**
6325
- * Request an airdrop of tokens to an account (devnet/testnet only)
6287
+ * Sign with multiple signers.
6288
+ * Returns a NEW Transaction instance.
6326
6289
  */
6327
- async requestAirdrop(pubkey, amount) {
6328
- const signature = await this.call("requestAirdrop", [
6329
- pubkey.toString(),
6330
- Number(amount)
6331
- ]);
6332
- return signature;
6333
- }
6334
- };
6335
-
6336
- // src/rpc/clients/client.ts
6337
- var RialoClient = class {
6338
- queryClient;
6339
- transactionClient;
6340
- transport;
6341
- constructor(transport) {
6342
- this.transport = transport;
6343
- this.queryClient = new QueryRpcClient(transport);
6344
- this.transactionClient = new TransactionRpcClient(transport);
6290
+ async signAllWith(signers) {
6291
+ let result = this;
6292
+ for (const signer of signers) {
6293
+ result = await result.signWith(signer);
6294
+ }
6295
+ return result;
6345
6296
  }
6346
6297
  /**
6347
- * Returns the configured RPC endpoint URL.
6298
+ * Partially sign the transaction (for multi-sig transactions).
6299
+ * Returns a NEW Transaction instance.
6300
+ *
6301
+ * @example
6302
+ * ```typescript
6303
+ * const signedTx = tx
6304
+ * .partialSign(signer1)
6305
+ * .partialSign(signer2);
6306
+ * ```
6348
6307
  */
6349
- getUrl() {
6350
- return this.transport.getUrl();
6308
+ partialSign(keypair) {
6309
+ return this.sign(keypair);
6351
6310
  }
6352
6311
  /**
6353
- * Retrieves the latest blockhash from the blockchain.
6354
- *
6355
- * Required for transaction creation and replay protection.
6312
+ * Partially sign with a Signer interface (async).
6313
+ * Returns a NEW Transaction instance.
6356
6314
  */
6357
- async getLatestBlockhash() {
6358
- return await this.queryClient.getLatestBlockhash();
6315
+ async partialSignWith(signer) {
6316
+ return this.signWith(signer);
6359
6317
  }
6360
6318
  /**
6361
- * Retrieves the balance of an account in kelvins (smallest unit).
6319
+ * Add a signature at a specific index.
6320
+ * Returns a NEW Transaction instance.
6321
+ *
6322
+ * Most users should use sign() or signAll() instead.
6362
6323
  */
6363
- async getBalance(pubkey) {
6364
- return await this.queryClient.getBalance(pubkey);
6324
+ addSignature(index, signature) {
6325
+ if (index < 0 || index >= this.signatures.length) {
6326
+ throw new TransactionError(
6327
+ "SIGNATURE_OUT_OF_BOUNDS" /* SIGNATURE_OUT_OF_BOUNDS */,
6328
+ `Signature index ${index} out of bounds (must be 0-${this.signatures.length - 1})`
6329
+ );
6330
+ }
6331
+ const sigBytes = signature instanceof Uint8Array ? signature : signature.toBytes();
6332
+ if (sigBytes.length !== SIGNATURE_LENGTH) {
6333
+ throw new TransactionError(
6334
+ "INVALID_SIGNATURE" /* INVALID_SIGNATURE */,
6335
+ `Signature must be ${SIGNATURE_LENGTH} bytes, got ${sigBytes.length}`
6336
+ );
6337
+ }
6338
+ const newSignatures = this.signatures.map(
6339
+ (sig, i) => i === index ? new Uint8Array(sigBytes) : new Uint8Array(sig)
6340
+ );
6341
+ return new _Transaction(this.message, newSignatures);
6365
6342
  }
6366
6343
  /**
6367
- * Retrieves detailed information about an account.
6344
+ * Add a signature for a specific public key.
6345
+ * Returns a NEW Transaction instance.
6368
6346
  *
6369
- * @returns Account info or null if account doesn't exist
6347
+ * Most users should use sign() or signAll() instead.
6370
6348
  */
6371
- async getAccountInfo(pubkey) {
6372
- return await this.queryClient.getAccountInfo(pubkey);
6349
+ addSignatureForPubkey(pubkey, signature) {
6350
+ const signerIndex = this.message.getSignerIndex(pubkey);
6351
+ if (signerIndex === -1) {
6352
+ throw TransactionError.signerNotFound(pubkey.toString());
6353
+ }
6354
+ return this.addSignature(signerIndex, signature);
6373
6355
  }
6374
6356
  /**
6375
- * Retrieves the current block height.
6357
+ * Check if transaction is fully signed (all signatures present).
6376
6358
  */
6377
- async getBlockHeight() {
6378
- return await this.queryClient.getBlockHeight();
6359
+ isSigned() {
6360
+ return this.signatures.every((sig) => sig.some((byte) => byte !== 0));
6379
6361
  }
6380
6362
  /**
6381
- * Retrieves detailed information about a transaction.
6382
- *
6383
- * @returns Transaction info or null if transaction not found
6363
+ * Check if a specific signature slot is filled.
6384
6364
  */
6385
- async getTransaction(signature) {
6386
- return await this.queryClient.getTransaction(signature);
6365
+ isSignaturePresent(index) {
6366
+ if (index < 0 || index >= this.signatures.length) {
6367
+ return false;
6368
+ }
6369
+ return this.signatures[index].some((byte) => byte !== 0);
6387
6370
  }
6388
6371
  /**
6389
- * Retrieves the total number of transactions processed since genesis.
6372
+ * Get all signatures (returns copies to prevent mutation).
6390
6373
  */
6391
- async getTransactionCount() {
6392
- return await this.queryClient.getTransactionCount();
6374
+ getSignatures() {
6375
+ return this.signatures.map((sig) => new Uint8Array(sig));
6393
6376
  }
6394
6377
  /**
6395
- * Retrieves the status of multiple transaction signatures.
6378
+ * Get a specific signature (returns copy).
6396
6379
  */
6397
- async getSignatureStatuses(signatures) {
6398
- return await this.queryClient.getSignatureStatuses(signatures);
6380
+ getSignature(index) {
6381
+ if (index < 0 || index >= this.signatures.length) {
6382
+ throw new TransactionError(
6383
+ "SIGNATURE_OUT_OF_BOUNDS" /* SIGNATURE_OUT_OF_BOUNDS */,
6384
+ `Signature index ${index} out of bounds`
6385
+ );
6386
+ }
6387
+ return new Uint8Array(this.signatures[index]);
6399
6388
  }
6400
6389
  /**
6401
- * Retrieves current epoch information.
6390
+ * Get a specific signature for a public key.
6402
6391
  */
6403
- async getEpochInfo() {
6404
- return await this.queryClient.getEpochInfo();
6392
+ getSignatureForPubkey(pubkey) {
6393
+ const signerIndex = this.message.getSignerIndex(pubkey);
6394
+ if (signerIndex === -1) {
6395
+ throw TransactionError.signerNotFound(pubkey.toString());
6396
+ }
6397
+ return this.getSignature(signerIndex);
6405
6398
  }
6406
6399
  /**
6407
- * Checks the health status of the RPC node.
6408
- *
6409
- * @returns "ok" if healthy, error message otherwise
6400
+ * Get required signers for this transaction.
6410
6401
  */
6411
- async getHealth() {
6412
- return await this.queryClient.getHealth();
6402
+ getSigners() {
6403
+ return this.message.getSigners();
6413
6404
  }
6414
6405
  /**
6415
- * Submits a signed transaction to the blockchain.
6416
- *
6417
- * @param transaction - Serialized signed transaction bytes
6418
- * @param options - Transaction submission options
6419
- * @returns Transaction signature
6406
+ * Get the number of required signatures.
6420
6407
  */
6421
- async sendTransaction(transaction, options) {
6422
- return await this.transactionClient.sendTransaction(transaction, options);
6408
+ getRequiredSignatureCount() {
6409
+ return this.message.header.numRequiredSignatures;
6423
6410
  }
6424
6411
  /**
6425
- * Requests an airdrop of tokens to an account.
6412
+ * Throw an error if the transaction is not fully signed.
6426
6413
  *
6427
- * **Note**: Only available on devnet and testnet.
6414
+ * @throws {TransactionError} If transaction is not fully signed
6428
6415
  *
6429
- * @param pubkey - Account to receive the airdrop
6430
- * @param amount - Amount in kelvins (smallest unit)
6431
- * @returns Transaction signature
6416
+ * @example
6417
+ * ```typescript
6418
+ * signedTx.ensureSigned(); // Throws if not signed
6419
+ * await client.sendTransaction(signedTx.serialize());
6420
+ * ```
6432
6421
  */
6433
- async requestAirdrop(pubkey, amount) {
6434
- return await this.transactionClient.requestAirdrop(pubkey, amount);
6422
+ ensureSigned() {
6423
+ if (!this.isSigned()) {
6424
+ const missingIndices = this.signatures.map((sig, i) => ({ sig, i })).filter(({ sig }) => !sig.some((byte) => byte !== 0)).map(({ i }) => i);
6425
+ const signers = this.getSigners();
6426
+ const missingSigners = missingIndices.map((i) => signers[i].toString());
6427
+ throw new TransactionError(
6428
+ "MISSING_SIGNATURE" /* MISSING_SIGNATURE */,
6429
+ `Transaction is not fully signed. Missing signatures for: ${missingSigners.join(", ")}`,
6430
+ { missingIndices, missingSigners }
6431
+ );
6432
+ }
6433
+ }
6434
+ /**
6435
+ * Serialize transaction to wire format.
6436
+ */
6437
+ serialize() {
6438
+ const compactU16Size = this.signatures.length < 128 ? 1 : 2;
6439
+ const sigsSize = compactU16Size + this.signatures.length * SIGNATURE_LENGTH;
6440
+ const messageBytes = this.message.serialize();
6441
+ const totalSize = sigsSize + messageBytes.length;
6442
+ const buffer = new Uint8Array(totalSize);
6443
+ let offset = 0;
6444
+ offset = writeCompactU16(buffer, offset, this.signatures.length);
6445
+ for (const sig of this.signatures) {
6446
+ buffer.set(sig, offset);
6447
+ offset += SIGNATURE_LENGTH;
6448
+ }
6449
+ buffer.set(messageBytes, offset);
6450
+ return buffer;
6435
6451
  }
6436
6452
  };
6437
6453
 
6438
- // src/rpc/http-transport.ts
6439
- var DEFAULT_CONFIG = {
6440
- timeout: 3e4,
6441
- // 30 seconds
6442
- maxRetries: 3,
6443
- retryBaseDelay: 1e3,
6444
- // 1 second
6445
- retryMaxDelay: 3e4,
6446
- // 30 seconds
6447
- headers: {}
6448
- };
6449
- var HttpTransport = class {
6450
- url;
6451
- config;
6452
- constructor(url, config = {}) {
6453
- this.url = url;
6454
- this.config = { ...DEFAULT_CONFIG, ...config };
6454
+ // src/transaction/transaction-builder.ts
6455
+ var TransactionBuilder = class _TransactionBuilder {
6456
+ payer;
6457
+ validFrom;
6458
+ instructions = [];
6459
+ constructor() {
6455
6460
  }
6456
6461
  /**
6457
- * Makes an HTTP request with automatic retry logic.
6458
- *
6459
- * Retries are attempted for network errors and server errors (5xx).
6460
- * Uses exponential backoff between retry attempts.
6462
+ * Create a new transaction builder.
6461
6463
  */
6462
- async request(body, requestDetails = {}) {
6463
- let lastError;
6464
- for (let attempt = 0; attempt <= this.config.maxRetries; attempt++) {
6465
- try {
6466
- return await this.makeRequest(body, requestDetails, attempt);
6467
- } catch (error) {
6468
- lastError = error;
6469
- if (error instanceof RpcError && !error.retryable) {
6470
- throw error;
6471
- }
6472
- if (attempt === this.config.maxRetries) {
6473
- throw error;
6474
- }
6475
- const delay = calculateBackoff(
6476
- attempt,
6477
- this.config.retryBaseDelay,
6478
- this.config.retryMaxDelay
6479
- );
6480
- await sleep(delay);
6481
- }
6482
- }
6483
- throw lastError;
6464
+ static create() {
6465
+ return new _TransactionBuilder();
6484
6466
  }
6485
6467
  /**
6486
- * Make a single HTTP request with timeout
6468
+ * Set the fee payer for this transaction.
6469
+ *
6470
+ * The payer will be the first account and must sign the transaction.
6471
+ * The payer pays for transaction fees.
6472
+ *
6473
+ * @param payer - Public key of the fee payer
6487
6474
  */
6488
- async makeRequest(body, requestDetails, attempt) {
6489
- const controller = new AbortController();
6490
- const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
6491
- try {
6492
- const options = {
6493
- method: "POST",
6494
- headers: {
6495
- "Content-Type": "application/json",
6496
- ...this.config.headers
6497
- },
6498
- body,
6499
- signal: controller.signal
6500
- };
6501
- const response = await fetch(this.url, options);
6502
- if (!response.ok) {
6503
- throw await this.handleHttpError(response, requestDetails, attempt);
6504
- }
6505
- const data = await response.json();
6506
- return data;
6507
- } catch (error) {
6508
- if (error instanceof Error && error.name === "AbortError") {
6509
- throw RpcError.requestTimeout(this.config.timeout, {
6510
- ...requestDetails,
6511
- url: this.url,
6512
- attempts: attempt + 1
6513
- });
6514
- }
6515
- if (error instanceof TypeError) {
6516
- throw RpcError.networkError(error.message, {
6517
- ...requestDetails,
6518
- url: this.url,
6519
- attempts: attempt + 1,
6520
- cause: error.message
6521
- });
6522
- }
6523
- if (error instanceof RpcError) {
6524
- throw error;
6525
- }
6526
- throw RpcError.networkError("Unknown network error", {
6527
- ...requestDetails,
6528
- url: this.url,
6529
- attempts: attempt + 1,
6530
- cause: error instanceof Error ? error.message : String(error)
6531
- });
6532
- } finally {
6533
- clearTimeout(timeoutId);
6534
- }
6475
+ setPayer(payer) {
6476
+ this.payer = payer;
6477
+ return this;
6535
6478
  }
6536
6479
  /**
6537
- * Handle HTTP error responses
6480
+ * Set the Transaction valid from.
6481
+ *
6482
+ * This is the time the transaction is valid from, in milliseconds since Unix epoch.
6483
+ * It can be used for additional replay protection or auditing.
6484
+ *
6485
+ * @param validFrom - Transaction valid from in milliseconds since Unix epoch
6538
6486
  */
6539
- async handleHttpError(response, requestDetails, attempt) {
6540
- const status = response.status;
6541
- if (status === 429) {
6542
- return RpcError.rateLimitExceeded({
6543
- ...requestDetails,
6544
- httpStatus: status,
6545
- url: this.url,
6546
- attempts: attempt + 1
6547
- });
6548
- }
6549
- if (status >= 500) {
6550
- return RpcError.networkError(`Server error: ${status}`, {
6551
- ...requestDetails,
6552
- httpStatus: status,
6553
- url: this.url,
6554
- attempts: attempt + 1
6555
- });
6556
- }
6557
- let message = `HTTP ${status}: ${response.statusText}`;
6558
- try {
6559
- const errorData = await response.json();
6560
- if (errorData && typeof errorData === "object" && "message" in errorData) {
6561
- message = String(errorData.message);
6562
- }
6563
- } catch {
6564
- }
6565
- return new RpcError(
6566
- "NETWORK_ERROR" /* NETWORK_ERROR */,
6567
- message,
6568
- {
6569
- ...requestDetails,
6570
- httpStatus: status,
6571
- url: this.url,
6572
- attempts: attempt + 1
6573
- },
6574
- false
6575
- // 4xx errors are not retryable
6576
- );
6487
+ setValidFrom(validFrom) {
6488
+ this.validFrom = validFrom;
6489
+ return this;
6577
6490
  }
6578
6491
  /**
6579
- * Returns the configured RPC endpoint URL.
6492
+ * Add an instruction to the transaction.
6493
+ *
6494
+ * @param instruction - Instruction to add
6580
6495
  */
6581
- getUrl() {
6582
- return this.url;
6583
- }
6584
- };
6585
-
6586
- // src/rpc/index.ts
6587
- function createRialoClient(url, config) {
6588
- const transport = new HttpTransport(url, config);
6589
- return new RialoClient(transport);
6590
- }
6591
-
6592
- // src/transaction/message.ts
6593
- var Message = class _Message {
6594
- /** Message header with signature requirements */
6595
- header;
6596
- /** All account public keys referenced in the transaction */
6597
- accountKeys;
6598
- /** Recent blockhash for replay protection */
6599
- recentBlockhash;
6600
- /** Transaction creation timestamp (milliseconds since Unix epoch) */
6601
- txCreationTime;
6602
- /** Compiled instructions with account indices */
6603
- instructions;
6604
- /** Cached serialized bytes */
6605
- serializedCache;
6606
- constructor(header, accountKeys, recentBlockhash, txCreationTime, instructions) {
6607
- this.header = Object.freeze({ ...header });
6608
- this.accountKeys = Object.freeze([...accountKeys]);
6609
- this.recentBlockhash = recentBlockhash;
6610
- this.txCreationTime = txCreationTime;
6611
- this.instructions = Object.freeze(
6612
- instructions.map((ix) => Object.freeze({ ...ix }))
6613
- );
6496
+ addInstruction(instruction) {
6497
+ this.instructions.push(instruction);
6498
+ return this;
6614
6499
  }
6615
6500
  /**
6616
- * Serialize message to bytes for signing.
6617
- * Result is cached for performance.
6501
+ * Add multiple instructions at once.
6502
+ *
6503
+ * @param instructions - Array of instructions to add
6618
6504
  */
6619
- serialize() {
6620
- if (!this.serializedCache) {
6621
- this.serializedCache = this.serializeInternal();
6622
- }
6623
- return new Uint8Array(this.serializedCache);
6505
+ addInstructions(instructions) {
6506
+ this.instructions.push(...instructions);
6507
+ return this;
6624
6508
  }
6625
6509
  /**
6626
- * Deserialize a message from wire format.
6510
+ * Build the transaction (unsigned).
6627
6511
  *
6628
- * @param data - Serialized message bytes
6629
- * @returns Deserialized Message
6512
+ * Returns an unsigned Transaction that's ready to be signed.
6513
+ *
6514
+ * @returns Unsigned Transaction
6515
+ * @throws {TransactionError} If payer, valid_from, or instructions are missing
6516
+ *
6517
+ * @example
6518
+ * ```typescript
6519
+ * const tx = builder.build();
6520
+ * const signedTx = tx.sign(keypair);
6521
+ * ```
6630
6522
  */
6631
- static deserialize(data) {
6632
- if (data.length < 3) {
6523
+ build() {
6524
+ if (!this.payer) {
6633
6525
  throw new TransactionError(
6634
- "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6635
- "Insufficient data for message header"
6526
+ "INVALID_ACCOUNT_META" /* INVALID_ACCOUNT_META */,
6527
+ "Transaction must have a fee payer. Use setPayer() to set the fee payer."
6636
6528
  );
6637
6529
  }
6638
- let cursor = 0;
6639
- const header = {
6640
- numRequiredSignatures: data[cursor++],
6641
- numReadonlySignedAccounts: data[cursor++],
6642
- numReadonlyUnsignedAccounts: data[cursor++]
6643
- };
6644
- const [accountKeysLength, newCursor1] = deserializeCompactU162(data, cursor);
6645
- cursor = newCursor1;
6646
- const accountKeys = [];
6647
- for (let i = 0; i < accountKeysLength; i++) {
6648
- if (data.length < cursor + 32) {
6649
- throw new TransactionError(
6650
- "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6651
- `Insufficient data for account key ${i}`
6652
- );
6653
- }
6654
- const keyBytes = data.slice(cursor, cursor + 32);
6655
- accountKeys.push(PublicKey.fromBytes(keyBytes));
6656
- cursor += 32;
6657
- }
6658
- if (data.length < cursor + 32) {
6530
+ if (!this.validFrom) {
6659
6531
  throw new TransactionError(
6660
- "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6661
- "Insufficient data for blockhash"
6532
+ "INVALID_MESSAGE_FORMAT" /* INVALID_MESSAGE_FORMAT */,
6533
+ "Transaction must have a valid from. Use setValidFrom() to set the valid from."
6662
6534
  );
6663
6535
  }
6664
- const recentBlockhash = Blockhash.fromBytes(
6665
- data.slice(cursor, cursor + 32)
6666
- );
6667
- cursor += 32;
6668
- if (data.length < cursor + 8) {
6669
- throw new TransactionError(
6670
- "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6671
- "Insufficient data for TxCreationTime"
6672
- );
6536
+ if (this.instructions.length === 0) {
6537
+ throw TransactionError.noInstructions();
6673
6538
  }
6674
- const txCreationTimeBytes = data.slice(cursor, cursor + 8);
6675
- const txCreationTime = BigInt.asUintN(64, new DataView(txCreationTimeBytes.buffer).getBigUint64(0));
6676
- cursor += 8;
6677
- const [instructionsLength, newCursor2] = deserializeCompactU162(
6678
- data,
6679
- cursor
6680
- );
6681
- cursor = newCursor2;
6682
- const instructions = [];
6683
- for (let i = 0; i < instructionsLength; i++) {
6684
- if (data.length < cursor + 1) {
6539
+ const accountTable = new AccountMetaTable();
6540
+ accountTable.add({
6541
+ pubkey: this.payer,
6542
+ isSigner: true,
6543
+ isWritable: true
6544
+ });
6545
+ for (const instruction of this.instructions) {
6546
+ accountTable.addAll(instruction.accounts);
6547
+ accountTable.add({
6548
+ pubkey: instruction.programId,
6549
+ isSigner: false,
6550
+ isWritable: false
6551
+ });
6552
+ }
6553
+ const accountKeys = accountTable.getPublicKeys();
6554
+ const header = accountTable.getHeader();
6555
+ const compiledInstructions = this.instructions.map((instruction) => {
6556
+ const programIdIndex = accountTable.getIndex(instruction.programId);
6557
+ if (programIdIndex === -1) {
6685
6558
  throw new TransactionError(
6686
- "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6687
- `Insufficient data for instruction ${i} program index`
6559
+ "INVALID_INSTRUCTION" /* INVALID_INSTRUCTION */,
6560
+ `Program ID ${instruction.programId.toString()} not found in account table`
6688
6561
  );
6689
6562
  }
6690
- const programIdIndex = data[cursor++];
6691
- const [accountIndexesLength, newCursor3] = deserializeCompactU162(
6692
- data,
6693
- cursor
6694
- );
6695
- cursor = newCursor3;
6696
- const accountKeyIndexes = [];
6697
- for (let j = 0; j < accountIndexesLength; j++) {
6698
- if (data.length < cursor + 1) {
6563
+ const accountKeyIndexes = instruction.accounts.map((meta) => {
6564
+ const index = accountTable.getIndex(meta.pubkey);
6565
+ if (index === -1) {
6699
6566
  throw new TransactionError(
6700
- "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6701
- `Insufficient data for instruction ${i} account index ${j}`
6567
+ "INVALID_INSTRUCTION" /* INVALID_INSTRUCTION */,
6568
+ `Account ${meta.pubkey.toString()} not found in account table`
6702
6569
  );
6703
6570
  }
6704
- accountKeyIndexes.push(data[cursor++]);
6705
- }
6706
- const [dataLength, newCursor4] = deserializeCompactU162(data, cursor);
6707
- cursor = newCursor4;
6708
- if (data.length < cursor + dataLength) {
6709
- throw new TransactionError(
6710
- "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6711
- `Insufficient data for instruction ${i} data`
6712
- );
6713
- }
6714
- const instructionData = data.slice(cursor, cursor + dataLength);
6715
- cursor += dataLength;
6716
- instructions.push({
6571
+ return index;
6572
+ });
6573
+ const compiled = {
6717
6574
  programIdIndex,
6718
6575
  accountKeyIndexes: Object.freeze(accountKeyIndexes),
6719
- data: instructionData
6720
- });
6721
- }
6722
- return new _Message(header, accountKeys, recentBlockhash, txCreationTime, instructions);
6723
- }
6724
- serializeInternal() {
6725
- const buffer = [];
6726
- buffer.push(this.header.numRequiredSignatures);
6727
- buffer.push(this.header.numReadonlySignedAccounts);
6728
- buffer.push(this.header.numReadonlyUnsignedAccounts);
6729
- this.serializeCompactArray(buffer, this.accountKeys, (buf, key) => {
6730
- buf.push(...key.toBytes());
6731
- });
6732
- buffer.push(...this.recentBlockhash.toBytes());
6733
- const txCreationTimeBuffer = new ArrayBuffer(8);
6734
- new DataView(txCreationTimeBuffer).setBigUint64(0, this.txCreationTime ?? BigInt(0));
6735
- buffer.push(...new Uint8Array(txCreationTimeBuffer));
6736
- this.serializeCompactArray(buffer, this.instructions, (buf, ix) => {
6737
- buf.push(ix.programIdIndex);
6738
- this.serializeCompactArray(buf, ix.accountKeyIndexes, (b, idx) => {
6739
- b.push(idx);
6740
- });
6741
- this.serializeCompactArray(buf, Array.from(ix.data), (b, byte) => {
6742
- b.push(byte);
6743
- });
6576
+ data: instruction.data
6577
+ };
6578
+ return compiled;
6744
6579
  });
6745
- return new Uint8Array(buffer);
6746
- }
6747
- serializeCompactArray(buffer, items, serializeItem) {
6748
- this.serializeCompactU16(buffer, items.length);
6749
- for (const item of items) {
6750
- serializeItem(buffer, item);
6751
- }
6580
+ const message = new Message(
6581
+ header,
6582
+ accountKeys,
6583
+ this.validFrom,
6584
+ compiledInstructions
6585
+ );
6586
+ return Transaction.fromMessage(message);
6752
6587
  }
6753
- serializeCompactU16(buffer, value) {
6754
- if (value < 0 || value > 65535) {
6755
- throw new Error(`Value out of range for compact-u16: ${value}`);
6756
- }
6757
- if (value <= 127) {
6758
- buffer.push(value);
6759
- return;
6760
- }
6761
- if (value <= 16383) {
6762
- buffer.push(value & 127 | 128);
6763
- buffer.push(value >> 7 & 127);
6764
- return;
6765
- }
6766
- buffer.push(value & 127 | 128);
6767
- buffer.push(value >> 7 & 127 | 128);
6768
- buffer.push(value >> 14 & 255);
6588
+ };
6589
+
6590
+ // src/rpc/errors.ts
6591
+ var RpcErrorCode = /* @__PURE__ */ ((RpcErrorCode2) => {
6592
+ RpcErrorCode2["REQUEST_TIMEOUT"] = "REQUEST_TIMEOUT";
6593
+ RpcErrorCode2["NETWORK_ERROR"] = "NETWORK_ERROR";
6594
+ RpcErrorCode2["CONNECTION_REFUSED"] = "CONNECTION_REFUSED";
6595
+ RpcErrorCode2["INVALID_NETWORK"] = "INVALID_NETWORK";
6596
+ RpcErrorCode2["INVALID_RESPONSE"] = "INVALID_RESPONSE";
6597
+ RpcErrorCode2["PARSE_ERROR"] = "PARSE_ERROR";
6598
+ RpcErrorCode2["INVALID_REQUEST"] = "INVALID_REQUEST";
6599
+ RpcErrorCode2["METHOD_NOT_FOUND"] = "METHOD_NOT_FOUND";
6600
+ RpcErrorCode2["INVALID_PARAMS"] = "INVALID_PARAMS";
6601
+ RpcErrorCode2["INTERNAL_ERROR"] = "INTERNAL_ERROR";
6602
+ RpcErrorCode2["TRANSACTION_REJECTED"] = "TRANSACTION_REJECTED";
6603
+ RpcErrorCode2["INSUFFICIENT_FUNDS"] = "INSUFFICIENT_FUNDS";
6604
+ RpcErrorCode2["ACCOUNT_NOT_FOUND"] = "ACCOUNT_NOT_FOUND";
6605
+ RpcErrorCode2["RATE_LIMIT_EXCEEDED"] = "RATE_LIMIT_EXCEEDED";
6606
+ RpcErrorCode2["NODE_UNHEALTHY"] = "NODE_UNHEALTHY";
6607
+ return RpcErrorCode2;
6608
+ })(RpcErrorCode || {});
6609
+ var RpcError = class _RpcError extends Error {
6610
+ code;
6611
+ details;
6612
+ retryable;
6613
+ constructor(code, message, details = {}, retryable = false) {
6614
+ super(message);
6615
+ this.name = "RpcError";
6616
+ this.code = code;
6617
+ this.details = details;
6618
+ this.retryable = retryable;
6769
6619
  }
6770
- /**
6771
- * Get all signers required for this message.
6772
- */
6773
- getSigners() {
6774
- return this.accountKeys.slice(0, this.header.numRequiredSignatures);
6620
+ static requestTimeout(timeoutMs, details) {
6621
+ return new _RpcError(
6622
+ "REQUEST_TIMEOUT" /* REQUEST_TIMEOUT */,
6623
+ `RPC request timed out after ${timeoutMs}ms. The node may be slow or unreachable.`,
6624
+ { ...details, timeout: timeoutMs },
6625
+ true
6626
+ // Retryable
6627
+ );
6775
6628
  }
6776
- /**
6777
- * Check if a public key is a required signer.
6778
- */
6779
- isSignerRequired(pubkey) {
6780
- return this.getSigners().some((signer) => signer.equals(pubkey));
6629
+ static networkError(message, details) {
6630
+ return new _RpcError(
6631
+ "NETWORK_ERROR" /* NETWORK_ERROR */,
6632
+ `Network error: ${message}. Check your internet connection and node URL.`,
6633
+ details,
6634
+ true
6635
+ // Retryable
6636
+ );
6781
6637
  }
6782
- /**
6783
- * Get the index of a signer in the signers array.
6784
- * Returns -1 if not a signer.
6785
- */
6786
- getSignerIndex(pubkey) {
6787
- return this.getSigners().findIndex((signer) => signer.equals(pubkey));
6638
+ static invalidResponse(details) {
6639
+ return new _RpcError(
6640
+ "INVALID_RESPONSE" /* INVALID_RESPONSE */,
6641
+ "Received invalid response from RPC node. The response format is unexpected.",
6642
+ details,
6643
+ false
6644
+ );
6788
6645
  }
6789
- };
6790
- function deserializeCompactU162(data, currentCursor) {
6791
- let cursor = currentCursor;
6792
- if (cursor >= data.length) {
6793
- throw new TransactionError(
6794
- "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6795
- "Insufficient data for compact-u16"
6646
+ static accountNotFound(pubkey) {
6647
+ return new _RpcError(
6648
+ "ACCOUNT_NOT_FOUND" /* ACCOUNT_NOT_FOUND */,
6649
+ `Account ${pubkey} not found on chain. It may not exist or has zero balance.`,
6650
+ { pubkey },
6651
+ false
6796
6652
  );
6797
6653
  }
6798
- const firstByte = data[cursor++];
6799
- if ((firstByte & 128) === 0) {
6800
- return [firstByte, cursor];
6801
- }
6802
- if (cursor >= data.length) {
6803
- throw new TransactionError(
6804
- "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6805
- "Incomplete compact-u16 encoding"
6654
+ static rateLimitExceeded(details) {
6655
+ return new _RpcError(
6656
+ "RATE_LIMIT_EXCEEDED" /* RATE_LIMIT_EXCEEDED */,
6657
+ "Rate limit exceeded. Too many requests to the RPC endpoint. Try again later or use a different endpoint.",
6658
+ details,
6659
+ true
6660
+ // Can retry after delay
6806
6661
  );
6807
6662
  }
6808
- const secondByte = data[cursor++];
6809
- if ((secondByte & 128) === 0) {
6810
- return [firstByte & 127 | secondByte << 7, cursor];
6663
+ static fromRpcCode(rpcCode, message, details) {
6664
+ const codeMap = {
6665
+ [-32700]: "PARSE_ERROR" /* PARSE_ERROR */,
6666
+ [-32600]: "INVALID_REQUEST" /* INVALID_REQUEST */,
6667
+ [-32601]: "METHOD_NOT_FOUND" /* METHOD_NOT_FOUND */,
6668
+ [-32602]: "INVALID_PARAMS" /* INVALID_PARAMS */,
6669
+ [-32603]: "INTERNAL_ERROR" /* INTERNAL_ERROR */,
6670
+ [429]: "RATE_LIMIT_EXCEEDED" /* RATE_LIMIT_EXCEEDED */
6671
+ };
6672
+ const code = codeMap[rpcCode] || "INTERNAL_ERROR" /* INTERNAL_ERROR */;
6673
+ const retryable = rpcCode === 429 || rpcCode === -32603;
6674
+ return new _RpcError(code, message, { ...details, rpcCode }, retryable);
6811
6675
  }
6812
- if (cursor >= data.length) {
6813
- throw new TransactionError(
6814
- "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6815
- "Incomplete compact-u16 encoding"
6816
- );
6676
+ toJSON() {
6677
+ return {
6678
+ code: this.code,
6679
+ message: this.message,
6680
+ details: this.details,
6681
+ retryable: this.retryable
6682
+ };
6817
6683
  }
6818
- const thirdByte = data[cursor++];
6819
- const value = firstByte & 127 | (secondByte & 127) << 7 | thirdByte << 14;
6820
- return [value, cursor];
6821
- }
6684
+ };
6822
6685
 
6823
- // src/transaction/transaction.ts
6824
- var Transaction = class _Transaction {
6825
- /** The unsigned message */
6826
- message;
6827
- /** Signatures (64 bytes each), aligned with message.header.numRequiredSignatures */
6828
- signatures;
6829
- // Private constructor - use static factories
6830
- constructor(message, signatures) {
6831
- this.message = message;
6832
- this.signatures = signatures.map((sig) => new Uint8Array(sig));
6833
- if (signatures.length !== message.header.numRequiredSignatures) {
6834
- throw new TransactionError(
6835
- "INVALID_SIGNATURE" /* INVALID_SIGNATURE */,
6836
- `Signature count (${signatures.length}) doesn't match required signers (${message.header.numRequiredSignatures})`
6837
- );
6838
- }
6686
+ // src/rpc/clients/base-client.ts
6687
+ var BaseRpcClient = class {
6688
+ transport;
6689
+ requestId = 1;
6690
+ constructor(transport) {
6691
+ this.transport = transport;
6839
6692
  }
6840
6693
  /**
6841
- * Create an unsigned transaction from a message.
6842
- * All signature slots are initialized to zero.
6694
+ * Makes a JSON-RPC 2.0 method call with type safety.
6843
6695
  *
6844
- * @internal - Users should use TransactionBuilder instead
6696
+ * Handles request serialization, response validation, and error mapping.
6845
6697
  */
6846
- static fromMessage(message) {
6847
- const numSignatures = message.header.numRequiredSignatures;
6848
- const signatures = Array.from(
6849
- { length: numSignatures },
6850
- () => new Uint8Array(SIGNATURE_LENGTH)
6851
- );
6852
- return new _Transaction(message, signatures);
6698
+ async call(method, params = []) {
6699
+ const requestId = this.requestId++;
6700
+ const request = {
6701
+ jsonrpc: "2.0",
6702
+ id: requestId,
6703
+ method,
6704
+ params
6705
+ };
6706
+ const requestBody = JSON.stringify(request);
6707
+ const requestDetails = { method, params, requestId };
6708
+ const data = await this.transport.request(requestBody, requestDetails);
6709
+ if (!this.isValidJsonRpcResponse(data)) {
6710
+ throw RpcError.invalidResponse({
6711
+ ...requestDetails,
6712
+ response: data
6713
+ });
6714
+ }
6715
+ const response = data;
6716
+ if (response.error) {
6717
+ throw RpcError.fromRpcCode(response.error.code, response.error.message, {
6718
+ ...requestDetails,
6719
+ rpcData: response.error.data
6720
+ });
6721
+ }
6722
+ if (!("result" in response)) {
6723
+ throw RpcError.invalidResponse({
6724
+ ...requestDetails,
6725
+ response
6726
+ });
6727
+ }
6728
+ return response.result;
6853
6729
  }
6854
6730
  /**
6855
- * Create transaction from message and existing signatures.
6856
- * @internal
6731
+ * Validate JSON-RPC response structure
6857
6732
  */
6858
- static fromMessageAndSignatures(message, signatures) {
6859
- return new _Transaction(message, signatures);
6733
+ isValidJsonRpcResponse(data) {
6734
+ if (typeof data !== "object" || data === null) {
6735
+ return false;
6736
+ }
6737
+ const response = data;
6738
+ return response.jsonrpc === "2.0" && typeof response.id === "number" && ("result" in response || "error" in response);
6860
6739
  }
6861
6740
  /**
6862
- * Deserialize a transaction from wire format.
6741
+ * Returns the configured RPC endpoint URL.
6863
6742
  */
6864
- static deserialize(data) {
6865
- if (data.length === 0) {
6866
- throw new TransactionError(
6867
- "SERIALIZATION_FAILED" /* SERIALIZATION_FAILED */,
6868
- "Cannot deserialize empty transaction data"
6869
- );
6870
- }
6871
- let cursor = 0;
6872
- const [signaturesLength, newCursor] = deserializeCompactU16(data, cursor);
6873
- cursor = newCursor;
6874
- const signatures = [];
6875
- for (let i = 0; i < signaturesLength; i++) {
6876
- if (data.length < cursor + SIGNATURE_LENGTH) {
6877
- throw new TransactionError(
6878
- "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6879
- `Insufficient data for signature ${i}: need ${SIGNATURE_LENGTH} bytes at offset ${cursor}`
6880
- );
6881
- }
6882
- const signature = data.slice(cursor, cursor + SIGNATURE_LENGTH);
6883
- signatures.push(signature);
6884
- cursor += SIGNATURE_LENGTH;
6743
+ getUrl() {
6744
+ return this.transport.getUrl();
6745
+ }
6746
+ };
6747
+
6748
+ // src/utils.ts
6749
+ function toBase64(bytes) {
6750
+ if (typeof btoa !== "undefined") {
6751
+ const chunkSize = 8192;
6752
+ let result = "";
6753
+ for (let i = 0; i < bytes.length; i += chunkSize) {
6754
+ const chunk = bytes.slice(i, i + chunkSize);
6755
+ result += String.fromCharCode(...chunk);
6885
6756
  }
6886
- if (cursor >= data.length) {
6887
- throw new TransactionError(
6888
- "INSUFFICIENT_DATA" /* INSUFFICIENT_DATA */,
6889
- "No message data found after signatures"
6890
- );
6757
+ return btoa(result);
6758
+ }
6759
+ if (typeof Buffer !== "undefined") {
6760
+ return Buffer.from(bytes).toString("base64");
6761
+ }
6762
+ throw new Error("No base64 encoding available in this environment");
6763
+ }
6764
+ function fromBase64(base64) {
6765
+ if (typeof atob !== "undefined") {
6766
+ const binary = atob(base64);
6767
+ const bytes = new Uint8Array(binary.length);
6768
+ for (let i = 0; i < binary.length; i++) {
6769
+ bytes[i] = binary.charCodeAt(i);
6891
6770
  }
6892
- const messageBytes = data.slice(cursor);
6893
- const message = Message.deserialize(messageBytes);
6894
- return new _Transaction(message, signatures);
6771
+ return bytes;
6895
6772
  }
6896
- getMessage() {
6897
- return this.message;
6773
+ if (typeof Buffer !== "undefined") {
6774
+ return new Uint8Array(Buffer.from(base64, "base64"));
6898
6775
  }
6776
+ throw new Error("No base64 decoding available in this environment");
6777
+ }
6778
+ function sleep(ms) {
6779
+ return new Promise((resolve) => setTimeout(resolve, ms));
6780
+ }
6781
+ function calculateBackoff(attempt, baseMs = 1e3, maxMs = 3e4) {
6782
+ const exponentialDelay = baseMs * 2 ** attempt;
6783
+ const jitter = Math.random() * 0.3 * exponentialDelay;
6784
+ return Math.min(exponentialDelay + jitter, maxMs);
6785
+ }
6786
+ function getDevnetUrl() {
6787
+ return URL_DEVNET;
6788
+ }
6789
+ function getTestnetUrl() {
6790
+ return URL_TESTNET;
6791
+ }
6792
+ function getMainnetUrl() {
6793
+ return URL_MAINNET;
6794
+ }
6795
+ function getLocalnetUrl() {
6796
+ return URL_LOCALNET;
6797
+ }
6798
+
6799
+ // src/rpc/clients/query-client.ts
6800
+ var QueryRpcClient = class extends BaseRpcClient {
6899
6801
  /**
6900
- * Sign the transaction with a keypair.
6901
- * Returns a NEW Transaction instance.
6902
- *
6903
- * @param keypair - Keypair to sign with
6904
- * @returns New Transaction instance with signature added
6905
- *
6906
- * @example
6907
- * ```typescript
6908
- * const signedTx = tx.sign(keypair);
6909
- * await client.sendTransaction(signedTx.serialize());
6910
- * ```
6802
+ * Get the balance of an account
6911
6803
  */
6912
- sign(keypair) {
6913
- const messageBytes = this.message.serialize();
6914
- const signature = keypair.sign(messageBytes);
6915
- return this.addSignatureForPubkey(keypair.publicKey, signature);
6804
+ async getBalance(pubkey) {
6805
+ const result = await this.call("getBalance", [
6806
+ { address: pubkey.toString() }
6807
+ ]);
6808
+ return BigInt(result.value);
6916
6809
  }
6917
6810
  /**
6918
- * Sign with multiple keypairs at once.
6919
- * Returns a NEW Transaction instance.
6920
- *
6921
- * @example
6922
- * ```typescript
6923
- * const signed = tx.signAll([keypair1, keypair2, keypair3]);
6924
- * ```
6811
+ * Get detailed information about an account
6925
6812
  */
6926
- signAll(keypairs) {
6927
- let result = this;
6928
- for (const keypair of keypairs) {
6929
- result = result.sign(keypair);
6813
+ async getAccountInfo(pubkey) {
6814
+ const result = await this.call("getAccountInfo", [{ address: pubkey.toString(), encoding: "base64" }]);
6815
+ if (!result.value) {
6816
+ return null;
6930
6817
  }
6931
- return result;
6818
+ return {
6819
+ balance: BigInt(result.value.balance),
6820
+ owner: PublicKey.fromString(result.value.owner),
6821
+ data: fromBase64(result.value.data),
6822
+ executable: result.value.executable,
6823
+ rentEpoch: BigInt(result.value.rentEpoch)
6824
+ };
6932
6825
  }
6933
6826
  /**
6934
- * Sign the transaction with a Signer interface (async).
6935
- * Returns a NEW Transaction instance.
6936
- *
6937
- * @example
6938
- * ```typescript
6939
- * const signedTx = await tx.signWith(browserWallet);
6940
- * ```
6827
+ * Get the current block height
6941
6828
  */
6942
- async signWith(signer) {
6943
- const pubkey = await signer.getPublicKey();
6944
- const messageBytes = this.message.serialize();
6945
- const signature = await signer.signMessage(messageBytes);
6946
- return this.addSignatureForPubkey(pubkey, signature);
6829
+ async getBlockHeight() {
6830
+ const result = await this.call("getBlockHeight", []);
6831
+ return BigInt(result);
6947
6832
  }
6948
6833
  /**
6949
- * Sign with multiple signers.
6950
- * Returns a NEW Transaction instance.
6834
+ * Get detailed information about a transaction
6951
6835
  */
6952
- async signAllWith(signers) {
6953
- let result = this;
6954
- for (const signer of signers) {
6955
- result = await result.signWith(signer);
6836
+ async getTransaction(signature) {
6837
+ const result = await this.call("getTransaction", [signature]);
6838
+ if (!result) {
6839
+ return null;
6956
6840
  }
6957
- return result;
6841
+ return {
6842
+ signature,
6843
+ slot: BigInt(result.slot),
6844
+ blockTime: result.blockTime ? BigInt(result.blockTime) : void 0,
6845
+ err: result.err
6846
+ };
6958
6847
  }
6959
6848
  /**
6960
- * Partially sign the transaction (for multi-sig transactions).
6961
- * Returns a NEW Transaction instance.
6962
- *
6963
- * @example
6964
- * ```typescript
6965
- * const signedTx = tx
6966
- * .partialSign(signer1)
6967
- * .partialSign(signer2);
6968
- * ```
6849
+ * Get the total number of transactions processed since genesis
6969
6850
  */
6970
- partialSign(keypair) {
6971
- return this.sign(keypair);
6851
+ async getTransactionCount() {
6852
+ const result = await this.call("getTransactionCount", []);
6853
+ return BigInt(result);
6972
6854
  }
6973
6855
  /**
6974
- * Partially sign with a Signer interface (async).
6975
- * Returns a NEW Transaction instance.
6856
+ * Get the status of multiple transaction signatures
6976
6857
  */
6977
- async partialSignWith(signer) {
6978
- return this.signWith(signer);
6858
+ async getSignatureStatuses(signatures) {
6859
+ const result = await this.call("getSignatureStatuses", [signatures]);
6860
+ return result.value.map((status) => {
6861
+ if (!status) {
6862
+ return null;
6863
+ }
6864
+ return {
6865
+ slot: BigInt(status.slot),
6866
+ confirmations: status.confirmations,
6867
+ err: status.err
6868
+ };
6869
+ });
6979
6870
  }
6980
6871
  /**
6981
- * Add a signature at a specific index.
6982
- * Returns a NEW Transaction instance.
6983
- *
6984
- * Most users should use sign() or signAll() instead.
6872
+ * Get epoch information
6985
6873
  */
6986
- addSignature(index, signature) {
6987
- if (index < 0 || index >= this.signatures.length) {
6988
- throw new TransactionError(
6989
- "SIGNATURE_OUT_OF_BOUNDS" /* SIGNATURE_OUT_OF_BOUNDS */,
6990
- `Signature index ${index} out of bounds (must be 0-${this.signatures.length - 1})`
6991
- );
6992
- }
6993
- const sigBytes = signature instanceof Uint8Array ? signature : signature.toBytes();
6994
- if (sigBytes.length !== SIGNATURE_LENGTH) {
6995
- throw new TransactionError(
6996
- "INVALID_SIGNATURE" /* INVALID_SIGNATURE */,
6997
- `Signature must be ${SIGNATURE_LENGTH} bytes, got ${sigBytes.length}`
6998
- );
6999
- }
7000
- const newSignatures = this.signatures.map(
7001
- (sig, i) => i === index ? new Uint8Array(sigBytes) : new Uint8Array(sig)
7002
- );
7003
- return new _Transaction(this.message, newSignatures);
6874
+ async getEpochInfo() {
6875
+ const result = await this.call("getEpochInfo", []);
6876
+ return {
6877
+ epoch: BigInt(result.epoch),
6878
+ slotIndex: BigInt(result.slotIndex),
6879
+ slotsInEpoch: BigInt(result.slotsInEpoch),
6880
+ absoluteSlot: BigInt(result.absoluteSlot),
6881
+ blockHeight: BigInt(result.blockHeight),
6882
+ transactionCount: result.transactionCount ? BigInt(result.transactionCount) : void 0
6883
+ };
7004
6884
  }
7005
6885
  /**
7006
- * Add a signature for a specific public key.
7007
- * Returns a NEW Transaction instance.
7008
- *
7009
- * Most users should use sign() or signAll() instead.
6886
+ * Get the health status of the node
7010
6887
  */
7011
- addSignatureForPubkey(pubkey, signature) {
7012
- const signerIndex = this.message.getSignerIndex(pubkey);
7013
- if (signerIndex === -1) {
7014
- throw TransactionError.signerNotFound(pubkey.toString());
7015
- }
7016
- return this.addSignature(signerIndex, signature);
6888
+ async getHealth() {
6889
+ const result = await this.call("getHealth", []);
6890
+ return result;
7017
6891
  }
6892
+ };
6893
+
6894
+ // src/rpc/clients/transaction-client.ts
6895
+ var TransactionRpcClient = class extends BaseRpcClient {
7018
6896
  /**
7019
- * Check if transaction is fully signed (all signatures present).
6897
+ * Submit a signed transaction to the blockchain
7020
6898
  */
7021
- isSigned() {
7022
- return this.signatures.every((sig) => sig.some((byte) => byte !== 0));
6899
+ async sendTransaction(transaction, options) {
6900
+ const base64Tx = toBase64(transaction);
6901
+ const config = {
6902
+ encoding: "base64",
6903
+ skipPreflight: options?.skipPreflight ?? false,
6904
+ maxRetries: options?.maxRetries ?? 5
6905
+ };
6906
+ const signature = await this.call("sendTransaction", [
6907
+ base64Tx,
6908
+ config
6909
+ ]);
6910
+ return signature;
7023
6911
  }
7024
6912
  /**
7025
- * Check if a specific signature slot is filled.
6913
+ * Request an airdrop of tokens to an account (devnet/testnet only)
7026
6914
  */
7027
- isSignaturePresent(index) {
7028
- if (index < 0 || index >= this.signatures.length) {
7029
- return false;
7030
- }
7031
- return this.signatures[index].some((byte) => byte !== 0);
6915
+ async requestAirdrop(pubkey, amount) {
6916
+ const signature = await this.call("requestAirdrop", [
6917
+ pubkey.toString(),
6918
+ Number(amount)
6919
+ ]);
6920
+ return signature;
6921
+ }
6922
+ };
6923
+
6924
+ // src/rpc/clients/client.ts
6925
+ var RialoClient = class {
6926
+ queryClient;
6927
+ transactionClient;
6928
+ transport;
6929
+ chain;
6930
+ constructor(transport, chain2) {
6931
+ this.chain = chain2;
6932
+ this.transport = transport;
6933
+ this.queryClient = new QueryRpcClient(transport);
6934
+ this.transactionClient = new TransactionRpcClient(transport);
7032
6935
  }
7033
6936
  /**
7034
- * Get all signatures (returns copies to prevent mutation).
6937
+ * Returns the configured RPC endpoint URL.
7035
6938
  */
7036
- getSignatures() {
7037
- return this.signatures.map((sig) => new Uint8Array(sig));
6939
+ getUrl() {
6940
+ return this.transport.getUrl();
7038
6941
  }
7039
6942
  /**
7040
- * Get a specific signature (returns copy).
6943
+ * Returns the chain identifier.
7041
6944
  */
7042
- getSignature(index) {
7043
- if (index < 0 || index >= this.signatures.length) {
7044
- throw new TransactionError(
7045
- "SIGNATURE_OUT_OF_BOUNDS" /* SIGNATURE_OUT_OF_BOUNDS */,
7046
- `Signature index ${index} out of bounds`
7047
- );
7048
- }
7049
- return new Uint8Array(this.signatures[index]);
6945
+ getChainIdentifier() {
6946
+ return this.chain.id;
7050
6947
  }
7051
6948
  /**
7052
- * Get a specific signature for a public key.
6949
+ * Retrieves the balance of an account in kelvins (smallest unit).
7053
6950
  */
7054
- getSignatureForPubkey(pubkey) {
7055
- const signerIndex = this.message.getSignerIndex(pubkey);
7056
- if (signerIndex === -1) {
7057
- throw TransactionError.signerNotFound(pubkey.toString());
7058
- }
7059
- return this.getSignature(signerIndex);
6951
+ async getBalance(pubkey) {
6952
+ return await this.queryClient.getBalance(pubkey);
7060
6953
  }
7061
6954
  /**
7062
- * Get required signers for this transaction.
6955
+ * Retrieves detailed information about an account.
6956
+ *
6957
+ * @returns Account info or null if account doesn't exist
7063
6958
  */
7064
- getSigners() {
7065
- return this.message.getSigners();
6959
+ async getAccountInfo(pubkey) {
6960
+ return await this.queryClient.getAccountInfo(pubkey);
7066
6961
  }
7067
6962
  /**
7068
- * Get the number of required signatures.
6963
+ * Retrieves the current block height.
7069
6964
  */
7070
- getRequiredSignatureCount() {
7071
- return this.message.header.numRequiredSignatures;
6965
+ async getBlockHeight() {
6966
+ return await this.queryClient.getBlockHeight();
7072
6967
  }
7073
6968
  /**
7074
- * Throw an error if the transaction is not fully signed.
7075
- *
7076
- * @throws {TransactionError} If transaction is not fully signed
6969
+ * Retrieves detailed information about a transaction.
7077
6970
  *
7078
- * @example
7079
- * ```typescript
7080
- * signedTx.ensureSigned(); // Throws if not signed
7081
- * await client.sendTransaction(signedTx.serialize());
7082
- * ```
6971
+ * @returns Transaction info or null if transaction not found
7083
6972
  */
7084
- ensureSigned() {
7085
- if (!this.isSigned()) {
7086
- const missingIndices = this.signatures.map((sig, i) => ({ sig, i })).filter(({ sig }) => !sig.some((byte) => byte !== 0)).map(({ i }) => i);
7087
- const signers = this.getSigners();
7088
- const missingSigners = missingIndices.map((i) => signers[i].toString());
7089
- throw new TransactionError(
7090
- "MISSING_SIGNATURE" /* MISSING_SIGNATURE */,
7091
- `Transaction is not fully signed. Missing signatures for: ${missingSigners.join(", ")}`,
7092
- { missingIndices, missingSigners }
7093
- );
7094
- }
6973
+ async getTransaction(signature) {
6974
+ return await this.queryClient.getTransaction(signature);
7095
6975
  }
7096
6976
  /**
7097
- * Serialize transaction to wire format.
6977
+ * Retrieves the total number of transactions processed since genesis.
7098
6978
  */
7099
- serialize() {
7100
- const compactU16Size = this.signatures.length < 128 ? 1 : 2;
7101
- const sigsSize = compactU16Size + this.signatures.length * SIGNATURE_LENGTH;
7102
- const messageBytes = this.message.serialize();
7103
- const totalSize = sigsSize + messageBytes.length;
7104
- const buffer = new Uint8Array(totalSize);
7105
- let offset = 0;
7106
- offset = writeCompactU16(buffer, offset, this.signatures.length);
7107
- for (const sig of this.signatures) {
7108
- buffer.set(sig, offset);
7109
- offset += SIGNATURE_LENGTH;
7110
- }
7111
- buffer.set(messageBytes, offset);
7112
- return buffer;
6979
+ async getTransactionCount() {
6980
+ return await this.queryClient.getTransactionCount();
7113
6981
  }
7114
- };
7115
-
7116
- // src/transaction/transaction-builder.ts
7117
- var TransactionBuilder = class _TransactionBuilder {
7118
- payer;
7119
- recentBlockhash;
7120
- txCreationTime;
7121
- instructions = [];
7122
- constructor() {
6982
+ /**
6983
+ * Retrieves the status of multiple transaction signatures.
6984
+ */
6985
+ async getSignatureStatuses(signatures) {
6986
+ return await this.queryClient.getSignatureStatuses(signatures);
7123
6987
  }
7124
6988
  /**
7125
- * Create a new transaction builder.
6989
+ * Retrieves current epoch information.
7126
6990
  */
7127
- static create() {
7128
- return new _TransactionBuilder();
6991
+ async getEpochInfo() {
6992
+ return await this.queryClient.getEpochInfo();
7129
6993
  }
7130
6994
  /**
7131
- * Set the fee payer for this transaction.
7132
- *
7133
- * The payer will be the first account and must sign the transaction.
7134
- * The payer pays for transaction fees.
6995
+ * Checks the health status of the RPC node.
7135
6996
  *
7136
- * @param payer - Public key of the fee payer
6997
+ * @returns "ok" if healthy, error message otherwise
7137
6998
  */
7138
- setPayer(payer) {
7139
- this.payer = payer;
7140
- return this;
6999
+ async getHealth() {
7000
+ return await this.queryClient.getHealth();
7141
7001
  }
7142
7002
  /**
7143
- * Set the recent blockhash for replay protection.
7144
- *
7145
- * Get this from client.getLatestBlockhash().
7146
- * Transactions are only valid for ~60 seconds after the blockhash.
7003
+ * Submits a signed transaction to the blockchain.
7147
7004
  *
7148
- * @param blockhash - Recent blockhash from the network
7005
+ * @param transaction - Serialized signed transaction bytes
7006
+ * @param options - Transaction submission options
7007
+ * @returns Transaction signature
7149
7008
  */
7150
- setRecentBlockhash(blockhash) {
7151
- this.recentBlockhash = blockhash;
7152
- return this;
7009
+ async sendTransaction(transaction, options) {
7010
+ return await this.transactionClient.sendTransaction(transaction, options);
7153
7011
  }
7154
7012
  /**
7155
- * Set the transaction creation timestamp.
7013
+ * Requests an airdrop of tokens to an account.
7156
7014
  *
7157
- * This is the time the transaction was created, in milliseconds since Unix epoch.
7158
- * It can be used for additional replay protection or auditing.
7015
+ * **Note**: Only available on devnet and testnet.
7159
7016
  *
7160
- * @param txCreationTime - Transaction creation time in milliseconds since Unix epoch
7017
+ * @param pubkey - Account to receive the airdrop
7018
+ * @param amount - Amount in kelvins (smallest unit)
7019
+ * @returns Transaction signature
7161
7020
  */
7162
- setTxCreationTime(txCreationTime) {
7163
- this.txCreationTime = txCreationTime;
7164
- return this;
7021
+ async requestAirdrop(pubkey, amount) {
7022
+ return await this.transactionClient.requestAirdrop(pubkey, amount);
7023
+ }
7024
+ };
7025
+
7026
+ // src/rpc/http-transport.ts
7027
+ var DEFAULT_CONFIG = {
7028
+ timeout: 3e4,
7029
+ // 30 seconds
7030
+ maxRetries: 3,
7031
+ retryBaseDelay: 1e3,
7032
+ // 1 second
7033
+ retryMaxDelay: 3e4,
7034
+ // 30 seconds
7035
+ headers: {}
7036
+ };
7037
+ var HttpTransport = class {
7038
+ url;
7039
+ config;
7040
+ constructor(url, config = {}) {
7041
+ this.url = url;
7042
+ this.config = { ...DEFAULT_CONFIG, ...config };
7165
7043
  }
7166
7044
  /**
7167
- * Add an instruction to the transaction.
7045
+ * Makes an HTTP request with automatic retry logic.
7168
7046
  *
7169
- * @param instruction - Instruction to add
7047
+ * Retries are attempted for network errors and server errors (5xx).
7048
+ * Uses exponential backoff between retry attempts.
7170
7049
  */
7171
- addInstruction(instruction) {
7172
- this.instructions.push(instruction);
7173
- return this;
7050
+ async request(body, requestDetails = {}) {
7051
+ let lastError;
7052
+ for (let attempt = 0; attempt <= this.config.maxRetries; attempt++) {
7053
+ try {
7054
+ return await this.makeRequest(body, requestDetails, attempt);
7055
+ } catch (error) {
7056
+ lastError = error;
7057
+ if (error instanceof RpcError && !error.retryable) {
7058
+ throw error;
7059
+ }
7060
+ if (attempt === this.config.maxRetries) {
7061
+ throw error;
7062
+ }
7063
+ const delay = calculateBackoff(
7064
+ attempt,
7065
+ this.config.retryBaseDelay,
7066
+ this.config.retryMaxDelay
7067
+ );
7068
+ await sleep(delay);
7069
+ }
7070
+ }
7071
+ throw lastError;
7174
7072
  }
7175
7073
  /**
7176
- * Add multiple instructions at once.
7177
- *
7178
- * @param instructions - Array of instructions to add
7074
+ * Make a single HTTP request with timeout
7179
7075
  */
7180
- addInstructions(instructions) {
7181
- this.instructions.push(...instructions);
7182
- return this;
7076
+ async makeRequest(body, requestDetails, attempt) {
7077
+ const controller = new AbortController();
7078
+ const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
7079
+ try {
7080
+ const options = {
7081
+ method: "POST",
7082
+ headers: {
7083
+ "Content-Type": "application/json",
7084
+ ...this.config.headers
7085
+ },
7086
+ body,
7087
+ signal: controller.signal
7088
+ };
7089
+ const response = await fetch(this.url, options);
7090
+ if (!response.ok) {
7091
+ throw await this.handleHttpError(response, requestDetails, attempt);
7092
+ }
7093
+ const data = await response.json();
7094
+ return data;
7095
+ } catch (error) {
7096
+ if (error instanceof Error && error.name === "AbortError") {
7097
+ throw RpcError.requestTimeout(this.config.timeout, {
7098
+ ...requestDetails,
7099
+ url: this.url,
7100
+ attempts: attempt + 1
7101
+ });
7102
+ }
7103
+ if (error instanceof TypeError) {
7104
+ throw RpcError.networkError(error.message, {
7105
+ ...requestDetails,
7106
+ url: this.url,
7107
+ attempts: attempt + 1,
7108
+ cause: error.message
7109
+ });
7110
+ }
7111
+ if (error instanceof RpcError) {
7112
+ throw error;
7113
+ }
7114
+ throw RpcError.networkError("Unknown network error", {
7115
+ ...requestDetails,
7116
+ url: this.url,
7117
+ attempts: attempt + 1,
7118
+ cause: error instanceof Error ? error.message : String(error)
7119
+ });
7120
+ } finally {
7121
+ clearTimeout(timeoutId);
7122
+ }
7183
7123
  }
7184
7124
  /**
7185
- * Build the transaction (unsigned).
7186
- *
7187
- * Returns an unsigned Transaction that's ready to be signed.
7188
- *
7189
- * @returns Unsigned Transaction
7190
- * @throws {TransactionError} If payer, blockhash, or instructions are missing
7191
- *
7192
- * @example
7193
- * ```typescript
7194
- * const tx = builder.build();
7195
- * const signedTx = tx.sign(keypair);
7196
- * ```
7125
+ * Handle HTTP error responses
7197
7126
  */
7198
- build() {
7199
- if (!this.payer) {
7200
- throw new TransactionError(
7201
- "INVALID_ACCOUNT_META" /* INVALID_ACCOUNT_META */,
7202
- "Transaction must have a fee payer. Use setPayer() to set the fee payer."
7203
- );
7204
- }
7205
- if (!this.recentBlockhash) {
7206
- throw new TransactionError(
7207
- "INVALID_MESSAGE_FORMAT" /* INVALID_MESSAGE_FORMAT */,
7208
- "Transaction must have a recent blockhash. Use setRecentBlockhash() to set the blockhash."
7209
- );
7210
- }
7211
- if (!this.txCreationTime) {
7212
- throw new TransactionError(
7213
- "INVALID_MESSAGE_FORMAT" /* INVALID_MESSAGE_FORMAT */,
7214
- "Transaction must have a creation timestamp. Use setTxCreationTime() to set the creation time."
7215
- );
7216
- }
7217
- if (this.instructions.length === 0) {
7218
- throw TransactionError.noInstructions();
7127
+ async handleHttpError(response, requestDetails, attempt) {
7128
+ const status = response.status;
7129
+ if (status === 429) {
7130
+ return RpcError.rateLimitExceeded({
7131
+ ...requestDetails,
7132
+ httpStatus: status,
7133
+ url: this.url,
7134
+ attempts: attempt + 1
7135
+ });
7219
7136
  }
7220
- const accountTable = new AccountMetaTable();
7221
- accountTable.add({
7222
- pubkey: this.payer,
7223
- isSigner: true,
7224
- isWritable: true
7225
- });
7226
- for (const instruction of this.instructions) {
7227
- accountTable.addAll(instruction.accounts);
7228
- accountTable.add({
7229
- pubkey: instruction.programId,
7230
- isSigner: false,
7231
- isWritable: false
7137
+ if (status >= 500) {
7138
+ return RpcError.networkError(`Server error: ${status}`, {
7139
+ ...requestDetails,
7140
+ httpStatus: status,
7141
+ url: this.url,
7142
+ attempts: attempt + 1
7232
7143
  });
7233
7144
  }
7234
- const accountKeys = accountTable.getPublicKeys();
7235
- const header = accountTable.getHeader();
7236
- const compiledInstructions = this.instructions.map((instruction) => {
7237
- const programIdIndex = accountTable.getIndex(instruction.programId);
7238
- if (programIdIndex === -1) {
7239
- throw new TransactionError(
7240
- "INVALID_INSTRUCTION" /* INVALID_INSTRUCTION */,
7241
- `Program ID ${instruction.programId.toString()} not found in account table`
7242
- );
7145
+ let message = `HTTP ${status}: ${response.statusText}`;
7146
+ try {
7147
+ const errorData = await response.json();
7148
+ if (errorData && typeof errorData === "object" && "message" in errorData) {
7149
+ message = String(errorData.message);
7243
7150
  }
7244
- const accountKeyIndexes = instruction.accounts.map((meta) => {
7245
- const index = accountTable.getIndex(meta.pubkey);
7246
- if (index === -1) {
7247
- throw new TransactionError(
7248
- "INVALID_INSTRUCTION" /* INVALID_INSTRUCTION */,
7249
- `Account ${meta.pubkey.toString()} not found in account table`
7250
- );
7251
- }
7252
- return index;
7253
- });
7254
- const compiled = {
7255
- programIdIndex,
7256
- accountKeyIndexes: Object.freeze(accountKeyIndexes),
7257
- data: instruction.data
7258
- };
7259
- return compiled;
7260
- });
7261
- const message = new Message(
7262
- header,
7263
- accountKeys,
7264
- this.recentBlockhash,
7265
- this.txCreationTime,
7266
- compiledInstructions
7151
+ } catch {
7152
+ }
7153
+ return new RpcError(
7154
+ "NETWORK_ERROR" /* NETWORK_ERROR */,
7155
+ message,
7156
+ {
7157
+ ...requestDetails,
7158
+ httpStatus: status,
7159
+ url: this.url,
7160
+ attempts: attempt + 1
7161
+ },
7162
+ false
7163
+ // 4xx errors are not retryable
7267
7164
  );
7268
- return Transaction.fromMessage(message);
7165
+ }
7166
+ /**
7167
+ * Returns the configured RPC endpoint URL.
7168
+ */
7169
+ getUrl() {
7170
+ return this.url;
7269
7171
  }
7270
7172
  };
7271
7173
 
7174
+ // src/rpc/index.ts
7175
+ function createRialoClient(config) {
7176
+ const { chain: chain2, endpoint, transport } = config;
7177
+ const url = endpoint ?? chain2.rpcUrl;
7178
+ const httpTransport = new HttpTransport(url, transport);
7179
+ return new RialoClient(httpTransport, config.chain);
7180
+ }
7181
+ function getDefaultRialoClientConfig(network) {
7182
+ switch (network) {
7183
+ case "mainnet":
7184
+ return { chain: RIALO_MAINNET_CHAIN };
7185
+ case "devnet":
7186
+ return { chain: RIALO_DEVNET_CHAIN };
7187
+ case "testnet":
7188
+ return { chain: RIALO_TESTNET_CHAIN };
7189
+ case "localnet":
7190
+ return { chain: RIALO_LOCALNET_CHAIN };
7191
+ default:
7192
+ throw new RpcError(
7193
+ "INVALID_NETWORK" /* INVALID_NETWORK */,
7194
+ `Unknown network: ${network}`
7195
+ );
7196
+ }
7197
+ }
7198
+
7272
7199
  // src/signer/keypair-signer.ts
7273
7200
  var KeypairSigner = class {
7274
7201
  constructor(keypair) {
@@ -7289,9 +7216,6 @@ var KeypairSigner = class {
7289
7216
  };
7290
7217
  /*! Bundled license information:
7291
7218
 
7292
- @scure/base/index.js:
7293
- (*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
7294
-
7295
7219
  @noble/ed25519/index.js:
7296
7220
  (*! noble-ed25519 - MIT License (c) 2019 Paul Miller (paulmillr.com) *)
7297
7221
 
@@ -7299,10 +7223,13 @@ var KeypairSigner = class {
7299
7223
  @noble/hashes/utils.js:
7300
7224
  (*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
7301
7225
 
7226
+ @scure/base/index.js:
7227
+ (*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
7228
+
7302
7229
  @scure/bip39/index.js:
7303
7230
  (*! scure-bip39 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) *)
7304
7231
  */
7305
7232
 
7306
- export { AccountMetaTable, BASE_DERIVATION_PATH, BLOCKHASH_LENGTH, BaseRpcClient, Blockhash, CryptoError, CryptoErrorCode, DEFAULT_NUM_ACCOUNTS, HttpTransport, KELVIN_PER_RLO, Keypair, KeypairSigner, Message, Mnemonic, PUBLIC_KEY_LENGTH, PublicKey, QueryRpcClient, RialoClient, RialoError, RialoErrorType, RpcError, RpcErrorCode, SECRET_KEY_LENGTH, SIGNATURE_LENGTH, SYSTEM_PROGRAM_ID, Signature, SystemInstruction, Transaction, TransactionBuilder, TransactionError, TransactionErrorCode, TransactionRpcClient, URL_DEVNET, URL_LOCALNET, URL_MAINNET, URL_TESTNET, calculateBackoff, createAccount, createBorshInstruction, createRialoClient, encodeBorshData, fromBase64, getDevnetUrl, getLocalnetUrl, getMainnetUrl, getTestnetUrl, sleep, toBase64, transferInstruction };
7233
+ export { AccountMetaTable, BASE_DERIVATION_PATH, BaseRpcClient, CryptoError, CryptoErrorCode, DEFAULT_NUM_ACCOUNTS, HttpTransport, KELVIN_PER_RLO, Keypair, KeypairSigner, Message, Mnemonic, PUBLIC_KEY_LENGTH, PublicKey, QueryRpcClient, RIALO_DEVNET_CHAIN, RIALO_LOCALNET_CHAIN, RIALO_MAINNET_CHAIN, RIALO_TESTNET_CHAIN, RialoClient, RialoError, RialoErrorType, RpcError, RpcErrorCode, SECRET_KEY_LENGTH, SIGNATURE_LENGTH, SYSTEM_PROGRAM_ID, Signature, SystemInstruction, Transaction, TransactionBuilder, TransactionError, TransactionErrorCode, TransactionRpcClient, URL_DEVNET, URL_LOCALNET, URL_MAINNET, URL_TESTNET, calculateBackoff, createAccount, createBorshInstruction, createRialoClient, encodeBorshData, fromBase64, getDefaultRialoClientConfig, getDevnetUrl, getLocalnetUrl, getMainnetUrl, getTestnetUrl, sleep, toBase64, transferInstruction };
7307
7234
  //# sourceMappingURL=index.mjs.map
7308
7235
  //# sourceMappingURL=index.mjs.map