@piprail/sdk 1.0.0 → 1.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.
- package/CHAINS.md +152 -0
- package/CHANGELOG.md +98 -0
- package/ERRORS.md +57 -5
- package/README.md +96 -13
- package/dist/{chunk-3TQJJ4SQ.js → chunk-DTIJYDG6.js} +16 -0
- package/dist/chunk-NK64H3RM.cjs +173 -0
- package/dist/index.cjs +77 -62
- package/dist/index.d.cts +75 -17
- package/dist/index.d.ts +75 -17
- package/dist/index.js +39 -24
- package/dist/{near-RVXGF7TW.js → near-RJUETWY3.js} +99 -12
- package/dist/{near-4P5XNMMB.cjs → near-VZ6XGVNJ.cjs} +116 -29
- package/dist/{solana-F7H4YDW5.cjs → solana-CRLWAM7C.cjs} +14 -14
- package/dist/{solana-7PZG3CDO.js → solana-USZHRZFN.js} +1 -1
- package/dist/{stellar-PAZ352JL.js → stellar-JZBVCLNV.js} +19 -4
- package/dist/{stellar-BPPQTLNI.cjs → stellar-LIGJKRRK.cjs} +36 -21
- package/dist/{sui-XV4YYSGV.cjs → sui-JLVWFDOS.cjs} +17 -17
- package/dist/{sui-6N4ZPAGD.js → sui-UBDATSQV.js} +1 -1
- package/dist/{ton-EFZKQAAK.js → ton-2N74GKNB.js} +2 -2
- package/dist/{ton-E5RLUPD2.cjs → ton-OVSQZ4OM.cjs} +15 -15
- package/dist/{tron-243DT6PF.js → tron-N3EAAKU7.js} +123 -5
- package/dist/{tron-3UDH7KGF.cjs → tron-V3A6L3X3.cjs} +148 -30
- package/dist/{xrpl-6NRFT5CA.cjs → xrpl-QECPQCFS.cjs} +42 -26
- package/dist/{xrpl-7GWXDAVZ.js → xrpl-RTT3UOLX.js} +25 -9
- package/package.json +5 -1
- package/dist/chunk-WQWNPAYQ.cjs +0 -157
|
@@ -9,7 +9,7 @@ var _chunkCQREG5LEcjs = require('./chunk-CQREG5LE.cjs');
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
var
|
|
12
|
+
var _chunkNK64H3RMcjs = require('./chunk-NK64H3RM.cjs');
|
|
13
13
|
|
|
14
14
|
// src/drivers/tron/index.ts
|
|
15
15
|
var _tronweb = require('tronweb');
|
|
@@ -61,7 +61,7 @@ async function payTron(params) {
|
|
|
61
61
|
return _nullishCoalesce(_nullishCoalesce(broadcast.txid, () => ( _optionalChain([broadcast, 'access', _7 => _7.transaction, 'optionalAccess', _8 => _8.txID]))), () => ( signed.txID));
|
|
62
62
|
}
|
|
63
63
|
if (isTronAffordability(broadcast.code, broadcast.message)) {
|
|
64
|
-
throw new (0,
|
|
64
|
+
throw new (0, _chunkNK64H3RMcjs.InsufficientFundsError)(
|
|
65
65
|
`Tron payment rejected (${_nullishCoalesce(broadcast.code, () => ( "broadcast"))}): not enough TRX for energy/bandwidth, or insufficient token balance.`
|
|
66
66
|
);
|
|
67
67
|
}
|
|
@@ -69,8 +69,30 @@ async function payTron(params) {
|
|
|
69
69
|
`Tron broadcast failed: ${_nullishCoalesce(broadcast.code, () => ( ""))} ${decodeMaybeHex(broadcast.message)}`.trim()
|
|
70
70
|
);
|
|
71
71
|
} catch (err) {
|
|
72
|
-
if (err instanceof
|
|
73
|
-
throw _nullishCoalesce(
|
|
72
|
+
if (err instanceof _chunkNK64H3RMcjs.InsufficientFundsError) throw err;
|
|
73
|
+
throw _nullishCoalesce(_chunkNK64H3RMcjs.toInsufficientFundsError.call(void 0, err), () => ( err));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function payTronNative(params) {
|
|
77
|
+
const { client, from, privateKey, accept } = params;
|
|
78
|
+
try {
|
|
79
|
+
const unsigned = await client.transactionBuilder.sendTrx(accept.payTo, Number(accept.amount), from);
|
|
80
|
+
const signed = await client.trx.sign(unsigned, privateKey);
|
|
81
|
+
const broadcast = await client.trx.sendRawTransaction(signed);
|
|
82
|
+
if (broadcast.result === true || broadcast.txid || _optionalChain([broadcast, 'access', _9 => _9.transaction, 'optionalAccess', _10 => _10.txID])) {
|
|
83
|
+
return _nullishCoalesce(_nullishCoalesce(broadcast.txid, () => ( _optionalChain([broadcast, 'access', _11 => _11.transaction, 'optionalAccess', _12 => _12.txID]))), () => ( signed.txID));
|
|
84
|
+
}
|
|
85
|
+
if (isTronAffordability(broadcast.code, broadcast.message)) {
|
|
86
|
+
throw new (0, _chunkNK64H3RMcjs.InsufficientFundsError)(
|
|
87
|
+
`Tron TRX payment rejected (${_nullishCoalesce(broadcast.code, () => ( "broadcast"))}): not enough TRX for the amount plus bandwidth (and the ~1 TRX account-creation fee if the recipient is new).`
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
throw new Error(
|
|
91
|
+
`Tron TRX broadcast failed: ${_nullishCoalesce(broadcast.code, () => ( ""))} ${decodeMaybeHex(broadcast.message)}`.trim()
|
|
92
|
+
);
|
|
93
|
+
} catch (err) {
|
|
94
|
+
if (err instanceof _chunkNK64H3RMcjs.InsufficientFundsError) throw err;
|
|
95
|
+
throw _nullishCoalesce(_chunkNK64H3RMcjs.toInsufficientFundsError.call(void 0, err), () => ( err));
|
|
74
96
|
}
|
|
75
97
|
}
|
|
76
98
|
function decodeMaybeHex(message) {
|
|
@@ -104,11 +126,11 @@ async function verifyTron(params) {
|
|
|
104
126
|
return txNotFound(txid);
|
|
105
127
|
}
|
|
106
128
|
if (!info || !info.id) return txNotFound(txid);
|
|
107
|
-
if (_optionalChain([info, 'access',
|
|
129
|
+
if (_optionalChain([info, 'access', _13 => _13.receipt, 'optionalAccess', _14 => _14.result]) !== "SUCCESS") {
|
|
108
130
|
return {
|
|
109
131
|
ok: false,
|
|
110
132
|
error: "tx_reverted",
|
|
111
|
-
detail: `Tron tx ${txid} did not succeed (receipt.result=${_nullishCoalesce(_optionalChain([info, 'access',
|
|
133
|
+
detail: `Tron tx ${txid} did not succeed (receipt.result=${_nullishCoalesce(_optionalChain([info, 'access', _15 => _15.receipt, 'optionalAccess', _16 => _16.result]), () => ( "none"))}).`
|
|
112
134
|
};
|
|
113
135
|
}
|
|
114
136
|
const ageSeconds = Math.floor(Date.now() / 1e3) - Math.floor(info.blockTimeStamp / 1e3);
|
|
@@ -142,6 +164,74 @@ async function verifyTron(params) {
|
|
|
142
164
|
}
|
|
143
165
|
};
|
|
144
166
|
}
|
|
167
|
+
async function verifyTronNative(params) {
|
|
168
|
+
const { reader, accept, txid, payToHex41, toBase58 } = params;
|
|
169
|
+
const required = BigInt(accept.amount);
|
|
170
|
+
let info;
|
|
171
|
+
try {
|
|
172
|
+
info = await reader.getTransactionInfo(txid);
|
|
173
|
+
} catch (e3) {
|
|
174
|
+
return txNotFound(txid);
|
|
175
|
+
}
|
|
176
|
+
if (!info || !info.id) return txNotFound(txid);
|
|
177
|
+
const ageSeconds = Math.floor(Date.now() / 1e3) - Math.floor(info.blockTimeStamp / 1e3);
|
|
178
|
+
if (Number.isFinite(ageSeconds) && ageSeconds > accept.maxTimeoutSeconds) {
|
|
179
|
+
return {
|
|
180
|
+
ok: false,
|
|
181
|
+
error: "payment_expired",
|
|
182
|
+
detail: `Payment is ${ageSeconds}s old; max allowed is ${accept.maxTimeoutSeconds}s.`
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
let tx;
|
|
186
|
+
try {
|
|
187
|
+
tx = await reader.getTransaction(txid);
|
|
188
|
+
} catch (e4) {
|
|
189
|
+
return txNotFound(txid);
|
|
190
|
+
}
|
|
191
|
+
if (!tx) return txNotFound(txid);
|
|
192
|
+
const ret = _optionalChain([tx, 'access', _17 => _17.ret, 'optionalAccess', _18 => _18[0], 'optionalAccess', _19 => _19.contractRet]);
|
|
193
|
+
if (ret && ret !== "SUCCESS") {
|
|
194
|
+
return { ok: false, error: "tx_reverted", detail: `Tron tx ${txid} did not succeed (contractRet=${ret}).` };
|
|
195
|
+
}
|
|
196
|
+
const contract = (_nullishCoalesce(_optionalChain([tx, 'access', _20 => _20.raw_data, 'optionalAccess', _21 => _21.contract]), () => ( [])))[0];
|
|
197
|
+
if (!contract || contract.type !== "TransferContract") {
|
|
198
|
+
return {
|
|
199
|
+
ok: false,
|
|
200
|
+
error: "transfer_not_found",
|
|
201
|
+
detail: `Tron tx ${txid} is not a native TRX transfer (TransferContract).`
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
const value = _nullishCoalesce(_optionalChain([contract, 'access', _22 => _22.parameter, 'optionalAccess', _23 => _23.value]), () => ( {}));
|
|
205
|
+
const to = String(_nullishCoalesce(value.to_address, () => ( ""))).toLowerCase().replace(/^0x/, "");
|
|
206
|
+
if (to !== payToHex41) {
|
|
207
|
+
return { ok: false, error: "wrong_recipient", detail: `Native TRX in ${txid} was not sent to ${accept.payTo}.` };
|
|
208
|
+
}
|
|
209
|
+
const amount = (() => {
|
|
210
|
+
try {
|
|
211
|
+
return BigInt(_nullishCoalesce(value.amount, () => ( 0)));
|
|
212
|
+
} catch (e5) {
|
|
213
|
+
return 0n;
|
|
214
|
+
}
|
|
215
|
+
})();
|
|
216
|
+
if (amount < required) {
|
|
217
|
+
return { ok: false, error: "amount_too_low", detail: `Sent ${amount} sun, required ${required}.` };
|
|
218
|
+
}
|
|
219
|
+
const from = String(_nullishCoalesce(value.owner_address, () => ( ""))).toLowerCase().replace(/^0x/, "");
|
|
220
|
+
return {
|
|
221
|
+
ok: true,
|
|
222
|
+
receipt: {
|
|
223
|
+
scheme: "onchain-proof",
|
|
224
|
+
success: true,
|
|
225
|
+
network: accept.network,
|
|
226
|
+
transaction: txid,
|
|
227
|
+
asset: "native",
|
|
228
|
+
amount: accept.amount,
|
|
229
|
+
payer: from ? toBase58(from) : "",
|
|
230
|
+
payTo: accept.payTo,
|
|
231
|
+
verifiedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
}
|
|
145
235
|
function sumTransfersTo(logs, tokenHex20, payToHex20) {
|
|
146
236
|
let total = 0n;
|
|
147
237
|
let from = null;
|
|
@@ -154,7 +244,7 @@ function sumTransfersTo(logs, tokenHex20, payToHex20) {
|
|
|
154
244
|
try {
|
|
155
245
|
total += BigInt(`0x${log.data}`);
|
|
156
246
|
from = last20(topics[1]);
|
|
157
|
-
} catch (
|
|
247
|
+
} catch (e6) {
|
|
158
248
|
}
|
|
159
249
|
}
|
|
160
250
|
return { total, from };
|
|
@@ -173,22 +263,22 @@ function txNotFound(txid) {
|
|
|
173
263
|
// src/drivers/tron/wallet.ts
|
|
174
264
|
function assertTronWallet(wallet, network) {
|
|
175
265
|
if (typeof wallet !== "object" || wallet === null) {
|
|
176
|
-
throw new (0,
|
|
266
|
+
throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
|
|
177
267
|
`chain ${network} is Tron; wallet must be { privateKey } (32-byte hex).`
|
|
178
268
|
);
|
|
179
269
|
}
|
|
180
270
|
if ("walletClient" in wallet) {
|
|
181
|
-
throw new (0,
|
|
271
|
+
throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
|
|
182
272
|
`chain ${network} is Tron; a viem { walletClient } can't be used \u2014 pass { privateKey } (32-byte hex).`
|
|
183
273
|
);
|
|
184
274
|
}
|
|
185
275
|
if ("secretKey" in wallet || "signer" in wallet || "mnemonic" in wallet || "keyPair" in wallet || "secret" in wallet || "keypair" in wallet || "seed" in wallet) {
|
|
186
|
-
throw new (0,
|
|
276
|
+
throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
|
|
187
277
|
`chain ${network} is Tron; that looks like a Solana/TON/Stellar/XRPL wallet \u2014 pass { privateKey } (32-byte hex).`
|
|
188
278
|
);
|
|
189
279
|
}
|
|
190
280
|
if (!("privateKey" in wallet)) {
|
|
191
|
-
throw new (0,
|
|
281
|
+
throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
|
|
192
282
|
`chain ${network} is Tron; wallet must be { privateKey } (32-byte hex).`
|
|
193
283
|
);
|
|
194
284
|
}
|
|
@@ -196,11 +286,11 @@ function assertTronWallet(wallet, network) {
|
|
|
196
286
|
}
|
|
197
287
|
function resolveTronPrivateKey(config) {
|
|
198
288
|
if (!config.privateKey) {
|
|
199
|
-
throw new (0,
|
|
289
|
+
throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)("Tron wallet needs { privateKey } (32-byte hex).");
|
|
200
290
|
}
|
|
201
291
|
const hex = config.privateKey.replace(/^0x/i, "").toLowerCase();
|
|
202
292
|
if (!/^[0-9a-f]{64}$/.test(hex)) {
|
|
203
|
-
throw new (0,
|
|
293
|
+
throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
|
|
204
294
|
"Tron wallet { privateKey } must be a 32-byte hex string (64 hex chars)."
|
|
205
295
|
);
|
|
206
296
|
}
|
|
@@ -227,6 +317,15 @@ function makeTronNetwork(preset, rpcUrl) {
|
|
|
227
317
|
const info = await tronWeb.trx.getTransactionInfo(txid);
|
|
228
318
|
if (!info || !info.id) return null;
|
|
229
319
|
return info;
|
|
320
|
+
},
|
|
321
|
+
// Raw tx (contracts + per-contract ret) for the native-TRX path. getTransaction
|
|
322
|
+
// throws on an unknown tx, so swallow → null; native verify gates finality on
|
|
323
|
+
// getTransactionInfo first anyway.
|
|
324
|
+
async getTransaction(txid) {
|
|
325
|
+
const tx = await tronWeb.trx.getTransaction(txid).catch(() => null);
|
|
326
|
+
const raw = tx;
|
|
327
|
+
if (!raw || !raw.raw_data) return null;
|
|
328
|
+
return raw;
|
|
230
329
|
}
|
|
231
330
|
};
|
|
232
331
|
return {
|
|
@@ -235,29 +334,27 @@ function makeTronNetwork(preset, rpcUrl) {
|
|
|
235
334
|
supports: (n) => n === network,
|
|
236
335
|
resolveToken(token) {
|
|
237
336
|
if (token === "native") {
|
|
238
|
-
|
|
239
|
-
`Tron payments are TRC-20 only \u2014 native TRX isn't a built-in asset. Use 'USDT' or a custom { address, decimals }.`
|
|
240
|
-
);
|
|
337
|
+
return { asset: "native", decimals: TRX_DECIMALS, symbol: "TRX" };
|
|
241
338
|
}
|
|
242
339
|
if (typeof token === "string") {
|
|
243
340
|
const info = preset.tokens[token.toUpperCase()];
|
|
244
341
|
if (!info) {
|
|
245
342
|
const known = Object.keys(preset.tokens).join(", ") || "(none built in)";
|
|
246
|
-
throw new (0,
|
|
343
|
+
throw new (0, _chunkNK64H3RMcjs.UnknownTokenError)(
|
|
247
344
|
`token "${token}" isn't built in for Tron (known: ${known}). Note: native USDC doesn't exist on Tron. Pass { address, decimals } for a custom TRC-20.`
|
|
248
345
|
);
|
|
249
346
|
}
|
|
250
347
|
return { asset: info.address, decimals: info.decimals, symbol: info.symbol };
|
|
251
348
|
}
|
|
252
|
-
|
|
349
|
+
_chunkNK64H3RMcjs.rejectForeignToken.call(void 0, token, "tron", network);
|
|
253
350
|
if (!("address" in token)) {
|
|
254
|
-
throw new (0,
|
|
351
|
+
throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
|
|
255
352
|
`chain ${network} is Tron; a custom token must be { address, decimals } (Base58 T\u2026 contract).`
|
|
256
353
|
);
|
|
257
354
|
}
|
|
258
355
|
const t = token;
|
|
259
356
|
if (t.address.startsWith("0x") || !tronWeb.isAddress(t.address)) {
|
|
260
|
-
throw new (0,
|
|
357
|
+
throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
|
|
261
358
|
`chain ${network} is Tron, but token address "${t.address}" is not a valid Tron contract (T\u2026).`
|
|
262
359
|
);
|
|
263
360
|
}
|
|
@@ -268,7 +365,7 @@ function makeTronNetwork(preset, rpcUrl) {
|
|
|
268
365
|
};
|
|
269
366
|
},
|
|
270
367
|
describeAsset(asset) {
|
|
271
|
-
if (asset === "native") return
|
|
368
|
+
if (asset === "native") return { symbol: "TRX", decimals: TRX_DECIMALS };
|
|
272
369
|
for (const info of Object.values(preset.tokens)) {
|
|
273
370
|
if (info.address === asset) return { symbol: info.symbol, decimals: info.decimals };
|
|
274
371
|
}
|
|
@@ -276,12 +373,12 @@ function makeTronNetwork(preset, rpcUrl) {
|
|
|
276
373
|
},
|
|
277
374
|
assertValidPayTo(payTo) {
|
|
278
375
|
if (payTo.startsWith("0x")) {
|
|
279
|
-
throw new (0,
|
|
376
|
+
throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
|
|
280
377
|
`chain ${network} is Tron, but payTo "${payTo}" looks like an EVM address.`
|
|
281
378
|
);
|
|
282
379
|
}
|
|
283
380
|
if (!tronWeb.isAddress(payTo)) {
|
|
284
|
-
throw new (0,
|
|
381
|
+
throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
|
|
285
382
|
`chain ${network} is Tron, but payTo "${payTo}" is not a valid Tron address (T\u2026).`
|
|
286
383
|
);
|
|
287
384
|
}
|
|
@@ -293,7 +390,10 @@ function makeTronNetwork(preset, rpcUrl) {
|
|
|
293
390
|
const privateKey = resolveTronPrivateKey(wallet._native);
|
|
294
391
|
const from = tronWeb.address.fromPrivateKey(privateKey);
|
|
295
392
|
if (!from) {
|
|
296
|
-
throw new (0,
|
|
393
|
+
throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)("Tron wallet { privateKey } could not derive an address.");
|
|
394
|
+
}
|
|
395
|
+
if (accept.asset === "native") {
|
|
396
|
+
return payTronNative({ client: tronWeb, from, privateKey, accept });
|
|
297
397
|
}
|
|
298
398
|
return payTron({
|
|
299
399
|
client: tronWeb,
|
|
@@ -309,16 +409,25 @@ function makeTronNetwork(preset, rpcUrl) {
|
|
|
309
409
|
try {
|
|
310
410
|
const info = await reader.getTransactionInfo(txid);
|
|
311
411
|
if (info) return { height: String(_nullishCoalesce(info.blockNumber, () => ( 0))) };
|
|
312
|
-
} catch (
|
|
412
|
+
} catch (e7) {
|
|
313
413
|
}
|
|
314
414
|
await _chunkCQREG5LEcjs.delay.call(void 0, 2500);
|
|
315
415
|
}
|
|
316
|
-
throw new (0,
|
|
416
|
+
throw new (0, _chunkNK64H3RMcjs.ConfirmationTimeoutError)(`Tron tx ${txid} did not solidify in time.`);
|
|
317
417
|
},
|
|
318
418
|
async estimateCost(accept, opts) {
|
|
419
|
+
if (accept.asset === "native") {
|
|
420
|
+
return _chunkNK64H3RMcjs.nativeCost.call(void 0, {
|
|
421
|
+
symbol: "TRX",
|
|
422
|
+
decimals: TRX_DECIMALS,
|
|
423
|
+
fee: 1300000n,
|
|
424
|
+
basis: "heuristic",
|
|
425
|
+
detail: "\u22480.27 TRX bandwidth (sender unstaked) + up to ~1 TRX if the recipient account is new"
|
|
426
|
+
});
|
|
427
|
+
}
|
|
319
428
|
const ENERGY_PRICE = 420n;
|
|
320
429
|
const BANDWIDTH_SUN = 345000n;
|
|
321
|
-
if (_optionalChain([opts, 'optionalAccess',
|
|
430
|
+
if (_optionalChain([opts, 'optionalAccess', _24 => _24.from])) {
|
|
322
431
|
try {
|
|
323
432
|
const r = await tronWeb.transactionBuilder.triggerConstantContract(
|
|
324
433
|
accept.asset,
|
|
@@ -332,7 +441,7 @@ function makeTronNetwork(preset, rpcUrl) {
|
|
|
332
441
|
);
|
|
333
442
|
const energy = BigInt(_nullishCoalesce(r.energy_used, () => ( 0)));
|
|
334
443
|
if (energy > 0n) {
|
|
335
|
-
return
|
|
444
|
+
return _chunkNK64H3RMcjs.nativeCost.call(void 0, {
|
|
336
445
|
symbol: "TRX",
|
|
337
446
|
decimals: TRX_DECIMALS,
|
|
338
447
|
fee: energy * ENERGY_PRICE + BANDWIDTH_SUN,
|
|
@@ -340,10 +449,10 @@ function makeTronNetwork(preset, rpcUrl) {
|
|
|
340
449
|
detail: `energy ${energy} @ ${ENERGY_PRICE} sun + bandwidth`
|
|
341
450
|
});
|
|
342
451
|
}
|
|
343
|
-
} catch (
|
|
452
|
+
} catch (e8) {
|
|
344
453
|
}
|
|
345
454
|
}
|
|
346
|
-
return
|
|
455
|
+
return _chunkNK64H3RMcjs.nativeCost.call(void 0, {
|
|
347
456
|
symbol: "TRX",
|
|
348
457
|
decimals: TRX_DECIMALS,
|
|
349
458
|
fee: 30000n * ENERGY_PRICE + BANDWIDTH_SUN,
|
|
@@ -353,6 +462,15 @@ function makeTronNetwork(preset, rpcUrl) {
|
|
|
353
462
|
},
|
|
354
463
|
async verify(ref, accept) {
|
|
355
464
|
const txid = stripTronPrefix(ref);
|
|
465
|
+
if (accept.asset === "native") {
|
|
466
|
+
return verifyTronNative({
|
|
467
|
+
reader,
|
|
468
|
+
accept,
|
|
469
|
+
txid,
|
|
470
|
+
payToHex41: tronWeb.address.toHex(accept.payTo).toLowerCase(),
|
|
471
|
+
toBase58: (h) => tronWeb.address.fromHex(h)
|
|
472
|
+
});
|
|
473
|
+
}
|
|
356
474
|
return verifyTron({
|
|
357
475
|
reader,
|
|
358
476
|
accept,
|
|
@@ -10,7 +10,8 @@ var _chunkCQREG5LEcjs = require('./chunk-CQREG5LE.cjs');
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
var _chunkNK64H3RMcjs = require('./chunk-NK64H3RM.cjs');
|
|
14
15
|
|
|
15
16
|
// src/drivers/xrpl/index.ts
|
|
16
17
|
var _xrpl = require('xrpl');
|
|
@@ -91,17 +92,18 @@ async function payXrpl(params) {
|
|
|
91
92
|
const res = await client.submit(signed.tx_blob);
|
|
92
93
|
const code = res.engine_result;
|
|
93
94
|
if (code.startsWith("tes")) return _nullishCoalesce(_optionalChain([res, 'access', _ => _.tx_json, 'optionalAccess', _2 => _2.hash]), () => ( signed.hash));
|
|
95
|
+
const recipientMsg = recipientNotReadyMessage(code);
|
|
96
|
+
if (recipientMsg) throw new (0, _chunkNK64H3RMcjs.RecipientNotReadyError)(recipientMsg, { cause: makeEngineError(res) });
|
|
94
97
|
if (isAffordabilityCode(code)) {
|
|
95
|
-
throw new (0,
|
|
96
|
-
`XRPL payment rejected
|
|
98
|
+
throw new (0, _chunkNK64H3RMcjs.InsufficientFundsError)(
|
|
99
|
+
`XRPL payment rejected: the sender can't cover it \u2014 balance or the 1 XRP base reserve. (XRPL: ${code})`,
|
|
100
|
+
{ cause: makeEngineError(res) }
|
|
97
101
|
);
|
|
98
102
|
}
|
|
99
|
-
throw
|
|
100
|
-
`XRPL payment rejected: ${code}${res.engine_result_message ? ` \u2014 ${res.engine_result_message}` : ""}`
|
|
101
|
-
);
|
|
103
|
+
throw makeEngineError(res);
|
|
102
104
|
} catch (err) {
|
|
103
|
-
if (err instanceof
|
|
104
|
-
throw _nullishCoalesce(
|
|
105
|
+
if (err instanceof _chunkNK64H3RMcjs.InsufficientFundsError || err instanceof _chunkNK64H3RMcjs.RecipientNotReadyError) throw err;
|
|
106
|
+
throw _nullishCoalesce(_chunkNK64H3RMcjs.toInsufficientFundsError.call(void 0, err), () => ( err));
|
|
105
107
|
}
|
|
106
108
|
}
|
|
107
109
|
function amountForAccept(accept) {
|
|
@@ -118,11 +120,25 @@ function feeForSubmit(openLedgerFee) {
|
|
|
118
120
|
const fee = Number(openLedgerFee);
|
|
119
121
|
return String(Number.isFinite(fee) && fee > 12 ? Math.ceil(fee) : 12);
|
|
120
122
|
}
|
|
121
|
-
function
|
|
122
|
-
return
|
|
123
|
-
|
|
123
|
+
function makeEngineError(res) {
|
|
124
|
+
return new Error(
|
|
125
|
+
`XRPL engine result ${res.engine_result}${res.engine_result_message ? ` \u2014 ${res.engine_result_message}` : ""}`
|
|
124
126
|
);
|
|
125
127
|
}
|
|
128
|
+
function recipientNotReadyMessage(code) {
|
|
129
|
+
if (/^tecNO_DST/.test(code))
|
|
130
|
+
return `XRPL destination isn't activated \u2014 an account must hold \u22651 XRP (the base reserve) to exist. Fund the destination with \u22651 XRP before it can receive. (XRPL: ${code})`;
|
|
131
|
+
if (/^tecNO_LINE/.test(code) || code === "tecPATH_DRY")
|
|
132
|
+
return `XRPL destination can't receive this currency \u2014 it needs a trustline for it (and the reserve to hold one). (XRPL: ${code})`;
|
|
133
|
+
if (code === "tecDST_TAG_NEEDED")
|
|
134
|
+
return `XRPL destination requires a DestinationTag to receive. (XRPL: ${code})`;
|
|
135
|
+
if (/^(tecNO_AUTH|tecNO_PERMISSION)/.test(code))
|
|
136
|
+
return `XRPL destination isn't authorized to hold this asset. (XRPL: ${code})`;
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
function isAffordabilityCode(code) {
|
|
140
|
+
return /^(tecUNFUNDED|tecINSUFF|terINSUF)/.test(code);
|
|
141
|
+
}
|
|
126
142
|
|
|
127
143
|
// src/drivers/xrpl/verify.ts
|
|
128
144
|
var RIPPLE_EPOCH_OFFSET = 946684800;
|
|
@@ -212,7 +228,7 @@ function deliveredBaseUnits(delivered, want, decimals) {
|
|
|
212
228
|
return null;
|
|
213
229
|
}
|
|
214
230
|
try {
|
|
215
|
-
return
|
|
231
|
+
return _chunkNK64H3RMcjs.floorUnits.call(void 0, delivered.value, decimals);
|
|
216
232
|
} catch (e3) {
|
|
217
233
|
return null;
|
|
218
234
|
}
|
|
@@ -236,22 +252,22 @@ function rpcFailed(nonce) {
|
|
|
236
252
|
|
|
237
253
|
function assertXrplWallet(wallet, network) {
|
|
238
254
|
if (typeof wallet !== "object" || wallet === null) {
|
|
239
|
-
throw new (0,
|
|
255
|
+
throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
|
|
240
256
|
`chain ${network} is XRPL; wallet must be { seed } (s\u2026 seed) or { wallet }.`
|
|
241
257
|
);
|
|
242
258
|
}
|
|
243
259
|
if ("privateKey" in wallet || "walletClient" in wallet) {
|
|
244
|
-
throw new (0,
|
|
260
|
+
throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
|
|
245
261
|
`chain ${network} is XRPL; an EVM wallet can't be used \u2014 pass { seed } (s\u2026 seed) or { wallet }.`
|
|
246
262
|
);
|
|
247
263
|
}
|
|
248
264
|
if ("secretKey" in wallet || "signer" in wallet || "mnemonic" in wallet || "keyPair" in wallet || "secret" in wallet || "keypair" in wallet) {
|
|
249
|
-
throw new (0,
|
|
265
|
+
throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
|
|
250
266
|
`chain ${network} is XRPL; that looks like a Solana/TON/Stellar wallet \u2014 pass { seed } (s\u2026 seed) or { wallet }.`
|
|
251
267
|
);
|
|
252
268
|
}
|
|
253
269
|
if (!("seed" in wallet) && !("wallet" in wallet)) {
|
|
254
|
-
throw new (0,
|
|
270
|
+
throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
|
|
255
271
|
`chain ${network} is XRPL; wallet must be { seed } (s\u2026 seed) or { wallet }.`
|
|
256
272
|
);
|
|
257
273
|
}
|
|
@@ -261,11 +277,11 @@ function resolveXrplWallet(config) {
|
|
|
261
277
|
if (config.wallet) return config.wallet;
|
|
262
278
|
if (config.seed) {
|
|
263
279
|
if (!_xrpl.isValidSecret.call(void 0, config.seed)) {
|
|
264
|
-
throw new (0,
|
|
280
|
+
throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)("XRPL wallet { seed } is not a valid s\u2026 secret seed.");
|
|
265
281
|
}
|
|
266
282
|
return _xrpl.Wallet.fromSeed(config.seed);
|
|
267
283
|
}
|
|
268
|
-
throw new (0,
|
|
284
|
+
throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)("XRPL wallet needs { seed } (s\u2026 seed) or { wallet }.");
|
|
269
285
|
}
|
|
270
286
|
|
|
271
287
|
// src/drivers/xrpl/index.ts
|
|
@@ -337,7 +353,7 @@ function makeXrplNetwork(preset, rpcUrl) {
|
|
|
337
353
|
const info = preset.tokens[token.toUpperCase()];
|
|
338
354
|
if (!info) {
|
|
339
355
|
const known = Object.keys(preset.tokens).join(", ") || "(none built in)";
|
|
340
|
-
throw new (0,
|
|
356
|
+
throw new (0, _chunkNK64H3RMcjs.UnknownTokenError)(
|
|
341
357
|
`token "${token}" isn't built in for XRPL (known: ${known}). Pass { issuer, currencyHex, decimals } for a custom IOU, or use 'native'.`
|
|
342
358
|
);
|
|
343
359
|
}
|
|
@@ -347,10 +363,10 @@ function makeXrplNetwork(preset, rpcUrl) {
|
|
|
347
363
|
symbol: info.symbol
|
|
348
364
|
};
|
|
349
365
|
}
|
|
350
|
-
|
|
366
|
+
_chunkNK64H3RMcjs.rejectForeignToken.call(void 0, token, "xrpl", network);
|
|
351
367
|
const t = token;
|
|
352
368
|
if (!t.issuer || !t.currencyHex || typeof t.decimals !== "number") {
|
|
353
|
-
throw new (0,
|
|
369
|
+
throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
|
|
354
370
|
`chain ${network} is XRPL; a custom token must be { issuer, currencyHex, decimals }.`
|
|
355
371
|
);
|
|
356
372
|
}
|
|
@@ -371,12 +387,12 @@ function makeXrplNetwork(preset, rpcUrl) {
|
|
|
371
387
|
},
|
|
372
388
|
assertValidPayTo(payTo) {
|
|
373
389
|
if (payTo.startsWith("0x")) {
|
|
374
|
-
throw new (0,
|
|
390
|
+
throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
|
|
375
391
|
`chain ${network} is XRPL, but payTo "${payTo}" looks like an EVM address.`
|
|
376
392
|
);
|
|
377
393
|
}
|
|
378
394
|
if (!_xrpl.isValidClassicAddress.call(void 0, payTo)) {
|
|
379
|
-
throw new (0,
|
|
395
|
+
throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
|
|
380
396
|
`chain ${network} is XRPL, but payTo "${payTo}" is not a valid XRPL account (r\u2026).`
|
|
381
397
|
);
|
|
382
398
|
}
|
|
@@ -399,14 +415,14 @@ function makeXrplNetwork(preset, rpcUrl) {
|
|
|
399
415
|
}
|
|
400
416
|
await _chunkCQREG5LEcjs.delay.call(void 0, 1500);
|
|
401
417
|
}
|
|
402
|
-
throw new (0,
|
|
418
|
+
throw new (0, _chunkNK64H3RMcjs.ConfirmationTimeoutError)(`XRPL tx ${ref} not validated on-ledger in time.`);
|
|
403
419
|
},
|
|
404
420
|
async estimateCost() {
|
|
405
421
|
try {
|
|
406
422
|
const drops = await payClient.feeDrops();
|
|
407
423
|
const n = Number(drops);
|
|
408
424
|
const fee = BigInt(Number.isFinite(n) && n > 12 ? Math.ceil(n) : 12);
|
|
409
|
-
return
|
|
425
|
+
return _chunkNK64H3RMcjs.nativeCost.call(void 0, {
|
|
410
426
|
symbol: XRP_SYMBOL,
|
|
411
427
|
decimals: XRP_DECIMALS,
|
|
412
428
|
fee,
|
|
@@ -414,7 +430,7 @@ function makeXrplNetwork(preset, rpcUrl) {
|
|
|
414
430
|
detail: `network fee ${fee} drops`
|
|
415
431
|
});
|
|
416
432
|
} catch (e5) {
|
|
417
|
-
return
|
|
433
|
+
return _chunkNK64H3RMcjs.nativeCost.call(void 0, {
|
|
418
434
|
symbol: XRP_SYMBOL,
|
|
419
435
|
decimals: XRP_DECIMALS,
|
|
420
436
|
fee: 12n,
|
|
@@ -4,13 +4,14 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
ConfirmationTimeoutError,
|
|
6
6
|
InsufficientFundsError,
|
|
7
|
+
RecipientNotReadyError,
|
|
7
8
|
UnknownTokenError,
|
|
8
9
|
WrongFamilyError,
|
|
9
10
|
floorUnits,
|
|
10
11
|
nativeCost,
|
|
11
12
|
rejectForeignToken,
|
|
12
13
|
toInsufficientFundsError
|
|
13
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-DTIJYDG6.js";
|
|
14
15
|
|
|
15
16
|
// src/drivers/xrpl/index.ts
|
|
16
17
|
import { isValidClassicAddress } from "xrpl";
|
|
@@ -91,16 +92,17 @@ async function payXrpl(params) {
|
|
|
91
92
|
const res = await client.submit(signed.tx_blob);
|
|
92
93
|
const code = res.engine_result;
|
|
93
94
|
if (code.startsWith("tes")) return res.tx_json?.hash ?? signed.hash;
|
|
95
|
+
const recipientMsg = recipientNotReadyMessage(code);
|
|
96
|
+
if (recipientMsg) throw new RecipientNotReadyError(recipientMsg, { cause: makeEngineError(res) });
|
|
94
97
|
if (isAffordabilityCode(code)) {
|
|
95
98
|
throw new InsufficientFundsError(
|
|
96
|
-
`XRPL payment rejected
|
|
99
|
+
`XRPL payment rejected: the sender can't cover it \u2014 balance or the 1 XRP base reserve. (XRPL: ${code})`,
|
|
100
|
+
{ cause: makeEngineError(res) }
|
|
97
101
|
);
|
|
98
102
|
}
|
|
99
|
-
throw
|
|
100
|
-
`XRPL payment rejected: ${code}${res.engine_result_message ? ` \u2014 ${res.engine_result_message}` : ""}`
|
|
101
|
-
);
|
|
103
|
+
throw makeEngineError(res);
|
|
102
104
|
} catch (err) {
|
|
103
|
-
if (err instanceof InsufficientFundsError) throw err;
|
|
105
|
+
if (err instanceof InsufficientFundsError || err instanceof RecipientNotReadyError) throw err;
|
|
104
106
|
throw toInsufficientFundsError(err) ?? err;
|
|
105
107
|
}
|
|
106
108
|
}
|
|
@@ -118,11 +120,25 @@ function feeForSubmit(openLedgerFee) {
|
|
|
118
120
|
const fee = Number(openLedgerFee);
|
|
119
121
|
return String(Number.isFinite(fee) && fee > 12 ? Math.ceil(fee) : 12);
|
|
120
122
|
}
|
|
121
|
-
function
|
|
122
|
-
return
|
|
123
|
-
|
|
123
|
+
function makeEngineError(res) {
|
|
124
|
+
return new Error(
|
|
125
|
+
`XRPL engine result ${res.engine_result}${res.engine_result_message ? ` \u2014 ${res.engine_result_message}` : ""}`
|
|
124
126
|
);
|
|
125
127
|
}
|
|
128
|
+
function recipientNotReadyMessage(code) {
|
|
129
|
+
if (/^tecNO_DST/.test(code))
|
|
130
|
+
return `XRPL destination isn't activated \u2014 an account must hold \u22651 XRP (the base reserve) to exist. Fund the destination with \u22651 XRP before it can receive. (XRPL: ${code})`;
|
|
131
|
+
if (/^tecNO_LINE/.test(code) || code === "tecPATH_DRY")
|
|
132
|
+
return `XRPL destination can't receive this currency \u2014 it needs a trustline for it (and the reserve to hold one). (XRPL: ${code})`;
|
|
133
|
+
if (code === "tecDST_TAG_NEEDED")
|
|
134
|
+
return `XRPL destination requires a DestinationTag to receive. (XRPL: ${code})`;
|
|
135
|
+
if (/^(tecNO_AUTH|tecNO_PERMISSION)/.test(code))
|
|
136
|
+
return `XRPL destination isn't authorized to hold this asset. (XRPL: ${code})`;
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
function isAffordabilityCode(code) {
|
|
140
|
+
return /^(tecUNFUNDED|tecINSUFF|terINSUF)/.test(code);
|
|
141
|
+
}
|
|
126
142
|
|
|
127
143
|
// src/drivers/xrpl/verify.ts
|
|
128
144
|
var RIPPLE_EPOCH_OFFSET = 946684800;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@piprail/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Accept x402 crypto payments across 24 chains — every major EVM chain plus Solana, TON, Tron, NEAR, Sui, 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",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"files": [
|
|
22
22
|
"dist",
|
|
23
23
|
"README.md",
|
|
24
|
+
"CHAINS.md",
|
|
24
25
|
"ERRORS.md",
|
|
25
26
|
"STANDARDS.md",
|
|
26
27
|
"CHANGELOG.md",
|
|
@@ -70,6 +71,9 @@
|
|
|
70
71
|
},
|
|
71
72
|
"homepage": "https://piprail.com",
|
|
72
73
|
"bugs": "https://github.com/piprail/piprail/issues",
|
|
74
|
+
"publishConfig": {
|
|
75
|
+
"access": "public"
|
|
76
|
+
},
|
|
73
77
|
"engines": {
|
|
74
78
|
"node": ">=20"
|
|
75
79
|
},
|