@naculus/connect-appkit-core 0.9.0 → 0.10.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/dist/index.cjs +87 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +52 -1
- package/dist/index.d.ts +52 -1
- package/dist/index.js +82 -17
- package/dist/index.js.map +1 -1
- package/package.json +6 -3
package/dist/index.cjs
CHANGED
|
@@ -44,6 +44,7 @@ __export(src_exports, {
|
|
|
44
44
|
createNotification: () => createNotification,
|
|
45
45
|
createNotificationSettingsStorage: () => createNotificationSettingsStorage,
|
|
46
46
|
createSolanaSessionKeyFlow: () => createSolanaSessionKeyFlow,
|
|
47
|
+
createX402WalletSigner: () => createX402WalletSigner,
|
|
47
48
|
decodeRevertReason: () => decodeRevertReason,
|
|
48
49
|
defaultSiwxDomain: () => defaultSiwxDomain,
|
|
49
50
|
defaultSiwxUri: () => defaultSiwxUri,
|
|
@@ -56,6 +57,7 @@ __export(src_exports, {
|
|
|
56
57
|
encodeErc20TransferFrom: () => encodeErc20TransferFrom,
|
|
57
58
|
explainSpend: () => explainSpend,
|
|
58
59
|
fetchUserOperationReceipt: () => fetchUserOperationReceipt,
|
|
60
|
+
findX402Provider: () => findX402Provider,
|
|
59
61
|
formatAuthorizationAmount: () => formatAuthorizationAmount,
|
|
60
62
|
getResolver: () => getResolver,
|
|
61
63
|
getSharedSessionKeyManager: () => getSharedSessionKeyManager,
|
|
@@ -86,6 +88,7 @@ __export(src_exports, {
|
|
|
86
88
|
resolveRevertReason: () => resolveRevertReason,
|
|
87
89
|
resolveSimulationEndpoint: () => resolveSimulationEndpoint,
|
|
88
90
|
resolveUserOpChain: () => resolveUserOpChain,
|
|
91
|
+
resolveX402Wallet: () => resolveX402Wallet,
|
|
89
92
|
sameExecutionIntent: () => sameExecutionIntent,
|
|
90
93
|
saveNotificationSettings: () => saveNotificationSettings,
|
|
91
94
|
selectChainCapabilities: () => selectChainCapabilities,
|
|
@@ -1381,39 +1384,44 @@ function createDelegationPolicyFlow(deps) {
|
|
|
1381
1384
|
|
|
1382
1385
|
// src/authorization.ts
|
|
1383
1386
|
var import_connect_core17 = require("@naculus/connect-core");
|
|
1384
|
-
function assetAddress(asset) {
|
|
1385
|
-
return asset.split(/[:/]/).at(-1);
|
|
1386
|
-
}
|
|
1387
1387
|
function groupDigits(value) {
|
|
1388
1388
|
let out = "";
|
|
1389
1389
|
for (let i = 0; i < value.length; i++)
|
|
1390
1390
|
out += (i && (value.length - i) % 3 === 0 ? "," : "") + value[i];
|
|
1391
1391
|
return out;
|
|
1392
1392
|
}
|
|
1393
|
-
function
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1393
|
+
function trustedMetadata(asset, options) {
|
|
1394
|
+
const trust = !options.trustedAssets ? "unchecked" : options.trustedAssets.some(
|
|
1395
|
+
(t) => canonicalAssetId(t) === canonicalAssetId(asset)
|
|
1396
|
+
) ? "trusted" : "unverified";
|
|
1397
|
+
return [trust, trust === "unverified" ? void 0 : options.assets?.[asset]];
|
|
1398
|
+
}
|
|
1399
|
+
function canonicalAssetId(asset) {
|
|
1400
|
+
return asset.replace(
|
|
1401
|
+
/^(eip155:[^/]+\/erc20:)(.+)$/,
|
|
1402
|
+
(_, prefix, reference) => prefix + reference.toLowerCase()
|
|
1403
|
+
);
|
|
1397
1404
|
}
|
|
1398
1405
|
function formatAuthorizationAmount(amount, metadata) {
|
|
1399
1406
|
const baseUnits = amount.toString();
|
|
1400
|
-
if (!metadata
|
|
1407
|
+
if (!metadata?.symbol || !Number.isSafeInteger(metadata.decimals) || metadata.decimals < 0 || metadata.decimals > 255) {
|
|
1401
1408
|
return {
|
|
1402
1409
|
formatted: `${groupDigits(baseUnits)} base units`
|
|
1403
1410
|
};
|
|
1404
1411
|
}
|
|
1405
1412
|
const decimals = metadata.decimals;
|
|
1406
1413
|
const padded = baseUnits.padStart(decimals + 1, "0");
|
|
1407
|
-
const integer =
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
return {
|
|
1414
|
+
const integer = padded.slice(0, decimals ? -decimals : void 0);
|
|
1415
|
+
let fraction = decimals ? padded.slice(-decimals) : "";
|
|
1416
|
+
while (fraction.endsWith("0")) fraction = fraction.slice(0, -1);
|
|
1417
|
+
return {
|
|
1418
|
+
formatted: `${groupDigits(integer)}${fraction ? `.${fraction}` : ""} ${metadata.symbol}`
|
|
1419
|
+
};
|
|
1411
1420
|
}
|
|
1412
1421
|
function relativeExpiry(expiresAt, now, locale) {
|
|
1413
1422
|
const seconds = expiresAt - now;
|
|
1414
1423
|
const absolute = Math.abs(seconds);
|
|
1415
|
-
const divisor = absolute >= 31536e3 ? 31536e3 : absolute >= 2592e3 ? 2592e3 : absolute >= 86400 ? 86400 : absolute >= 3600 ? 3600 : absolute >= 60 ? 60 : 1;
|
|
1416
|
-
const unit = divisor === 31536e3 ? "year" : divisor === 2592e3 ? "month" : divisor === 86400 ? "day" : divisor === 3600 ? "hour" : divisor === 60 ? "minute" : "second";
|
|
1424
|
+
const [divisor, unit] = absolute >= 31536e3 ? [31536e3, "year"] : absolute >= 2592e3 ? [2592e3, "month"] : absolute >= 86400 ? [86400, "day"] : absolute >= 3600 ? [3600, "hour"] : absolute >= 60 ? [60, "minute"] : [1, "second"];
|
|
1417
1425
|
const value = Math.round(seconds / divisor);
|
|
1418
1426
|
if (typeof Intl.RelativeTimeFormat !== "function") {
|
|
1419
1427
|
const count = Math.abs(value);
|
|
@@ -1431,10 +1439,11 @@ function describeAuthorization(input, options = {}) {
|
|
|
1431
1439
|
label,
|
|
1432
1440
|
principal: input.principal ?? null,
|
|
1433
1441
|
grants: input.grants.map((grant) => {
|
|
1434
|
-
const metadata =
|
|
1442
|
+
const [assetTrust, metadata] = trustedMetadata(grant.asset, options);
|
|
1435
1443
|
return {
|
|
1436
1444
|
asset: grant.asset,
|
|
1437
|
-
|
|
1445
|
+
assetTrust,
|
|
1446
|
+
assetLabel: metadata?.symbol || grant.asset.split(":").at(-1),
|
|
1438
1447
|
recipients: grant.recipients.map((full) => ({
|
|
1439
1448
|
shortened: full.length <= 14 ? full : `${full.slice(0, 6)}\u2026${full.slice(-6)}`,
|
|
1440
1449
|
full
|
|
@@ -1487,7 +1496,7 @@ function explainSpend(authorization, request, options = {}) {
|
|
|
1487
1496
|
const remainingTotal = authorization.grants[verdict.grant].maxTotal - request.spentSoFar - request.amount;
|
|
1488
1497
|
const remainingTotalFormatted = formatAuthorizationAmount(
|
|
1489
1498
|
remainingTotal,
|
|
1490
|
-
|
|
1499
|
+
trustedMetadata(authorization.grants[verdict.grant].asset, options)[1]
|
|
1491
1500
|
);
|
|
1492
1501
|
return {
|
|
1493
1502
|
allowed: true,
|
|
@@ -1569,6 +1578,57 @@ function describePayment(input, result) {
|
|
|
1569
1578
|
};
|
|
1570
1579
|
}
|
|
1571
1580
|
|
|
1581
|
+
// src/x402-wallet.ts
|
|
1582
|
+
var import_connect_core18 = require("@naculus/connect-core");
|
|
1583
|
+
var import_payments_x402 = require("@naculus/payments-x402");
|
|
1584
|
+
function findX402Provider(session, sources) {
|
|
1585
|
+
if (!session) return null;
|
|
1586
|
+
if (session.walletType === "eip6963" || session.id.startsWith("eip6963-")) {
|
|
1587
|
+
return sources.injected?.find((wallet) => wallet.id === session.walletId)?.provider ?? null;
|
|
1588
|
+
}
|
|
1589
|
+
if (session.walletType === "walletconnect") {
|
|
1590
|
+
return sources.walletConnect ?? null;
|
|
1591
|
+
}
|
|
1592
|
+
return null;
|
|
1593
|
+
}
|
|
1594
|
+
function unavailable(reason) {
|
|
1595
|
+
return { provider: null, address: null, reason };
|
|
1596
|
+
}
|
|
1597
|
+
function resolveX402Wallet(session, provider) {
|
|
1598
|
+
if (!session) return unavailable("no-session");
|
|
1599
|
+
const namespace = session.namespaces.eip155;
|
|
1600
|
+
if (!namespace) return unavailable("not-evm");
|
|
1601
|
+
const isInjected = session.walletType === "eip6963" || session.id.startsWith("eip6963-");
|
|
1602
|
+
const isWalletConnect = session.walletType === "walletconnect";
|
|
1603
|
+
if (!isInjected && !isWalletConnect || !provider?.request) {
|
|
1604
|
+
return unavailable("unsupported-wallet-type");
|
|
1605
|
+
}
|
|
1606
|
+
for (const account of namespace.accounts) {
|
|
1607
|
+
const parsed = (0, import_connect_core18.parseCaip10)(account);
|
|
1608
|
+
const address = parsed?.namespace === "eip155" ? parsed.address : account;
|
|
1609
|
+
if ((0, import_connect_core18.isEvmAddress)(address)) {
|
|
1610
|
+
return {
|
|
1611
|
+
provider,
|
|
1612
|
+
address,
|
|
1613
|
+
reason: null
|
|
1614
|
+
};
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
return unavailable("not-evm");
|
|
1618
|
+
}
|
|
1619
|
+
function createX402WalletSigner(session, provider, switchChain) {
|
|
1620
|
+
const resolved = resolveX402Wallet(session, provider);
|
|
1621
|
+
if (resolved.reason) return { signer: null, reason: resolved.reason };
|
|
1622
|
+
return {
|
|
1623
|
+
signer: (0, import_payments_x402.walletX402Signer)({
|
|
1624
|
+
provider: resolved.provider,
|
|
1625
|
+
address: resolved.address,
|
|
1626
|
+
switchChain
|
|
1627
|
+
}),
|
|
1628
|
+
reason: null
|
|
1629
|
+
};
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1572
1632
|
// src/mpp-session.ts
|
|
1573
1633
|
function record2(value) {
|
|
1574
1634
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
@@ -1600,11 +1660,11 @@ function readMppRecoveryChannelId(error) {
|
|
|
1600
1660
|
}
|
|
1601
1661
|
|
|
1602
1662
|
// src/solana-session-key.ts
|
|
1603
|
-
var
|
|
1663
|
+
var import_connect_core19 = require("@naculus/connect-core");
|
|
1604
1664
|
function send(rpc) {
|
|
1605
1665
|
const sendTransaction = rpc.sendTransaction;
|
|
1606
1666
|
if (!sendTransaction) {
|
|
1607
|
-
throw new
|
|
1667
|
+
throw new import_connect_core19.WalletError(
|
|
1608
1668
|
"invalid_input",
|
|
1609
1669
|
"The Solana RPC must implement sendTransaction to approve or revoke."
|
|
1610
1670
|
);
|
|
@@ -1642,7 +1702,7 @@ function createSolanaSessionKeyFlow(deps) {
|
|
|
1642
1702
|
} catch (cause) {
|
|
1643
1703
|
await manager.revoke(draft.id).catch(() => {
|
|
1644
1704
|
});
|
|
1645
|
-
throw new
|
|
1705
|
+
throw new import_connect_core19.WalletError(
|
|
1646
1706
|
"rpc_error",
|
|
1647
1707
|
`The approval could not be confirmed as sent (${cause instanceof Error ? cause.message : String(cause)}); the key is revoked here. Call revoke("${draft.id}") to send the on-chain Revoke in case it landed.`
|
|
1648
1708
|
);
|
|
@@ -1653,7 +1713,7 @@ function createSolanaSessionKeyFlow(deps) {
|
|
|
1653
1713
|
async revoke(id) {
|
|
1654
1714
|
const key = (await list()).find((k) => k.id === id);
|
|
1655
1715
|
if (!key) {
|
|
1656
|
-
throw new
|
|
1716
|
+
throw new import_connect_core19.WalletError(
|
|
1657
1717
|
"invalid_input",
|
|
1658
1718
|
`No Solana session key ${id} for this owner.`
|
|
1659
1719
|
);
|
|
@@ -1665,7 +1725,7 @@ function createSolanaSessionKeyFlow(deps) {
|
|
|
1665
1725
|
rpc
|
|
1666
1726
|
);
|
|
1667
1727
|
const signed = await owner.signTransaction(transaction);
|
|
1668
|
-
const revocation = (0,
|
|
1728
|
+
const revocation = (0, import_connect_core19.verifySignedOwnerTransaction)(signed, {
|
|
1669
1729
|
kind: "revoke",
|
|
1670
1730
|
revocation: {
|
|
1671
1731
|
owner: key.owner,
|
|
@@ -1680,7 +1740,7 @@ function createSolanaSessionKeyFlow(deps) {
|
|
|
1680
1740
|
}
|
|
1681
1741
|
|
|
1682
1742
|
// src/web3-store.ts
|
|
1683
|
-
var
|
|
1743
|
+
var import_connect_core20 = require("@naculus/connect-core");
|
|
1684
1744
|
function withTimeout(promise, ms, label = "Operation") {
|
|
1685
1745
|
let timeoutId;
|
|
1686
1746
|
const timeout = new Promise((_, reject) => {
|
|
@@ -1702,7 +1762,7 @@ async function withRetry(fn, options) {
|
|
|
1702
1762
|
lastError = error;
|
|
1703
1763
|
if (attempt < options.maxRetries) {
|
|
1704
1764
|
const delay = options.baseDelay * 2 ** attempt;
|
|
1705
|
-
|
|
1765
|
+
import_connect_core20.logger.warn(
|
|
1706
1766
|
"appkit/core",
|
|
1707
1767
|
`Retry attempt ${attempt + 1}/${options.maxRetries} after ${delay}ms`
|
|
1708
1768
|
);
|
|
@@ -1840,6 +1900,7 @@ function siwxResultToSession(result, now = /* @__PURE__ */ new Date()) {
|
|
|
1840
1900
|
createNotification,
|
|
1841
1901
|
createNotificationSettingsStorage,
|
|
1842
1902
|
createSolanaSessionKeyFlow,
|
|
1903
|
+
createX402WalletSigner,
|
|
1843
1904
|
decodeRevertReason,
|
|
1844
1905
|
defaultSiwxDomain,
|
|
1845
1906
|
defaultSiwxUri,
|
|
@@ -1852,6 +1913,7 @@ function siwxResultToSession(result, now = /* @__PURE__ */ new Date()) {
|
|
|
1852
1913
|
encodeErc20TransferFrom,
|
|
1853
1914
|
explainSpend,
|
|
1854
1915
|
fetchUserOperationReceipt,
|
|
1916
|
+
findX402Provider,
|
|
1855
1917
|
formatAuthorizationAmount,
|
|
1856
1918
|
getResolver,
|
|
1857
1919
|
getSharedSessionKeyManager,
|
|
@@ -1882,6 +1944,7 @@ function siwxResultToSession(result, now = /* @__PURE__ */ new Date()) {
|
|
|
1882
1944
|
resolveRevertReason,
|
|
1883
1945
|
resolveSimulationEndpoint,
|
|
1884
1946
|
resolveUserOpChain,
|
|
1947
|
+
resolveX402Wallet,
|
|
1885
1948
|
sameExecutionIntent,
|
|
1886
1949
|
saveNotificationSettings,
|
|
1887
1950
|
selectChainCapabilities,
|