@coordination-network/network-member-client 0.0.1 → 0.1.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
@@ -108,7 +108,7 @@ async function readIdentity(identityReader, networkId) {
108
108
  return await identityReader.getIdentity(networkId);
109
109
  }
110
110
  catch (error) {
111
- throw new NetworkMemberClientError("REGISTRY_UNAVAILABLE", `identity read failed for ${networkId}`, error);
111
+ throw new NetworkMemberClientError("REGISTRY_UNAVAILABLE", "identity read failed", error);
112
112
  }
113
113
  }
114
114
  /**
@@ -167,7 +167,7 @@ async function submitRegistration(request, { domain, identityReader, prover, wri
167
167
  }
168
168
  throw error;
169
169
  }
170
- throw new NetworkMemberClientError("REGISTRY_UNAVAILABLE", `registration submission failed for ${networkId}`, error);
170
+ throw new NetworkMemberClientError("REGISTRY_UNAVAILABLE", "registration submission failed", error);
171
171
  }
172
172
  }
173
173
 
@@ -587,7 +587,7 @@ const GAS_LIMITS = {
587
587
  verificationGasLimit: 500000n,
588
588
  preVerificationGas: 100000n,
589
589
  paymasterVerificationGasLimit: 600000n,
590
- paymasterPostOpGasLimit: 50000n
590
+ paymasterPostOpGasLimit: 0n
591
591
  };
592
592
  const GAS_FEE_PER_GAS = 1000000000n; // 1 gwei
593
593
  /**
@@ -743,7 +743,7 @@ class SponsoredIdentityRegistryWriter {
743
743
  if (receipt.revertReason !== undefined && decodedErrorName(receipt.revertReason) === "AlreadyRegistered") {
744
744
  throw new RegistryRevertError("AlreadyRegistered", receipt.revertReason);
745
745
  }
746
- throw new Error(`sponsored registerIdentity user operation reverted for ${networkId}`);
746
+ throw new Error("sponsored registerIdentity user operation reverted");
747
747
  }
748
748
  return { txHash: receipt.transactionHash, sponsorship };
749
749
  }
@@ -758,6 +758,38 @@ function decodedErrorName(revertReason) {
758
758
  }
759
759
  }
760
760
 
761
+ /**
762
+ * Sponsored AnnouncementSubmitter: relays `ERC5564Announcer.announce` through {@link SponsoredRelay},
763
+ * so the indexed `caller` of the `Announcement` is a one-time sender, not the member. A direct
764
+ * `ERC5564AnnouncerClient` would put one fixed address on every delivery the member makes.
765
+ */
766
+ class SponsoredAnnouncementSubmitter {
767
+ constructor(announcerAddress, relay) {
768
+ this.announcerAddress = announcerAddress;
769
+ this.relay = relay;
770
+ }
771
+ async announce(announcement) {
772
+ const { receipt } = await this.relay.relay({
773
+ target: this.announcerAddress,
774
+ data: viem.encodeFunctionData({
775
+ abi: ERC5564_ANNOUNCER_ABI,
776
+ functionName: "announce",
777
+ args: [
778
+ BigInt(announcement.schemeId),
779
+ announcement.stealthAddress,
780
+ announcement.ephemeralPublicKey,
781
+ announcement.metadata
782
+ ]
783
+ })
784
+ });
785
+ // The announcer has no named errors, so the raw revert data is all there is to report. Assigned,
786
+ // not passed as an option, because the repo's ES2020 target has no ErrorOptions.
787
+ if (!receipt.success)
788
+ throw Object.assign(new Error("sponsored announce reverted"), { cause: receipt.revertReason });
789
+ return receipt.transactionHash;
790
+ }
791
+ }
792
+
761
793
  /**
762
794
  * The `CredentialRevocationRegistry` fragments a writer needs. The errors matter as much as the
763
795
  * function: `InvalidLowLeaf` is the one a caller recomputes an index and retries on, and
@@ -965,6 +997,7 @@ exports.RevocationRevertError = RevocationRevertError;
965
997
  exports.SemaphoreGroupClient = SemaphoreGroupClient;
966
998
  exports.SemaphoreRegistrationProver = SemaphoreRegistrationProver;
967
999
  exports.SemaphoreRevocationProver = SemaphoreRevocationProver;
1000
+ exports.SponsoredAnnouncementSubmitter = SponsoredAnnouncementSubmitter;
968
1001
  exports.SponsoredIdentityRegistryWriter = SponsoredIdentityRegistryWriter;
969
1002
  exports.SponsoredRelay = SponsoredRelay;
970
1003
  exports.SponsoredRevocationWriter = SponsoredRevocationWriter;
package/dist/index.js CHANGED
@@ -106,7 +106,7 @@ async function readIdentity(identityReader, networkId) {
106
106
  return await identityReader.getIdentity(networkId);
107
107
  }
108
108
  catch (error) {
109
- throw new NetworkMemberClientError("REGISTRY_UNAVAILABLE", `identity read failed for ${networkId}`, error);
109
+ throw new NetworkMemberClientError("REGISTRY_UNAVAILABLE", "identity read failed", error);
110
110
  }
111
111
  }
112
112
  /**
@@ -165,7 +165,7 @@ async function submitRegistration(request, { domain, identityReader, prover, wri
165
165
  }
166
166
  throw error;
167
167
  }
168
- throw new NetworkMemberClientError("REGISTRY_UNAVAILABLE", `registration submission failed for ${networkId}`, error);
168
+ throw new NetworkMemberClientError("REGISTRY_UNAVAILABLE", "registration submission failed", error);
169
169
  }
170
170
  }
171
171
 
@@ -585,7 +585,7 @@ const GAS_LIMITS = {
585
585
  verificationGasLimit: 500000n,
586
586
  preVerificationGas: 100000n,
587
587
  paymasterVerificationGasLimit: 600000n,
588
- paymasterPostOpGasLimit: 50000n
588
+ paymasterPostOpGasLimit: 0n
589
589
  };
590
590
  const GAS_FEE_PER_GAS = 1000000000n; // 1 gwei
591
591
  /**
@@ -741,7 +741,7 @@ class SponsoredIdentityRegistryWriter {
741
741
  if (receipt.revertReason !== undefined && decodedErrorName(receipt.revertReason) === "AlreadyRegistered") {
742
742
  throw new RegistryRevertError("AlreadyRegistered", receipt.revertReason);
743
743
  }
744
- throw new Error(`sponsored registerIdentity user operation reverted for ${networkId}`);
744
+ throw new Error("sponsored registerIdentity user operation reverted");
745
745
  }
746
746
  return { txHash: receipt.transactionHash, sponsorship };
747
747
  }
@@ -756,6 +756,38 @@ function decodedErrorName(revertReason) {
756
756
  }
757
757
  }
758
758
 
759
+ /**
760
+ * Sponsored AnnouncementSubmitter: relays `ERC5564Announcer.announce` through {@link SponsoredRelay},
761
+ * so the indexed `caller` of the `Announcement` is a one-time sender, not the member. A direct
762
+ * `ERC5564AnnouncerClient` would put one fixed address on every delivery the member makes.
763
+ */
764
+ class SponsoredAnnouncementSubmitter {
765
+ constructor(announcerAddress, relay) {
766
+ this.announcerAddress = announcerAddress;
767
+ this.relay = relay;
768
+ }
769
+ async announce(announcement) {
770
+ const { receipt } = await this.relay.relay({
771
+ target: this.announcerAddress,
772
+ data: encodeFunctionData({
773
+ abi: ERC5564_ANNOUNCER_ABI,
774
+ functionName: "announce",
775
+ args: [
776
+ BigInt(announcement.schemeId),
777
+ announcement.stealthAddress,
778
+ announcement.ephemeralPublicKey,
779
+ announcement.metadata
780
+ ]
781
+ })
782
+ });
783
+ // The announcer has no named errors, so the raw revert data is all there is to report. Assigned,
784
+ // not passed as an option, because the repo's ES2020 target has no ErrorOptions.
785
+ if (!receipt.success)
786
+ throw Object.assign(new Error("sponsored announce reverted"), { cause: receipt.revertReason });
787
+ return receipt.transactionHash;
788
+ }
789
+ }
790
+
759
791
  /**
760
792
  * The `CredentialRevocationRegistry` fragments a writer needs. The errors matter as much as the
761
793
  * function: `InvalidLowLeaf` is the one a caller recomputes an index and retries on, and
@@ -949,4 +981,4 @@ class EntryPointSubmitter {
949
981
  }
950
982
  }
951
983
 
952
- export { ApprovedIssuerSetClient, BundlerRpcSubmitter, CREDENTIAL_REVOCATION_REGISTRY_ABI, DirectRevocationWriter, ERC5564AnnouncerClient, EntryPointSubmitter, IdentityRegistryClient, IdentityRegistryWriter, NetworkMemberClientError, RegistryRevertError, RevocationRevertError, SemaphoreGroupClient, SemaphoreRegistrationProver, SemaphoreRevocationProver, SponsoredIdentityRegistryWriter, SponsoredRelay, SponsoredRevocationWriter, deliverToStealth, fetchIssuerMembershipWitness, issueVC, parseUserOperationReceipt, submitRegistration };
984
+ export { ApprovedIssuerSetClient, BundlerRpcSubmitter, CREDENTIAL_REVOCATION_REGISTRY_ABI, DirectRevocationWriter, ERC5564AnnouncerClient, EntryPointSubmitter, IdentityRegistryClient, IdentityRegistryWriter, NetworkMemberClientError, RegistryRevertError, RevocationRevertError, SemaphoreGroupClient, SemaphoreRegistrationProver, SemaphoreRevocationProver, SponsoredAnnouncementSubmitter, SponsoredIdentityRegistryWriter, SponsoredRelay, SponsoredRevocationWriter, deliverToStealth, fetchIssuerMembershipWitness, issueVC, parseUserOperationReceipt, submitRegistration };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coordination-network/network-member-client",
3
- "version": "0.0.1",
3
+ "version": "0.1.0",
4
4
  "description": "Issues a UserApproval credential and its Merkle path into the approved-issuer set for network-member apps, refreshable as the set changes.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -36,19 +36,20 @@
36
36
  "build": "rimraf dist types && rollup -c rollup.config.mjs"
37
37
  },
38
38
  "dependencies": {
39
- "@coordination-network/credential": "^0.0.1",
40
- "@coordination-network/identity": "^0.0.1",
41
- "@coordination-network/issuer-set": "^0.0.1",
42
- "@coordination-network/network-member-proof": "^0.0.1",
43
- "@coordination-network/user-client": "^0.0.1",
44
- "@semaphore-protocol/group": "4.14.3",
45
- "@semaphore-protocol/identity": "4.14.3",
46
- "@semaphore-protocol/proof": "4.14.3",
39
+ "@coordination-network/credential": "^0.1.0",
40
+ "@coordination-network/identity": "^0.1.0",
41
+ "@coordination-network/issuer-set": "^0.1.0",
42
+ "@coordination-network/network-member-proof": "^0.1.0",
43
+ "@coordination-network/user-client": "^0.1.0",
44
+ "@semaphore-protocol/group": "4.14.4",
45
+ "@semaphore-protocol/identity": "4.14.4",
46
+ "@semaphore-protocol/proof": "4.14.4",
47
47
  "viem": "^2.55.11"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@rollup/plugin-typescript": "^12.3.0",
51
51
  "@types/jest": "^30.0.0",
52
+ "ffjavascript": "0.3.1",
52
53
  "rimraf": "^6.1.3",
53
54
  "rollup": "^4.62.2",
54
55
  "rollup-plugin-cleanup": "^3.2.1",
package/src/adapters.ts CHANGED
@@ -213,7 +213,7 @@ export class ApprovedIssuerSetClient implements ContractLeafReader {
213
213
  }
214
214
  }
215
215
 
216
- const ERC5564_ANNOUNCER_ABI = [
216
+ export const ERC5564_ANNOUNCER_ABI = [
217
217
  {
218
218
  type: "function",
219
219
  name: "announce",
package/src/index.ts CHANGED
@@ -42,6 +42,7 @@ export {
42
42
  } from "./adapters"
43
43
  export type { SponsoredIdentityRegistryWriterParams } from "./sponsored"
44
44
  export { SponsoredIdentityRegistryWriter } from "./sponsored"
45
+ export { SponsoredAnnouncementSubmitter } from "./sponsored-announcement"
45
46
  export type { RelayCall, RelayedCall, SponsoredMemberKeys, SponsoredRelayParams } from "./sponsored-relay"
46
47
  export { SponsoredRelay } from "./sponsored-relay"
47
48
  export {
@@ -0,0 +1,40 @@
1
+ import { encodeFunctionData } from "viem"
2
+ import type { Address, Hex } from "viem"
3
+ import { ERC5564_ANNOUNCER_ABI } from "./adapters"
4
+ import { SponsoredRelay } from "./sponsored-relay"
5
+ import type { Announcement, AnnouncementSubmitter } from "./types"
6
+
7
+ /**
8
+ * Sponsored AnnouncementSubmitter: relays `ERC5564Announcer.announce` through {@link SponsoredRelay},
9
+ * so the indexed `caller` of the `Announcement` is a one-time sender, not the member. A direct
10
+ * `ERC5564AnnouncerClient` would put one fixed address on every delivery the member makes.
11
+ */
12
+ export class SponsoredAnnouncementSubmitter implements AnnouncementSubmitter {
13
+ constructor(
14
+ readonly announcerAddress: Address,
15
+ private readonly relay: SponsoredRelay
16
+ ) {}
17
+
18
+ async announce(announcement: Announcement): Promise<Hex> {
19
+ const { receipt } = await this.relay.relay({
20
+ target: this.announcerAddress,
21
+ data: encodeFunctionData({
22
+ abi: ERC5564_ANNOUNCER_ABI,
23
+ functionName: "announce",
24
+ args: [
25
+ BigInt(announcement.schemeId),
26
+ announcement.stealthAddress,
27
+ announcement.ephemeralPublicKey,
28
+ announcement.metadata
29
+ ]
30
+ })
31
+ })
32
+
33
+ // The announcer has no named errors, so the raw revert data is all there is to report. Assigned,
34
+ // not passed as an option, because the repo's ES2020 target has no ErrorOptions.
35
+ if (!receipt.success)
36
+ throw Object.assign(new Error("sponsored announce reverted"), { cause: receipt.revertReason })
37
+
38
+ return receipt.transactionHash
39
+ }
40
+ }
@@ -42,7 +42,7 @@ const GAS_LIMITS = {
42
42
  verificationGasLimit: 500_000n,
43
43
  preVerificationGas: 100_000n,
44
44
  paymasterVerificationGasLimit: 600_000n,
45
- paymasterPostOpGasLimit: 50_000n
45
+ paymasterPostOpGasLimit: 0n
46
46
  } as const
47
47
  const GAS_FEE_PER_GAS = 1_000_000_000n // 1 gwei
48
48
 
package/src/sponsored.ts CHANGED
@@ -46,7 +46,7 @@ export class SponsoredIdentityRegistryWriter implements RegistrationWriter {
46
46
  if (receipt.revertReason !== undefined && decodedErrorName(receipt.revertReason) === "AlreadyRegistered") {
47
47
  throw new RegistryRevertError("AlreadyRegistered", receipt.revertReason)
48
48
  }
49
- throw new Error(`sponsored registerIdentity user operation reverted for ${networkId}`)
49
+ throw new Error("sponsored registerIdentity user operation reverted")
50
50
  }
51
51
 
52
52
  return { txHash: receipt.transactionHash, sponsorship }
package/src/submit.ts CHANGED
@@ -37,7 +37,7 @@ async function readIdentity(identityReader: IdentityReader, networkId: Hex): Pro
37
37
  try {
38
38
  return await identityReader.getIdentity(networkId)
39
39
  } catch (error) {
40
- throw new NetworkMemberClientError("REGISTRY_UNAVAILABLE", `identity read failed for ${networkId}`, error)
40
+ throw new NetworkMemberClientError("REGISTRY_UNAVAILABLE", "identity read failed", error)
41
41
  }
42
42
  }
43
43
 
@@ -102,10 +102,6 @@ export async function submitRegistration(
102
102
  }
103
103
  throw error
104
104
  }
105
- throw new NetworkMemberClientError(
106
- "REGISTRY_UNAVAILABLE",
107
- `registration submission failed for ${networkId}`,
108
- error
109
- )
105
+ throw new NetworkMemberClientError("REGISTRY_UNAVAILABLE", "registration submission failed", error)
110
106
  }
111
107
  }
package/types/index.d.ts CHANGED
@@ -434,6 +434,18 @@ declare class SponsoredIdentityRegistryWriter implements RegistrationWriter {
434
434
  registerIdentity(networkId: Hex32, metaStealthAddress: Hex$1, proof: NetworkMemberProof): Promise<RegistrationWrite>;
435
435
  }
436
436
 
437
+ /**
438
+ * Sponsored AnnouncementSubmitter: relays `ERC5564Announcer.announce` through {@link SponsoredRelay},
439
+ * so the indexed `caller` of the `Announcement` is a one-time sender, not the member. A direct
440
+ * `ERC5564AnnouncerClient` would put one fixed address on every delivery the member makes.
441
+ */
442
+ declare class SponsoredAnnouncementSubmitter implements AnnouncementSubmitter {
443
+ readonly announcerAddress: Address$1;
444
+ private readonly relay;
445
+ constructor(announcerAddress: Address$1, relay: SponsoredRelay);
446
+ announce(announcement: Announcement): Promise<Hex$1>;
447
+ }
448
+
437
449
  /**
438
450
  * The `CredentialRevocationRegistry` fragments a writer needs. The errors matter as much as the
439
451
  * function: `InvalidLowLeaf` is the one a caller recomputes an index and retries on, and
@@ -546,5 +558,5 @@ declare class DirectRevocationWriter implements RevocationRegistryWriter {
546
558
  revoke(commitment: bigint, lowLeafIndex: bigint, proof: NetworkMemberProof): Promise<RevocationWrite>;
547
559
  }
548
560
 
549
- export { ApprovedIssuerSetClient, BundlerRpcSubmitter, CREDENTIAL_REVOCATION_REGISTRY_ABI, DirectRevocationWriter, ERC5564AnnouncerClient, EntryPointSubmitter, IdentityRegistryClient, IdentityRegistryWriter, NetworkMemberClientError, RegistryRevertError, RevocationRevertError, SemaphoreGroupClient, SemaphoreRegistrationProver, SemaphoreRevocationProver, SponsoredIdentityRegistryWriter, SponsoredRelay, SponsoredRevocationWriter, deliverToStealth, fetchIssuerMembershipWitness, issueVC, parseUserOperationReceipt, submitRegistration };
561
+ export { ApprovedIssuerSetClient, BundlerRpcSubmitter, CREDENTIAL_REVOCATION_REGISTRY_ABI, DirectRevocationWriter, ERC5564AnnouncerClient, EntryPointSubmitter, IdentityRegistryClient, IdentityRegistryWriter, NetworkMemberClientError, RegistryRevertError, RevocationRevertError, SemaphoreGroupClient, SemaphoreRegistrationProver, SemaphoreRevocationProver, SponsoredAnnouncementSubmitter, SponsoredIdentityRegistryWriter, SponsoredRelay, SponsoredRevocationWriter, deliverToStealth, fetchIssuerMembershipWitness, issueVC, parseUserOperationReceipt, submitRegistration };
550
562
  export type { Announcement, AnnouncementSubmitter, DeliverToStealthParams, DeliverToStealthPorts, DeliveredToStealth, FetchIssuerMembershipWitnessParams, GroupMirror, IdentityReader, IssueVCPorts, IssuedCredential, IssuerMembershipWitnessResult, NetworkMemberClientErrorCode, RegistrationProver, RegistrationWrite, RegistrationWriter, RelayCall, RelayedCall, RevocationProver, RevocationRegistryWriter, RevocationWrite, SemaphoreRegistrationProverParams, SemaphoreRevocationProverParams, SponsoredIdentityRegistryWriterParams, SponsoredMemberKeys, SponsoredRelayParams, SponsoredUserOperation, Sponsorship, SubmitRegistrationPorts, SubmitRegistrationResult, UserOperationReceipt, UserOperationSubmitter };