@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.
@@ -1,12 +1,13 @@
1
1
  import {
2
2
  ConfirmationTimeoutError,
3
3
  InsufficientFundsError,
4
+ RecipientNotReadyError,
4
5
  UnknownTokenError,
5
6
  WrongFamilyError,
6
7
  nativeCost,
7
8
  rejectForeignToken,
8
9
  toInsufficientFundsError
9
- } from "./chunk-3TQJJ4SQ.js";
10
+ } from "./chunk-DTIJYDG6.js";
10
11
 
11
12
  // src/drivers/near/index.ts
12
13
  import { JsonRpcProvider, Account, actions } from "near-api-js";
@@ -52,8 +53,8 @@ async function payNear(params) {
52
53
  return res.hash;
53
54
  } catch (err) {
54
55
  if (isNearRegistrationError(err)) {
55
- throw new Error(
56
- `NEAR ft_transfer failed: recipient ${accept.payTo} isn't registered on token ${accept.asset} (NEP-145 storage_deposit). Register it once (\u22480.00125 NEAR) before it can receive.`,
56
+ throw new RecipientNotReadyError(
57
+ `NEAR recipient ${accept.payTo} isn't registered on token ${accept.asset} (NEP-145 storage_deposit) \u2014 register it once (\u22480.00125 NEAR) before it can receive. (NEAR: not registered)`,
57
58
  { cause: err }
58
59
  );
59
60
  }
@@ -66,6 +67,21 @@ async function payNear(params) {
66
67
  throw toInsufficientFundsError(err) ?? err;
67
68
  }
68
69
  }
70
+ async function payNearNative(params) {
71
+ const { client, accept } = params;
72
+ try {
73
+ const res = await client.nativeTransfer({ receiverId: accept.payTo, amount: accept.amount });
74
+ return res.hash;
75
+ } catch (err) {
76
+ if (isNearAffordability(err)) {
77
+ throw new InsufficientFundsError(
78
+ err instanceof Error ? err.message : "Insufficient NEAR balance for the payment.",
79
+ { cause: err }
80
+ );
81
+ }
82
+ throw toInsufficientFundsError(err) ?? err;
83
+ }
84
+ }
69
85
  function isNearRegistrationError(err) {
70
86
  const m = err instanceof Error ? err.message : String(err);
71
87
  return /not registered|storage_?deposit|The account .* is not registered/i.test(m);
@@ -103,6 +119,41 @@ async function verifyNear(params) {
103
119
  if (!tx.success) {
104
120
  return { ok: false, error: "tx_reverted", detail: `NEAR tx ${hash} failed on-chain.` };
105
121
  }
122
+ if (accept.asset === "native") {
123
+ if (typeof tx.timestampMs !== "number") {
124
+ return { ok: false, error: "payment_expired", detail: `Cannot bound the age of native NEAR tx ${hash} (no block time) \u2014 failing closed.` };
125
+ }
126
+ const ageSeconds = Math.floor(Date.now() / 1e3) - Math.floor(tx.timestampMs / 1e3);
127
+ if (ageSeconds > accept.maxTimeoutSeconds) {
128
+ return { ok: false, error: "payment_expired", detail: `Payment is ${ageSeconds}s old; max allowed is ${accept.maxTimeoutSeconds}s.` };
129
+ }
130
+ if (tx.receiverId !== accept.payTo) {
131
+ return { ok: false, error: "transfer_not_found", detail: `Native NEAR tx ${hash} did not pay ${accept.payTo} (receiver ${tx.receiverId ?? "unknown"}).` };
132
+ }
133
+ let paid2;
134
+ try {
135
+ paid2 = BigInt(tx.nativeDeposit ?? "0");
136
+ } catch {
137
+ paid2 = 0n;
138
+ }
139
+ if (paid2 < required) {
140
+ return { ok: false, error: "amount_too_low", detail: `Native NEAR transfer to ${accept.payTo} was ${paid2} yocto, required ${required}.` };
141
+ }
142
+ return {
143
+ ok: true,
144
+ receipt: {
145
+ scheme: "onchain-proof",
146
+ success: true,
147
+ network: accept.network,
148
+ transaction: hash,
149
+ asset: "native",
150
+ amount: accept.amount,
151
+ payer: senderId,
152
+ payTo: accept.payTo,
153
+ verifiedAt: (/* @__PURE__ */ new Date()).toISOString()
154
+ }
155
+ };
156
+ }
106
157
  if (typeof tx.timestampMs === "number") {
107
158
  const ageSeconds = Math.floor(Date.now() / 1e3) - Math.floor(tx.timestampMs / 1e3);
108
159
  if (ageSeconds > accept.maxTimeoutSeconds) {
@@ -232,7 +283,21 @@ function makeNearNetwork(preset, rpcUrl) {
232
283
  executorId: r.outcome.executor_id,
233
284
  logs: r.outcome.logs ?? []
234
285
  }));
235
- return { success, receipts };
286
+ const txn = outcome.transaction;
287
+ const receiverId = txn?.receiver_id;
288
+ const nativeDeposit = sumTransferDeposits(txn?.actions).toString();
289
+ let timestampMs;
290
+ try {
291
+ const blockHash = outcome.transaction_outcome?.block_hash;
292
+ if (blockHash) {
293
+ const block = await provider.viewBlock({ blockId: blockHash });
294
+ const header = block.header;
295
+ const ns = header?.timestamp_nanosec ?? (header?.timestamp != null ? String(header.timestamp) : void 0);
296
+ if (ns != null) timestampMs = Number(BigInt(ns) / 1000000n);
297
+ }
298
+ } catch {
299
+ }
300
+ return { success, receipts, receiverId, nativeDeposit, timestampMs };
236
301
  }
237
302
  };
238
303
  return {
@@ -241,9 +306,7 @@ function makeNearNetwork(preset, rpcUrl) {
241
306
  supports: (n) => n === network,
242
307
  resolveToken(token) {
243
308
  if (token === "native") {
244
- throw new UnknownTokenError(
245
- `NEAR payments are NEP-141 token only \u2014 native NEAR isn't a built-in payment asset (a native transfer carries no memo to bind the payment). Use 'USDC' / 'USDT' or a custom { contractId, decimals }.`
246
- );
309
+ return { asset: "native", decimals: NEAR_DECIMALS, symbol: "NEAR" };
247
310
  }
248
311
  if (typeof token === "string") {
249
312
  const info = preset.tokens[token.toUpperCase()];
@@ -269,7 +332,7 @@ function makeNearNetwork(preset, rpcUrl) {
269
332
  };
270
333
  },
271
334
  describeAsset(asset) {
272
- if (asset === "native") return null;
335
+ if (asset === "native") return { symbol: "NEAR", decimals: NEAR_DECIMALS };
273
336
  for (const info of Object.values(preset.tokens)) {
274
337
  if (info.contractId === asset) return { symbol: info.symbol, decimals: info.decimals };
275
338
  }
@@ -293,6 +356,11 @@ function makeNearNetwork(preset, rpcUrl) {
293
356
  async send(wallet, accept) {
294
357
  const { accountId, signer } = resolveNearWallet(wallet._native);
295
358
  const account = new Account(accountId, provider, signer);
359
+ const hashOf = (outcome) => {
360
+ const hash2 = outcome.transaction?.hash;
361
+ if (!hash2) throw new Error("NEAR: signAndSendTransaction returned no tx hash.");
362
+ return hash2;
363
+ };
296
364
  const client = {
297
365
  async ftTransfer({ contractId, receiverId, amount, memo, gas, deposit }) {
298
366
  const outcome = await account.signAndSendTransaction({
@@ -301,12 +369,17 @@ function makeNearNetwork(preset, rpcUrl) {
301
369
  actions.functionCall("ft_transfer", { receiver_id: receiverId, amount, memo }, gas, deposit)
302
370
  ]
303
371
  });
304
- const hash2 = outcome.transaction?.hash;
305
- if (!hash2) throw new Error("NEAR: signAndSendTransaction returned no tx hash.");
306
- return { hash: hash2 };
372
+ return { hash: hashOf(outcome) };
373
+ },
374
+ async nativeTransfer({ receiverId, amount }) {
375
+ const outcome = await account.signAndSendTransaction({
376
+ receiverId,
377
+ actions: [actions.transfer(BigInt(amount))]
378
+ });
379
+ return { hash: hashOf(outcome) };
307
380
  }
308
381
  };
309
- const hash = await payNear({ client, accept });
382
+ const hash = accept.asset === "native" ? await payNearNative({ client, accept }) : await payNear({ client, accept });
310
383
  return encodeRef(accountId, hash);
311
384
  },
312
385
  async confirm(ref) {
@@ -341,6 +414,20 @@ function decodeRef(ref) {
341
414
  if (i < 0) return { senderId: "", hash: ref };
342
415
  return { senderId: ref.slice(0, i), hash: ref.slice(i + 1) };
343
416
  }
417
+ function sumTransferDeposits(actions2) {
418
+ if (!Array.isArray(actions2)) return 0n;
419
+ let sum = 0n;
420
+ for (const a of actions2) {
421
+ const t = a.Transfer ?? a.transfer;
422
+ if (t && t.deposit != null) {
423
+ try {
424
+ sum += BigInt(t.deposit);
425
+ } catch {
426
+ }
427
+ }
428
+ }
429
+ return sum;
430
+ }
344
431
  export {
345
432
  nearDriver
346
433
  };
@@ -6,7 +6,8 @@
6
6
 
7
7
 
8
8
 
9
- var _chunkWQWNPAYQcjs = require('./chunk-WQWNPAYQ.cjs');
9
+
10
+ var _chunkNK64H3RMcjs = require('./chunk-NK64H3RM.cjs');
10
11
 
11
12
  // src/drivers/near/index.ts
12
13
  var _nearapijs = require('near-api-js');
@@ -52,18 +53,33 @@ async function payNear(params) {
52
53
  return res.hash;
53
54
  } catch (err) {
54
55
  if (isNearRegistrationError(err)) {
55
- throw new Error(
56
- `NEAR ft_transfer failed: recipient ${accept.payTo} isn't registered on token ${accept.asset} (NEP-145 storage_deposit). Register it once (\u22480.00125 NEAR) before it can receive.`,
56
+ throw new (0, _chunkNK64H3RMcjs.RecipientNotReadyError)(
57
+ `NEAR recipient ${accept.payTo} isn't registered on token ${accept.asset} (NEP-145 storage_deposit) \u2014 register it once (\u22480.00125 NEAR) before it can receive. (NEAR: not registered)`,
57
58
  { cause: err }
58
59
  );
59
60
  }
60
61
  if (isNearAffordability(err)) {
61
- throw new (0, _chunkWQWNPAYQcjs.InsufficientFundsError)(
62
+ throw new (0, _chunkNK64H3RMcjs.InsufficientFundsError)(
62
63
  err instanceof Error ? err.message : "Insufficient NEAR balance for the payment.",
63
64
  { cause: err }
64
65
  );
65
66
  }
66
- throw _nullishCoalesce(_chunkWQWNPAYQcjs.toInsufficientFundsError.call(void 0, err), () => ( err));
67
+ throw _nullishCoalesce(_chunkNK64H3RMcjs.toInsufficientFundsError.call(void 0, err), () => ( err));
68
+ }
69
+ }
70
+ async function payNearNative(params) {
71
+ const { client, accept } = params;
72
+ try {
73
+ const res = await client.nativeTransfer({ receiverId: accept.payTo, amount: accept.amount });
74
+ return res.hash;
75
+ } catch (err) {
76
+ if (isNearAffordability(err)) {
77
+ throw new (0, _chunkNK64H3RMcjs.InsufficientFundsError)(
78
+ err instanceof Error ? err.message : "Insufficient NEAR balance for the payment.",
79
+ { cause: err }
80
+ );
81
+ }
82
+ throw _nullishCoalesce(_chunkNK64H3RMcjs.toInsufficientFundsError.call(void 0, err), () => ( err));
67
83
  }
68
84
  }
69
85
  function isNearRegistrationError(err) {
@@ -103,6 +119,41 @@ async function verifyNear(params) {
103
119
  if (!tx.success) {
104
120
  return { ok: false, error: "tx_reverted", detail: `NEAR tx ${hash} failed on-chain.` };
105
121
  }
122
+ if (accept.asset === "native") {
123
+ if (typeof tx.timestampMs !== "number") {
124
+ return { ok: false, error: "payment_expired", detail: `Cannot bound the age of native NEAR tx ${hash} (no block time) \u2014 failing closed.` };
125
+ }
126
+ const ageSeconds = Math.floor(Date.now() / 1e3) - Math.floor(tx.timestampMs / 1e3);
127
+ if (ageSeconds > accept.maxTimeoutSeconds) {
128
+ return { ok: false, error: "payment_expired", detail: `Payment is ${ageSeconds}s old; max allowed is ${accept.maxTimeoutSeconds}s.` };
129
+ }
130
+ if (tx.receiverId !== accept.payTo) {
131
+ return { ok: false, error: "transfer_not_found", detail: `Native NEAR tx ${hash} did not pay ${accept.payTo} (receiver ${_nullishCoalesce(tx.receiverId, () => ( "unknown"))}).` };
132
+ }
133
+ let paid2;
134
+ try {
135
+ paid2 = BigInt(_nullishCoalesce(tx.nativeDeposit, () => ( "0")));
136
+ } catch (e3) {
137
+ paid2 = 0n;
138
+ }
139
+ if (paid2 < required) {
140
+ return { ok: false, error: "amount_too_low", detail: `Native NEAR transfer to ${accept.payTo} was ${paid2} yocto, required ${required}.` };
141
+ }
142
+ return {
143
+ ok: true,
144
+ receipt: {
145
+ scheme: "onchain-proof",
146
+ success: true,
147
+ network: accept.network,
148
+ transaction: hash,
149
+ asset: "native",
150
+ amount: accept.amount,
151
+ payer: senderId,
152
+ payTo: accept.payTo,
153
+ verifiedAt: (/* @__PURE__ */ new Date()).toISOString()
154
+ }
155
+ };
156
+ }
106
157
  if (typeof tx.timestampMs === "number") {
107
158
  const ageSeconds = Math.floor(Date.now() / 1e3) - Math.floor(tx.timestampMs / 1e3);
108
159
  if (ageSeconds > accept.maxTimeoutSeconds) {
@@ -124,7 +175,7 @@ async function verifyNear(params) {
124
175
  if (d.new_owner_id === accept.payTo && (_nullishCoalesce(d.memo, () => ( ""))) === nonce) {
125
176
  try {
126
177
  paid += BigInt(_nullishCoalesce(d.amount, () => ( "0")));
127
- } catch (e3) {
178
+ } catch (e4) {
128
179
  }
129
180
  if (!payer) payer = _nullishCoalesce(d.old_owner_id, () => ( ""));
130
181
  }
@@ -165,22 +216,22 @@ function txNotFound(hash) {
165
216
 
166
217
  function assertNearWallet(wallet, network) {
167
218
  if (typeof wallet !== "object" || wallet === null) {
168
- throw new (0, _chunkWQWNPAYQcjs.WrongFamilyError)(
219
+ throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
169
220
  `chain ${network} is NEAR; wallet must be { accountId, privateKey } (privateKey = ed25519:\u2026).`
170
221
  );
171
222
  }
172
223
  if ("walletClient" in wallet) {
173
- throw new (0, _chunkWQWNPAYQcjs.WrongFamilyError)(
224
+ throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
174
225
  `chain ${network} is NEAR; a viem { walletClient } can't be used \u2014 pass { accountId, privateKey }.`
175
226
  );
176
227
  }
177
228
  if ("secretKey" in wallet || "signer" in wallet || "mnemonic" in wallet || "keyPair" in wallet || "secret" in wallet || "seed" in wallet || "keypair" in wallet) {
178
- throw new (0, _chunkWQWNPAYQcjs.WrongFamilyError)(
229
+ throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
179
230
  `chain ${network} is NEAR; that looks like another family's wallet \u2014 pass { accountId, privateKey }.`
180
231
  );
181
232
  }
182
233
  if (!("accountId" in wallet) || !("privateKey" in wallet)) {
183
- throw new (0, _chunkWQWNPAYQcjs.WrongFamilyError)(
234
+ throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
184
235
  `chain ${network} is NEAR; wallet must be { accountId, privateKey } (privateKey = ed25519:\u2026).`
185
236
  );
186
237
  }
@@ -188,13 +239,13 @@ function assertNearWallet(wallet, network) {
188
239
  }
189
240
  function resolveNearWallet(config) {
190
241
  if (!config.accountId || !config.privateKey) {
191
- throw new (0, _chunkWQWNPAYQcjs.WrongFamilyError)("NEAR wallet needs { accountId, privateKey } (privateKey = ed25519:\u2026).");
242
+ throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)("NEAR wallet needs { accountId, privateKey } (privateKey = ed25519:\u2026).");
192
243
  }
193
244
  let signer;
194
245
  try {
195
246
  signer = _nearapijs.KeyPairSigner.fromSecretKey(config.privateKey);
196
247
  } catch (cause) {
197
- throw new (0, _chunkWQWNPAYQcjs.WrongFamilyError)("NEAR wallet { privateKey } is not a valid ed25519:\u2026 secret key.", {
248
+ throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)("NEAR wallet { privateKey } is not a valid ed25519:\u2026 secret key.", {
198
249
  cause
199
250
  });
200
251
  }
@@ -232,7 +283,21 @@ function makeNearNetwork(preset, rpcUrl) {
232
283
  executorId: r.outcome.executor_id,
233
284
  logs: _nullishCoalesce(r.outcome.logs, () => ( []))
234
285
  }));
235
- return { success, receipts };
286
+ const txn = outcome.transaction;
287
+ const receiverId = _optionalChain([txn, 'optionalAccess', _ => _.receiver_id]);
288
+ const nativeDeposit = sumTransferDeposits(_optionalChain([txn, 'optionalAccess', _2 => _2.actions])).toString();
289
+ let timestampMs;
290
+ try {
291
+ const blockHash = _optionalChain([outcome, 'access', _3 => _3.transaction_outcome, 'optionalAccess', _4 => _4.block_hash]);
292
+ if (blockHash) {
293
+ const block = await provider.viewBlock({ blockId: blockHash });
294
+ const header = block.header;
295
+ const ns = _nullishCoalesce(_optionalChain([header, 'optionalAccess', _5 => _5.timestamp_nanosec]), () => ( (_optionalChain([header, 'optionalAccess', _6 => _6.timestamp]) != null ? String(header.timestamp) : void 0)));
296
+ if (ns != null) timestampMs = Number(BigInt(ns) / 1000000n);
297
+ }
298
+ } catch (e5) {
299
+ }
300
+ return { success, receipts, receiverId, nativeDeposit, timestampMs };
236
301
  }
237
302
  };
238
303
  return {
@@ -241,24 +306,22 @@ function makeNearNetwork(preset, rpcUrl) {
241
306
  supports: (n) => n === network,
242
307
  resolveToken(token) {
243
308
  if (token === "native") {
244
- throw new (0, _chunkWQWNPAYQcjs.UnknownTokenError)(
245
- `NEAR payments are NEP-141 token only \u2014 native NEAR isn't a built-in payment asset (a native transfer carries no memo to bind the payment). Use 'USDC' / 'USDT' or a custom { contractId, decimals }.`
246
- );
309
+ return { asset: "native", decimals: NEAR_DECIMALS, symbol: "NEAR" };
247
310
  }
248
311
  if (typeof token === "string") {
249
312
  const info = preset.tokens[token.toUpperCase()];
250
313
  if (!info) {
251
314
  const known = Object.keys(preset.tokens).join(", ") || "(none built in)";
252
- throw new (0, _chunkWQWNPAYQcjs.UnknownTokenError)(
315
+ throw new (0, _chunkNK64H3RMcjs.UnknownTokenError)(
253
316
  `token "${token}" isn't built in for NEAR (known: ${known}). Pass { contractId, decimals } for a custom NEP-141.`
254
317
  );
255
318
  }
256
319
  return { asset: info.contractId, decimals: info.decimals, symbol: info.symbol };
257
320
  }
258
- _chunkWQWNPAYQcjs.rejectForeignToken.call(void 0, token, "near", network);
321
+ _chunkNK64H3RMcjs.rejectForeignToken.call(void 0, token, "near", network);
259
322
  const t = token;
260
323
  if (!t.contractId || typeof t.decimals !== "number") {
261
- throw new (0, _chunkWQWNPAYQcjs.WrongFamilyError)(
324
+ throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
262
325
  `chain ${network} is NEAR; a custom token must be { contractId, decimals }.`
263
326
  );
264
327
  }
@@ -269,7 +332,7 @@ function makeNearNetwork(preset, rpcUrl) {
269
332
  };
270
333
  },
271
334
  describeAsset(asset) {
272
- if (asset === "native") return null;
335
+ if (asset === "native") return { symbol: "NEAR", decimals: NEAR_DECIMALS };
273
336
  for (const info of Object.values(preset.tokens)) {
274
337
  if (info.contractId === asset) return { symbol: info.symbol, decimals: info.decimals };
275
338
  }
@@ -277,12 +340,12 @@ function makeNearNetwork(preset, rpcUrl) {
277
340
  },
278
341
  assertValidPayTo(payTo) {
279
342
  if (payTo.startsWith("0x")) {
280
- throw new (0, _chunkWQWNPAYQcjs.WrongFamilyError)(
343
+ throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
281
344
  `chain ${network} is NEAR, but payTo "${payTo}" looks like an EVM/Sui 0x address.`
282
345
  );
283
346
  }
284
347
  if (!isValidNearAccountId(payTo)) {
285
- throw new (0, _chunkWQWNPAYQcjs.WrongFamilyError)(
348
+ throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
286
349
  `chain ${network} is NEAR, but payTo "${payTo}" is not a valid NEAR account id.`
287
350
  );
288
351
  }
@@ -293,6 +356,11 @@ function makeNearNetwork(preset, rpcUrl) {
293
356
  async send(wallet, accept) {
294
357
  const { accountId, signer } = resolveNearWallet(wallet._native);
295
358
  const account = new (0, _nearapijs.Account)(accountId, provider, signer);
359
+ const hashOf = (outcome) => {
360
+ const hash2 = _optionalChain([outcome, 'access', _7 => _7.transaction, 'optionalAccess', _8 => _8.hash]);
361
+ if (!hash2) throw new Error("NEAR: signAndSendTransaction returned no tx hash.");
362
+ return hash2;
363
+ };
296
364
  const client = {
297
365
  async ftTransfer({ contractId, receiverId, amount, memo, gas, deposit }) {
298
366
  const outcome = await account.signAndSendTransaction({
@@ -301,12 +369,17 @@ function makeNearNetwork(preset, rpcUrl) {
301
369
  _nearapijs.actions.functionCall("ft_transfer", { receiver_id: receiverId, amount, memo }, gas, deposit)
302
370
  ]
303
371
  });
304
- const hash2 = _optionalChain([outcome, 'access', _ => _.transaction, 'optionalAccess', _2 => _2.hash]);
305
- if (!hash2) throw new Error("NEAR: signAndSendTransaction returned no tx hash.");
306
- return { hash: hash2 };
372
+ return { hash: hashOf(outcome) };
373
+ },
374
+ async nativeTransfer({ receiverId, amount }) {
375
+ const outcome = await account.signAndSendTransaction({
376
+ receiverId,
377
+ actions: [_nearapijs.actions.transfer(BigInt(amount))]
378
+ });
379
+ return { hash: hashOf(outcome) };
307
380
  }
308
381
  };
309
- const hash = await payNear({ client, accept });
382
+ const hash = accept.asset === "native" ? await payNearNative({ client, accept }) : await payNear({ client, accept });
310
383
  return encodeRef(accountId, hash);
311
384
  },
312
385
  async confirm(ref) {
@@ -314,12 +387,12 @@ function makeNearNetwork(preset, rpcUrl) {
314
387
  try {
315
388
  const tx = await reader.txStatus(hash, senderId);
316
389
  if (tx && tx.success) return { height: "0" };
317
- } catch (e4) {
390
+ } catch (e6) {
318
391
  }
319
- throw new (0, _chunkWQWNPAYQcjs.ConfirmationTimeoutError)(`NEAR tx ${hash} not confirmed in time.`);
392
+ throw new (0, _chunkNK64H3RMcjs.ConfirmationTimeoutError)(`NEAR tx ${hash} not confirmed in time.`);
320
393
  },
321
394
  async estimateCost() {
322
- return _chunkWQWNPAYQcjs.nativeCost.call(void 0, {
395
+ return _chunkNK64H3RMcjs.nativeCost.call(void 0, {
323
396
  symbol: "NEAR",
324
397
  decimals: NEAR_DECIMALS,
325
398
  fee: 1500000000000000000000n,
@@ -341,6 +414,20 @@ function decodeRef(ref) {
341
414
  if (i < 0) return { senderId: "", hash: ref };
342
415
  return { senderId: ref.slice(0, i), hash: ref.slice(i + 1) };
343
416
  }
417
+ function sumTransferDeposits(actions2) {
418
+ if (!Array.isArray(actions2)) return 0n;
419
+ let sum = 0n;
420
+ for (const a of actions2) {
421
+ const t = _nullishCoalesce(a.Transfer, () => ( a.transfer));
422
+ if (t && t.deposit != null) {
423
+ try {
424
+ sum += BigInt(t.deposit);
425
+ } catch (e7) {
426
+ }
427
+ }
428
+ }
429
+ return sum;
430
+ }
344
431
 
345
432
 
346
433
  exports.nearDriver = nearDriver;
@@ -5,7 +5,7 @@
5
5
 
6
6
 
7
7
 
8
- var _chunkWQWNPAYQcjs = require('./chunk-WQWNPAYQ.cjs');
8
+ var _chunkNK64H3RMcjs = require('./chunk-NK64H3RM.cjs');
9
9
 
10
10
  // src/drivers/solana/index.ts
11
11
  var _web3js = require('@solana/web3.js');
@@ -199,12 +199,12 @@ function notFound(signature) {
199
199
  var _bs58 = require('bs58'); var _bs582 = _interopRequireDefault(_bs58);
200
200
  function toKeypair(wallet, network) {
201
201
  if (typeof wallet !== "object" || wallet === null) {
202
- throw new (0, _chunkWQWNPAYQcjs.WrongFamilyError)(
202
+ throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
203
203
  `chain ${network} is Solana; wallet must be { secretKey } or { signer }.`
204
204
  );
205
205
  }
206
206
  if ("privateKey" in wallet || "walletClient" in wallet) {
207
- throw new (0, _chunkWQWNPAYQcjs.WrongFamilyError)(
207
+ throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
208
208
  `chain ${network} is Solana; an EVM wallet can't be used \u2014 pass { secretKey } or { signer }.`
209
209
  );
210
210
  }
@@ -216,7 +216,7 @@ function toKeypair(wallet, network) {
216
216
  const bytes = typeof sk === "string" ? _bs582.default.decode(sk) : sk;
217
217
  return _web3js.Keypair.fromSecretKey(bytes);
218
218
  }
219
- throw new (0, _chunkWQWNPAYQcjs.WrongFamilyError)(
219
+ throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
220
220
  `chain ${network} is Solana; wallet must be { secretKey } or { signer }.`
221
221
  );
222
222
  }
@@ -245,15 +245,15 @@ function makeSolanaNetwork(preset, rpcUrl) {
245
245
  const info = preset.tokens[token.toUpperCase()];
246
246
  if (!info) {
247
247
  const known = Object.keys(preset.tokens).join(", ") || "(none built in)";
248
- throw new (0, _chunkWQWNPAYQcjs.UnknownTokenError)(
248
+ throw new (0, _chunkNK64H3RMcjs.UnknownTokenError)(
249
249
  `token "${token}" isn't built in for Solana (known: ${known}). Pass { mint, decimals } instead, or use 'native'.`
250
250
  );
251
251
  }
252
252
  return { asset: info.mint, decimals: info.decimals, symbol: info.symbol };
253
253
  }
254
- _chunkWQWNPAYQcjs.rejectForeignToken.call(void 0, token, "solana", network);
254
+ _chunkNK64H3RMcjs.rejectForeignToken.call(void 0, token, "solana", network);
255
255
  if (!("mint" in token)) {
256
- throw new (0, _chunkWQWNPAYQcjs.WrongFamilyError)(
256
+ throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
257
257
  `chain ${network} is Solana; a custom token must be { mint, decimals }.`
258
258
  );
259
259
  }
@@ -272,14 +272,14 @@ function makeSolanaNetwork(preset, rpcUrl) {
272
272
  },
273
273
  assertValidPayTo(payTo) {
274
274
  if (payTo.startsWith("0x")) {
275
- throw new (0, _chunkWQWNPAYQcjs.WrongFamilyError)(
275
+ throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
276
276
  `chain ${network} is Solana, but payTo "${payTo}" looks like an EVM address.`
277
277
  );
278
278
  }
279
279
  try {
280
280
  new (0, _web3js.PublicKey)(payTo);
281
281
  } catch (e2) {
282
- throw new (0, _chunkWQWNPAYQcjs.WrongFamilyError)(
282
+ throw new (0, _chunkNK64H3RMcjs.WrongFamilyError)(
283
283
  `chain ${network} is Solana, but payTo "${payTo}" is not a base58 address.`
284
284
  );
285
285
  }
@@ -291,7 +291,7 @@ function makeSolanaNetwork(preset, rpcUrl) {
291
291
  try {
292
292
  return await paySolana({ connection, keypair: wallet._native, accept });
293
293
  } catch (err) {
294
- throw _nullishCoalesce(_chunkWQWNPAYQcjs.toInsufficientFundsError.call(void 0, err), () => ( err));
294
+ throw _nullishCoalesce(_chunkNK64H3RMcjs.toInsufficientFundsError.call(void 0, err), () => ( err));
295
295
  }
296
296
  },
297
297
  async confirm(ref) {
@@ -302,20 +302,20 @@ function makeSolanaNetwork(preset, rpcUrl) {
302
302
  });
303
303
  info = value[0];
304
304
  } catch (err) {
305
- throw new (0, _chunkWQWNPAYQcjs.ConfirmationTimeoutError)(
305
+ throw new (0, _chunkNK64H3RMcjs.ConfirmationTimeoutError)(
306
306
  `Solana payment ${ref} could not be confirmed (RPC read failed).`,
307
307
  { cause: err }
308
308
  );
309
309
  }
310
310
  if (!info || info.err || info.confirmationStatus !== "confirmed" && info.confirmationStatus !== "finalized") {
311
- throw new (0, _chunkWQWNPAYQcjs.ConfirmationTimeoutError)(`Solana payment ${ref} did not confirm in time.`);
311
+ throw new (0, _chunkNK64H3RMcjs.ConfirmationTimeoutError)(`Solana payment ${ref} did not confirm in time.`);
312
312
  }
313
313
  return { height: String(info.slot) };
314
314
  },
315
315
  async estimateCost(accept) {
316
316
  const base = 5000n;
317
317
  if (accept.asset === "native") {
318
- return _chunkWQWNPAYQcjs.nativeCost.call(void 0, {
318
+ return _chunkNK64H3RMcjs.nativeCost.call(void 0, {
319
319
  symbol: "SOL",
320
320
  decimals: SOL_DECIMALS,
321
321
  fee: base,
@@ -324,7 +324,7 @@ function makeSolanaNetwork(preset, rpcUrl) {
324
324
  });
325
325
  }
326
326
  const ataRent = 2039280n;
327
- return _chunkWQWNPAYQcjs.nativeCost.call(void 0, {
327
+ return _chunkNK64H3RMcjs.nativeCost.call(void 0, {
328
328
  symbol: "SOL",
329
329
  decimals: SOL_DECIMALS,
330
330
  fee: base + ataRent,
@@ -5,7 +5,7 @@ import {
5
5
  nativeCost,
6
6
  rejectForeignToken,
7
7
  toInsufficientFundsError
8
- } from "./chunk-3TQJJ4SQ.js";
8
+ } from "./chunk-DTIJYDG6.js";
9
9
 
10
10
  // src/drivers/solana/index.ts
11
11
  import { Connection, PublicKey as PublicKey2 } from "@solana/web3.js";
@@ -4,13 +4,14 @@ import {
4
4
  import {
5
5
  ConfirmationTimeoutError,
6
6
  InsufficientFundsError,
7
+ RecipientNotReadyError,
7
8
  UnknownTokenError,
8
9
  WrongFamilyError,
9
10
  nativeCost,
10
11
  parseUnits,
11
12
  rejectForeignToken,
12
13
  toInsufficientFundsError
13
- } from "./chunk-3TQJJ4SQ.js";
14
+ } from "./chunk-DTIJYDG6.js";
14
15
 
15
16
  // src/drivers/stellar/index.ts
16
17
  import { Horizon, StrKey as StrKey2 } from "@stellar/stellar-sdk";
@@ -93,15 +94,29 @@ function assetForAccept(accept) {
93
94
  }
94
95
  function mapSubmitError(err) {
95
96
  const codes = extractResultCodes(err);
96
- if (codes.some((c) => /underfunded|insufficient|low_reserve|no_trust/i.test(c))) {
97
+ const seen = codes.join(", ");
98
+ const has = (re) => codes.some((c) => re.test(c));
99
+ if (has(/op_no_destination/i)) {
100
+ return new RecipientNotReadyError(
101
+ `Stellar destination account doesn't exist yet \u2014 create it with \u22651 XLM (the base reserve) before it can receive. (Stellar: ${seen})`,
102
+ { cause: err }
103
+ );
104
+ }
105
+ if (has(/op_(no_trust|line_full|not_authorized)/i) && !has(/src_no_trust/i)) {
106
+ return new RecipientNotReadyError(
107
+ `Stellar destination can't hold this asset \u2014 it needs a trustline for it (and to be authorized) before it can receive. (Stellar: ${seen})`,
108
+ { cause: err }
109
+ );
110
+ }
111
+ if (has(/underfunded|insufficient|low_reserve|src_no_trust/i)) {
97
112
  return new InsufficientFundsError(
98
- "Stellar payment failed: insufficient balance/reserve, or the sender has no trustline for this asset.",
113
+ `Stellar payment failed: the sender can't cover it \u2014 balance, base reserve, or no trustline to send this asset. (Stellar: ${seen})`,
99
114
  { cause: err }
100
115
  );
101
116
  }
102
117
  if (isAccountNotFound(err)) {
103
118
  return new InsufficientFundsError(
104
- "Stellar source account not found on-chain \u2014 fund it (\u2265 base reserve) before it can pay.",
119
+ "Stellar source account not found on-chain \u2014 fund the sender (\u2265 base reserve) before it can pay.",
105
120
  { cause: err }
106
121
  );
107
122
  }