@toon-protocol/relay 1.3.3 → 1.3.4
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/{chunk-ZKWFGHZ7.js → chunk-NYKVCNJL.js} +131 -57
- package/dist/chunk-NYKVCNJL.js.map +1 -0
- package/dist/cli.js +11 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +29 -0
- package/dist/index.js +1 -1
- package/package.json +3 -3
- package/dist/chunk-ZKWFGHZ7.js.map +0 -1
|
@@ -1246,6 +1246,48 @@ import {
|
|
|
1246
1246
|
fromMnemonic,
|
|
1247
1247
|
fromSecretKey
|
|
1248
1248
|
} from "@toon-protocol/sdk";
|
|
1249
|
+
|
|
1250
|
+
// src/launcher/handlers/oblivious-write-handler.ts
|
|
1251
|
+
import { verifyEvent as verifyEvent2 } from "nostr-tools/pure";
|
|
1252
|
+
function createObliviousWriteHandler(config) {
|
|
1253
|
+
return {
|
|
1254
|
+
async handleWrite(c) {
|
|
1255
|
+
let body;
|
|
1256
|
+
try {
|
|
1257
|
+
body = await c.req.json();
|
|
1258
|
+
} catch {
|
|
1259
|
+
return c.json({ error: "Invalid request body" }, 400);
|
|
1260
|
+
}
|
|
1261
|
+
if (!body.event) {
|
|
1262
|
+
return c.json({ error: "Missing required field: event" }, 400);
|
|
1263
|
+
}
|
|
1264
|
+
const event = body.event;
|
|
1265
|
+
const payer = c.req.header("X-TOON-Payer");
|
|
1266
|
+
const amount = c.req.header("X-TOON-Amount");
|
|
1267
|
+
const chain = c.req.header("X-TOON-Chain");
|
|
1268
|
+
console.log(
|
|
1269
|
+
`[oblivious-write] event=${event.id} payer=${payer ?? "-"} amount=${amount ?? "-"} chain=${chain ?? "-"}`
|
|
1270
|
+
);
|
|
1271
|
+
if (!config.devMode && !verifyEvent2(event)) {
|
|
1272
|
+
return c.json({ error: "Invalid event signature" }, 422);
|
|
1273
|
+
}
|
|
1274
|
+
config.eventStore.store(event);
|
|
1275
|
+
config.onStored?.(event);
|
|
1276
|
+
return c.json(
|
|
1277
|
+
{
|
|
1278
|
+
eventId: event.id,
|
|
1279
|
+
storedAt: Math.floor(Date.now() / 1e3),
|
|
1280
|
+
payer,
|
|
1281
|
+
amount,
|
|
1282
|
+
chain
|
|
1283
|
+
},
|
|
1284
|
+
200
|
|
1285
|
+
);
|
|
1286
|
+
}
|
|
1287
|
+
};
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
// src/launcher/town.ts
|
|
1249
1291
|
import {
|
|
1250
1292
|
BootstrapService,
|
|
1251
1293
|
createDiscoveryTracker,
|
|
@@ -1325,6 +1367,12 @@ async function startRelay(config) {
|
|
|
1325
1367
|
"RelayConfig: provide either connector or connectorUrl, not both"
|
|
1326
1368
|
);
|
|
1327
1369
|
}
|
|
1370
|
+
const obliviousMode = config.obliviousMode ?? process.env["TOON_OBLIVIOUS_MODE"] === "true";
|
|
1371
|
+
if (obliviousMode && (hasConnector || hasConnectorUrl)) {
|
|
1372
|
+
throw new Error(
|
|
1373
|
+
"RelayConfig: obliviousMode is mutually exclusive with connector/connectorUrl (an oblivious relay runs no embedded connector)"
|
|
1374
|
+
);
|
|
1375
|
+
}
|
|
1328
1376
|
if (hasConnectorUrl && config.ilpAddress === void 0) {
|
|
1329
1377
|
throw new Error(
|
|
1330
1378
|
"RelayConfig: ilpAddress is required when connectorUrl is set (must fall under the parent connector prefix, e.g. g.townhouse.<self>)"
|
|
@@ -1342,7 +1390,7 @@ async function startRelay(config) {
|
|
|
1342
1390
|
const connectorUrl = config.connectorUrl;
|
|
1343
1391
|
const basePricePerByte = config.feePerEvent !== void 0 ? BigInt(config.feePerEvent) : config.basePricePerByte ?? 10n;
|
|
1344
1392
|
const routingBufferPercent = config.routingBufferPercent ?? 10;
|
|
1345
|
-
const x402Enabled = config.x402Enabled ?? false;
|
|
1393
|
+
const x402Enabled = obliviousMode ? false : config.x402Enabled ?? false;
|
|
1346
1394
|
const knownPeers = [...config.knownPeers ?? []];
|
|
1347
1395
|
const dataDir = config.dataDir ?? "./data";
|
|
1348
1396
|
const devMode = config.devMode ?? false;
|
|
@@ -1362,7 +1410,7 @@ async function startRelay(config) {
|
|
|
1362
1410
|
const publishSeedEntryFlag = config.publishSeedEntry ?? false;
|
|
1363
1411
|
const externalRelayUrl = config.externalRelayUrl ?? (config.ator?.enabled && config.ator.anonAddress ? config.ator.anonAddress : void 0);
|
|
1364
1412
|
const requestedChain = process.env["TOON_CHAIN"] || config.chain;
|
|
1365
|
-
const relayOnly = requestedChain === "none";
|
|
1413
|
+
const relayOnly = requestedChain === "none" || obliviousMode;
|
|
1366
1414
|
if (relayOnly) {
|
|
1367
1415
|
console.log("[Town] connector.relay_only", {
|
|
1368
1416
|
reason: "no settlement chain configured (chain=none)"
|
|
@@ -1398,10 +1446,11 @@ async function startRelay(config) {
|
|
|
1398
1446
|
seedRelays,
|
|
1399
1447
|
publishSeedEntry: publishSeedEntryFlag,
|
|
1400
1448
|
...externalRelayUrl && { externalRelayUrl },
|
|
1401
|
-
chain: chainConfig.name
|
|
1449
|
+
chain: chainConfig.name,
|
|
1450
|
+
obliviousMode
|
|
1402
1451
|
};
|
|
1403
1452
|
let autoCreatedConnector = null;
|
|
1404
|
-
if (!hasConnector) {
|
|
1453
|
+
if (!hasConnector && !obliviousMode) {
|
|
1405
1454
|
const btpServerPort = config.btpServerPort ?? 3e3;
|
|
1406
1455
|
const connectorLogger = createConnectorLogger(
|
|
1407
1456
|
nodeId,
|
|
@@ -1488,7 +1537,7 @@ async function startRelay(config) {
|
|
|
1488
1537
|
const effectiveConnector = config.connector ?? autoCreatedConnector;
|
|
1489
1538
|
mkdirSync(dataDir, { recursive: true });
|
|
1490
1539
|
const dbPath = join(dataDir, "events.db");
|
|
1491
|
-
const eventStore = new SqliteEventStore(dbPath);
|
|
1540
|
+
const eventStore = config.eventStore ?? new SqliteEventStore(dbPath);
|
|
1492
1541
|
const effectiveChainRpcUrls = config.chainRpcUrls ?? (relayOnly ? void 0 : { [chainKey]: chainConfig.rpcUrl });
|
|
1493
1542
|
const effectivePreferredTokens = config.preferredTokens ?? (relayOnly ? void 0 : { [chainKey]: chainConfig.usdcAddress });
|
|
1494
1543
|
const effectiveTokenNetworks = config.tokenNetworks ?? (chainConfig.tokenNetworkAddress ? { [chainKey]: chainConfig.tokenNetworkAddress } : void 0);
|
|
@@ -1514,13 +1563,13 @@ async function startRelay(config) {
|
|
|
1514
1563
|
preferredTokens: effectivePreferredTokens,
|
|
1515
1564
|
tokenNetworks: effectiveTokenNetworks
|
|
1516
1565
|
};
|
|
1517
|
-
if (effectiveConnector
|
|
1566
|
+
if (effectiveConnector?.openChannel && effectiveConnector.getChannelState) {
|
|
1518
1567
|
channelClient = createDirectChannelClient(
|
|
1519
1568
|
effectiveConnector
|
|
1520
1569
|
);
|
|
1521
1570
|
}
|
|
1522
1571
|
}
|
|
1523
|
-
const adminClient = createDirectConnectorAdmin(effectiveConnector);
|
|
1572
|
+
const adminClient = effectiveConnector ? createDirectConnectorAdmin(effectiveConnector) : void 0;
|
|
1524
1573
|
const verifier = createVerificationPipeline({ devMode });
|
|
1525
1574
|
const pricer = createPricingValidator({
|
|
1526
1575
|
basePricePerByte,
|
|
@@ -1635,38 +1684,40 @@ async function startRelay(config) {
|
|
|
1635
1684
|
})
|
|
1636
1685
|
);
|
|
1637
1686
|
});
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1687
|
+
if (!obliviousMode) {
|
|
1688
|
+
app.post("/handle-packet", async (c) => {
|
|
1689
|
+
try {
|
|
1690
|
+
const body = await c.req.json();
|
|
1691
|
+
if (body.amount === void 0 || body.amount === null || body.destination === void 0 || body.destination === null || body.data === void 0 || body.data === null) {
|
|
1692
|
+
return c.json(
|
|
1693
|
+
{ accept: false, code: "F00", message: "Missing required fields" },
|
|
1694
|
+
400
|
|
1695
|
+
);
|
|
1696
|
+
}
|
|
1697
|
+
const result = await handlePacket(body);
|
|
1698
|
+
if (result.accept) {
|
|
1699
|
+
try {
|
|
1700
|
+
const toonBytes = Buffer.from(body.data, "base64");
|
|
1701
|
+
const decoded = decodeEventFromToon2(toonBytes);
|
|
1702
|
+
if (decoded && decoded.kind === ILP_PEER_INFO_KIND) {
|
|
1703
|
+
discoveryTrackerRef.current?.processEvent(decoded);
|
|
1704
|
+
}
|
|
1705
|
+
} catch {
|
|
1654
1706
|
}
|
|
1655
|
-
} catch {
|
|
1656
1707
|
}
|
|
1708
|
+
return c.json(result, result.accept ? 200 : 400);
|
|
1709
|
+
} catch (error) {
|
|
1710
|
+
console.error("[Town] handle-packet error:", error);
|
|
1711
|
+
return c.json(
|
|
1712
|
+
{ accept: false, code: "T00", message: "Internal server error" },
|
|
1713
|
+
500
|
|
1714
|
+
);
|
|
1657
1715
|
}
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
return c.json(
|
|
1662
|
-
{ accept: false, code: "T00", message: "Internal server error" },
|
|
1663
|
-
500
|
|
1664
|
-
);
|
|
1665
|
-
}
|
|
1666
|
-
});
|
|
1667
|
-
const ilpClient = createDirectIlpClient(effectiveConnector, {
|
|
1716
|
+
});
|
|
1717
|
+
}
|
|
1718
|
+
const ilpClient = effectiveConnector ? createDirectIlpClient(effectiveConnector, {
|
|
1668
1719
|
toonDecoder: (bytes) => decodeEventFromToon2(bytes)
|
|
1669
|
-
});
|
|
1720
|
+
}) : void 0;
|
|
1670
1721
|
let x402WalletClient;
|
|
1671
1722
|
let x402PublicClient;
|
|
1672
1723
|
if (x402Enabled) {
|
|
@@ -1700,21 +1751,38 @@ async function startRelay(config) {
|
|
|
1700
1751
|
}
|
|
1701
1752
|
}
|
|
1702
1753
|
}
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1754
|
+
if (obliviousMode) {
|
|
1755
|
+
const obliviousHandler = createObliviousWriteHandler({
|
|
1756
|
+
eventStore,
|
|
1757
|
+
devMode,
|
|
1758
|
+
onStored: (event) => {
|
|
1759
|
+
try {
|
|
1760
|
+
wsRelayRef.current?.broadcastEvent(event);
|
|
1761
|
+
} catch {
|
|
1762
|
+
}
|
|
1763
|
+
if (event.kind === ILP_PEER_INFO_KIND) {
|
|
1764
|
+
discoveryTrackerRef.current?.processEvent(event);
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
});
|
|
1768
|
+
app.post("/write", (c) => obliviousHandler.handleWrite(c));
|
|
1769
|
+
} else {
|
|
1770
|
+
const x402Handler = createX402Handler({
|
|
1771
|
+
x402Enabled,
|
|
1772
|
+
chainConfig,
|
|
1773
|
+
basePricePerByte,
|
|
1774
|
+
routingBufferPercent,
|
|
1775
|
+
facilitatorAddress: config.facilitatorAddress ?? identity.evmAddress,
|
|
1776
|
+
ownPubkey: identity.pubkey,
|
|
1777
|
+
devMode,
|
|
1778
|
+
eventStore,
|
|
1779
|
+
ilpClient,
|
|
1780
|
+
walletClient: x402WalletClient,
|
|
1781
|
+
publicClient: x402PublicClient
|
|
1782
|
+
});
|
|
1783
|
+
app.get("/publish", (c) => x402Handler.handlePublish(c));
|
|
1784
|
+
app.post("/publish", (c) => x402Handler.handlePublish(c));
|
|
1785
|
+
}
|
|
1718
1786
|
const blsServer = serve({
|
|
1719
1787
|
fetch: app.fetch,
|
|
1720
1788
|
port: blsPort
|
|
@@ -1728,11 +1796,15 @@ async function startRelay(config) {
|
|
|
1728
1796
|
await wsRelay.start();
|
|
1729
1797
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
1730
1798
|
let running = true;
|
|
1731
|
-
|
|
1799
|
+
if (adminClient) {
|
|
1800
|
+
bootstrapService.setConnectorAdmin(adminClient);
|
|
1801
|
+
}
|
|
1732
1802
|
if (channelClient) {
|
|
1733
1803
|
bootstrapService.setChannelClient(channelClient);
|
|
1734
1804
|
}
|
|
1735
|
-
|
|
1805
|
+
if (ilpClient) {
|
|
1806
|
+
bootstrapService.setIlpClient(ilpClient);
|
|
1807
|
+
}
|
|
1736
1808
|
bootstrapService.on((event) => {
|
|
1737
1809
|
switch (event.type) {
|
|
1738
1810
|
case "bootstrap:peer-registered":
|
|
@@ -1745,7 +1817,7 @@ async function startRelay(config) {
|
|
|
1745
1817
|
break;
|
|
1746
1818
|
}
|
|
1747
1819
|
});
|
|
1748
|
-
if (effectiveConnector
|
|
1820
|
+
if (effectiveConnector?.setPacketHandler) {
|
|
1749
1821
|
effectiveConnector.setPacketHandler(async (request) => {
|
|
1750
1822
|
const result = await handlePacket(request);
|
|
1751
1823
|
if (result.accept && discoveryTrackerRef.current) {
|
|
@@ -1771,7 +1843,9 @@ async function startRelay(config) {
|
|
|
1771
1843
|
secretKey: identity.secretKey,
|
|
1772
1844
|
settlementInfo
|
|
1773
1845
|
});
|
|
1774
|
-
|
|
1846
|
+
if (adminClient) {
|
|
1847
|
+
discoveryTracker.setConnectorAdmin(adminClient);
|
|
1848
|
+
}
|
|
1775
1849
|
if (channelClient) {
|
|
1776
1850
|
discoveryTracker.setChannelClient(channelClient);
|
|
1777
1851
|
}
|
|
@@ -1841,7 +1915,7 @@ async function startRelay(config) {
|
|
|
1841
1915
|
eventStore.store(ilpInfoEvent);
|
|
1842
1916
|
const firstPeer = knownPeers[0];
|
|
1843
1917
|
const genesisResult = results[0];
|
|
1844
|
-
if (firstPeer && genesisResult) {
|
|
1918
|
+
if (ilpClient && firstPeer && genesisResult) {
|
|
1845
1919
|
const genesisIlpAddress = genesisResult.peerInfo.ilpAddress;
|
|
1846
1920
|
const toonBytes = encodeEventToToon3(ilpInfoEvent);
|
|
1847
1921
|
const base64Toon = Buffer.from(toonBytes).toString("base64");
|
|
@@ -1897,7 +1971,7 @@ async function startRelay(config) {
|
|
|
1897
1971
|
eventStore.store(serviceDiscoveryEvent);
|
|
1898
1972
|
const firstPeer = knownPeers[0];
|
|
1899
1973
|
const genesisResult = results[0];
|
|
1900
|
-
if (firstPeer && genesisResult) {
|
|
1974
|
+
if (ilpClient && firstPeer && genesisResult) {
|
|
1901
1975
|
const genesisIlpAddress = genesisResult.peerInfo.ilpAddress;
|
|
1902
1976
|
const sdToonBytes = encodeEventToToon3(serviceDiscoveryEvent);
|
|
1903
1977
|
const sdBase64Toon = Buffer.from(sdToonBytes).toString("base64");
|
|
@@ -2026,4 +2100,4 @@ export {
|
|
|
2026
2100
|
startRelay,
|
|
2027
2101
|
startTown
|
|
2028
2102
|
};
|
|
2029
|
-
//# sourceMappingURL=chunk-
|
|
2103
|
+
//# sourceMappingURL=chunk-NYKVCNJL.js.map
|