@anywalletkit/protocol-swap2-core 0.5.0 → 0.6.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/README.md +1 -1
- package/dist/{chunk-IC3MZIMB.js → chunk-IGTMUTNJ.js} +39 -16
- package/dist/chunk-IGTMUTNJ.js.map +1 -0
- package/dist/{chunk-OWO27YBK.js → chunk-JFGMF6FO.js} +2 -2
- package/dist/{chunk-3Y6HV2OL.js → chunk-ZMWK3RQ4.js} +3 -2
- package/dist/chunk-ZMWK3RQ4.js.map +1 -0
- package/dist/index.cjs +40 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/dist/remote.cjs +2 -1
- package/dist/remote.cjs.map +1 -1
- package/dist/remote.d.cts +6 -0
- package/dist/remote.d.ts +6 -0
- package/dist/remote.js +1 -1
- package/dist/swap2/base.cjs +38 -15
- package/dist/swap2/base.cjs.map +1 -1
- package/dist/swap2/base.js +1 -1
- package/dist/swap2/single.cjs +38 -15
- package/dist/swap2/single.cjs.map +1 -1
- package/dist/swap2/single.js +2 -2
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +7 -0
- package/dist/types.d.ts +7 -0
- package/package.json +10 -8
- package/dist/chunk-3Y6HV2OL.js.map +0 -1
- package/dist/chunk-IC3MZIMB.js.map +0 -1
- /package/dist/{chunk-OWO27YBK.js.map → chunk-JFGMF6FO.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -266,7 +266,8 @@ function remoteProvider(opts) {
|
|
|
266
266
|
},
|
|
267
267
|
...opts.supportsChain ? { supportsChain: opts.supportsChain.bind(opts) } : {},
|
|
268
268
|
...opts.supportsChainPair ? { supportsChainPair: opts.supportsChainPair.bind(opts) } : {},
|
|
269
|
-
...opts.supportsSameChain !== void 0 ? { supportsSameChain: opts.supportsSameChain } : {}
|
|
269
|
+
...opts.supportsSameChain !== void 0 ? { supportsSameChain: opts.supportsSameChain } : {},
|
|
270
|
+
...opts.claimTargets ? { claimTargets: opts.claimTargets } : {}
|
|
270
271
|
};
|
|
271
272
|
}
|
|
272
273
|
|
|
@@ -297,12 +298,14 @@ var inFlightKey = (fromChain, o) => JSON.stringify(
|
|
|
297
298
|
[fromChain, o.fromToken, o.toToken, o.toChain, o.recipient, o.refundAddress, o.fromTokenAmount, o.toTokenAmount, o.minAmountOut, o.slippage],
|
|
298
299
|
(_k, v) => typeof v === "bigint" ? v.toString() : v
|
|
299
300
|
);
|
|
301
|
+
var LOST_ANSWER = /socket hang up|ECONNRESET|ECONNABORTED|ETIMEDOUT|EPIPE|ENETUNREACH|EHOSTUNREACH|EAI_AGAIN|UND_ERR_[A-Z_]+|timed? ?out|TimeoutError|request aborted|AbortError|connection (?:closed|reset)|fetch failed|failed to fetch|network request failed|other side closed/i;
|
|
300
302
|
function maybeSent(error) {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
|
|
303
|
+
const chain = [];
|
|
304
|
+
for (let e = error, i = 0; e && typeof e === "object" && i < 6; e = e.cause, i++) chain.push(e);
|
|
305
|
+
for (const e of chain) if (e.maybeSent === true) return typeof e.hash === "string" && e.hash ? { hash: e.hash } : {};
|
|
306
|
+
if (chain.some((e) => e.answered === true)) return null;
|
|
307
|
+
const texts = chain.length ? chain.map((e) => [e.message, e.code, e.name].filter((x) => typeof x === "string").join(" ")) : [String(error)];
|
|
308
|
+
return texts.some((t) => LOST_ANSWER.test(t)) ? {} : null;
|
|
306
309
|
}
|
|
307
310
|
var NATIVE_DECIMALS = Object.freeze({
|
|
308
311
|
"eip155:5042": 18
|
|
@@ -386,22 +389,24 @@ function reviewedIdentity(plan) {
|
|
|
386
389
|
return JSON.stringify(pinned, (_k, v) => typeof v === "bigint" ? v.toString() : v);
|
|
387
390
|
}
|
|
388
391
|
var SWAP2_ID_PREFIX = "awk1";
|
|
389
|
-
function encodeId(provider, intentId, sourceTxHash) {
|
|
392
|
+
function encodeId(provider, intentId, sourceTxHash, destTxHash) {
|
|
390
393
|
const enc = (v) => encodeURIComponent(v).replace(/\./g, "%2E");
|
|
391
|
-
|
|
394
|
+
const parts = [provider, intentId, ...sourceTxHash != null ? [sourceTxHash, ...destTxHash != null ? [destTxHash] : []] : []];
|
|
395
|
+
return `${SWAP2_ID_PREFIX}.${parts.map(enc).join(".")}`;
|
|
392
396
|
}
|
|
393
397
|
function decodeId(id) {
|
|
394
398
|
try {
|
|
395
399
|
if (!id.startsWith(`${SWAP2_ID_PREFIX}.`)) throw new Error("unsupported id version");
|
|
396
400
|
const parts = id.slice(SWAP2_ID_PREFIX.length + 1).split(".");
|
|
397
|
-
if (parts.length < 2 || parts.length >
|
|
401
|
+
if (parts.length < 2 || parts.length > 4 || !parts[0] || !parts[1]) throw new Error("invalid id shape");
|
|
398
402
|
const provider = decodeURIComponent(parts[0]);
|
|
399
403
|
const intentId = decodeURIComponent(parts[1]);
|
|
400
404
|
const sourceTxHash = parts[2] ? decodeURIComponent(parts[2]) : void 0;
|
|
401
|
-
|
|
405
|
+
const destTxHash = parts[3] ? decodeURIComponent(parts[3]) : void 0;
|
|
406
|
+
if (!/^[A-Za-z0-9_-]+$/.test(provider) || !intentId || parts[2] !== void 0 && !sourceTxHash || parts[3] !== void 0 && !destTxHash) {
|
|
402
407
|
throw new Error("invalid id contents");
|
|
403
408
|
}
|
|
404
|
-
return { provider, intentId, ...sourceTxHash ? { sourceTxHash } : {} };
|
|
409
|
+
return { provider, intentId, ...sourceTxHash ? { sourceTxHash } : {}, ...destTxHash ? { destTxHash } : {} };
|
|
405
410
|
} catch {
|
|
406
411
|
throw new Swap2ValidationError("swap2: malformed swap2 status id");
|
|
407
412
|
}
|
|
@@ -453,13 +458,19 @@ function toCaip2(chain, fallback) {
|
|
|
453
458
|
}
|
|
454
459
|
return swap2ChainId(chain);
|
|
455
460
|
}
|
|
461
|
+
function nonEmptyRef(ref, side) {
|
|
462
|
+
if (typeof ref !== "string" || ref.trim() === "") throw new Swap2ValidationError(`swap2: ${side} token must not be empty (pass the symbol or the contract address)`);
|
|
463
|
+
return ref;
|
|
464
|
+
}
|
|
456
465
|
function toSymbol(caip2, ref) {
|
|
466
|
+
nonEmptyRef(ref, "source");
|
|
457
467
|
const byToken = ref.startsWith("0x") || ref.length > 20 ? (0, import_swap2_assets2.ccAssetByToken)(caip2, ref) : void 0;
|
|
458
468
|
if (byToken) return byToken.symbol;
|
|
459
469
|
if ((0, import_swap2_assets2.ccAsset)(caip2, ref)) return ref;
|
|
460
470
|
return ref;
|
|
461
471
|
}
|
|
462
472
|
function toDestAddress(caip2, ref, allowUnlisted = false) {
|
|
473
|
+
nonEmptyRef(ref, "destination");
|
|
463
474
|
if (ref.startsWith("0x")) return ref;
|
|
464
475
|
const asset = (0, import_swap2_assets2.ccAssetByToken)(caip2, ref) ?? (0, import_swap2_assets2.ccAsset)(caip2, ref);
|
|
465
476
|
if (!asset) {
|
|
@@ -827,7 +838,7 @@ var BaseSwap2Protocol = class extends import_core.Swap2Protocol {
|
|
|
827
838
|
throw new Error("swap2: provider build does not match the validated quote transaction");
|
|
828
839
|
}
|
|
829
840
|
} else if (!unsigned.bodyBoc && !unsigned.typedData) {
|
|
830
|
-
if (!q.depositAddress || unsigned.to !== q.depositAddress || (unsigned.memo ?? null) !== q.depositMemo) {
|
|
841
|
+
if (!q.depositAddress || unsigned.to !== q.depositAddress || (unsigned.memo ?? null) !== q.depositMemo || unsigned.data !== void 0 || unsigned.approvalAddress !== void 0 || unsigned.serializedTx !== void 0) {
|
|
831
842
|
throw new Error("swap2: provider build does not match the validated quote deposit");
|
|
832
843
|
}
|
|
833
844
|
}
|
|
@@ -1182,10 +1193,10 @@ var BaseSwap2Protocol = class extends import_core.Swap2Protocol {
|
|
|
1182
1193
|
}
|
|
1183
1194
|
/** Status of a swap by the id `swap2()` returned, asked from the provider that executed it. */
|
|
1184
1195
|
async getSwap2Status(id, _options) {
|
|
1185
|
-
const { provider: name, intentId, sourceTxHash } = decodeId(id);
|
|
1196
|
+
const { provider: name, intentId, sourceTxHash, destTxHash } = decodeId(id);
|
|
1186
1197
|
const provider = this.providerFor(name);
|
|
1187
1198
|
if (!provider) throw new Error(`swap2: no swap2 found for id '${id}'`);
|
|
1188
|
-
return mapStatus(await provider.trackIntent(sourceTxHash
|
|
1199
|
+
return mapStatus(await provider.trackIntent({ intentId, ...sourceTxHash != null ? { sourceTxHash } : {}, ...destTxHash != null ? { destTxHash } : {} }));
|
|
1189
1200
|
}
|
|
1190
1201
|
/**
|
|
1191
1202
|
* Two-phase routes (CCTP-style burn-and-mint): once `getSwap2Status` reports
|
|
@@ -1231,6 +1242,17 @@ var BaseSwap2Protocol = class extends import_core.Swap2Protocol {
|
|
|
1231
1242
|
if (unsigned.chainId !== void 0 && String(unsigned.chainId) !== expectedId) {
|
|
1232
1243
|
throw new Error(`swap2: claim chainId ${unsigned.chainId} does not match ${unsigned.chain}`);
|
|
1233
1244
|
}
|
|
1245
|
+
if (typeof provider.claimTargets !== "function") {
|
|
1246
|
+
throw new Swap2UnsupportedOperationError(`swap2: provider '${name}' declares no claimTargets \u2014 a claim may only call contracts the provider names for its chain`);
|
|
1247
|
+
}
|
|
1248
|
+
const targets = provider.claimTargets(unsigned.chain).map((a) => a.toLowerCase());
|
|
1249
|
+
if (!targets.includes(unsigned.to.toLowerCase())) {
|
|
1250
|
+
throw new Swap2ValidationError(`swap2: claim target ${unsigned.to} is not a contract '${name}' declares for ${unsigned.chain} \u2014 refused`);
|
|
1251
|
+
}
|
|
1252
|
+
const claimCall = (0, import_tx_preview_evm.decodeCall)({ to: unsigned.to, data: unsigned.data, value: 0n });
|
|
1253
|
+
if (claimCall.transfer || claimCall.approval) {
|
|
1254
|
+
throw new Swap2ValidationError(`swap2: claim calldata (${claimCall.method}) moves tokens or grants an allowance \u2014 refused`);
|
|
1255
|
+
}
|
|
1234
1256
|
const actual = await readAccountChain(signer);
|
|
1235
1257
|
if (actual == null) throw new Error(`swap2: destination account chain identity is unavailable for ${unsigned.chain}`);
|
|
1236
1258
|
const actualText = typeof actual === "string" ? actual : String(actual);
|
|
@@ -1246,7 +1268,7 @@ var BaseSwap2Protocol = class extends import_core.Swap2Protocol {
|
|
|
1246
1268
|
});
|
|
1247
1269
|
if (!sent.hash) throw new Swap2ExecutionError("swap2: account did not return a claim transaction hash");
|
|
1248
1270
|
this.emitPhase("broadcast", { hash: sent.hash });
|
|
1249
|
-
return { hash: sent.hash, chain: unsigned.chain, id };
|
|
1271
|
+
return { hash: sent.hash, chain: unsigned.chain, id: encodeId(name, intentId, sourceTxHash, sent.hash) };
|
|
1250
1272
|
}
|
|
1251
1273
|
/** The inherited bridge() has no floor field: quote first, then bind execution
|
|
1252
1274
|
* to that quote's minimum so the inherited convenience API stays safe. */
|
|
@@ -1306,7 +1328,9 @@ var BaseSwap2Protocol = class extends import_core.Swap2Protocol {
|
|
|
1306
1328
|
if ((wantFrom || wantTo) && c.caip2 !== wantFrom && c.caip2 !== wantTo) continue;
|
|
1307
1329
|
for (const a of c.assets) {
|
|
1308
1330
|
out.push({
|
|
1309
|
-
|
|
1331
|
+
// What quoteSwap2 takes back: the contract, or the symbol of the native coin — never the
|
|
1332
|
+
// provider-specific assetId, which is "" for most catalog entries (round 3, M25).
|
|
1333
|
+
token: a.contract ?? a.symbol,
|
|
1310
1334
|
chain: c.caip2,
|
|
1311
1335
|
symbol: a.symbol,
|
|
1312
1336
|
decimals: a.decimals,
|