@toon-protocol/client 0.20.2 → 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 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;
package/dist/index.js CHANGED
@@ -4059,6 +4059,7 @@ var JsonFileChannelStore = class {
4059
4059
 
4060
4060
  // src/balance/WalletBalanceReader.ts
4061
4061
  import { createPublicClient as createPublicClient2, http as http2, defineChain as defineChain2 } from "viem";
4062
+ import { sha256 as sha2564 } from "@noble/hashes/sha2.js";
4062
4063
  var ERC20_READ_ABI = [
4063
4064
  { name: "balanceOf", type: "function", stateMutability: "view", inputs: [{ name: "account", type: "address" }], outputs: [{ type: "uint256" }] },
4064
4065
  { name: "decimals", type: "function", stateMutability: "view", inputs: [], outputs: [{ type: "uint8" }] },
@@ -4173,6 +4174,62 @@ async function readMinaBalance(opts) {
4173
4174
  assetScale: 9
4174
4175
  };
4175
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
+ }
4176
4233
  var errText = (e) => e instanceof Error ? e.message : String(e);
4177
4234
  function foldNative(out, settled, errors) {
4178
4235
  if (settled.status === "fulfilled") out.native = settled.value;
@@ -4237,24 +4294,28 @@ async function readWalletBalances(sources) {
4237
4294
  );
4238
4295
  }
4239
4296
  if (sources.mina) {
4240
- const { chainKey = "mina", graphqlUrl, owner } = sources.mina;
4297
+ const { chainKey = "mina", graphqlUrl, owner, tokenId } = sources.mina;
4241
4298
  tasks.push(
4242
4299
  (async () => {
4243
4300
  const out = { chain: "mina", chainKey, address: owner, tokens: [] };
4244
4301
  const errors = [];
4245
- const nativeR = await Promise.allSettled([readMinaBalance({ graphqlUrl, owner, fetchImpl })]);
4302
+ const [nativeR, tokenR] = await Promise.allSettled([
4303
+ readMinaBalance({ graphqlUrl, owner, fetchImpl }),
4304
+ tokenId ? readMinaTokenBalance({ graphqlUrl, owner, tokenId, fetchImpl }) : Promise.resolve(void 0)
4305
+ ]);
4246
4306
  foldNative(
4247
4307
  out,
4248
- nativeR[0].status === "fulfilled" ? {
4308
+ nativeR.status === "fulfilled" ? {
4249
4309
  status: "fulfilled",
4250
4310
  value: {
4251
- symbol: nativeR[0].value.asset,
4252
- amount: nativeR[0].value.amount,
4253
- decimals: nativeR[0].value.assetScale
4311
+ symbol: nativeR.value.asset,
4312
+ amount: nativeR.value.amount,
4313
+ decimals: nativeR.value.assetScale
4254
4314
  }
4255
- } : nativeR[0],
4315
+ } : nativeR,
4256
4316
  errors
4257
4317
  );
4318
+ foldToken(out, tokenR, void 0, errors);
4258
4319
  finalizeChain(out, errors);
4259
4320
  return out;
4260
4321
  })()
@@ -5938,7 +5999,12 @@ var ToonClient = class {
5938
5999
  if (mina?.graphqlUrl) {
5939
6000
  const minaAddress = this.getMinaAddress() ?? (await ensureDerived())?.mina.publicKey;
5940
6001
  if (minaAddress) {
5941
- sources.mina = { chainKey: "mina", graphqlUrl: mina.graphqlUrl, owner: minaAddress };
6002
+ sources.mina = {
6003
+ chainKey: "mina",
6004
+ graphqlUrl: mina.graphqlUrl,
6005
+ owner: minaAddress,
6006
+ ...mina.tokenId ? { tokenId: mina.tokenId } : {}
6007
+ };
5942
6008
  }
5943
6009
  }
5944
6010
  return readWalletBalances(sources);