@toon-protocol/client 0.14.10 → 0.14.12
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.d.ts +63 -3
- package/dist/index.js +101 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1264,6 +1264,21 @@ declare class ToonClient {
|
|
|
1264
1264
|
}>;
|
|
1265
1265
|
/** Where a tracked channel sits in the withdraw journey. */
|
|
1266
1266
|
getChannelCloseState(channelId: string): 'open' | 'closing' | 'settleable' | 'settled';
|
|
1267
|
+
getSettleableAt(channelId: string): bigint | undefined;
|
|
1268
|
+
/**
|
|
1269
|
+
* Re-hydrate a RESUMED channel's on-chain deposit. Persisted channel state
|
|
1270
|
+
* omits `depositTotal`, so after a daemon restart the tracked deposit is `0`
|
|
1271
|
+
* and the wallet shows 0 spendable even though real collateral is locked
|
|
1272
|
+
* on-chain. Read the participant's `deposit` from the `participants` mapping
|
|
1273
|
+
* and update the tracked total so `depositTotal - cumulativeAmount` is right.
|
|
1274
|
+
* Best-effort by caller (await + catch); returns the on-chain deposit, or
|
|
1275
|
+
* `undefined` when it can't be read (no channel manager / on-chain client /
|
|
1276
|
+
* EVM address).
|
|
1277
|
+
*/
|
|
1278
|
+
rehydrateChannelDeposit(channelId: string, opts: {
|
|
1279
|
+
chain: string;
|
|
1280
|
+
tokenNetworkAddress: string;
|
|
1281
|
+
}): Promise<bigint | undefined>;
|
|
1267
1282
|
/**
|
|
1268
1283
|
* Read the on-chain settlement-token balance of this client's OWN wallet on
|
|
1269
1284
|
* each configured chain (EVM token, Solana SPL, native MINA). A free read — no
|
|
@@ -1358,6 +1373,26 @@ declare class ConnectorError extends ToonClientError {
|
|
|
1358
1373
|
declare class ValidationError extends ToonClientError {
|
|
1359
1374
|
constructor(message: string, cause?: Error);
|
|
1360
1375
|
}
|
|
1376
|
+
/**
|
|
1377
|
+
* Thrown when the one-time on-chain payment-channel OPEN reverts because the
|
|
1378
|
+
* local settlement wallet has no native gas to pay for its own
|
|
1379
|
+
* approve/openChannel/setTotalDeposit transactions. This is the channel OPEN
|
|
1380
|
+
* only — per-write settlement rides ILP-over-HTTP and never spends gas. We
|
|
1381
|
+
* remap ONLY this case so callers get an actionable message (fund the wallet)
|
|
1382
|
+
* instead of the raw viem "...exceeds the balance of the account" string
|
|
1383
|
+
* (toon-meta#65). Retryable once the wallet is funded; the underlying viem/RPC
|
|
1384
|
+
* error is preserved as `cause`.
|
|
1385
|
+
*/
|
|
1386
|
+
declare class ChannelFundingError extends ToonClientError {
|
|
1387
|
+
readonly retryable = true;
|
|
1388
|
+
constructor(message: string, cause?: Error);
|
|
1389
|
+
}
|
|
1390
|
+
/**
|
|
1391
|
+
* True when `err` (or any error in its nested `cause` chain) is an
|
|
1392
|
+
* insufficient-native-gas revert. viem wraps the node error one or more levels
|
|
1393
|
+
* deep, so the whole chain is flattened and scanned.
|
|
1394
|
+
*/
|
|
1395
|
+
declare function isInsufficientGasError(err: unknown): boolean;
|
|
1361
1396
|
|
|
1362
1397
|
/**
|
|
1363
1398
|
* Configuration options for HttpRuntimeClient.
|
|
@@ -2238,6 +2273,23 @@ declare class OnChainChannelClient implements ConnectorChannelClient {
|
|
|
2238
2273
|
}>;
|
|
2239
2274
|
/** Read + destructure the EVM `channels(bytes32)` view. */
|
|
2240
2275
|
private readEvmChannel;
|
|
2276
|
+
/**
|
|
2277
|
+
* Read a participant's on-chain channel state — `deposit` (locked collateral),
|
|
2278
|
+
* `nonce`, and `transferredAmount` — straight from the `participants` mapping.
|
|
2279
|
+
* Takes the chain + token-network explicitly so it works for a channel that
|
|
2280
|
+
* was RESUMED from disk (no in-memory `channelContext` yet), which is exactly
|
|
2281
|
+
* when the daemon needs to re-hydrate the deposit it doesn't persist.
|
|
2282
|
+
*/
|
|
2283
|
+
readEvmParticipantState(opts: {
|
|
2284
|
+
chain: string;
|
|
2285
|
+
tokenNetworkAddress: string;
|
|
2286
|
+
channelId: string;
|
|
2287
|
+
participant: string;
|
|
2288
|
+
}): Promise<{
|
|
2289
|
+
deposit: bigint;
|
|
2290
|
+
nonce: bigint;
|
|
2291
|
+
transferredAmount: bigint;
|
|
2292
|
+
}>;
|
|
2241
2293
|
/**
|
|
2242
2294
|
* Opens a REAL on-chain Solana payment channel.
|
|
2243
2295
|
*
|
|
@@ -2284,14 +2336,22 @@ declare class OnChainChannelClient implements ConnectorChannelClient {
|
|
|
2284
2336
|
*/
|
|
2285
2337
|
private openMinaChannel;
|
|
2286
2338
|
/**
|
|
2287
|
-
* Opens an EVM payment channel on-chain
|
|
2339
|
+
* Opens an EVM payment channel on-chain, remapping the one-time
|
|
2340
|
+
* insufficient-native-gas revert into an actionable {@link ChannelFundingError}
|
|
2341
|
+
* so callers surface "fund the wallet" instead of the raw viem
|
|
2342
|
+
* "...exceeds the balance of the account" string (toon-meta#65). Only the gas
|
|
2343
|
+
* case is remapped; every other error propagates unchanged.
|
|
2344
|
+
*/
|
|
2345
|
+
private openEvmChannel;
|
|
2346
|
+
/**
|
|
2347
|
+
* Raw EVM channel-open (no gas-error remapping — see {@link openEvmChannel}).
|
|
2288
2348
|
*
|
|
2289
2349
|
* 1. Approve token spend if needed
|
|
2290
2350
|
* 2. Call TokenNetwork.openChannel()
|
|
2291
2351
|
* 3. Extract channelId from ChannelOpened event
|
|
2292
2352
|
* 4. Deposit initial funds if specified
|
|
2293
2353
|
*/
|
|
2294
|
-
private
|
|
2354
|
+
private openEvmChannelUnchecked;
|
|
2295
2355
|
/**
|
|
2296
2356
|
* Gets the current state of a payment channel from on-chain data.
|
|
2297
2357
|
*/
|
|
@@ -3519,4 +3579,4 @@ declare function loadKeystore(path: string, password: string): string;
|
|
|
3519
3579
|
*/
|
|
3520
3580
|
declare function writeKeystoreFile(path: string, keystore: EncryptedKeystore): void;
|
|
3521
3581
|
|
|
3522
|
-
export { type BackupPayload, type BalanceProofParams, BtpRuntimeClient, type BtpRuntimeClientConfig, type ChainMetadata, type ChainSigner, ChannelManager, type ClaimMessage, type ClaimResolver, ConnectorError, type DiscoveredIlpPeer, type EVMClaimMessage, type EncryptedKeystore, EvmSigner, type FaucetChain, type FundWalletOptions, type FundWalletResult, type H402FetchOptions, Http402Client, type Http402ClientConfig, HttpConnectorAdmin, type HttpConnectorAdminConfig, HttpIlpClient, type HttpIlpClientConfig, type HttpIlpClientFactory, HttpRuntimeClient, type HttpRuntimeClientConfig, ILP_CLAIM_HEADER, ILP_CLAIM_WRAPPED_HEADER, ILP_PEER_ID_HEADER, type IlpTransportChoice, type InteractionResultContent, KeyManager, type KeyManagerConfig, type MinaClaimMessage, type MinaDepositReader, MinaSigner, type MinaSignerOptions, NetworkError, OnChainChannelClient, type OnChainChannelClientConfig, type ParsedFulfillHttp, type ParsedX402Challenge, type PasskeyInfo, type PetDvmProvider, type PetInteractionEventData, type PetInteractionRequestParams, type PetInteractionResultData, type PetListing, type PetListingFilterOptions, type PetListingParams, type PetPurchaseRequestParams, type ProofStatus, type PublishEventResult, type RequestBlobStorageParams, type RequestBlobStorageResult, type RetryOptions, type SelectIlpTransportOptions, type SignedBalanceProof, type SolanaChannelClientOptions, type SolanaClaimMessage, SolanaSigner, type StatValues, type ToonChannelAccept, ToonClient, type ToonClientConfig, ToonClientError, type ToonIdentity, type ToonSigners, type ToonStartResult, type UnsignedNostrEvent, ValidationError, type VaultData, applyDefaults, applyNetworkPresets, buildBackupEvent, buildBackupFilter, buildPetInteractionRequest, buildPetListingEvent, buildPetPurchaseRequest, buildSettlementInfo, buildStoreWriteEnvelope, decryptMnemonic, defaultFaucetTimeout, deriveFromNsec, deriveFullIdentity, deriveNostrKeyFromMnemonic, encryptMnemonic, filterPetDvmProviders, filterPetListings, fundWallet, generateKeystore, generateMnemonic, generateRandomIdentity, getNetworkStatus, httpEndpointToBtpUrl, importKeystore, isPrfSupported, loadKeystore, parseBackupPayload, parseFulfillHttp, parseFulfillHttpBytes, parseHttpResponse, parsePetInteractionEvent, parsePetInteractionResult, parsePetListing, parseX402Body, parseX402Challenge, proxyIlpEndpoint, readDiscoveredIlpPeer, readMinaDepositTotal, requestBlobStorage, selectIlpTransport, serializeHttpRequest, validateConfig, validateMnemonic, withRetry, writeKeystoreFile };
|
|
3582
|
+
export { type BackupPayload, type BalanceProofParams, BtpRuntimeClient, type BtpRuntimeClientConfig, type ChainMetadata, type ChainSigner, ChannelFundingError, ChannelManager, type ClaimMessage, type ClaimResolver, ConnectorError, type DiscoveredIlpPeer, type EVMClaimMessage, type EncryptedKeystore, EvmSigner, type FaucetChain, type FundWalletOptions, type FundWalletResult, type H402FetchOptions, Http402Client, type Http402ClientConfig, HttpConnectorAdmin, type HttpConnectorAdminConfig, HttpIlpClient, type HttpIlpClientConfig, type HttpIlpClientFactory, HttpRuntimeClient, type HttpRuntimeClientConfig, ILP_CLAIM_HEADER, ILP_CLAIM_WRAPPED_HEADER, ILP_PEER_ID_HEADER, type IlpTransportChoice, type InteractionResultContent, KeyManager, type KeyManagerConfig, type MinaClaimMessage, type MinaDepositReader, MinaSigner, type MinaSignerOptions, NetworkError, OnChainChannelClient, type OnChainChannelClientConfig, type ParsedFulfillHttp, type ParsedX402Challenge, type PasskeyInfo, type PetDvmProvider, type PetInteractionEventData, type PetInteractionRequestParams, type PetInteractionResultData, type PetListing, type PetListingFilterOptions, type PetListingParams, type PetPurchaseRequestParams, type ProofStatus, type PublishEventResult, type RequestBlobStorageParams, type RequestBlobStorageResult, type RetryOptions, type SelectIlpTransportOptions, type SignedBalanceProof, type SolanaChannelClientOptions, type SolanaClaimMessage, SolanaSigner, type StatValues, type ToonChannelAccept, ToonClient, type ToonClientConfig, ToonClientError, type ToonIdentity, type ToonSigners, type ToonStartResult, type UnsignedNostrEvent, ValidationError, type VaultData, applyDefaults, applyNetworkPresets, buildBackupEvent, buildBackupFilter, buildPetInteractionRequest, buildPetListingEvent, buildPetPurchaseRequest, buildSettlementInfo, buildStoreWriteEnvelope, decryptMnemonic, defaultFaucetTimeout, deriveFromNsec, deriveFullIdentity, deriveNostrKeyFromMnemonic, encryptMnemonic, filterPetDvmProviders, filterPetListings, fundWallet, generateKeystore, generateMnemonic, generateRandomIdentity, getNetworkStatus, httpEndpointToBtpUrl, importKeystore, isInsufficientGasError, isPrfSupported, loadKeystore, parseBackupPayload, parseFulfillHttp, parseFulfillHttpBytes, parseHttpResponse, parsePetInteractionEvent, parsePetInteractionResult, parsePetListing, parseX402Body, parseX402Challenge, proxyIlpEndpoint, readDiscoveredIlpPeer, readMinaDepositTotal, requestBlobStorage, selectIlpTransport, serializeHttpRequest, validateConfig, validateMnemonic, withRetry, writeKeystoreFile };
|
package/dist/index.js
CHANGED
|
@@ -80,6 +80,29 @@ var PeerAlreadyExistsError = class extends ToonClientError {
|
|
|
80
80
|
this.name = "PeerAlreadyExistsError";
|
|
81
81
|
}
|
|
82
82
|
};
|
|
83
|
+
var ChannelFundingError = class extends ToonClientError {
|
|
84
|
+
retryable = true;
|
|
85
|
+
constructor(message, cause) {
|
|
86
|
+
super(message, "CHANNEL_FUNDING", cause);
|
|
87
|
+
this.name = "ChannelFundingError";
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var INSUFFICIENT_GAS_MARKERS = [
|
|
91
|
+
"exceeds the balance of the account",
|
|
92
|
+
"insufficient funds for gas",
|
|
93
|
+
"insufficient funds for intrinsic transaction cost",
|
|
94
|
+
"insufficient funds for transfer"
|
|
95
|
+
];
|
|
96
|
+
function isInsufficientGasError(err) {
|
|
97
|
+
const parts = [];
|
|
98
|
+
let cur = err;
|
|
99
|
+
for (let i = 0; i < 10 && cur != null; i++) {
|
|
100
|
+
parts.push(cur instanceof Error ? cur.message : String(cur));
|
|
101
|
+
cur = cur instanceof Error ? cur.cause : void 0;
|
|
102
|
+
}
|
|
103
|
+
const text = parts.join(" | ").toLowerCase();
|
|
104
|
+
return INSUFFICIENT_GAS_MARKERS.some((m) => text.includes(m));
|
|
105
|
+
}
|
|
83
106
|
|
|
84
107
|
// src/keys/KeyDerivation.ts
|
|
85
108
|
import { generateSecretKey, getPublicKey } from "nostr-tools/pure";
|
|
@@ -2300,6 +2323,17 @@ var TOKEN_NETWORK_ABI = [
|
|
|
2300
2323
|
{ name: "participant2", type: "address" }
|
|
2301
2324
|
]
|
|
2302
2325
|
},
|
|
2326
|
+
{
|
|
2327
|
+
name: "participants",
|
|
2328
|
+
type: "function",
|
|
2329
|
+
stateMutability: "view",
|
|
2330
|
+
inputs: [{ type: "bytes32" }, { type: "address" }],
|
|
2331
|
+
outputs: [
|
|
2332
|
+
{ name: "deposit", type: "uint256" },
|
|
2333
|
+
{ name: "nonce", type: "uint256" },
|
|
2334
|
+
{ name: "transferredAmount", type: "uint256" }
|
|
2335
|
+
]
|
|
2336
|
+
},
|
|
2303
2337
|
{
|
|
2304
2338
|
name: "ChannelOpened",
|
|
2305
2339
|
type: "event",
|
|
@@ -2631,6 +2665,23 @@ var OnChainChannelClient = class {
|
|
|
2631
2665
|
});
|
|
2632
2666
|
return { settlementTimeout: res[0], state: Number(res[1]), closedAt: res[2] };
|
|
2633
2667
|
}
|
|
2668
|
+
/**
|
|
2669
|
+
* Read a participant's on-chain channel state — `deposit` (locked collateral),
|
|
2670
|
+
* `nonce`, and `transferredAmount` — straight from the `participants` mapping.
|
|
2671
|
+
* Takes the chain + token-network explicitly so it works for a channel that
|
|
2672
|
+
* was RESUMED from disk (no in-memory `channelContext` yet), which is exactly
|
|
2673
|
+
* when the daemon needs to re-hydrate the deposit it doesn't persist.
|
|
2674
|
+
*/
|
|
2675
|
+
async readEvmParticipantState(opts) {
|
|
2676
|
+
const { publicClient } = this.createClients(opts.chain);
|
|
2677
|
+
const res = await publicClient.readContract({
|
|
2678
|
+
address: opts.tokenNetworkAddress,
|
|
2679
|
+
abi: TOKEN_NETWORK_ABI,
|
|
2680
|
+
functionName: "participants",
|
|
2681
|
+
args: [opts.channelId, opts.participant]
|
|
2682
|
+
});
|
|
2683
|
+
return { deposit: res[0], nonce: res[1], transferredAmount: res[2] };
|
|
2684
|
+
}
|
|
2634
2685
|
/**
|
|
2635
2686
|
* Opens a REAL on-chain Solana payment channel.
|
|
2636
2687
|
*
|
|
@@ -2762,14 +2813,33 @@ var OnChainChannelClient = class {
|
|
|
2762
2813
|
};
|
|
2763
2814
|
}
|
|
2764
2815
|
/**
|
|
2765
|
-
* Opens an EVM payment channel on-chain
|
|
2816
|
+
* Opens an EVM payment channel on-chain, remapping the one-time
|
|
2817
|
+
* insufficient-native-gas revert into an actionable {@link ChannelFundingError}
|
|
2818
|
+
* so callers surface "fund the wallet" instead of the raw viem
|
|
2819
|
+
* "...exceeds the balance of the account" string (toon-meta#65). Only the gas
|
|
2820
|
+
* case is remapped; every other error propagates unchanged.
|
|
2821
|
+
*/
|
|
2822
|
+
async openEvmChannel(params) {
|
|
2823
|
+
try {
|
|
2824
|
+
return await this.openEvmChannelUnchecked(params);
|
|
2825
|
+
} catch (err) {
|
|
2826
|
+
if (!isInsufficientGasError(err)) throw err;
|
|
2827
|
+
const chainFamily = params.chain.split(":")[0] || params.chain;
|
|
2828
|
+
throw new ChannelFundingError(
|
|
2829
|
+
`Settlement wallet ${this.evmSigner.address} has no gas on ${chainFamily} to open a payment channel. Run toon_fund_wallet (or fund the wallet) and retry.`,
|
|
2830
|
+
err instanceof Error ? err : void 0
|
|
2831
|
+
);
|
|
2832
|
+
}
|
|
2833
|
+
}
|
|
2834
|
+
/**
|
|
2835
|
+
* Raw EVM channel-open (no gas-error remapping — see {@link openEvmChannel}).
|
|
2766
2836
|
*
|
|
2767
2837
|
* 1. Approve token spend if needed
|
|
2768
2838
|
* 2. Call TokenNetwork.openChannel()
|
|
2769
2839
|
* 3. Extract channelId from ChannelOpened event
|
|
2770
2840
|
* 4. Deposit initial funds if specified
|
|
2771
2841
|
*/
|
|
2772
|
-
async
|
|
2842
|
+
async openEvmChannelUnchecked(params) {
|
|
2773
2843
|
const {
|
|
2774
2844
|
chain,
|
|
2775
2845
|
tokenNetwork,
|
|
@@ -5010,6 +5080,33 @@ var ToonClient = class {
|
|
|
5010
5080
|
if (!this.channelManager) throw new Error("ChannelManager not initialized");
|
|
5011
5081
|
return this.channelManager.getChannelCloseState(channelId);
|
|
5012
5082
|
}
|
|
5083
|
+
getSettleableAt(channelId) {
|
|
5084
|
+
if (!this.channelManager) throw new Error("ChannelManager not initialized");
|
|
5085
|
+
return this.channelManager.getSettleableAt(channelId);
|
|
5086
|
+
}
|
|
5087
|
+
/**
|
|
5088
|
+
* Re-hydrate a RESUMED channel's on-chain deposit. Persisted channel state
|
|
5089
|
+
* omits `depositTotal`, so after a daemon restart the tracked deposit is `0`
|
|
5090
|
+
* and the wallet shows 0 spendable even though real collateral is locked
|
|
5091
|
+
* on-chain. Read the participant's `deposit` from the `participants` mapping
|
|
5092
|
+
* and update the tracked total so `depositTotal - cumulativeAmount` is right.
|
|
5093
|
+
* Best-effort by caller (await + catch); returns the on-chain deposit, or
|
|
5094
|
+
* `undefined` when it can't be read (no channel manager / on-chain client /
|
|
5095
|
+
* EVM address).
|
|
5096
|
+
*/
|
|
5097
|
+
async rehydrateChannelDeposit(channelId, opts) {
|
|
5098
|
+
if (!this.channelManager || !this.onChainChannelClient) return void 0;
|
|
5099
|
+
const participant = this.getEvmAddress();
|
|
5100
|
+
if (!participant) return void 0;
|
|
5101
|
+
const { deposit } = await this.onChainChannelClient.readEvmParticipantState({
|
|
5102
|
+
chain: opts.chain,
|
|
5103
|
+
tokenNetworkAddress: opts.tokenNetworkAddress,
|
|
5104
|
+
channelId,
|
|
5105
|
+
participant
|
|
5106
|
+
});
|
|
5107
|
+
this.channelManager.setDepositTotal(channelId, deposit);
|
|
5108
|
+
return deposit;
|
|
5109
|
+
}
|
|
5013
5110
|
/**
|
|
5014
5111
|
* Read the on-chain settlement-token balance of this client's OWN wallet on
|
|
5015
5112
|
* each configured chain (EVM token, Solana SPL, native MINA). A free read — no
|
|
@@ -7045,6 +7142,7 @@ function writeKeystoreFile(path, keystore) {
|
|
|
7045
7142
|
}
|
|
7046
7143
|
export {
|
|
7047
7144
|
BtpRuntimeClient,
|
|
7145
|
+
ChannelFundingError,
|
|
7048
7146
|
ChannelManager,
|
|
7049
7147
|
ConnectorError,
|
|
7050
7148
|
EvmSigner,
|
|
@@ -7102,6 +7200,7 @@ export {
|
|
|
7102
7200
|
guardedRenderDispatch,
|
|
7103
7201
|
httpEndpointToBtpUrl,
|
|
7104
7202
|
importKeystore,
|
|
7203
|
+
isInsufficientGasError,
|
|
7105
7204
|
isPrfSupported,
|
|
7106
7205
|
isTrustDowngrade,
|
|
7107
7206
|
loadKeystore,
|