@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.
- package/CHANGELOG.md +448 -0
- package/README.md +1 -0
- package/dist/{algorand-Q3TUQLPK.cjs → algorand-4FTTEV7X.cjs} +212 -51
- package/dist/{algorand-25FMBCT3.js → algorand-KJ5XHSMT.js} +164 -3
- package/dist/{aptos-VBJONBFY.cjs → aptos-5QBXJ6NV.cjs} +255 -39
- package/dist/{aptos-SBV6SGDP.js → aptos-H5VLH2QL.js} +217 -1
- package/dist/{chunk-QONQSZHJ.cjs → chunk-6XTNI2OQ.cjs} +44 -44
- package/dist/{chunk-OXEFPLZA.cjs → chunk-6ZRAIQXF.cjs} +4 -4
- package/dist/chunk-GVCGUSTE.js +30 -0
- package/dist/{chunk-V2IJ5HUW.cjs → chunk-MZAJQYM3.cjs} +1 -0
- package/dist/chunk-MZXVXC3C.cjs +30 -0
- package/dist/{chunk-2CX7XRZK.js → chunk-TZDVZCTC.js} +1 -0
- package/dist/{chunk-C52H5TYB.js → chunk-YXBQKBDH.js} +2 -2
- package/dist/index.cjs +2906 -1262
- package/dist/index.d.cts +679 -21
- package/dist/index.d.ts +679 -21
- package/dist/index.js +2678 -1034
- package/dist/{ledger-Crc1bZox.d.cts → ledger-DkHUORUe.d.cts} +7 -0
- package/dist/{ledger-Crc1bZox.d.ts → ledger-DkHUORUe.d.ts} +7 -0
- package/dist/{near-OLKCMTBI.js → near-5X2CQGML.js} +197 -1
- package/dist/{near-5LTTDU6G.cjs → near-XSQXEIHT.cjs} +242 -46
- package/dist/node.d.cts +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/{solana-AI2G7V33.cjs → solana-TIEJV742.cjs} +218 -53
- package/dist/{solana-HTKDRTD3.js → solana-WRXL54MR.js} +174 -9
- package/dist/{stellar-E2KWEV2E.cjs → stellar-5GMZJBTA.cjs} +200 -30
- package/dist/{stellar-EUFZLX6J.js → stellar-YQLOIFDD.js} +172 -2
- package/dist/{sui-KCIITCYH.js → sui-JFQSDNSZ.js} +165 -3
- package/dist/{sui-Q3NJOJZS.cjs → sui-WIZEAO7E.cjs} +185 -23
- package/dist/{ton-J7TQWRN4.cjs → ton-AGTKLQA5.cjs} +264 -22
- package/dist/{ton-WH2JVQOO.js → ton-OZKFNRLT.js} +244 -2
- package/dist/{tron-FXBXDNEY.js → tron-HG3IOOCG.js} +283 -1
- package/dist/{tron-HIPMOX7S.cjs → tron-S4WX7OHY.cjs} +323 -41
- package/dist/{xrpl-RUOB37QH.js → xrpl-5K444RGX.js} +238 -6
- package/dist/{xrpl-SVVS445B.cjs → xrpl-G2FKFXRI.cjs} +289 -57
- package/package.json +12 -2
- 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-
|
|
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-
|
|
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")
|
|
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
|
},
|