@piprail/sdk 3.0.0 → 3.1.1

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.
@@ -89,6 +89,13 @@ async function payXrpl(params) {
89
89
  client.feeDrops(),
90
90
  client.currentLedgerIndex()
91
91
  ]);
92
+ for (const [field, value] of [["Sequence", sequence], ["LastLedgerSequence", ledgerIndex]]) {
93
+ if (!Number.isSafeInteger(value) || value < 0) {
94
+ throw new Error(
95
+ `XRPL: could not read ${field} from the ledger (got ${String(value)}) \u2014 the RPC read failed or was throttled. NOTHING was signed or submitted, so this is safe to retry. A dedicated rpcUrl avoids the public cluster's rate limits.`
96
+ );
97
+ }
98
+ }
92
99
  const tx = {
93
100
  TransactionType: "Payment",
94
101
  Account: wallet.classicAddress,
@@ -695,6 +702,8 @@ function resolveXrplWallet(config) {
695
702
  function isXrplActNotFound(e) {
696
703
  return /actNotFound/i.test(String(e?.message ?? e));
697
704
  }
705
+ var XRPL_BASE_RESERVE_DROPS = 1000000n;
706
+ var XRPL_OWNER_RESERVE_DROPS = 200000n;
698
707
  var xrplDriver = {
699
708
  family: "xrpl",
700
709
  resolve(opts) {
@@ -736,7 +745,13 @@ function makeXrplNetwork(preset, rpcUrl) {
736
745
  },
737
746
  async currentLedgerIndex() {
738
747
  const r = await rpc("ledger_current", {});
739
- return r.ledger_current_index;
748
+ const index = r.ledger_current_index ?? r.ledger_index;
749
+ if (typeof index !== "number") {
750
+ throw new Error(
751
+ `XRPL: ledger_current returned neither ledger_current_index nor ledger_index (got ${JSON.stringify(Object.keys(r ?? {}))}). Nothing was signed or submitted.`
752
+ );
753
+ }
754
+ return index;
740
755
  },
741
756
  async submit(txBlob) {
742
757
  return rpc("submit", { tx_blob: txBlob });
@@ -924,16 +939,22 @@ function makeXrplNetwork(preset, rpcUrl) {
924
939
  return { token: null, native: null };
925
940
  }
926
941
  let native = null;
942
+ let ownerCount = 0n;
927
943
  try {
928
944
  const r = await rpc("account_info", {
929
945
  account: owner,
930
946
  ledger_index: "validated"
931
947
  });
932
948
  native = BigInt(r.account_data.Balance);
949
+ ownerCount = BigInt(r.account_data.OwnerCount ?? 0);
933
950
  } catch (e) {
934
951
  native = isXrplActNotFound(e) ? 0n : null;
935
952
  }
936
- if (isXrpNative(asset)) return { token: native, native };
953
+ if (isXrpNative(asset)) {
954
+ if (native === null) return { token: null, native };
955
+ const reserve = XRPL_BASE_RESERVE_DROPS + XRPL_OWNER_RESERVE_DROPS * ownerCount;
956
+ return { token: native > reserve ? native - reserve : 0n, native };
957
+ }
937
958
  let token = null;
938
959
  try {
939
960
  const [currencyHex, issuer] = asset.split(":");
@@ -89,6 +89,13 @@ async function payXrpl(params) {
89
89
  client.feeDrops(),
90
90
  client.currentLedgerIndex()
91
91
  ]);
92
+ for (const [field, value] of [["Sequence", sequence], ["LastLedgerSequence", ledgerIndex]]) {
93
+ if (!Number.isSafeInteger(value) || value < 0) {
94
+ throw new Error(
95
+ `XRPL: could not read ${field} from the ledger (got ${String(value)}) \u2014 the RPC read failed or was throttled. NOTHING was signed or submitted, so this is safe to retry. A dedicated rpcUrl avoids the public cluster's rate limits.`
96
+ );
97
+ }
98
+ }
92
99
  const tx = {
93
100
  TransactionType: "Payment",
94
101
  Account: wallet.classicAddress,
@@ -695,6 +702,8 @@ function resolveXrplWallet(config) {
695
702
  function isXrplActNotFound(e) {
696
703
  return /actNotFound/i.test(String(_nullishCoalesce(_optionalChain([e, 'optionalAccess', _30 => _30.message]), () => ( e))));
697
704
  }
705
+ var XRPL_BASE_RESERVE_DROPS = 1000000n;
706
+ var XRPL_OWNER_RESERVE_DROPS = 200000n;
698
707
  var xrplDriver = {
699
708
  family: "xrpl",
700
709
  resolve(opts) {
@@ -736,7 +745,13 @@ function makeXrplNetwork(preset, rpcUrl) {
736
745
  },
737
746
  async currentLedgerIndex() {
738
747
  const r = await rpc("ledger_current", {});
739
- return r.ledger_current_index;
748
+ const index = _nullishCoalesce(r.ledger_current_index, () => ( r.ledger_index));
749
+ if (typeof index !== "number") {
750
+ throw new Error(
751
+ `XRPL: ledger_current returned neither ledger_current_index nor ledger_index (got ${JSON.stringify(Object.keys(_nullishCoalesce(r, () => ( {}))))}). Nothing was signed or submitted.`
752
+ );
753
+ }
754
+ return index;
740
755
  },
741
756
  async submit(txBlob) {
742
757
  return rpc("submit", { tx_blob: txBlob });
@@ -924,16 +939,22 @@ function makeXrplNetwork(preset, rpcUrl) {
924
939
  return { token: null, native: null };
925
940
  }
926
941
  let native = null;
942
+ let ownerCount = 0n;
927
943
  try {
928
944
  const r = await rpc("account_info", {
929
945
  account: owner,
930
946
  ledger_index: "validated"
931
947
  });
932
948
  native = BigInt(r.account_data.Balance);
949
+ ownerCount = BigInt(_nullishCoalesce(r.account_data.OwnerCount, () => ( 0)));
933
950
  } catch (e) {
934
951
  native = isXrplActNotFound(e) ? 0n : null;
935
952
  }
936
- if (isXrpNative(asset)) return { token: native, native };
953
+ if (isXrpNative(asset)) {
954
+ if (native === null) return { token: null, native };
955
+ const reserve = XRPL_BASE_RESERVE_DROPS + XRPL_OWNER_RESERVE_DROPS * ownerCount;
956
+ return { token: native > reserve ? native - reserve : 0n, native };
957
+ }
937
958
  let token = null;
938
959
  try {
939
960
  const [currencyHex, issuer] = asset.split(":");
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@piprail/sdk",
3
- "version": "3.0.0",
4
- "description": "Accept x402 crypto payments across 30 chains \u2014 every major EVM chain plus Solana, TON, Tron, NEAR, Sui, Aptos, Algorand, Stellar & XRPL \u2014 in a couple of lines. No backend, no database, no fee; payments settle straight to your wallet.",
3
+ "version": "3.1.1",
4
+ "description": "Accept x402 crypto payments across 30 chains every major EVM chain plus Solana, TON, Tron, NEAR, Sui, Aptos, Algorand, Stellar & XRPL in a couple of lines. No backend, no database, no fee; payments settle straight to your wallet.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.js",