@elisym/sdk 0.10.4 → 0.11.0

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.cjs CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var memo = require('@solana-program/memo');
3
4
  var system = require('@solana-program/system');
4
5
  var token = require('@solana-program/token');
5
6
  var kit = require('@solana/kit');
@@ -64,6 +65,7 @@ var LAMPORTS_PER_SOL = 1e9;
64
65
  var PROTOCOL_FEE_BPS = 300;
65
66
  var PROTOCOL_TREASURY = "GY7vnWMkKpftU4nQ16C2ATkj1JwrQpHhknkaBUn67VTy";
66
67
  var PROTOCOL_PROGRAM_ID_DEVNET = "BrX1CRkSgvcjxBvc2bgc3QqgWjinusofDmeP7ZVxvwrE";
68
+ var ELISYM_PROTOCOL_TAG = "ELiZksgwDt41LaeuPDLkUfWgFXhGgVayTMP7L5nTSEL8";
67
69
  function getProtocolProgramId(cluster) {
68
70
  switch (cluster) {
69
71
  case "devnet":
@@ -119,13 +121,13 @@ function decodeConfig(encodedAccount) {
119
121
  getConfigDecoder()
120
122
  );
121
123
  }
122
- async function fetchConfig(rpc, address3, config) {
123
- const maybeAccount = await fetchMaybeConfig(rpc, address3, config);
124
+ async function fetchConfig(rpc, address4, config) {
125
+ const maybeAccount = await fetchMaybeConfig(rpc, address4, config);
124
126
  kit.assertAccountExists(maybeAccount);
125
127
  return maybeAccount;
126
128
  }
127
- async function fetchMaybeConfig(rpc, address3, config) {
128
- const maybeAccount = await kit.fetchEncodedAccount(rpc, address3, config);
129
+ async function fetchMaybeConfig(rpc, address4, config) {
130
+ const maybeAccount = await kit.fetchEncodedAccount(rpc, address4, config);
129
131
  return decodeConfig(maybeAccount);
130
132
  }
131
133
  if (process.env.NODE_ENV !== "production") ;
@@ -597,7 +599,9 @@ var SolanaPaymentStrategy = class {
597
599
  if (!Number.isInteger(computeUnitLimit) || computeUnitLimit <= 0) {
598
600
  throw new Error(`Invalid computeUnitLimit: ${computeUnitLimit}. Must be a positive integer.`);
599
601
  }
600
- const paymentInstructions = await buildPaymentInstructions(paymentRequest, payerSigner);
602
+ const paymentInstructions = await buildPaymentInstructions(paymentRequest, payerSigner, {
603
+ jobEventId: options?.jobEventId
604
+ });
601
605
  const priorityFeeMicroLamports = options?.priorityFeeMicroLamports ?? await estimatePriorityFeeMicroLamports(rpc, {
602
606
  percentile: options?.priorityFeePercentile ?? DEFAULT_PRIORITY_FEE_PERCENTILE
603
607
  });
@@ -894,9 +898,10 @@ function bigIntDelta(post, pre) {
894
898
  function waitMs(ms) {
895
899
  return new Promise((resolve) => setTimeout(resolve, ms));
896
900
  }
897
- async function buildPaymentInstructions(paymentRequest, payerSigner) {
901
+ async function buildPaymentInstructions(paymentRequest, payerSigner, options) {
898
902
  const recipient = kit.address(paymentRequest.recipient);
899
903
  const reference = kit.address(paymentRequest.reference);
904
+ const protocolTag = kit.address(ELISYM_PROTOCOL_TAG);
900
905
  const feeAmount = paymentRequest.fee_amount ?? 0;
901
906
  const providerAmount = paymentRequest.fee_address && feeAmount > 0 ? paymentRequest.amount - feeAmount : paymentRequest.amount;
902
907
  if (providerAmount <= 0) {
@@ -904,6 +909,7 @@ async function buildPaymentInstructions(paymentRequest, payerSigner) {
904
909
  `Fee amount (${feeAmount}) exceeds or equals total amount (${paymentRequest.amount}). Cannot create transaction with non-positive provider amount.`
905
910
  );
906
911
  }
912
+ const memoInstruction = options?.jobEventId ? memo.getAddMemoInstruction({ memo: `elisym:v1:${options.jobEventId}` }) : null;
907
913
  const asset = resolveAssetFromPaymentRequest(paymentRequest);
908
914
  if (!asset.mint) {
909
915
  const providerTransferIx2 = system.getTransferSolInstruction({
@@ -911,14 +917,19 @@ async function buildPaymentInstructions(paymentRequest, payerSigner) {
911
917
  destination: recipient,
912
918
  amount: BigInt(providerAmount)
913
919
  });
914
- const providerTransferIxWithReference2 = {
920
+ const providerTransferIxWithMarkers2 = {
915
921
  ...providerTransferIx2,
916
922
  accounts: [
917
923
  ...providerTransferIx2.accounts,
918
- { address: reference, role: kit.AccountRole.READONLY }
924
+ { address: reference, role: kit.AccountRole.READONLY },
925
+ { address: protocolTag, role: kit.AccountRole.READONLY }
919
926
  ]
920
927
  };
921
- const instructions2 = [providerTransferIxWithReference2];
928
+ const instructions2 = [];
929
+ if (memoInstruction) {
930
+ instructions2.push(memoInstruction);
931
+ }
932
+ instructions2.push(providerTransferIxWithMarkers2);
922
933
  if (paymentRequest.fee_address && feeAmount > 0) {
923
934
  instructions2.push(
924
935
  system.getTransferSolInstruction({
@@ -943,6 +954,9 @@ async function buildPaymentInstructions(paymentRequest, payerSigner) {
943
954
  mint
944
955
  });
945
956
  const instructions = [];
957
+ if (memoInstruction) {
958
+ instructions.push(memoInstruction);
959
+ }
946
960
  instructions.push(
947
961
  token.getCreateAssociatedTokenIdempotentInstruction(
948
962
  {
@@ -982,11 +996,15 @@ async function buildPaymentInstructions(paymentRequest, payerSigner) {
982
996
  amount: BigInt(providerAmount),
983
997
  decimals: asset.decimals
984
998
  });
985
- const providerTransferIxWithReference = {
999
+ const providerTransferIxWithMarkers = {
986
1000
  ...providerTransferIx,
987
- accounts: [...providerTransferIx.accounts, { address: reference, role: kit.AccountRole.READONLY }]
1001
+ accounts: [
1002
+ ...providerTransferIx.accounts,
1003
+ { address: reference, role: kit.AccountRole.READONLY },
1004
+ { address: protocolTag, role: kit.AccountRole.READONLY }
1005
+ ]
988
1006
  };
989
- instructions.push(providerTransferIxWithReference);
1007
+ instructions.push(providerTransferIxWithMarkers);
990
1008
  if (treasuryAta && paymentRequest.fee_address && feeAmount > 0) {
991
1009
  instructions.push(
992
1010
  token.getTransferCheckedInstruction({
@@ -1141,21 +1159,6 @@ var DiscoveryService = class {
1141
1159
  constructor(pool) {
1142
1160
  this.pool = pool;
1143
1161
  }
1144
- /** Count elisym agents (kind:31990 with "elisym" tag). */
1145
- async fetchAllAgentCount() {
1146
- const events = await this.pool.querySync({
1147
- kinds: [KIND_APP_HANDLER],
1148
- "#t": ["elisym"]
1149
- });
1150
- const uniquePubkeys = /* @__PURE__ */ new Set();
1151
- for (const event of events) {
1152
- if (!nostrTools.verifyEvent(event)) {
1153
- continue;
1154
- }
1155
- uniquePubkeys.add(event.pubkey);
1156
- }
1157
- return uniquePubkeys.size;
1158
- }
1159
1162
  /**
1160
1163
  * Fetch a single page of elisym agents with relay-side pagination.
1161
1164
  * Uses `until` cursor for Nostr cursor-based pagination.
@@ -2918,6 +2921,83 @@ async function doVerifyOnce(rpc, txSignature, expectedRecipient) {
2918
2921
  }
2919
2922
  return { verified: false, txSignature: sigStr, reason: "recipient_mismatch" };
2920
2923
  }
2924
+ var DEFAULT_LIMIT = 1e3;
2925
+ var NATIVE_KEY = "native";
2926
+ async function aggregateNetworkStats(rpc, options) {
2927
+ const limit = options?.limit ?? DEFAULT_LIMIT;
2928
+ const concurrency = options?.concurrency ?? DEFAULTS.QUERY_MAX_CONCURRENCY;
2929
+ const tag = kit.address(ELISYM_PROTOCOL_TAG);
2930
+ const signatures = await rpc.getSignaturesForAddress(tag, { limit, before: options?.before }).send();
2931
+ const validSigs = signatures.filter((entry) => entry.err === null);
2932
+ if (validSigs.length === 0) {
2933
+ return { jobCount: 0, volumeByAsset: {} };
2934
+ }
2935
+ const volumeByAsset = {};
2936
+ let jobCount = 0;
2937
+ for (let start = 0; start < validSigs.length; start += concurrency) {
2938
+ const batch = validSigs.slice(start, start + concurrency);
2939
+ const txResults = await Promise.all(
2940
+ batch.map(
2941
+ (entry) => rpc.getTransaction(entry.signature, {
2942
+ commitment: "confirmed",
2943
+ encoding: "json",
2944
+ maxSupportedTransactionVersion: 0
2945
+ }).send().catch(() => null)
2946
+ )
2947
+ );
2948
+ for (const tx of txResults) {
2949
+ if (!tx?.meta || tx.meta.err) {
2950
+ continue;
2951
+ }
2952
+ jobCount += 1;
2953
+ accumulateTransfers(tx, volumeByAsset);
2954
+ }
2955
+ }
2956
+ const latest = validSigs[0]?.signature;
2957
+ const oldest = validSigs.at(-1)?.signature;
2958
+ return {
2959
+ jobCount,
2960
+ volumeByAsset,
2961
+ latestSignature: latest,
2962
+ oldestSignature: oldest
2963
+ };
2964
+ }
2965
+ function accumulateTransfers(tx, volumeByAsset) {
2966
+ const raw = tx;
2967
+ const meta = raw.meta;
2968
+ if (!meta) {
2969
+ return;
2970
+ }
2971
+ const preTokens = meta.preTokenBalances ?? [];
2972
+ const postTokens = meta.postTokenBalances ?? [];
2973
+ const isSpl = postTokens.length > 0 || preTokens.length > 0;
2974
+ if (isSpl) {
2975
+ accumulateSplDeltas(preTokens, postTokens, volumeByAsset);
2976
+ return;
2977
+ }
2978
+ accumulateNativeDeltas(meta.preBalances, meta.postBalances, volumeByAsset);
2979
+ }
2980
+ function accumulateSplDeltas(pre, post, volumeByAsset) {
2981
+ for (const postEntry of post) {
2982
+ const preEntry = pre.find((entry) => entry.accountIndex === postEntry.accountIndex);
2983
+ const preAmount = preEntry ? BigInt(preEntry.uiTokenAmount.amount) : 0n;
2984
+ const postAmount = BigInt(postEntry.uiTokenAmount.amount);
2985
+ const delta = postAmount - preAmount;
2986
+ if (delta > 0n) {
2987
+ volumeByAsset[postEntry.mint] = (volumeByAsset[postEntry.mint] ?? 0n) + delta;
2988
+ }
2989
+ }
2990
+ }
2991
+ function accumulateNativeDeltas(pre, post, volumeByAsset) {
2992
+ for (let i = 1; i < post.length; i++) {
2993
+ const preValue = pre[i] ?? 0n;
2994
+ const postValue = post[i] ?? 0n;
2995
+ const delta = BigInt(postValue) - BigInt(preValue);
2996
+ if (delta > 0n) {
2997
+ volumeByAsset[NATIVE_KEY] = (volumeByAsset[NATIVE_KEY] ?? 0n) + delta;
2998
+ }
2999
+ }
3000
+ }
2921
3001
  var SessionSpendLimitEntrySchema = zod.z.object({
2922
3002
  chain: zod.z.enum(["solana"]),
2923
3003
  token: zod.z.string().min(1).max(16).regex(/^[a-z0-9]+$/, "token must be lowercase alphanumeric"),
@@ -3123,6 +3203,7 @@ exports.DEFAULTS = DEFAULTS;
3123
3203
  exports.DEFAULT_KIND_OFFSET = DEFAULT_KIND_OFFSET;
3124
3204
  exports.DEFAULT_REDACT_PATHS = DEFAULT_REDACT_PATHS;
3125
3205
  exports.DiscoveryService = DiscoveryService;
3206
+ exports.ELISYM_PROTOCOL_TAG = ELISYM_PROTOCOL_TAG;
3126
3207
  exports.ElisymClient = ElisymClient;
3127
3208
  exports.ElisymIdentity = ElisymIdentity;
3128
3209
  exports.GlobalConfigSchema = GlobalConfigSchema;
@@ -3152,6 +3233,7 @@ exports.SECRET_REDACT_PATHS = SECRET_REDACT_PATHS;
3152
3233
  exports.SessionSpendLimitEntrySchema = SessionSpendLimitEntrySchema;
3153
3234
  exports.SolanaPaymentStrategy = SolanaPaymentStrategy;
3154
3235
  exports.USDC_SOLANA_DEVNET = USDC_SOLANA_DEVNET;
3236
+ exports.aggregateNetworkStats = aggregateNetworkStats;
3155
3237
  exports.assertExpiry = assertExpiry;
3156
3238
  exports.assertLamports = assertLamports;
3157
3239
  exports.assetByKey = assetByKey;