@toon-protocol/client 0.20.1 → 0.20.3
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 +19 -13
- package/dist/index.js +81 -12
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -107,6 +107,8 @@ interface WalletBalanceSources {
|
|
|
107
107
|
chainKey?: string;
|
|
108
108
|
graphqlUrl: string;
|
|
109
109
|
owner: string;
|
|
110
|
+
/** Settlement-token Field id (decimal). Reads the token balance when set. */
|
|
111
|
+
tokenId?: string;
|
|
110
112
|
};
|
|
111
113
|
/** Injectable fetch (Solana/Mina JSON-RPC & GraphQL) for tests. */
|
|
112
114
|
fetchImpl?: typeof fetch;
|
|
@@ -427,7 +429,7 @@ interface ToonClientConfig {
|
|
|
427
429
|
}>;
|
|
428
430
|
/** File path for persisting payment channel nonce/amount state across restarts */
|
|
429
431
|
channelStorePath?: string;
|
|
430
|
-
/** Nostr relay URL for peer discovery. Default: 'ws
|
|
432
|
+
/** Nostr relay URL for peer discovery. Default: 'wss://relay-ws.devnet.toonprotocol.dev' */
|
|
431
433
|
relayUrl?: string;
|
|
432
434
|
/**
|
|
433
435
|
* Known peers to bootstrap with.
|
|
@@ -3932,17 +3934,21 @@ declare function buildSettlementInfo(rawConfig: ToonClientConfig): ClientSettlem
|
|
|
3932
3934
|
/**
|
|
3933
3935
|
* Devnet faucet helper.
|
|
3934
3936
|
*
|
|
3935
|
-
* The deployed TOON devnet exposes a faucet that drips
|
|
3936
|
-
* chain address so a client can open payment channels and pay
|
|
3937
|
+
* The deployed TOON devnet exposes a faucet that drips the settlement token
|
|
3938
|
+
* (USDC) to a given chain address so a client can open payment channels and pay
|
|
3939
|
+
* for writes. This helper hits the USDC-ONLY faucet legs — it funds USDC and
|
|
3940
|
+
* assumes the wallet already holds enough native gas to transact:
|
|
3937
3941
|
*
|
|
3938
|
-
* EVM `POST {faucetUrl}/api/request`
|
|
3939
|
-
* Solana `POST {faucetUrl}/api/solana/request`
|
|
3940
|
-
* Mina `POST {faucetUrl}/api/mina/request`
|
|
3942
|
+
* EVM `POST {faucetUrl}/api/base-sepolia/request` body `{ address }` → USDC (Base Sepolia mint)
|
|
3943
|
+
* Solana `POST {faucetUrl}/api/solana/usdc-request` body `{ address }` → USDC (no SOL leg)
|
|
3944
|
+
* Mina `POST {faucetUrl}/api/mina/usdc-request` body `{ address }` → USDC (no MINA leg)
|
|
3941
3945
|
*
|
|
3942
3946
|
* Devnet edge (today): `https://faucet.devnet.toonprotocol.dev`.
|
|
3943
3947
|
*
|
|
3944
3948
|
* All three chains are live on the deployed faucet — the request shape is
|
|
3945
|
-
* identical (`{ address }`); only the path differs.
|
|
3949
|
+
* identical (`{ address }`); only the path differs. (The EVM leg mints the
|
|
3950
|
+
* ungated mock USDC on Base Sepolia and best-effort tops up gas; the Solana and
|
|
3951
|
+
* Mina legs are strictly USDC-only and expect the address to already hold gas.)
|
|
3946
3952
|
*/
|
|
3947
3953
|
/** Supported faucet chains. */
|
|
3948
3954
|
type FaucetChain = 'evm' | 'solana' | 'mina';
|
|
@@ -3969,12 +3975,12 @@ interface FundWalletOptions {
|
|
|
3969
3975
|
/**
|
|
3970
3976
|
* Default faucet request timeout (ms) for a chain.
|
|
3971
3977
|
*
|
|
3972
|
-
* EVM and Solana
|
|
3973
|
-
*
|
|
3974
|
-
*
|
|
3975
|
-
*
|
|
3976
|
-
*
|
|
3977
|
-
*
|
|
3978
|
+
* The EVM (Base Sepolia mint) and Solana USDC legs respond in a few seconds, so
|
|
3979
|
+
* 30s is plenty. The Mina USDC leg TRANSFERS the token via an o1js-proven
|
|
3980
|
+
* transaction on a chain that settles much more slowly: the drip routinely
|
|
3981
|
+
* succeeds server-side but takes well over 30s to answer the HTTP request, so a
|
|
3982
|
+
* flat 30s budget makes the client give up on a request that actually worked.
|
|
3983
|
+
* Give mina a much longer budget.
|
|
3978
3984
|
*/
|
|
3979
3985
|
declare function defaultFaucetTimeout(chain: FaucetChain): number;
|
|
3980
3986
|
/**
|
package/dist/index.js
CHANGED
|
@@ -470,7 +470,10 @@ function applyDefaults(rawConfig) {
|
|
|
470
470
|
connectorUrl,
|
|
471
471
|
// Surface the derived `POST /ilp` endpoint so HTTP mode selects HttpIlpClient.
|
|
472
472
|
...connectorHttpEndpoint ? { connectorHttpEndpoint } : {},
|
|
473
|
-
|
|
473
|
+
// Last-resort relay default. An explicit `config.relayUrl` always wins;
|
|
474
|
+
// `applyNetworkPresets` does not set a per-network relay, so this fallback
|
|
475
|
+
// points at the public devnet relay rather than a dead localhost socket.
|
|
476
|
+
relayUrl: config.relayUrl ?? "wss://relay-ws.devnet.toonprotocol.dev",
|
|
474
477
|
queryTimeout: config.queryTimeout ?? 3e4,
|
|
475
478
|
maxRetries: config.maxRetries ?? 3,
|
|
476
479
|
retryDelay: config.retryDelay ?? 1e3,
|
|
@@ -4056,6 +4059,7 @@ var JsonFileChannelStore = class {
|
|
|
4056
4059
|
|
|
4057
4060
|
// src/balance/WalletBalanceReader.ts
|
|
4058
4061
|
import { createPublicClient as createPublicClient2, http as http2, defineChain as defineChain2 } from "viem";
|
|
4062
|
+
import { sha256 as sha2564 } from "@noble/hashes/sha2.js";
|
|
4059
4063
|
var ERC20_READ_ABI = [
|
|
4060
4064
|
{ name: "balanceOf", type: "function", stateMutability: "view", inputs: [{ name: "account", type: "address" }], outputs: [{ type: "uint256" }] },
|
|
4061
4065
|
{ name: "decimals", type: "function", stateMutability: "view", inputs: [], outputs: [{ type: "uint8" }] },
|
|
@@ -4170,6 +4174,62 @@ async function readMinaBalance(opts) {
|
|
|
4170
4174
|
assetScale: 9
|
|
4171
4175
|
};
|
|
4172
4176
|
}
|
|
4177
|
+
var BASE58_ALPHABET2 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
4178
|
+
function base58encode(bytes) {
|
|
4179
|
+
let num = 0n;
|
|
4180
|
+
for (const b of bytes) num = num * 256n + BigInt(b);
|
|
4181
|
+
let out = "";
|
|
4182
|
+
while (num > 0n) {
|
|
4183
|
+
out = BASE58_ALPHABET2[Number(num % 58n)] + out;
|
|
4184
|
+
num /= 58n;
|
|
4185
|
+
}
|
|
4186
|
+
for (const b of bytes) {
|
|
4187
|
+
if (b === 0) out = "1" + out;
|
|
4188
|
+
else break;
|
|
4189
|
+
}
|
|
4190
|
+
return out;
|
|
4191
|
+
}
|
|
4192
|
+
function minaTokenIdToBase58(tokenId) {
|
|
4193
|
+
if (!/^\d+$/.test(tokenId)) {
|
|
4194
|
+
throw new Error(`Mina tokenId must be a decimal Field string: "${tokenId}"`);
|
|
4195
|
+
}
|
|
4196
|
+
let field = BigInt(tokenId);
|
|
4197
|
+
const le = new Uint8Array(32);
|
|
4198
|
+
for (let i = 0; i < 32; i++) {
|
|
4199
|
+
le[i] = Number(field & 0xffn);
|
|
4200
|
+
field >>= 8n;
|
|
4201
|
+
}
|
|
4202
|
+
const body = new Uint8Array(1 + 32);
|
|
4203
|
+
body[0] = 28;
|
|
4204
|
+
body.set(le, 1);
|
|
4205
|
+
const checksum = sha2564(sha2564(body)).slice(0, 4);
|
|
4206
|
+
const raw = new Uint8Array(body.length + 4);
|
|
4207
|
+
raw.set(body, 0);
|
|
4208
|
+
raw.set(checksum, body.length);
|
|
4209
|
+
return base58encode(raw);
|
|
4210
|
+
}
|
|
4211
|
+
async function readMinaTokenBalance(opts) {
|
|
4212
|
+
const fetchImpl = opts.fetchImpl ?? fetch;
|
|
4213
|
+
const token = minaTokenIdToBase58(opts.tokenId);
|
|
4214
|
+
const query = "query($pk:PublicKey!,$t:TokenId){account(publicKey:$pk,token:$t){balance{total}}}";
|
|
4215
|
+
const res = await fetchImpl(opts.graphqlUrl, {
|
|
4216
|
+
method: "POST",
|
|
4217
|
+
headers: { "content-type": "application/json" },
|
|
4218
|
+
body: JSON.stringify({ query, variables: { pk: opts.owner, t: token } })
|
|
4219
|
+
});
|
|
4220
|
+
if (!res.ok) throw new Error(`Mina GraphQL request failed: HTTP ${res.status}`);
|
|
4221
|
+
const json = await res.json();
|
|
4222
|
+
if (json.errors && json.errors.length > 0) {
|
|
4223
|
+
throw new Error(`Mina GraphQL error: ${json.errors[0]?.message ?? "unknown"}`);
|
|
4224
|
+
}
|
|
4225
|
+
return {
|
|
4226
|
+
chain: "mina",
|
|
4227
|
+
address: opts.owner,
|
|
4228
|
+
amount: String(json.data?.account?.balance?.total ?? "0"),
|
|
4229
|
+
asset: "USDC",
|
|
4230
|
+
assetScale: 9
|
|
4231
|
+
};
|
|
4232
|
+
}
|
|
4173
4233
|
var errText = (e) => e instanceof Error ? e.message : String(e);
|
|
4174
4234
|
function foldNative(out, settled, errors) {
|
|
4175
4235
|
if (settled.status === "fulfilled") out.native = settled.value;
|
|
@@ -4234,24 +4294,28 @@ async function readWalletBalances(sources) {
|
|
|
4234
4294
|
);
|
|
4235
4295
|
}
|
|
4236
4296
|
if (sources.mina) {
|
|
4237
|
-
const { chainKey = "mina", graphqlUrl, owner } = sources.mina;
|
|
4297
|
+
const { chainKey = "mina", graphqlUrl, owner, tokenId } = sources.mina;
|
|
4238
4298
|
tasks.push(
|
|
4239
4299
|
(async () => {
|
|
4240
4300
|
const out = { chain: "mina", chainKey, address: owner, tokens: [] };
|
|
4241
4301
|
const errors = [];
|
|
4242
|
-
const nativeR = await Promise.allSettled([
|
|
4302
|
+
const [nativeR, tokenR] = await Promise.allSettled([
|
|
4303
|
+
readMinaBalance({ graphqlUrl, owner, fetchImpl }),
|
|
4304
|
+
tokenId ? readMinaTokenBalance({ graphqlUrl, owner, tokenId, fetchImpl }) : Promise.resolve(void 0)
|
|
4305
|
+
]);
|
|
4243
4306
|
foldNative(
|
|
4244
4307
|
out,
|
|
4245
|
-
nativeR
|
|
4308
|
+
nativeR.status === "fulfilled" ? {
|
|
4246
4309
|
status: "fulfilled",
|
|
4247
4310
|
value: {
|
|
4248
|
-
symbol: nativeR
|
|
4249
|
-
amount: nativeR
|
|
4250
|
-
decimals: nativeR
|
|
4311
|
+
symbol: nativeR.value.asset,
|
|
4312
|
+
amount: nativeR.value.amount,
|
|
4313
|
+
decimals: nativeR.value.assetScale
|
|
4251
4314
|
}
|
|
4252
|
-
} : nativeR
|
|
4315
|
+
} : nativeR,
|
|
4253
4316
|
errors
|
|
4254
4317
|
);
|
|
4318
|
+
foldToken(out, tokenR, void 0, errors);
|
|
4255
4319
|
finalizeChain(out, errors);
|
|
4256
4320
|
return out;
|
|
4257
4321
|
})()
|
|
@@ -5935,7 +5999,12 @@ var ToonClient = class {
|
|
|
5935
5999
|
if (mina?.graphqlUrl) {
|
|
5936
6000
|
const minaAddress = this.getMinaAddress() ?? (await ensureDerived())?.mina.publicKey;
|
|
5937
6001
|
if (minaAddress) {
|
|
5938
|
-
sources.mina = {
|
|
6002
|
+
sources.mina = {
|
|
6003
|
+
chainKey: "mina",
|
|
6004
|
+
graphqlUrl: mina.graphqlUrl,
|
|
6005
|
+
owner: minaAddress,
|
|
6006
|
+
...mina.tokenId ? { tokenId: mina.tokenId } : {}
|
|
6007
|
+
};
|
|
5939
6008
|
}
|
|
5940
6009
|
}
|
|
5941
6010
|
return readWalletBalances(sources);
|
|
@@ -6868,11 +6937,11 @@ function defaultFaucetTimeout(chain) {
|
|
|
6868
6937
|
function faucetPath(chain) {
|
|
6869
6938
|
switch (chain) {
|
|
6870
6939
|
case "evm":
|
|
6871
|
-
return "/api/request";
|
|
6940
|
+
return "/api/base-sepolia/request";
|
|
6872
6941
|
case "solana":
|
|
6873
|
-
return "/api/solana/request";
|
|
6942
|
+
return "/api/solana/usdc-request";
|
|
6874
6943
|
case "mina":
|
|
6875
|
-
return "/api/mina/request";
|
|
6944
|
+
return "/api/mina/usdc-request";
|
|
6876
6945
|
}
|
|
6877
6946
|
}
|
|
6878
6947
|
async function fundWallet(faucetUrl, address, chain, options = {}) {
|