@piprail/sdk 2.16.2 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/CHANGELOG.md +448 -0
  2. package/README.md +1 -0
  3. package/dist/{algorand-Q3TUQLPK.cjs → algorand-4FTTEV7X.cjs} +212 -51
  4. package/dist/{algorand-25FMBCT3.js → algorand-KJ5XHSMT.js} +164 -3
  5. package/dist/{aptos-VBJONBFY.cjs → aptos-5QBXJ6NV.cjs} +255 -39
  6. package/dist/{aptos-SBV6SGDP.js → aptos-H5VLH2QL.js} +217 -1
  7. package/dist/{chunk-QONQSZHJ.cjs → chunk-6XTNI2OQ.cjs} +44 -44
  8. package/dist/{chunk-OXEFPLZA.cjs → chunk-6ZRAIQXF.cjs} +4 -4
  9. package/dist/chunk-GVCGUSTE.js +30 -0
  10. package/dist/{chunk-V2IJ5HUW.cjs → chunk-MZAJQYM3.cjs} +1 -0
  11. package/dist/chunk-MZXVXC3C.cjs +30 -0
  12. package/dist/{chunk-2CX7XRZK.js → chunk-TZDVZCTC.js} +1 -0
  13. package/dist/{chunk-C52H5TYB.js → chunk-YXBQKBDH.js} +2 -2
  14. package/dist/index.cjs +2906 -1262
  15. package/dist/index.d.cts +679 -21
  16. package/dist/index.d.ts +679 -21
  17. package/dist/index.js +2678 -1034
  18. package/dist/{ledger-Crc1bZox.d.cts → ledger-DkHUORUe.d.cts} +7 -0
  19. package/dist/{ledger-Crc1bZox.d.ts → ledger-DkHUORUe.d.ts} +7 -0
  20. package/dist/{near-OLKCMTBI.js → near-5X2CQGML.js} +197 -1
  21. package/dist/{near-5LTTDU6G.cjs → near-XSQXEIHT.cjs} +242 -46
  22. package/dist/node.d.cts +2 -2
  23. package/dist/node.d.ts +2 -2
  24. package/dist/{solana-AI2G7V33.cjs → solana-TIEJV742.cjs} +218 -53
  25. package/dist/{solana-HTKDRTD3.js → solana-WRXL54MR.js} +174 -9
  26. package/dist/{stellar-E2KWEV2E.cjs → stellar-5GMZJBTA.cjs} +200 -30
  27. package/dist/{stellar-EUFZLX6J.js → stellar-YQLOIFDD.js} +172 -2
  28. package/dist/{sui-KCIITCYH.js → sui-JFQSDNSZ.js} +165 -3
  29. package/dist/{sui-Q3NJOJZS.cjs → sui-WIZEAO7E.cjs} +185 -23
  30. package/dist/{ton-J7TQWRN4.cjs → ton-AGTKLQA5.cjs} +264 -22
  31. package/dist/{ton-WH2JVQOO.js → ton-OZKFNRLT.js} +244 -2
  32. package/dist/{tron-FXBXDNEY.js → tron-HG3IOOCG.js} +283 -1
  33. package/dist/{tron-HIPMOX7S.cjs → tron-S4WX7OHY.cjs} +323 -41
  34. package/dist/{xrpl-RUOB37QH.js → xrpl-5K444RGX.js} +238 -6
  35. package/dist/{xrpl-SVVS445B.cjs → xrpl-G2FKFXRI.cjs} +289 -57
  36. package/package.json +12 -2
  37. package/dist/{chunk-QU25LSVS.js → chunk-5GRBEMCA.js} +44 -44
@@ -1,6 +1,9 @@
1
1
  import {
2
2
  ALGORAND_SPEC_CAIP2
3
- } from "./chunk-2CX7XRZK.js";
3
+ } from "./chunk-TZDVZCTC.js";
4
+ import {
5
+ applySlippage
6
+ } from "./chunk-GVCGUSTE.js";
4
7
  import {
5
8
  ConfirmationTimeoutError,
6
9
  InsufficientFundsError,
@@ -10,10 +13,11 @@ import {
10
13
  UnsupportedSchemeError,
11
14
  WrongFamilyError,
12
15
  assertNoLegacyWalletKey,
16
+ formatUnits,
13
17
  nativeCost,
14
18
  rejectForeignToken,
15
19
  toInsufficientFundsError
16
- } from "./chunk-QU25LSVS.js";
20
+ } from "./chunk-5GRBEMCA.js";
17
21
 
18
22
  // src/drivers/algorand/index.ts
19
23
  import algosdk3 from "algosdk";
@@ -86,6 +90,144 @@ function firstLine(message) {
86
90
  return message.split("\n")[0].slice(0, 160);
87
91
  }
88
92
 
93
+ // src/drivers/algorand/swap.ts
94
+ var VESTIGE_API = "https://api.vestigelabs.org";
95
+ var ALGO_ASA = 0;
96
+ function sourceFor(poolFee) {
97
+ const fee = typeof poolFee === "number" ? `${(poolFee * 100).toFixed(2)}%` : "the pool's own fee";
98
+ return {
99
+ kind: "provider",
100
+ name: "Vestige",
101
+ note: `Third-party Algorand DEX aggregator (api.vestigelabs.org), used keyless. It returns an UNSIGNED atomic transaction group in which every signer is you: nobody co-signs and nothing is delegated. Pool fee on this route: ${fee}. PipRail adds nothing.`
102
+ };
103
+ }
104
+ function asaId(t) {
105
+ if (t.asset === "native") return ALGO_ASA;
106
+ const n = Number(t.asset);
107
+ return Number.isSafeInteger(n) && n > 0 ? n : null;
108
+ }
109
+ function side(t, amount) {
110
+ const decimals = t.asset === "native" ? ALGO_DECIMALS : t.decimals;
111
+ return {
112
+ asset: t.asset,
113
+ symbol: t.symbol ?? (t.asset === "native" ? "ALGO" : t.asset),
114
+ decimals,
115
+ amount: amount.toString(),
116
+ amountFormatted: formatUnits(amount, decimals)
117
+ };
118
+ }
119
+ async function req(url, init) {
120
+ const ctrl = new AbortController();
121
+ const timer = setTimeout(() => ctrl.abort(), 15e3);
122
+ try {
123
+ const res = await fetch(url, { ...init ?? {}, signal: ctrl.signal });
124
+ if (!res.ok) return null;
125
+ return await res.json();
126
+ } catch {
127
+ return null;
128
+ } finally {
129
+ clearTimeout(timer);
130
+ }
131
+ }
132
+ async function quoteAlgorandSwap(p) {
133
+ if (p.wantAmount <= 0n) return null;
134
+ const fromAsa = asaId(p.from);
135
+ const toAsa = asaId(p.to);
136
+ if (fromAsa === null || toAsa === null || fromAsa === toAsa) return null;
137
+ const quoteFor = (amountIn) => req(
138
+ `${VESTIGE_API}/swap/v4?from_asa=${fromAsa}&to_asa=${toAsa}&amount=${amountIn.toString()}&mode=sef&denominating_asset_id=0`
139
+ );
140
+ const fromDecimals = p.from.asset === "native" ? ALGO_DECIMALS : p.from.decimals;
141
+ let probeIn = 10n ** BigInt(Math.max(fromDecimals - 2, 1));
142
+ let probeOut = 0;
143
+ for (let step = 0; step < 4; step += 1) {
144
+ const probe = await quoteFor(probeIn);
145
+ const out = probe?.amount_out;
146
+ if (out && out > 0) {
147
+ probeOut = out;
148
+ break;
149
+ }
150
+ probeIn *= 10n;
151
+ }
152
+ if (!probeOut) return null;
153
+ let needIn = (probeIn * p.wantAmount + BigInt(probeOut) - 1n) / BigInt(probeOut);
154
+ needIn = applySlippage(needIn, p.slippageBps);
155
+ const real = await quoteFor(needIn);
156
+ const realOut = real?.amount_out;
157
+ if (!realOut) return null;
158
+ if (BigInt(Math.floor(realOut)) < p.wantAmount) return null;
159
+ const poolFee = real.single?.transactions?.[0]?.swaps?.[0]?.fee;
160
+ return {
161
+ source: sourceFor(poolFee),
162
+ network: p.network,
163
+ from: side(p.from, needIn),
164
+ to: side(p.to, BigInt(Math.floor(realOut))),
165
+ maxSpend: needIn.toString(),
166
+ maxSpendFormatted: formatUnits(needIn, fromDecimals),
167
+ slippageBps: p.slippageBps,
168
+ // The build endpoint wants the ENTIRE quote response back, unmodified.
169
+ route: { quote: real }
170
+ };
171
+ }
172
+ async function swapAlgorand(p) {
173
+ const route = p.quote.route;
174
+ if (!route?.quote) {
175
+ throw new Error("Algorand: swap quote is missing its Vestige routing data \u2014 re-quote before swapping.");
176
+ }
177
+ const slippage = p.quote.slippageBps / 1e4;
178
+ const unsigned = await req(
179
+ `${VESTIGE_API}/swap/v4/transactions?sender=${p.signer.addr}&slippage=${slippage}`,
180
+ {
181
+ method: "POST",
182
+ headers: { "content-type": "application/json" },
183
+ body: JSON.stringify(route.quote)
184
+ }
185
+ );
186
+ if (!unsigned?.length) {
187
+ throw new RecipientNotReadyError(
188
+ "Vestige could not build this swap. The usual cause is that your account is not opted in to the asset you are swapping INTO: opt in first, then re-quote. Nothing was spent."
189
+ );
190
+ }
191
+ for (const t of unsigned) {
192
+ if (t.signers && t.signers.some((s) => s !== p.signer.addr)) {
193
+ throw new Error(
194
+ "Algorand swap refused: the built group asks a third party to co-sign, which this rail must never do. Nothing was signed."
195
+ );
196
+ }
197
+ }
198
+ try {
199
+ const signed = unsigned.map((t) => {
200
+ const decoded = p.algosdk.decodeUnsignedTransaction(Buffer.from(t.txn, "base64"));
201
+ return decoded.signTxn(p.signer.sk);
202
+ });
203
+ const res = await p.algod.sendRawTransaction(signed).do();
204
+ const txid = res.txid ?? res.txId;
205
+ if (!txid) throw new Error("Algorand: sendRawTransaction returned no transaction id.");
206
+ return {
207
+ transaction: txid,
208
+ network: p.quote.network,
209
+ source: p.quote.source,
210
+ from: p.quote.from,
211
+ to: p.quote.to
212
+ };
213
+ } catch (err) {
214
+ const msg = String(err?.message ?? err);
215
+ if (/asset .* missing|not opted in|receiver error/i.test(msg)) {
216
+ throw new RecipientNotReadyError(
217
+ `Algorand swap refused: your account must opt in to the asset you are swapping INTO first. (${msg.slice(0, 140)})`,
218
+ { cause: err }
219
+ );
220
+ }
221
+ if (/overspend|insufficient|below min/i.test(msg)) {
222
+ throw new InsufficientFundsError(
223
+ `Algorand swap failed: the account can't cover it (balance, the 0.1 ALGO minimum, or group fees). (${msg.slice(0, 140)})`,
224
+ { cause: err }
225
+ );
226
+ }
227
+ throw err;
228
+ }
229
+ }
230
+
89
231
  // src/drivers/algorand/exact.ts
90
232
  import algosdk from "algosdk";
91
233
  var ZERO_ADDRESS = algosdk.Address.zeroAddress().toString();
@@ -408,6 +550,8 @@ function resolveAlgorandWallet(config) {
408
550
  }
409
551
 
410
552
  // src/drivers/algorand/index.ts
553
+ var ALGO_MIN_BALANCE = 100000n;
554
+ var ALGO_MIN_BALANCE_PER_ASSET = 100000n;
411
555
  var algorandDriver = {
412
556
  family: "algorand",
413
557
  resolve(opts) {
@@ -556,6 +700,11 @@ function makeAlgorandNetwork(preset, algodUrl) {
556
700
  detail: "min fee 1000 \xB5Algos (1 transaction)"
557
701
  });
558
702
  },
703
+ /** The bound wallet's own address — where THIS wallet gets paid. Derived from the key
704
+ * material only: no RPC, nothing moved. See {@link ResolvedNetwork.addressOf}. */
705
+ async addressOf(wallet) {
706
+ return String(resolveAlgorandWallet(wallet._native).addr);
707
+ },
559
708
  async balanceOf(wallet, asset) {
560
709
  let owner;
561
710
  try {
@@ -570,7 +719,11 @@ function makeAlgorandNetwork(preset, algodUrl) {
570
719
  return { token: null, native: null };
571
720
  }
572
721
  const native = info.amount != null ? BigInt(info.amount) : null;
573
- if (asset === "native") return { token: native, native };
722
+ if (asset === "native") {
723
+ if (native === null) return { token: null, native };
724
+ const min = info.minBalance != null ? BigInt(info.minBalance) : ALGO_MIN_BALANCE + ALGO_MIN_BALANCE_PER_ASSET * BigInt((info.assets ?? []).length);
725
+ return { token: native > min ? native - min : 0n, native };
726
+ }
574
727
  const assetId = parseAlgorandAssetId(asset);
575
728
  const holding = (info.assets ?? []).find((a) => Number(a.assetId) === assetId);
576
729
  return { token: holding ? BigInt(holding.amount) : 0n, native };
@@ -590,6 +743,14 @@ function makeAlgorandNetwork(preset, algodUrl) {
590
743
  return { ready: "unknown" };
591
744
  }
592
745
  },
746
+ /* ---- swap (OPTIONAL, opt-in): via Vestige, keyless + no integrator fee. See ./swap.ts ---- */
747
+ async quoteSwap({ from, to, wantAmount, slippageBps }) {
748
+ return quoteAlgorandSwap({ network, from, to, wantAmount, slippageBps });
749
+ },
750
+ async swap(wallet, quote) {
751
+ const signer = resolveAlgorandWallet(wallet._native);
752
+ return swapAlgorand({ algosdk: algosdk3, algod, signer, quote });
753
+ },
593
754
  async verify(_ref, accept) {
594
755
  return verifyAlgorand({ reader, accept });
595
756
  },