@molpha/sdk 0.2.0-dev-20261011134323 → 0.3.0-dev-20261022065307

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 CHANGED
@@ -13,7 +13,7 @@ Links: [molpha.io](https://molpha.io) · [GitHub](https://github.com/Molpha/sdk)
13
13
  Use it to:
14
14
 
15
15
  - subscribe to a Molpha plan on Solana;
16
- - derive a source id from an API config;
16
+ - derive a source id from a source definition;
17
17
  - request a threshold-signed attestation from the gateway;
18
18
  - submit the signed result on-chain (`submit_attestation`);
19
19
  - verify/read the latest feed value;
@@ -30,7 +30,7 @@ At a high level:
30
30
  ```text
31
31
  Consumer
32
32
  └─ subscribes (USDC) on Solana
33
- └─ derives sourceId = keccak256(canonical apiConfig)
33
+ └─ derives sourceId = keccak256(canonical source)
34
34
  └─ signs a RequestAuth bound to (programId, gateway, sourceId, signaturesRequired, authTimestamp)
35
35
 
36
36
  Gateway
@@ -100,7 +100,7 @@ The package is ESM with `"sideEffects": false`, so gateway-only or read-only app
100
100
 
101
101
  ```ts
102
102
  import { web3 } from "@anchor-lang/core";
103
- import { MolphaSDK, PlanType, deriveSourceIdString } from "@molpha/sdk";
103
+ import { MolphaSDK, PlanType, jsonPriceSource } from "@molpha/sdk";
104
104
  import { walletFromKeypairFile } from "@molpha/sdk/utils";
105
105
 
106
106
  const wallet = walletFromKeypairFile("~/.config/solana/id.json");
@@ -116,19 +116,17 @@ await sdk.solana.subscribe(PlanType.Basic, {
116
116
  maxPriceUsdc: plan.subscriptionPrice,
117
117
  });
118
118
 
119
- const apiConfig = {
120
- url: "https://api.example.com/price",
121
- responseParser: "$.price",
122
- };
119
+ // GET the URL, read the JSON number at $.price, sign it as an int256 with 6 decimals.
120
+ const source = jsonPriceSource({ url: "https://api.example.com/price", path: "$.price", decimals: 6 });
123
121
  const signaturesRequired = 3;
124
122
 
125
123
  const { result, signature, feed } = await sdk.requestAndSubmit({
126
- apiConfig,
124
+ source,
127
125
  signaturesRequired,
128
126
  });
129
127
 
130
128
  // The round's identity, for reads and cross-chain verification.
131
- const sourceId = deriveSourceIdString(apiConfig); // === result.payload.sourceId
129
+ const sourceId = source.idHex; // === "0x" + result.payload.sourceId
132
130
  ```
133
131
 
134
132
  `requestAndSubmit` requests a threshold-signed attestation from the gateway (against the current on-chain registry version) and submits it to Solana via `submit_attestation` in one call. The first successful submit creates the feed account for `(sourceId, signaturesRequired, submitter)` if it does not already exist.
@@ -251,7 +249,7 @@ Gateway auth is resolved automatically when you use `MolphaSDK`:
251
249
  3. Else omit auth and use an all-zero `authSig`.
252
250
 
253
251
  `MolphaSDK` passes the resolved signer to `sdk.gateway` as its default, so
254
- `sdk.gateway.requestSignedData({ apiConfig, signaturesRequired })` authenticates without an
252
+ `sdk.gateway.requestSignedData({ source, signaturesRequired })` authenticates without an
255
253
  explicit `signer`. Standalone `new MolphaGateway(...)` omits auth unless you pass
256
254
  a `defaultSigner` (third constructor arg) or per-call `signer`.
257
255
 
@@ -290,7 +288,8 @@ import { web3 } from "@anchor-lang/core";
290
288
  import {
291
289
  MolphaSDK,
292
290
  PlanType,
293
- deriveSourceIdString,
291
+ jsonPriceSource,
292
+ defineSource,
294
293
  } from "@molpha/sdk";
295
294
  import { walletFromKeypairFile } from "@molpha/sdk/utils";
296
295
 
@@ -317,40 +316,55 @@ const { pricePaid } = await sdk.solana.subscribe(PlanType.Basic, {
317
316
 
318
317
  `maxPriceUsdc` is a safety bound. The transaction aborts if the live plan price is higher than the amount the user approved.
319
318
 
320
- ### 2. Source id
319
+ ### 2. Source
321
320
 
322
- There is no create-feed instruction. A data source is identified by its canonical API config:
321
+ There is no create-feed instruction. A data source is one JSON document, identified by its canonical bytes:
323
322
 
324
323
  ```text
325
- sourceId = keccak256(JSON.stringify(canonicalizeAPIConfig(apiConfig)))
324
+ sourceId = keccak256(canonical source bytes)
326
325
  ```
327
326
 
328
327
  ```ts
329
- const apiConfig = {
330
- url: "https://api.example.com/price",
331
- responseParser: "$.price",
332
- };
328
+ // The common case: one JSON number from one URL.
329
+ const source = jsonPriceSource({ url: "https://api.example.com/price", path: "$.price", decimals: 6 });
330
+ source.idHex; // "0x" + 64 hex chars
331
+ ```
332
+
333
+ `defineSource` builds anything else. A source has up to four typed **inputs** (an HTTP request, an EVM or Starknet call, storage slot or balance read at a pinned block, or a Solana account), a **transform** (a JSON expression over exact decimals), **assertions** that must hold before anyone signs, an **output** type that fixes how the result becomes the signed 32 bytes (`int256`, `uint256`, `bool`, `bytes32`, `string32`, `keccak256`), and an optional [tolerance policy](#median-tolerance-mode):
333
334
 
334
- const sourceId = deriveSourceIdString(apiConfig); // 64 hex chars, no 0x
335
+ ```ts
336
+ import { defineSource, sx } from "@molpha/sdk";
337
+
338
+ const source = defineSource({
339
+ inputs: {
340
+ rate: sx.evmCall({
341
+ chain: "eip155:1", to: "0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0", sig: "stEthPerToken()",
342
+ finality: { mode: "finalized", lagMs: 900_000 }, // read a finalized block 15 minutes behind the round
343
+ decode: sx.abiDecode(["uint256"], { rate: "0" }),
344
+ }),
345
+ },
346
+ transform: sx.ref("rate.rate"),
347
+ output: { type: "uint256", decimals: 18 },
348
+ });
335
349
  ```
336
350
 
337
- The canonical JSON has the fixed key order `url`, `method`, `headers` (sorted by UTF-16 code units, `{}` if empty), `responseParser`, `valueTransform` and, for [tolerance mode](#median-tolerance-mode), a trailing `aggregation`. The key is omitted for exact mode, so existing five-field configs keep their `sourceId`.
351
+ On the wire a source has every key present and every number a string; `defineSource` and the builders (`sx.*`) fill the defaults and convert JS numbers, and a document that breaks a rule throws a `SourceError` naming the path before any request is made. The schema, the operators and the limits are in the node client's `docs/source-format.md`.
338
352
 
339
- The gateway, the Solana program and the EVM/Starknet verifiers all recompute `sourceId` from the same canonical config, so pass the same `apiConfig` (including `{{secret.*}}` placeholders) every time. `signaturesRequired` is **not** part of `sourceId`: on Solana a feed account is keyed by `(sourceId, signaturesRequired, submitter)`, so the same source can be tracked at different quorums.
353
+ The canonical form is UTF-8 JSON with sorted keys, no whitespace, and numbers as strings (a strict subset of RFC 8785). The gateway, the nodes and this SDK all recompute `sourceId` from the same document, so pass the same `source` (including `{{secret.*}}` placeholders) every time; the Solana program and the EVM/Starknet verifiers treat it as an opaque `bytes32`. `signaturesRequired` is **not** part of `sourceId`: on Solana a feed account is keyed by `(sourceId, signaturesRequired, submitter)`, so the same source can be tracked at different quorums.
340
354
 
341
355
  ### 3. Request signed data from the gateway
342
356
 
343
357
  ```ts
344
358
  const signaturesRequired = 3;
345
359
  const result = await sdk.gateway.requestSignedData({
346
- apiConfig,
360
+ source,
347
361
  signaturesRequired,
348
362
  });
349
363
  ```
350
364
 
351
365
  The gateway round uses the current on-chain registry version. Selected verifier nodes independently fetch/recompute the result and sign only if the observed value matches the canonical result.
352
366
 
353
- The returned `Attestation` matches the cross-VM struct (`payload` + `signature`), plus gateway-only `value` (human-readable) and `fresh`. `payload` carries `sourceId`, the signed 32-byte `value`, `timestamp`, `registryVersion`, and `signaturesRequired`; `signature` carries the aggregate Schnorr material and `signersBitmap`. `signaturesRequired` must be at least the protocol's `min_signers` (currently 3) or the chain rejects the submit.
367
+ The returned `Attestation` matches the cross-VM struct (`payload` + `signature`), plus gateway-only `value` (the signed word rendered by the source's output type), `fresh` and, for a `keccak256` output, `valuePreimage`. `payload` carries `sourceId`, the signed 32-byte `value`, `timestamp`, `registryVersion`, and `signaturesRequired`; `signature` carries the aggregate Schnorr material and `signersBitmap`. `signaturesRequired` must be at least the protocol's `min_signers` (currently 3) or the chain rejects the submit.
354
368
 
355
369
  A gateway response is a coordination result, not proof of settlement or of on-chain verification. Consumers still decide freshness, source, quorum and replay policy.
356
370
 
@@ -362,7 +376,7 @@ const { signature, feed } = await sdk.solana.submitAttestation(result);
362
376
 
363
377
  `submit_attestation` takes `{ attestation: { payload, signature }, rawValue, coalitionKey }` plus one read-only `Node` account per signer (ascending signer-bit order, resolved from the registry snapshot the round was signed against). The SDK builds all of it: it fetches the signer `Node` accounts in one batched read, sums their secp256k1 keys into the affine **coalition key** (`computeCoalitionKey`), and checks the program's signer-count bounds before sending. The coalition key is unsigned instruction data that the program checks projectively against its own sum, so a wrong key only fails the transaction. Pass `{ coalitionKey }` to skip the `Node` fetch when you already hold it.
364
378
 
365
- If the signed 32-byte value is the keccak digest of a longer preimage, pass `{ rawValue }` (up to 256 bytes). The SDK verifies the digest before sending:
379
+ A source with a `keccak256` output signs the digest of a longer byte string. The gateway returns those bytes as `result.valuePreimage`, and `submitAttestation` passes them as `rawValue` when they are at most 256 bytes, verifying the digest before sending (the program then stores the preimage's hash and marks the feed `Hash`). To pass a preimage yourself:
366
380
 
367
381
  ```ts
368
382
  const { signature, feed } = await sdk.solana.submitAttestation(result, { rawValue });
@@ -386,7 +400,7 @@ The subscription read does not expose usage: the program stores no `used_rounds`
386
400
 
387
401
  ```ts
388
402
  const { result, signature, feed } = await sdk.requestAndSubmit({
389
- apiConfig,
403
+ source,
390
404
  signaturesRequired,
391
405
  });
392
406
  ```
@@ -394,7 +408,7 @@ const { result, signature, feed } = await sdk.requestAndSubmit({
394
408
  This is equivalent to:
395
409
 
396
410
  ```ts
397
- const result = await sdk.gateway.requestSignedData({ apiConfig, signaturesRequired });
411
+ const result = await sdk.gateway.requestSignedData({ source, signaturesRequired });
398
412
  const { signature, feed } = await sdk.solana.submitAttestation(result);
399
413
  ```
400
414
 
@@ -460,7 +474,7 @@ round is a single gateway POST.
460
474
  const context = await sdk.gateway.prepareContext();
461
475
 
462
476
  // Reuse it across rounds — no prelude fetches.
463
- const result = await sdk.gateway.requestSignedData({ apiConfig, signaturesRequired, context });
477
+ const result = await sdk.gateway.requestSignedData({ source, signaturesRequired, context });
464
478
  ```
465
479
 
466
480
  `context` is a `Partial<RoundContext>`, so you can cache only what you have
@@ -468,7 +482,7 @@ and let `requestSignedData` fetch the rest:
468
482
 
469
483
  ```ts
470
484
  const result = await sdk.gateway.requestSignedData({
471
- apiConfig,
485
+ source,
472
486
  signaturesRequired,
473
487
  context: { nodes }, // registryVersion + redundancyBuffer + nodeCount still fetched fresh
474
488
  });
@@ -482,37 +496,34 @@ disagrees with it. The same `context` field is accepted by `requestAndSubmit`.
482
496
 
483
497
  ## Median tolerance mode
484
498
 
485
- By default every signing node must observe the identical value. For noisy numeric sources
486
- (prices), add an `aggregation` object and the selected nodes instead exchange signed
499
+ By default every signing node must produce the identical 32 bytes. For noisy numeric sources
500
+ (prices), add a tolerance policy and the selected nodes instead exchange signed
487
501
  observations, drop stale ones and outliers, and sign the **lower median** of
488
502
  `signaturesRequired` surviving observations:
489
503
 
490
504
  ```ts
491
- const apiConfig = {
505
+ const source = jsonPriceSource({
492
506
  url: "https://api.example.com/price",
493
- responseParser: "$.price",
494
- aggregation: {
495
- mode: "tolerance",
496
- rule: "median",
497
- maxDeviationBps: 50, // u32: allowed distance from the lower median, in bps
498
- maxAgeMs: 2000, // > 0: max observation age in milliseconds
499
- numeric: { type: "int256", decimals: 8 }, // value = round-half-even(price * 10^8)
507
+ path: "$.price",
508
+ decimals: 8, // value = round-half-even(price * 10^8)
509
+ tolerance: {
510
+ maxDeviationBps: 50, // allowed distance from the lower median, in bps
511
+ maxAgeMs: 2000, // > 0: max observation age in milliseconds
500
512
  },
501
- };
513
+ });
502
514
 
503
- const { result } = await sdk.requestAndSubmit({ apiConfig, signaturesRequired: 5 });
515
+ const { result } = await sdk.requestAndSubmit({ source, signaturesRequired: 5 });
504
516
  ```
505
517
 
506
- Rules (the node is the reference; the SDK rejects violations before any request is made, with `AggregationConfigError`):
518
+ With `defineSource` the policy is the `aggregation` field (`{ maxDeviationBps, maxAgeMs }`). Rules (the node is the reference; the SDK rejects violations before any request is made, with `SourceError`):
507
519
 
508
- - `aggregation` is part of the `sourceId` and is **omitted** for exact mode. `mode: "exact"` is rejected because it would change the identity.
509
- - Only `rule: "median"` and `numeric.type: "int256"` are supported. `decimals` is `0..255`, `maxDeviationBps` a u32, `maxAgeMs` a positive integer.
510
- - Tolerance needs `signaturesRequired >= 3`.
511
- - The nested object is rebuilt in canonical order (`mode`, `rule`, `maxDeviationBps`, `maxAgeMs`, `numeric{type, decimals}`); extra or reordered keys on your input never reach the hash. For the config above, `sourceId` hashes exactly `{"url":...,"method":"GET","headers":{},"responseParser":"$.price","valueTransform":"","aggregation":{"mode":"tolerance","rule":"median","maxDeviationBps":50,"maxAgeMs":2000,"numeric":{"type":"int256","decimals":8}}}` (pinned against the node's Go test `TestAggregationSourceIdentity`).
512
- - The signed value is a signed `int256` (two's-complement `bytes32`). For tolerance results `Attestation.value` is rendered from the signed `payload.value` at the source's `decimals`, and `signature.signersBitmap` / signature fields must come from the response, since the nodes choose the final signing set after the observation exchange.
513
- - The gateway must forward `aggregation` to the nodes. If it derives a different identity, the response's `sourceId` / `configHash` will not match and the SDK throws; a gateway that echoes `aggregation` in its response must echo the requested policy.
520
+ - `aggregation` is part of the `sourceId`; `null` (or omitted) is exact mode.
521
+ - Only `rule: "median"` is supported, `maxAgeMs` must be positive, and the source's `output` must be `int256`: its `decimals` is the scale of the signed value, so there is no separate numeric block.
522
+ - Tolerance needs `signaturesRequired >= 3` (`assertToleranceQuorum`).
523
+ - The signed value is a signed `int256` (two's-complement `bytes32`). For tolerance results `Attestation.value` is rendered from the signed `payload.value` at the output's `decimals`, and `signature.signersBitmap` / signature fields must come from the response, since the nodes choose the final signing set after the observation exchange.
524
+ - Each node's observation is the final result of its transform, so the median is taken after any arithmetic, and a false assertion drops that node's observation.
514
525
 
515
- Helpers for the signed value (mirror the node's `new/tolerance` package):
526
+ Helpers for the signed value (mirror the node's `eval` package):
516
527
 
517
528
  ```ts
518
529
  import {
@@ -530,14 +541,15 @@ const price = formatInt256Decimal(Uint8Array.from(feedState!.value), 8);
530
541
 
531
542
  ## Private APIs and encrypted secrets
532
543
 
533
- Sources can use private APIs without sending plaintext secrets to the gateway.
544
+ Sources can use private APIs without sending plaintext secrets to the gateway. A `{{secret.NAME}}` placeholder may stand in an `http` input's URL (after the host and port, which stay literal), a header value or a request body text; anywhere else it is rejected.
534
545
 
535
546
  ```ts
536
547
  const result = await sdk.gateway.requestSignedData({
537
- apiConfig: {
548
+ source: jsonPriceSource({
538
549
  url: "https://api.example.com/private-price?key={{secret.apiKey}}",
539
- responseParser: "$.price",
540
- },
550
+ path: "$.price",
551
+ decimals: 6,
552
+ }),
541
553
  signaturesRequired,
542
554
  encrypt: {
543
555
  secrets: {
@@ -549,7 +561,7 @@ const result = await sdk.gateway.requestSignedData({
549
561
 
550
562
  `MolphaSDK` wires `verifyNodeKeys` to `solana.verifyNodeKeysForPrivateApi`, which authenticates gateway node encryption keys against the on-chain `Node` accounts of the round's registry snapshot (`registry.nodes[index]`) before secrets are encrypted.
551
563
 
552
- Secrets are encrypted into per-node envelopes. The gateway coordinates the round but should not receive plaintext API credentials. Secrets are encrypted for every node of the registry (the committee is unknown until the gateway stamps the round), and the gateway forwards only the selected nodes' envelopes. `verifyNodeKeys` therefore authenticates all of them. The encrypted plaintext is the canonical config (including `aggregation`) with secrets substituted.
564
+ Secrets are encrypted into per-node envelopes. The gateway coordinates the round but should not receive plaintext API credentials. Secrets are encrypted for every node of the registry (the committee is unknown until the gateway stamps the round), and the gateway forwards only the selected nodes' envelopes. `verifyNodeKeys` therefore authenticates all of them. The encrypted plaintext is the canonical source with secrets substituted; a node accepts it only if it equals the public source everywhere except at the placeholders, so a secret can authenticate a read but cannot change what is read.
553
565
 
554
566
  Private API access is still an active security-sensitive surface. Do not treat encrypted secret delivery as production-ready until gateway/node-side test vectors and validation are complete.
555
567
 
@@ -564,7 +576,7 @@ source still costs exactly one round of subscription quota.
564
576
  import { createEvmSignerFromPrivateKey } from "@molpha/sdk";
565
577
 
566
578
  const result = await sdk.gateway.requestSignedData({
567
- apiConfig,
579
+ source,
568
580
  signaturesRequired,
569
581
  sourcePayment: {
570
582
  signer: createEvmSignerFromPrivateKey(process.env.EVM_PRIVATE_KEY!),
@@ -591,8 +603,9 @@ settled stay spent if the round then fails; unsettled ones expire worthless. The
591
603
  refund path and none is needed.
592
604
 
593
605
  Source payment is per-round access material, like a credential. It never enters
594
- `sourceId`, so a paid and an unpaid fetch of the same API config share one source
595
- identity.
606
+ `sourceId`, so a paid and an unpaid fetch of the same source share one source
607
+ identity. A paid source has exactly one `http` input: the authorization names no host, so the
608
+ nodes attach it to that input.
596
609
 
597
610
  ### Without a source wallet
598
611
 
@@ -604,7 +617,7 @@ detail. This is terminal — the round is never retried blindly.
604
617
  import { UpstreamPaymentRequiredError } from "@molpha/sdk";
605
618
 
606
619
  try {
607
- await sdk.gateway.requestSignedData({ apiConfig, signaturesRequired });
620
+ await sdk.gateway.requestSignedData({ source, signaturesRequired });
608
621
  } catch (err) {
609
622
  if (err instanceof UpstreamPaymentRequiredError) {
610
623
  console.log(`${err.quote.resource} needs ${err.quote.eligibleSetSize} paid fetches`);
@@ -644,7 +657,7 @@ The verifier's entrypoint is
644
657
  ```ts
645
658
  import { buildEvmVerifierArgs } from "@molpha/sdk";
646
659
 
647
- const result = await sdk.gateway.requestSignedData({ apiConfig, signaturesRequired });
660
+ const result = await sdk.gateway.requestSignedData({ source, signaturesRequired });
648
661
 
649
662
  const { attestation, maxAge } = buildEvmVerifierArgs(result, { maxAge: 300 });
650
663
  ```
@@ -797,7 +810,7 @@ The verifier's entrypoint is `verify(attestation: Attestation, max_age: u64) ->
797
810
  ```ts
798
811
  import { buildStarknetVerifierArgs } from "@molpha/sdk";
799
812
 
800
- const result = await sdk.gateway.requestSignedData({ apiConfig, signaturesRequired });
813
+ const result = await sdk.gateway.requestSignedData({ source, signaturesRequired });
801
814
 
802
815
  const { attestation, maxAge } = buildStarknetVerifierArgs(result, { maxAge: 300 });
803
816
  ```
@@ -1,12 +1,20 @@
1
1
  import { web3 } from '@anchor-lang/core';
2
2
  import { address, getAddressEncoder, getAddressDecoder } from '@solana/kit';
3
3
 
4
- // src/solana/kit.ts
5
- var TOKEN_PROGRAM_ADDRESS = address("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
4
+ var __defProp = Object.defineProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var TOKEN_PROGRAM_ADDRESS = address(
10
+ "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
11
+ );
6
12
  var ASSOCIATED_TOKEN_PROGRAM_ADDRESS = address(
7
13
  "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
8
14
  );
9
- var SYSTEM_PROGRAM_ADDRESS = address("11111111111111111111111111111111");
15
+ var SYSTEM_PROGRAM_ADDRESS = address(
16
+ "11111111111111111111111111111111"
17
+ );
10
18
  var addressEncoder = getAddressEncoder();
11
19
  var addressDecoder = getAddressDecoder();
12
20
  function toSolanaAddress(value) {
@@ -22,7 +30,10 @@ function addressFromBytes(bytes) {
22
30
  return addressDecoder.decode(bytes);
23
31
  }
24
32
  function findProgramAddressSync(seeds, programAddress) {
25
- const [pda] = web3.PublicKey.findProgramAddressSync(seeds, toPublicKey(programAddress));
33
+ const [pda] = web3.PublicKey.findProgramAddressSync(
34
+ seeds,
35
+ toPublicKey(programAddress)
36
+ );
26
37
  return toSolanaAddress(pda);
27
38
  }
28
39
  function getAssociatedTokenAddressSync(mint, owner, tokenProgram = TOKEN_PROGRAM_ADDRESS) {
@@ -41,6 +52,6 @@ function keypairFromSecretKey(secretKey) {
41
52
  return web3.Keypair.fromSecretKey(secretKey);
42
53
  }
43
54
 
44
- export { SYSTEM_PROGRAM_ADDRESS, TOKEN_PROGRAM_ADDRESS, addressBytes, addressFromBytes, findProgramAddressSync, getAssociatedTokenAddressSync, keypairFromSecretKey, setComputeUnitLimit, setComputeUnitPrice, toPublicKey, toSolanaAddress };
45
- //# sourceMappingURL=chunk-H77BBZOL.js.map
46
- //# sourceMappingURL=chunk-H77BBZOL.js.map
55
+ export { SYSTEM_PROGRAM_ADDRESS, TOKEN_PROGRAM_ADDRESS, __export, addressBytes, addressFromBytes, findProgramAddressSync, getAssociatedTokenAddressSync, keypairFromSecretKey, setComputeUnitLimit, setComputeUnitPrice, toPublicKey, toSolanaAddress };
56
+ //# sourceMappingURL=chunk-KLHORIAC.js.map
57
+ //# sourceMappingURL=chunk-KLHORIAC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/solana/kit.ts"],"names":[],"mappings":";;;;;;;;AAqBO,IAAM,qBAAA,GAAwB,OAAA;AAAA,EACnC;AACF;AACO,IAAM,gCAAA,GAAmC,OAAA;AAAA,EAC9C;AACF,CAAA;AACO,IAAM,sBAAA,GAAyB,OAAA;AAAA,EACpC;AACF;AAEA,IAAM,iBAAiB,iBAAA,EAAkB;AACzC,IAAM,iBAAiB,iBAAA,EAAkB;AAElC,SAAS,gBAAgB,KAAA,EAA+B;AAC7D,EAAA,OAAO,QAAQ,OAAO,KAAA,KAAU,WAAW,KAAA,GAAQ,KAAA,CAAM,UAAU,CAAA;AACrE;AAEO,SAAS,YACd,KAAA,EACqC;AACrC,EAAA,OAAO,iBAAiB,IAAA,CAAK,SAAA,GAAY,QAAQ,IAAI,IAAA,CAAK,UAAU,KAAK,CAAA;AAC3E;AAEO,SAAS,aAAa,KAAA,EAAkC;AAC7D,EAAA,OAAO,WAAW,IAAA,CAAK,cAAA,CAAe,OAAO,eAAA,CAAgB,KAAK,CAAC,CAAC,CAAA;AACtE;AAGO,SAAS,iBAAiB,KAAA,EAA4B;AAC3D,EAAA,OAAO,cAAA,CAAe,OAAO,KAAK,CAAA;AACpC;AAEO,SAAS,sBAAA,CACd,OACA,cAAA,EACS;AACT,EAAA,MAAM,CAAC,GAAG,CAAA,GAAI,IAAA,CAAK,SAAA,CAAU,sBAAA;AAAA,IAC3B,KAAA;AAAA,IACA,YAAY,cAAc;AAAA,GAC5B;AACA,EAAA,OAAO,gBAAgB,GAAG,CAAA;AAC5B;AAaO,SAAS,6BAAA,CACd,IAAA,EACA,KAAA,EACA,YAAA,GAA8B,qBAAA,EACrB;AACT,EAAA,OAAO,sBAAA;AAAA,IACL,CAAC,aAAa,KAAK,CAAA,EAAG,aAAa,YAAY,CAAA,EAAG,YAAA,CAAa,IAAI,CAAC,CAAA;AAAA,IACpE;AAAA,GACF;AACF;AAEO,SAAS,oBAAoB,KAAA,EAAkC;AACpE,EAAA,OAAO,IAAA,CAAK,oBAAA,CAAqB,mBAAA,CAAoB,EAAE,OAAO,CAAA;AAChE;AAEO,SAAS,oBAAoB,aAAA,EAA0C;AAC5E,EAAA,OAAO,IAAA,CAAK,oBAAA,CAAqB,mBAAA,CAAoB,EAAE,eAAe,CAAA;AACxE;AAEO,SAAS,qBAAqB,SAAA,EAAsC;AACzE,EAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,SAAS,CAAA;AAC7C","file":"chunk-KLHORIAC.js","sourcesContent":["import { web3 } from \"@anchor-lang/core\";\nimport {\n address,\n getAddressDecoder,\n getAddressEncoder,\n type Address,\n} from \"@solana/kit\";\n\nexport type SolanaAddress =\n Address | string | InstanceType<typeof web3.PublicKey>;\nexport type SolanaConnection = InstanceType<typeof web3.Connection>;\nexport type SolanaKeypair = InstanceType<typeof web3.Keypair>;\nexport type SolanaInstruction = InstanceType<\n typeof web3.TransactionInstruction\n>;\nexport type SolanaAccountMeta = {\n pubkey: InstanceType<typeof web3.PublicKey>;\n isSigner: boolean;\n isWritable: boolean;\n};\n\nexport const TOKEN_PROGRAM_ADDRESS = address(\n \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n);\nexport const ASSOCIATED_TOKEN_PROGRAM_ADDRESS = address(\n \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n);\nexport const SYSTEM_PROGRAM_ADDRESS = address(\n \"11111111111111111111111111111111\",\n);\n\nconst addressEncoder = getAddressEncoder();\nconst addressDecoder = getAddressDecoder();\n\nexport function toSolanaAddress(value: SolanaAddress): Address {\n return address(typeof value === \"string\" ? value : value.toBase58());\n}\n\nexport function toPublicKey(\n value: SolanaAddress,\n): InstanceType<typeof web3.PublicKey> {\n return value instanceof web3.PublicKey ? value : new web3.PublicKey(value);\n}\n\nexport function addressBytes(value: SolanaAddress): Uint8Array {\n return Uint8Array.from(addressEncoder.encode(toSolanaAddress(value)));\n}\n\n/** Base58 `Address` from 32 raw bytes (e.g. a `Registry.nodes[i]` entry). */\nexport function addressFromBytes(bytes: Uint8Array): Address {\n return addressDecoder.decode(bytes);\n}\n\nexport function findProgramAddressSync(\n seeds: Uint8Array[],\n programAddress: SolanaAddress,\n): Address {\n const [pda] = web3.PublicKey.findProgramAddressSync(\n seeds,\n toPublicKey(programAddress),\n );\n return toSolanaAddress(pda);\n}\n\nexport function findProgramPublicKeySync(\n seeds: Uint8Array[],\n programAddress: SolanaAddress,\n): InstanceType<typeof web3.PublicKey> {\n const [pda] = web3.PublicKey.findProgramAddressSync(\n seeds,\n toPublicKey(programAddress),\n );\n return pda;\n}\n\nexport function getAssociatedTokenAddressSync(\n mint: SolanaAddress,\n owner: SolanaAddress,\n tokenProgram: SolanaAddress = TOKEN_PROGRAM_ADDRESS,\n): Address {\n return findProgramAddressSync(\n [addressBytes(owner), addressBytes(tokenProgram), addressBytes(mint)],\n ASSOCIATED_TOKEN_PROGRAM_ADDRESS,\n );\n}\n\nexport function setComputeUnitLimit(units: number): SolanaInstruction {\n return web3.ComputeBudgetProgram.setComputeUnitLimit({ units });\n}\n\nexport function setComputeUnitPrice(microLamports: number): SolanaInstruction {\n return web3.ComputeBudgetProgram.setComputeUnitPrice({ microLamports });\n}\n\nexport function keypairFromSecretKey(secretKey: Uint8Array): SolanaKeypair {\n return web3.Keypair.fromSecretKey(secretKey);\n}\n\nexport function generateKeypair(): SolanaKeypair {\n return web3.Keypair.generate();\n}\n"]}