@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,8 +1,9 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkMZAJQYM3cjs = require('./chunk-MZAJQYM3.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
|
+
var _chunkMZXVXC3Ccjs = require('./chunk-MZXVXC3C.cjs');
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
|
|
@@ -13,7 +14,10 @@ var _chunkV2IJ5HUWcjs = require('./chunk-V2IJ5HUW.cjs');
|
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
var _chunk6XTNI2OQcjs = require('./chunk-6XTNI2OQ.cjs');
|
|
17
21
|
|
|
18
22
|
// src/drivers/algorand/index.ts
|
|
19
23
|
var _algosdk = require('algosdk'); var _algosdk2 = _interopRequireDefault(_algosdk);
|
|
@@ -61,13 +65,13 @@ async function payAlgorand(params) {
|
|
|
61
65
|
} catch (err) {
|
|
62
66
|
const mapped = mapAlgorandError(err, accept.payTo);
|
|
63
67
|
if (mapped) throw mapped;
|
|
64
|
-
throw _nullishCoalesce(
|
|
68
|
+
throw _nullishCoalesce(_chunk6XTNI2OQcjs.toInsufficientFundsError.call(void 0, err), () => ( err));
|
|
65
69
|
}
|
|
66
70
|
}
|
|
67
71
|
function mapAlgorandError(err, payTo) {
|
|
68
72
|
const m = err instanceof Error ? err.message : String(err);
|
|
69
73
|
if (/must optin/i.test(m) || /missing from/i.test(m) && m.includes(payTo)) {
|
|
70
|
-
return new (0,
|
|
74
|
+
return new (0, _chunk6XTNI2OQcjs.RecipientNotReadyError)(
|
|
71
75
|
`Algorand recipient ${payTo} hasn't opted into this asset \u2014 it must opt in (a 0-amount asset transfer to itself) before it can receive. (Algorand: ${firstLine(m)})`,
|
|
72
76
|
{ cause: err }
|
|
73
77
|
);
|
|
@@ -75,7 +79,7 @@ function mapAlgorandError(err, payTo) {
|
|
|
75
79
|
if (/overspend|below min|min(imum)? balance|tried to spend|balance \d+ below|asset \d+ missing from|insufficient|underflow/i.test(
|
|
76
80
|
m
|
|
77
81
|
)) {
|
|
78
|
-
return new (0,
|
|
82
|
+
return new (0, _chunk6XTNI2OQcjs.InsufficientFundsError)(
|
|
79
83
|
`Algorand payment failed: the sender can't cover it \u2014 token balance, ALGO for fees, the 0.1-ALGO minimum balance, or a missing asset opt-in on the sender. (Algorand: ${firstLine(m)})`,
|
|
80
84
|
{ cause: err }
|
|
81
85
|
);
|
|
@@ -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: _nullishCoalesce(t.symbol, () => ( (t.asset === "native" ? "ALGO" : t.asset))),
|
|
114
|
+
decimals,
|
|
115
|
+
amount: amount.toString(),
|
|
116
|
+
amountFormatted: _chunk6XTNI2OQcjs.formatUnits.call(void 0, 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, { ..._nullishCoalesce(init, () => ( {})), signal: ctrl.signal });
|
|
124
|
+
if (!res.ok) return null;
|
|
125
|
+
return await res.json();
|
|
126
|
+
} catch (e2) {
|
|
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 = _optionalChain([probe, 'optionalAccess', _ => _.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 = _chunkMZXVXC3Ccjs.applySlippage.call(void 0, needIn, p.slippageBps);
|
|
155
|
+
const real = await quoteFor(needIn);
|
|
156
|
+
const realOut = _optionalChain([real, 'optionalAccess', _2 => _2.amount_out]);
|
|
157
|
+
if (!realOut) return null;
|
|
158
|
+
if (BigInt(Math.floor(realOut)) < p.wantAmount) return null;
|
|
159
|
+
const poolFee = _optionalChain([real, 'access', _3 => _3.single, 'optionalAccess', _4 => _4.transactions, 'optionalAccess', _5 => _5[0], 'optionalAccess', _6 => _6.swaps, 'optionalAccess', _7 => _7[0], 'optionalAccess', _8 => _8.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: _chunk6XTNI2OQcjs.formatUnits.call(void 0, 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 (!_optionalChain([route, 'optionalAccess', _9 => _9.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 (!_optionalChain([unsigned, 'optionalAccess', _10 => _10.length])) {
|
|
187
|
+
throw new (0, _chunk6XTNI2OQcjs.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 = _nullishCoalesce(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(_nullishCoalesce(_optionalChain([err, 'optionalAccess', _11 => _11.message]), () => ( err)));
|
|
215
|
+
if (/asset .* missing|not opted in|receiver error/i.test(msg)) {
|
|
216
|
+
throw new (0, _chunk6XTNI2OQcjs.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 (0, _chunk6XTNI2OQcjs.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
|
|
|
91
233
|
var ZERO_ADDRESS = _algosdk2.default.Address.zeroAddress().toString();
|
|
@@ -101,34 +243,34 @@ function isSet(addr) {
|
|
|
101
243
|
}
|
|
102
244
|
function randomNote() {
|
|
103
245
|
const g = globalThis.crypto;
|
|
104
|
-
if (!_optionalChain([g, 'optionalAccess',
|
|
105
|
-
throw new (0,
|
|
246
|
+
if (!_optionalChain([g, 'optionalAccess', _12 => _12.getRandomValues])) {
|
|
247
|
+
throw new (0, _chunk6XTNI2OQcjs.UnsupportedSchemeError)("Algorand exact: no Web Crypto CSPRNG available to generate a unique note.");
|
|
106
248
|
}
|
|
107
249
|
return g.getRandomValues(new Uint8Array(32));
|
|
108
250
|
}
|
|
109
251
|
async function payExactAlgorand(input) {
|
|
110
252
|
const { suggestedParams, sk, sender, accept } = input;
|
|
111
253
|
if (accept.asset === "native") {
|
|
112
|
-
throw new (0,
|
|
254
|
+
throw new (0, _chunk6XTNI2OQcjs.UnsupportedSchemeError)(
|
|
113
255
|
"Algorand exact is ASA-only (an asset transfer); native ALGO is not exact-payable. Pay via onchain-proof."
|
|
114
256
|
);
|
|
115
257
|
}
|
|
116
|
-
const feePayer = _optionalChain([accept, 'access',
|
|
258
|
+
const feePayer = _optionalChain([accept, 'access', _13 => _13.extra, 'optionalAccess', _14 => _14.feePayer]);
|
|
117
259
|
if (!feePayer) {
|
|
118
|
-
throw new (0,
|
|
260
|
+
throw new (0, _chunk6XTNI2OQcjs.UnsupportedSchemeError)("Algorand exact rail must advertise extra.feePayer (the fee sponsor address).");
|
|
119
261
|
}
|
|
120
262
|
const assetId = parseAlgorandAssetId(accept.asset);
|
|
121
263
|
if (assetId === null) {
|
|
122
|
-
throw new (0,
|
|
264
|
+
throw new (0, _chunk6XTNI2OQcjs.UnsupportedSchemeError)(`Algorand exact rail asset "${accept.asset}" must be a numeric ASA id.`);
|
|
123
265
|
}
|
|
124
266
|
if (!_algosdk2.default.isValidAddress(feePayer)) {
|
|
125
|
-
throw new (0,
|
|
267
|
+
throw new (0, _chunk6XTNI2OQcjs.UnsupportedSchemeError)(`Algorand exact: extra.feePayer "${feePayer}" is not a valid Algorand address.`);
|
|
126
268
|
}
|
|
127
269
|
if (!_algosdk2.default.isValidAddress(accept.payTo)) {
|
|
128
|
-
throw new (0,
|
|
270
|
+
throw new (0, _chunk6XTNI2OQcjs.UnsupportedSchemeError)(`Algorand exact: payTo "${accept.payTo}" is not a valid Algorand address.`);
|
|
129
271
|
}
|
|
130
272
|
if (feePayer === sender) {
|
|
131
|
-
throw new (0,
|
|
273
|
+
throw new (0, _chunk6XTNI2OQcjs.UnsupportedSchemeError)(
|
|
132
274
|
"Algorand exact: the fee payer must differ from the payer \u2014 the buyer must pay ZERO ALGO (the sponsor pays the pooled fee)."
|
|
133
275
|
);
|
|
134
276
|
}
|
|
@@ -168,20 +310,20 @@ function decodeElement(bytes) {
|
|
|
168
310
|
try {
|
|
169
311
|
const st = _algosdk2.default.decodeSignedTransaction(bytes);
|
|
170
312
|
return { txn: st.txn, signed: st.sig != null || st.msig != null || st.lsig != null, raw: bytes };
|
|
171
|
-
} catch (
|
|
313
|
+
} catch (e3) {
|
|
172
314
|
return { txn: _algosdk2.default.decodeUnsignedTransaction(bytes), signed: false, raw: bytes };
|
|
173
315
|
}
|
|
174
316
|
}
|
|
175
317
|
async function verifyAndSettleExactAlgorand(input) {
|
|
176
318
|
const { client, feePayerSk, feePayerAddr, payload, accept } = input;
|
|
177
|
-
const railFeePayer = _optionalChain([accept, 'access',
|
|
178
|
-
if (!railFeePayer) throw new (0,
|
|
319
|
+
const railFeePayer = _optionalChain([accept, 'access', _15 => _15.extra, 'optionalAccess', _16 => _16.feePayer]);
|
|
320
|
+
if (!railFeePayer) throw new (0, _chunk6XTNI2OQcjs.SettlementError)("Algorand exact: rail is missing extra.feePayer.");
|
|
179
321
|
if (railFeePayer !== feePayerAddr) {
|
|
180
|
-
throw new (0,
|
|
322
|
+
throw new (0, _chunk6XTNI2OQcjs.SettlementError)("Algorand exact: the gate relayer address does not match the rail extra.feePayer \u2014 misconfigured rail.");
|
|
181
323
|
}
|
|
182
324
|
const assetId = parseAlgorandAssetId(accept.asset);
|
|
183
|
-
if (assetId === null) throw new (0,
|
|
184
|
-
if (!_algosdk2.default.isValidAddress(accept.payTo)) throw new (0,
|
|
325
|
+
if (assetId === null) throw new (0, _chunk6XTNI2OQcjs.SettlementError)(`Algorand exact: rail asset "${accept.asset}" is not a numeric ASA id.`);
|
|
326
|
+
if (!_algosdk2.default.isValidAddress(accept.payTo)) throw new (0, _chunk6XTNI2OQcjs.SettlementError)(`Algorand exact: rail payTo "${accept.payTo}" is invalid.`);
|
|
185
327
|
const { paymentIndex, paymentGroup } = payload;
|
|
186
328
|
if (paymentGroup.length !== GROUP_SIZE) {
|
|
187
329
|
return fail("signature_invalid", `Algorand exact expects a ${GROUP_SIZE}-transaction group (payment + fee), got ${paymentGroup.length}.`);
|
|
@@ -209,7 +351,7 @@ async function verifyAndSettleExactAlgorand(input) {
|
|
|
209
351
|
return fail("transfer_not_found", `Transfer asset id ${at.assetIndex} \u2260 rail asset ${assetId}.`);
|
|
210
352
|
}
|
|
211
353
|
if (!addrEq(at.receiver, accept.payTo)) {
|
|
212
|
-
return fail("wrong_recipient", `Transfer pays ${_optionalChain([at, 'access',
|
|
354
|
+
return fail("wrong_recipient", `Transfer pays ${_optionalChain([at, 'access', _17 => _17.receiver, 'optionalAccess', _18 => _18.toString, 'call', _19 => _19()])}, not payTo ${accept.payTo}.`);
|
|
213
355
|
}
|
|
214
356
|
if (BigInt(at.amount) < BigInt(accept.amount)) {
|
|
215
357
|
return fail("amount_too_low", `Transfer pays ${at.amount} of the ASA, required ${accept.amount}.`);
|
|
@@ -224,7 +366,7 @@ async function verifyAndSettleExactAlgorand(input) {
|
|
|
224
366
|
return fail("signature_invalid", "The fee transaction must be a payment (pay) transaction.");
|
|
225
367
|
}
|
|
226
368
|
if (!addrEq(fee.sender, railFeePayer)) {
|
|
227
|
-
return fail("signature_invalid", `The fee transaction sender ${_optionalChain([fee, 'access',
|
|
369
|
+
return fail("signature_invalid", `The fee transaction sender ${_optionalChain([fee, 'access', _20 => _20.sender, 'optionalAccess', _21 => _21.toString, 'call', _22 => _22()])} is not the rail fee payer ${railFeePayer}.`);
|
|
228
370
|
}
|
|
229
371
|
if (BigInt(fee.payment.amount) !== 0n) {
|
|
230
372
|
return fail("signature_invalid", "The fee transaction must move 0 ALGO (it only pools the group fee).");
|
|
@@ -247,7 +389,7 @@ async function verifyAndSettleExactAlgorand(input) {
|
|
|
247
389
|
try {
|
|
248
390
|
feeSigned = fee.signTxn(feePayerSk);
|
|
249
391
|
} catch (err) {
|
|
250
|
-
throw new (0,
|
|
392
|
+
throw new (0, _chunk6XTNI2OQcjs.SettlementError)(`Algorand exact settle: the gate could not sign the fee transaction (${shorten(err instanceof Error ? err.message : String(err))}).`, { cause: err });
|
|
251
393
|
}
|
|
252
394
|
const signedGroup = elements.map((el, i) => i === paymentIndex ? payElement.raw : feeSigned);
|
|
253
395
|
try {
|
|
@@ -259,7 +401,7 @@ async function verifyAndSettleExactAlgorand(input) {
|
|
|
259
401
|
if (/overspend|below min|underflow|insufficient|asset|frozen|opt|missing/i.test(m)) return fail("tx_reverted", `Group would fail on-chain: ${shorten(m)}.`);
|
|
260
402
|
return fail("tx_reverted", `Group would fail on-chain: ${shorten(m)}.`);
|
|
261
403
|
}
|
|
262
|
-
} catch (
|
|
404
|
+
} catch (e4) {
|
|
263
405
|
}
|
|
264
406
|
const buyerTxid = pay.txID();
|
|
265
407
|
try {
|
|
@@ -269,7 +411,7 @@ async function verifyAndSettleExactAlgorand(input) {
|
|
|
269
411
|
if (/signature|sig|auth|malformed/i.test(m)) return fail("signature_invalid", `Settle rejected \u2014 bad signature: ${shorten(m)}.`);
|
|
270
412
|
if (/already in ledger|already committed|duplicate/i.test(m)) return fail("tx_already_used", `This payment was already settled: ${shorten(m)}.`);
|
|
271
413
|
if (/\bround\b|expired|lifetime|stale|validity/i.test(m)) return fail("payment_expired", `Settle rejected \u2014 validity window expired: ${shorten(m)}.`);
|
|
272
|
-
throw new (0,
|
|
414
|
+
throw new (0, _chunk6XTNI2OQcjs.SettlementError)(
|
|
273
415
|
`Algorand exact settle: the group failed to submit (${shorten(m)}). The buyer's signed transaction is still valid \u2014 fund/fix the fee payer (${railFeePayer}) and the buyer can re-present it.`,
|
|
274
416
|
{ cause: err }
|
|
275
417
|
);
|
|
@@ -278,10 +420,10 @@ async function verifyAndSettleExactAlgorand(input) {
|
|
|
278
420
|
try {
|
|
279
421
|
round = await client.waitForConfirmation(buyerTxid);
|
|
280
422
|
} catch (err) {
|
|
281
|
-
throw new (0,
|
|
423
|
+
throw new (0, _chunk6XTNI2OQcjs.SettlementError)(`Algorand exact settle: submitted ${buyerTxid} but confirmation read failed (${shorten(err instanceof Error ? err.message : String(err))}). It likely landed \u2014 re-verify before re-presenting; do NOT re-pay.`, { cause: err });
|
|
282
424
|
}
|
|
283
425
|
if (round === null) {
|
|
284
|
-
throw new (0,
|
|
426
|
+
throw new (0, _chunk6XTNI2OQcjs.SettlementError)(`Algorand exact settle: submitted ${buyerTxid} but it did not confirm in time. It likely landed \u2014 re-verify before re-presenting; do NOT re-pay.`);
|
|
285
427
|
}
|
|
286
428
|
return {
|
|
287
429
|
ok: true,
|
|
@@ -308,7 +450,7 @@ async function verifyAlgorand(params) {
|
|
|
308
450
|
let txs;
|
|
309
451
|
try {
|
|
310
452
|
txs = await reader.transactionsForAccount(accept.payTo, 200);
|
|
311
|
-
} catch (
|
|
453
|
+
} catch (e5) {
|
|
312
454
|
return rpcFailed(nonce);
|
|
313
455
|
}
|
|
314
456
|
const tx = txs.find((t) => typeof t.note === "string" && t.note === nonce);
|
|
@@ -337,7 +479,7 @@ async function verifyAlgorand(params) {
|
|
|
337
479
|
let paid = 0n;
|
|
338
480
|
try {
|
|
339
481
|
paid = tx.amount ? BigInt(tx.amount) : 0n;
|
|
340
|
-
} catch (
|
|
482
|
+
} catch (e6) {
|
|
341
483
|
paid = 0n;
|
|
342
484
|
}
|
|
343
485
|
if (paid < required) {
|
|
@@ -377,13 +519,13 @@ function rpcFailed(nonce) {
|
|
|
377
519
|
|
|
378
520
|
function assertAlgorandWallet(wallet, network) {
|
|
379
521
|
if (typeof wallet !== "object" || wallet === null) {
|
|
380
|
-
throw new (0,
|
|
522
|
+
throw new (0, _chunk6XTNI2OQcjs.WrongFamilyError)(
|
|
381
523
|
`chain ${network} is Algorand; wallet must be { key } (25-word mnemonic) or { account }.`
|
|
382
524
|
);
|
|
383
525
|
}
|
|
384
|
-
|
|
526
|
+
_chunk6XTNI2OQcjs.assertNoLegacyWalletKey.call(void 0, wallet, "Algorand");
|
|
385
527
|
if (!("key" in wallet) && !("account" in wallet)) {
|
|
386
|
-
throw new (0,
|
|
528
|
+
throw new (0, _chunk6XTNI2OQcjs.WrongFamilyError)(
|
|
387
529
|
`chain ${network} is Algorand; wallet must be { key } (25-word mnemonic) or { account }.`
|
|
388
530
|
);
|
|
389
531
|
}
|
|
@@ -398,16 +540,18 @@ function resolveAlgorandWallet(config) {
|
|
|
398
540
|
const { addr, sk } = _algosdk2.default.mnemonicToSecretKey(config.key);
|
|
399
541
|
return { addr: addr.toString(), sk };
|
|
400
542
|
} catch (cause) {
|
|
401
|
-
throw new (0,
|
|
543
|
+
throw new (0, _chunk6XTNI2OQcjs.WrongFamilyError)(
|
|
402
544
|
"Algorand wallet { key } is not a valid 25-word Algorand mnemonic.",
|
|
403
545
|
{ cause }
|
|
404
546
|
);
|
|
405
547
|
}
|
|
406
548
|
}
|
|
407
|
-
throw new (0,
|
|
549
|
+
throw new (0, _chunk6XTNI2OQcjs.WrongFamilyError)("Algorand wallet needs { key } (25-word mnemonic) or { account }.");
|
|
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) {
|
|
@@ -450,12 +594,12 @@ function makeAlgorandNetwork(preset, algodUrl) {
|
|
|
450
594
|
const settleClient = {
|
|
451
595
|
async simulate(signedGroup) {
|
|
452
596
|
const resp = await algod.simulateRawTransactions(signedGroup).do();
|
|
453
|
-
const fm = _optionalChain([resp, 'optionalAccess',
|
|
597
|
+
const fm = _optionalChain([resp, 'optionalAccess', _23 => _23.txnGroups, 'optionalAccess', _24 => _24[0], 'optionalAccess', _25 => _25.failureMessage]);
|
|
454
598
|
return { failureMessage: fm && fm.length > 0 ? fm : null };
|
|
455
599
|
},
|
|
456
600
|
async submit(signedGroup) {
|
|
457
601
|
const res = await algod.sendRawTransaction(signedGroup).do();
|
|
458
|
-
return _nullishCoalesce(_optionalChain([res, 'optionalAccess',
|
|
602
|
+
return _nullishCoalesce(_optionalChain([res, 'optionalAccess', _26 => _26.txid]), () => ( ""));
|
|
459
603
|
},
|
|
460
604
|
async waitForConfirmation(txid) {
|
|
461
605
|
const info = await _algosdk2.default.waitForConfirmation(algod, txid, 10);
|
|
@@ -472,7 +616,7 @@ function makeAlgorandNetwork(preset, algodUrl) {
|
|
|
472
616
|
// spec id to the driver still matches. Mirrors TON's legacy-id tolerance; the
|
|
473
617
|
// normalizeNetwork alias remains the canonical seam. We still EMIT the padded form —
|
|
474
618
|
// changing that would break every deployed PipRail 2.x buyer, so it waits for a major.
|
|
475
|
-
supports: (n) => n === network || n ===
|
|
619
|
+
supports: (n) => n === network || n === _chunkMZAJQYM3cjs.ALGORAND_SPEC_CAIP2,
|
|
476
620
|
resolveToken(token) {
|
|
477
621
|
if (token === "native") {
|
|
478
622
|
return { asset: "native", decimals: ALGO_DECIMALS, symbol: ALGO_SYMBOL };
|
|
@@ -481,16 +625,16 @@ function makeAlgorandNetwork(preset, algodUrl) {
|
|
|
481
625
|
const info = preset.tokens[token.toUpperCase()];
|
|
482
626
|
if (!info) {
|
|
483
627
|
const known = Object.keys(preset.tokens).join(", ") || "(none built in)";
|
|
484
|
-
throw new (0,
|
|
628
|
+
throw new (0, _chunk6XTNI2OQcjs.UnknownTokenError)(
|
|
485
629
|
`token "${token}" isn't built in for Algorand (known: ${known}). Pass { assetId, decimals } for a custom ASA, or use 'native'.`
|
|
486
630
|
);
|
|
487
631
|
}
|
|
488
632
|
return { asset: algorandAssetId(info.assetId), decimals: info.decimals, symbol: info.symbol };
|
|
489
633
|
}
|
|
490
|
-
|
|
634
|
+
_chunk6XTNI2OQcjs.rejectForeignToken.call(void 0, token, "algorand", network);
|
|
491
635
|
const t = token;
|
|
492
636
|
if (typeof t.assetId !== "number" || typeof t.decimals !== "number") {
|
|
493
|
-
throw new (0,
|
|
637
|
+
throw new (0, _chunk6XTNI2OQcjs.WrongFamilyError)(
|
|
494
638
|
`chain ${network} is Algorand; a custom token must be { assetId, decimals }.`
|
|
495
639
|
);
|
|
496
640
|
}
|
|
@@ -511,12 +655,12 @@ function makeAlgorandNetwork(preset, algodUrl) {
|
|
|
511
655
|
},
|
|
512
656
|
assertValidPayTo(payTo) {
|
|
513
657
|
if (payTo.startsWith("0x")) {
|
|
514
|
-
throw new (0,
|
|
658
|
+
throw new (0, _chunk6XTNI2OQcjs.WrongFamilyError)(
|
|
515
659
|
`chain ${network} is Algorand, but payTo "${payTo}" looks like an EVM address.`
|
|
516
660
|
);
|
|
517
661
|
}
|
|
518
662
|
if (!_algosdk2.default.isValidAddress(payTo)) {
|
|
519
|
-
throw new (0,
|
|
663
|
+
throw new (0, _chunk6XTNI2OQcjs.WrongFamilyError)(
|
|
520
664
|
`chain ${network} is Algorand, but payTo "${payTo}" is not a valid Algorand address.`
|
|
521
665
|
);
|
|
522
666
|
}
|
|
@@ -533,14 +677,14 @@ function makeAlgorandNetwork(preset, algodUrl) {
|
|
|
533
677
|
const info = await _algosdk2.default.waitForConfirmation(algod, ref, 10);
|
|
534
678
|
return { height: String(_nullishCoalesce(info.confirmedRound, () => ( 0))) };
|
|
535
679
|
} catch (err) {
|
|
536
|
-
throw new (0,
|
|
680
|
+
throw new (0, _chunk6XTNI2OQcjs.ConfirmationTimeoutError)(`Algorand tx ${ref} did not confirm in time.`, {
|
|
537
681
|
cause: err
|
|
538
682
|
});
|
|
539
683
|
}
|
|
540
684
|
},
|
|
541
685
|
async estimateCost(accept) {
|
|
542
686
|
if (accept.scheme === "exact") {
|
|
543
|
-
return
|
|
687
|
+
return _chunk6XTNI2OQcjs.nativeCost.call(void 0, {
|
|
544
688
|
symbol: ALGO_SYMBOL,
|
|
545
689
|
decimals: ALGO_DECIMALS,
|
|
546
690
|
fee: 0n,
|
|
@@ -548,7 +692,7 @@ function makeAlgorandNetwork(preset, algodUrl) {
|
|
|
548
692
|
detail: "gasless \u2014 the fee payer (facilitator/relayer) pools the group fee; the buyer pays 0 ALGO"
|
|
549
693
|
});
|
|
550
694
|
}
|
|
551
|
-
return
|
|
695
|
+
return _chunk6XTNI2OQcjs.nativeCost.call(void 0, {
|
|
552
696
|
symbol: ALGO_SYMBOL,
|
|
553
697
|
decimals: ALGO_DECIMALS,
|
|
554
698
|
fee: 1000n,
|
|
@@ -556,21 +700,30 @@ 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 {
|
|
562
711
|
owner = resolveAlgorandWallet(wallet._native).addr;
|
|
563
|
-
} catch (
|
|
712
|
+
} catch (e7) {
|
|
564
713
|
return { token: null, native: null };
|
|
565
714
|
}
|
|
566
715
|
let info;
|
|
567
716
|
try {
|
|
568
717
|
info = await algod.accountInformation(owner).do();
|
|
569
|
-
} catch (
|
|
718
|
+
} catch (e8) {
|
|
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((_nullishCoalesce(info.assets, () => ( []))).length);
|
|
725
|
+
return { token: native > min ? native - min : 0n, native };
|
|
726
|
+
}
|
|
574
727
|
const assetId = parseAlgorandAssetId(asset);
|
|
575
728
|
const holding = (_nullishCoalesce(info.assets, () => ( []))).find((a) => Number(a.assetId) === assetId);
|
|
576
729
|
return { token: holding ? BigInt(holding.amount) : 0n, native };
|
|
@@ -584,12 +737,20 @@ function makeAlgorandNetwork(preset, algodUrl) {
|
|
|
584
737
|
const optedIn = (_nullishCoalesce(info.assets, () => ( []))).some((a) => Number(a.assetId) === assetId);
|
|
585
738
|
return optedIn ? { ready: true } : { ready: false, reason: "NOT_OPTED_IN" };
|
|
586
739
|
} catch (e) {
|
|
587
|
-
if (/does not exist|no accounts found|404|account not found/i.test(String(_nullishCoalesce(_optionalChain([e, 'optionalAccess',
|
|
740
|
+
if (/does not exist|no accounts found|404|account not found/i.test(String(_nullishCoalesce(_optionalChain([e, 'optionalAccess', _27 => _27.message]), () => ( e))))) {
|
|
588
741
|
return { ready: false, reason: "NOT_OPTED_IN" };
|
|
589
742
|
}
|
|
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: _algosdk2.default, algod, signer, quote });
|
|
753
|
+
},
|
|
593
754
|
async verify(_ref, accept) {
|
|
594
755
|
return verifyAlgorand({ reader, accept });
|
|
595
756
|
},
|
|
@@ -635,7 +796,7 @@ function makeAlgorandNetwork(preset, algodUrl) {
|
|
|
635
796
|
if (!fp && relayer) {
|
|
636
797
|
try {
|
|
637
798
|
fp = resolveAlgorandWallet(relayer._native).addr;
|
|
638
|
-
} catch (
|
|
799
|
+
} catch (e9) {
|
|
639
800
|
return null;
|
|
640
801
|
}
|
|
641
802
|
}
|
|
@@ -679,7 +840,7 @@ function adaptTxn(raw) {
|
|
|
679
840
|
function decodeNote(bytes) {
|
|
680
841
|
try {
|
|
681
842
|
return new TextDecoder().decode(bytes);
|
|
682
|
-
} catch (
|
|
843
|
+
} catch (e10) {
|
|
683
844
|
return void 0;
|
|
684
845
|
}
|
|
685
846
|
}
|