@fibscope/agent 0.1.4 → 0.1.5
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 +7 -1
- package/index.mjs +209 -53
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -74,7 +74,7 @@ The agent pushes to `POST /agent/v1/report` with:
|
|
|
74
74
|
|
|
75
75
|
```json
|
|
76
76
|
{
|
|
77
|
-
"agentVersion": "0.1.
|
|
77
|
+
"agentVersion": "0.1.5",
|
|
78
78
|
"chain": "testnet",
|
|
79
79
|
"collectedAt": 1710000000000,
|
|
80
80
|
"publicIp": "54.179.226.154",
|
|
@@ -100,6 +100,12 @@ For an `API_NODE_PAYMENT`, the agent confirms the sender deposit and checks for
|
|
|
100
100
|
|
|
101
101
|
The command result includes provider and receiver balance views before payment, after payment, and at close. The receiver view reverses the provider-local and provider-remote balances so the receiving channel's credited local balance and remaining inbound capacity are explicit.
|
|
102
102
|
|
|
103
|
+
## Owner N2N Test Lifecycle
|
|
104
|
+
|
|
105
|
+
`N2N_PAYMENT` is an owner-authorized test command. It never confirms or charges an API test-wallet deposit. The selected source node checks its own funding wallet and existing routes, connects the receiving peer, opens a direct channel from its own funding when needed, sends over Fiber, and optionally closes only the channel created by that test.
|
|
106
|
+
|
|
107
|
+
When both FNN instances publish the same public IPv4 address, the agent dials the receiving P2P port through loopback so same-VPS nodes can complete the Fiber handshake. Command results include structured source selection, peer connection, channel creation, balance movement, Fiber transfer, optional close, and partial failure steps.
|
|
108
|
+
|
|
103
109
|
## Resilience
|
|
104
110
|
|
|
105
111
|
Collection and transmission are independent loops:
|
package/index.mjs
CHANGED
|
@@ -33,7 +33,7 @@ import { virtualizePayment } from "./lib/route/route.mjs";
|
|
|
33
33
|
import { chooseFnnInstance, describeFnnInstance, discoverFnnInstances, rpcResponds } from "./lib/fnn-discovery.mjs";
|
|
34
34
|
import { buildObservedPeerAddress, discoverPublicIpv4, publishablePeerAddresses } from "./lib/public-peer-address.mjs";
|
|
35
35
|
|
|
36
|
-
const AGENT_VERSION = "0.1.
|
|
36
|
+
const AGENT_VERSION = "0.1.5";
|
|
37
37
|
const DEFAULT_CONFIG_PATH = ".fiber/agent.json";
|
|
38
38
|
const DEFAULT_STATUS_PATH = ".fiber/agent-status.json";
|
|
39
39
|
const DEFAULT_PUSH_INTERVAL_MS = 15_000;
|
|
@@ -1145,6 +1145,7 @@ async function executeAndReportCommand(runtime, command) {
|
|
|
1145
1145
|
command: command.command,
|
|
1146
1146
|
status: "failed",
|
|
1147
1147
|
error: message(error),
|
|
1148
|
+
result: error?.commandResult && typeof error.commandResult === "object" ? error.commandResult : undefined,
|
|
1148
1149
|
};
|
|
1149
1150
|
await postCommandResult(config, body);
|
|
1150
1151
|
console.warn(formatCommandEvent("failed", command, config, "error", body.error));
|
|
@@ -1180,6 +1181,9 @@ async function executeAgentCommand(runtime, command) {
|
|
|
1180
1181
|
if (name === "API_NODE_PAYMENT" || name === "NODE_PAYMENT") {
|
|
1181
1182
|
return acceptApiNodePayment(runtime, params);
|
|
1182
1183
|
}
|
|
1184
|
+
if (name === "N2N_PAYMENT" || name === "NODE_TO_NODE_PAYMENT") {
|
|
1185
|
+
return acceptApiNodePayment(runtime, params, { ownerFunded: true });
|
|
1186
|
+
}
|
|
1183
1187
|
if (name === "API_WALLET_PAYMENT" || name === "WALLET_PAYMENT") {
|
|
1184
1188
|
return acceptApiWalletPayment(runtime, params);
|
|
1185
1189
|
}
|
|
@@ -1545,15 +1549,23 @@ async function acceptApiWalletPayment(runtime, params) {
|
|
|
1545
1549
|
};
|
|
1546
1550
|
}
|
|
1547
1551
|
|
|
1548
|
-
async function acceptApiNodePayment(runtime, params) {
|
|
1552
|
+
async function acceptApiNodePayment(runtime, params, options = {}) {
|
|
1549
1553
|
const config = runtime.config ?? runtime;
|
|
1554
|
+
const ownerFunded = options.ownerFunded === true;
|
|
1550
1555
|
const info = await rpcCall(config.fiberRpcUrl, "node_info", [], config.timeoutMs);
|
|
1551
1556
|
const depositTxHash = textValue(params.depositTxHash);
|
|
1552
|
-
const deposit = depositTxHash ? await waitForCkbTransaction(config, depositTxHash, params) : undefined;
|
|
1557
|
+
const deposit = !ownerFunded && depositTxHash ? await waitForCkbTransaction(config, depositTxHash, params) : undefined;
|
|
1553
1558
|
const targetPubkey = normalizePeerPubkey(firstTextValue(params.receiverNode, params.targetPubkey, params.destinationNode, params.pubkey));
|
|
1554
|
-
const
|
|
1559
|
+
const publishedPeerAddress = firstTextValue(params.peerAddress, params.receiverPeerAddress, params.address);
|
|
1560
|
+
const peerAddress = resolveN2nPeerAddress(config, publishedPeerAddress, boolValue(params.sameHost, false));
|
|
1555
1561
|
const provisionChannel = boolValue(params.provisionChannel, true);
|
|
1556
1562
|
const closeChannelAfterPayment = provisionChannel && boolValue(params.closeChannelAfterPayment, false);
|
|
1563
|
+
const source = {
|
|
1564
|
+
nodeId: textValue(params.sourceNodeId) || undefined,
|
|
1565
|
+
pubkey: normalizePeerPubkey(readNodeId(info)),
|
|
1566
|
+
displayName: textValue(params.sourceNodeName) || undefined,
|
|
1567
|
+
fundingBefore: ownerFunded ? await collectFundingState(config).catch(() => undefined) : undefined,
|
|
1568
|
+
};
|
|
1557
1569
|
let existingChannel;
|
|
1558
1570
|
let routeProbe;
|
|
1559
1571
|
try {
|
|
@@ -1603,6 +1615,53 @@ async function acceptApiNodePayment(runtime, params) {
|
|
|
1603
1615
|
keysend: true,
|
|
1604
1616
|
});
|
|
1605
1617
|
} catch (error) {
|
|
1618
|
+
const partialOpen = error?.commandResult && typeof error.commandResult === "object" ? error.commandResult : undefined;
|
|
1619
|
+
if (ownerFunded) {
|
|
1620
|
+
let recovery;
|
|
1621
|
+
let recoveryError;
|
|
1622
|
+
try {
|
|
1623
|
+
const openedChannelId = channelIdOf(paymentChannel);
|
|
1624
|
+
if (channelOpen && openedChannelId) {
|
|
1625
|
+
recovery = await settleFiberChannel(runtime, { channelId: openedChannelId, force: false, feeRate: "1000" });
|
|
1626
|
+
await waitForChannelClosed(config.fiberRpcUrl, openedChannelId, 10 * 60_000, 5_000);
|
|
1627
|
+
}
|
|
1628
|
+
} catch (failure) {
|
|
1629
|
+
recoveryError = message(failure);
|
|
1630
|
+
}
|
|
1631
|
+
const fundingAfter = await collectFundingState(config).catch(() => undefined);
|
|
1632
|
+
const lifecycle = nodePaymentLifecycle({
|
|
1633
|
+
source,
|
|
1634
|
+
targetPubkey,
|
|
1635
|
+
publishedPeerAddress,
|
|
1636
|
+
peerAddress,
|
|
1637
|
+
provisionChannel,
|
|
1638
|
+
closeChannelAfterPayment,
|
|
1639
|
+
existingChannel,
|
|
1640
|
+
routeProbe,
|
|
1641
|
+
channelOpen: channelOpen ?? partialOpen,
|
|
1642
|
+
paymentChannel,
|
|
1643
|
+
channelBeforePayment,
|
|
1644
|
+
fiberPayment,
|
|
1645
|
+
fundingAfter,
|
|
1646
|
+
failure: message(error),
|
|
1647
|
+
recovery,
|
|
1648
|
+
recoveryError,
|
|
1649
|
+
});
|
|
1650
|
+
throw commandResultError(`N2N transfer failed while preparing the peer, channel, or Fiber payment: ${message(error)}. No API test wallet was charged.`, {
|
|
1651
|
+
ok: false,
|
|
1652
|
+
action: "N2N_PAYMENT",
|
|
1653
|
+
mode: "Owner-funded node-to-node test",
|
|
1654
|
+
paymentStatus: "failed",
|
|
1655
|
+
source,
|
|
1656
|
+
receiverNode: targetPubkey,
|
|
1657
|
+
amount: textValue(params.amountShannons ?? params.amount) || undefined,
|
|
1658
|
+
assetType: textValue(params.assetType ?? params.asset) || "CKB",
|
|
1659
|
+
fiberPayment,
|
|
1660
|
+
channelLifecycle: lifecycle,
|
|
1661
|
+
fundingBefore: source.fundingBefore,
|
|
1662
|
+
fundingAfter,
|
|
1663
|
+
});
|
|
1664
|
+
}
|
|
1606
1665
|
let refund;
|
|
1607
1666
|
let refundError;
|
|
1608
1667
|
try {
|
|
@@ -1657,19 +1716,22 @@ async function acceptApiNodePayment(runtime, params) {
|
|
|
1657
1716
|
}
|
|
1658
1717
|
}
|
|
1659
1718
|
let refreshed;
|
|
1719
|
+
const fundingAfter = ownerFunded ? await collectFundingState(config).catch(() => undefined) : undefined;
|
|
1660
1720
|
if (typeof runtime.collect === "function" && typeof runtime.push === "function") {
|
|
1661
1721
|
refreshed = await pushWithRegistrationRetry(runtime, await runtime.collect(), {
|
|
1662
|
-
intent: "api-node-payment-completed",
|
|
1722
|
+
intent: ownerFunded ? "n2n-payment-completed" : "api-node-payment-completed",
|
|
1663
1723
|
retryOnRateLimit: true,
|
|
1664
1724
|
maxRateLimitRetries: 1,
|
|
1665
1725
|
}).catch((error) => ({ ok: false, error: message(error) }));
|
|
1666
1726
|
}
|
|
1667
1727
|
return {
|
|
1668
1728
|
ok: true,
|
|
1669
|
-
action: "API_NODE_PAYMENT",
|
|
1670
|
-
mode: "API-managed Fiber node payment",
|
|
1729
|
+
action: ownerFunded ? "N2N_PAYMENT" : "API_NODE_PAYMENT",
|
|
1730
|
+
mode: ownerFunded ? "Owner-funded node-to-node test" : "API-managed Fiber node payment",
|
|
1671
1731
|
paymentStatus: "completed",
|
|
1672
|
-
message:
|
|
1732
|
+
message: ownerFunded
|
|
1733
|
+
? "The selected source node funded or reused the Fiber route and sent the N2N payment without charging an API test wallet."
|
|
1734
|
+
: "Sender deposit is confirmed and the provider agent submitted the Fiber payment to the recipient node.",
|
|
1673
1735
|
paymentId: textValue(params.paymentId) || undefined,
|
|
1674
1736
|
quoteId: textValue(params.quoteId) || undefined,
|
|
1675
1737
|
candidateId: textValue(params.candidateId) || undefined,
|
|
@@ -1687,29 +1749,36 @@ async function acceptApiNodePayment(runtime, params) {
|
|
|
1687
1749
|
depositAmount: textValue(params.depositAmount) || undefined,
|
|
1688
1750
|
deposit,
|
|
1689
1751
|
fiberPayment,
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1752
|
+
source: ownerFunded ? { ...source, fundingAfter } : undefined,
|
|
1753
|
+
fundingBefore: ownerFunded ? source.fundingBefore : undefined,
|
|
1754
|
+
fundingAfter,
|
|
1755
|
+
channelLifecycle: nodePaymentLifecycle({
|
|
1756
|
+
source,
|
|
1757
|
+
targetPubkey,
|
|
1758
|
+
publishedPeerAddress,
|
|
1759
|
+
peerAddress,
|
|
1760
|
+
provisionChannel,
|
|
1761
|
+
closeChannelAfterPayment,
|
|
1762
|
+
existingChannel,
|
|
1695
1763
|
routeProbe,
|
|
1696
1764
|
channelOpen,
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1765
|
+
paymentChannel,
|
|
1766
|
+
paymentChannelId,
|
|
1767
|
+
channelBeforePayment,
|
|
1768
|
+
channelAfterPayment,
|
|
1769
|
+
fiberPayment,
|
|
1702
1770
|
channelClose,
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
},
|
|
1771
|
+
channelClosed,
|
|
1772
|
+
fundingAfter,
|
|
1773
|
+
}),
|
|
1707
1774
|
fundingRefresh: refreshed,
|
|
1708
1775
|
routeExecution: {
|
|
1709
1776
|
status: "fiber_send_payment",
|
|
1710
1777
|
reason: channelOpen
|
|
1711
|
-
? "No viable route existed, so the
|
|
1712
|
-
:
|
|
1778
|
+
? "No viable route existed, so the source connected the receiving peer, opened a direct channel, sent the payment, and applied the requested close policy."
|
|
1779
|
+
: ownerFunded
|
|
1780
|
+
? "The selected source node used its existing outbound Fiber liquidity."
|
|
1781
|
+
: "The provider used existing outbound Fiber liquidity after confirming the payer deposit.",
|
|
1713
1782
|
},
|
|
1714
1783
|
node: {
|
|
1715
1784
|
pubkey: normalizePeerPubkey(readNodeId(info)),
|
|
@@ -1719,6 +1788,77 @@ async function acceptApiNodePayment(runtime, params) {
|
|
|
1719
1788
|
};
|
|
1720
1789
|
}
|
|
1721
1790
|
|
|
1791
|
+
export function nodePaymentLifecycle(input) {
|
|
1792
|
+
const channelOpen = input.channelOpen && typeof input.channelOpen === "object" ? input.channelOpen : undefined;
|
|
1793
|
+
const connectResult = channelOpen?.connectResult;
|
|
1794
|
+
const channelId = input.paymentChannelId || channelIdOf(input.paymentChannel) || channelIdOf(channelOpen?.channel);
|
|
1795
|
+
const existingRoute = Boolean(input.existingChannel) || input.routeProbe?.status === "success";
|
|
1796
|
+
const peerStatus = existingRoute ? "skipped" : connectResult ? "completed" : input.failure ? "failed" : "pending";
|
|
1797
|
+
const channelStatus = existingRoute ? "skipped" : channelId || channelOpen?.openResult ? "completed" : input.failure ? "failed" : "pending";
|
|
1798
|
+
const paymentStatus = input.fiberPayment ? "completed" : input.failure ? "failed" : "pending";
|
|
1799
|
+
const closeStatus = !input.closeChannelAfterPayment
|
|
1800
|
+
? "skipped"
|
|
1801
|
+
: input.channelClosed ? "completed"
|
|
1802
|
+
: input.channelClose?.status === "failed" || input.failure ? "failed" : "pending";
|
|
1803
|
+
return omitUndefined({
|
|
1804
|
+
mode: channelOpen && !existingRoute ? "provisioned_direct_channel" : input.existingChannel ? "existing_direct_channel" : "existing_routed_liquidity",
|
|
1805
|
+
provisionRequested: input.provisionChannel,
|
|
1806
|
+
closeRequested: input.closeChannelAfterPayment,
|
|
1807
|
+
source: {
|
|
1808
|
+
nodeId: input.source?.nodeId,
|
|
1809
|
+
pubkey: input.source?.pubkey,
|
|
1810
|
+
displayName: input.source?.displayName,
|
|
1811
|
+
fundingBefore: input.source?.fundingBefore,
|
|
1812
|
+
fundingAfter: input.fundingAfter,
|
|
1813
|
+
},
|
|
1814
|
+
peer: {
|
|
1815
|
+
pubkey: input.targetPubkey,
|
|
1816
|
+
publishedAddress: input.publishedPeerAddress || undefined,
|
|
1817
|
+
dialAddress: input.peerAddress || undefined,
|
|
1818
|
+
sameHostLoopback: Boolean(input.publishedPeerAddress && input.peerAddress && input.publishedPeerAddress !== input.peerAddress),
|
|
1819
|
+
},
|
|
1820
|
+
routeProbe: input.routeProbe,
|
|
1821
|
+
peerConnect: connectResult,
|
|
1822
|
+
channelOpen,
|
|
1823
|
+
channelId: channelId || undefined,
|
|
1824
|
+
providerBeforePayment: input.channelBeforePayment?.provider,
|
|
1825
|
+
receiverBeforePayment: input.channelBeforePayment?.receiver,
|
|
1826
|
+
providerAfterPayment: input.channelAfterPayment?.provider,
|
|
1827
|
+
receiverAfterPayment: input.channelAfterPayment?.receiver,
|
|
1828
|
+
channelClose: input.channelClose,
|
|
1829
|
+
providerAtClose: input.channelClosed?.provider,
|
|
1830
|
+
receiverAtClose: input.channelClosed?.receiver,
|
|
1831
|
+
finalChannelState: input.channelClosed?.state ?? input.channelAfterPayment?.state,
|
|
1832
|
+
recovery: input.recovery,
|
|
1833
|
+
recoveryError: input.recoveryError,
|
|
1834
|
+
failure: input.failure,
|
|
1835
|
+
steps: [
|
|
1836
|
+
{ key: "source_selected", label: "Source node selected", status: "completed", detail: input.source?.displayName || shortText(input.source?.pubkey, 10, 8) },
|
|
1837
|
+
{ key: "peer_connect", label: "Receiving peer connected", status: peerStatus, detail: existingRoute ? "Existing route does not require a new direct peer connection." : input.failure && !connectResult ? input.failure : input.peerAddress },
|
|
1838
|
+
{ key: "channel_open", label: "Channel ready", status: channelStatus, detail: existingRoute ? "Existing Fiber liquidity selected." : channelId ? `Channel ${shortText(channelId, 10, 8)}` : input.failure },
|
|
1839
|
+
{ key: "fiber_transfer", label: "Funds moved over Fiber", status: paymentStatus, detail: input.fiberPayment ? `Payment ${shortText(input.fiberPayment.paymentHash ?? input.fiberPayment.payment_hash ?? input.fiberPayment.targetPubkey, 10, 8)}` : input.failure },
|
|
1840
|
+
...(input.closeChannelAfterPayment ? [{ key: "channel_close", label: "Provisioned channel closed", status: closeStatus, detail: input.channelClose?.error ?? input.channelClosed?.state } ] : []),
|
|
1841
|
+
],
|
|
1842
|
+
});
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1845
|
+
export function resolveN2nPeerAddress(config, address, sameHost) {
|
|
1846
|
+
const normalized = textValue(address);
|
|
1847
|
+
if (!normalized) return "";
|
|
1848
|
+
const addressIp = /\/ip4\/([^/]+)/i.exec(normalized)?.[1];
|
|
1849
|
+
const localPublicIp = textValue(config.publicIp);
|
|
1850
|
+
if ((sameHost || (addressIp && localPublicIp && addressIp === localPublicIp)) && addressIp) {
|
|
1851
|
+
return normalized.replace(/\/ip4\/[^/]+/i, "/ip4/127.0.0.1");
|
|
1852
|
+
}
|
|
1853
|
+
return normalized;
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1856
|
+
function commandResultError(errorMessage, commandResult) {
|
|
1857
|
+
const error = new Error(errorMessage);
|
|
1858
|
+
error.commandResult = commandResult;
|
|
1859
|
+
return error;
|
|
1860
|
+
}
|
|
1861
|
+
|
|
1722
1862
|
async function waitForCkbTransaction(config, txHash, params = {}) {
|
|
1723
1863
|
const rpcUrl = resolveCkbIndexerUrl(config);
|
|
1724
1864
|
if (!rpcUrl) throw new Error("No CKB RPC URL is configured for deposit confirmation.");
|
|
@@ -2072,37 +2212,53 @@ async function openFiberChannel(config, params) {
|
|
|
2072
2212
|
|
|
2073
2213
|
const fundingCheck = await assertChannelFundingAvailable(config, openRequest.funding_amount);
|
|
2074
2214
|
let connectResult;
|
|
2075
|
-
|
|
2076
|
-
if (connectFirst) {
|
|
2077
|
-
connectResult = await ensurePeerConnected(config, peer, pubkey);
|
|
2078
|
-
}
|
|
2079
|
-
const openResult = await openChannelWhenPeerReady(config, peer, pubkey, openRequest, params);
|
|
2215
|
+
let openResult;
|
|
2080
2216
|
let channelWatch;
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2217
|
+
const connectFirst = boolValue(params.connectFirst, true) && !boolValue(params.skipConnect, false);
|
|
2218
|
+
try {
|
|
2219
|
+
if (connectFirst) connectResult = await ensurePeerConnected(config, peer, pubkey);
|
|
2220
|
+
openResult = await openChannelWhenPeerReady(config, peer, pubkey, openRequest, params);
|
|
2221
|
+
if (!boolValue(params.wait, false) && !boolValue(params.waitUntilReady, false)) {
|
|
2222
|
+
channelWatch = await watchForImmediateChannelFailure(
|
|
2223
|
+
config.fiberRpcUrl,
|
|
2224
|
+
pubkey,
|
|
2225
|
+
positiveNumber(params.failureWatchMs ?? config.channelFailureWatchMs, DEFAULT_CHANNEL_FAILURE_WATCH_MS),
|
|
2226
|
+
positiveNumber(params.failurePollMs ?? params.pollMs ?? config.channelFailurePollMs, DEFAULT_CHANNEL_FAILURE_POLL_MS),
|
|
2227
|
+
);
|
|
2228
|
+
}
|
|
2229
|
+
const result = {
|
|
2230
|
+
ok: true,
|
|
2231
|
+
action: "OPEN_CHANNEL",
|
|
2232
|
+
peerPubkey: pubkey,
|
|
2233
|
+
peer: peer.meta,
|
|
2234
|
+
peerAddress: peer.address,
|
|
2235
|
+
fundingAmount: openRequest.funding_amount,
|
|
2236
|
+
public: openRequest.public,
|
|
2237
|
+
fundingCheck,
|
|
2238
|
+
connectResult,
|
|
2239
|
+
openResult,
|
|
2240
|
+
channelWatch,
|
|
2241
|
+
};
|
|
2242
|
+
if (boolValue(params.wait, false) || boolValue(params.waitUntilReady, false)) {
|
|
2243
|
+
result.channel = await waitForChannel(config.fiberRpcUrl, pubkey, positiveNumber(params.waitTimeoutMs, 20 * 60_000), positiveNumber(params.pollMs, 10_000));
|
|
2244
|
+
}
|
|
2245
|
+
return result;
|
|
2246
|
+
} catch (error) {
|
|
2247
|
+
throw commandResultError(message(error), {
|
|
2248
|
+
ok: false,
|
|
2249
|
+
action: "OPEN_CHANNEL",
|
|
2250
|
+
peerPubkey: pubkey,
|
|
2251
|
+
peer: peer.meta,
|
|
2252
|
+
peerAddress: peer.address,
|
|
2253
|
+
fundingAmount: openRequest.funding_amount,
|
|
2254
|
+
public: openRequest.public,
|
|
2255
|
+
fundingCheck,
|
|
2256
|
+
connectResult,
|
|
2257
|
+
openResult,
|
|
2258
|
+
channelWatch,
|
|
2259
|
+
failure: message(error),
|
|
2260
|
+
});
|
|
2104
2261
|
}
|
|
2105
|
-
return result;
|
|
2106
2262
|
}
|
|
2107
2263
|
|
|
2108
2264
|
async function settleFiberChannel(runtime, params) {
|