opacity-issuer-core 0.2.1
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/LICENSE +21 -0
- package/README.md +44 -0
- package/dist/chunk-2STMWRIV.js +164 -0
- package/dist/chunk-2STMWRIV.js.map +1 -0
- package/dist/chunk-3L7NNVUV.cjs +184 -0
- package/dist/chunk-3L7NNVUV.cjs.map +1 -0
- package/dist/chunk-54Q3MU62.js +29 -0
- package/dist/chunk-54Q3MU62.js.map +1 -0
- package/dist/chunk-7ODYBEZH.js +889 -0
- package/dist/chunk-7ODYBEZH.js.map +1 -0
- package/dist/chunk-GMPQFX25.cjs +923 -0
- package/dist/chunk-GMPQFX25.cjs.map +1 -0
- package/dist/chunk-HJQZWNZJ.cjs +33 -0
- package/dist/chunk-HJQZWNZJ.cjs.map +1 -0
- package/dist/documents/index.cjs +170 -0
- package/dist/documents/index.cjs.map +1 -0
- package/dist/documents/index.d.cts +1370 -0
- package/dist/documents/index.d.ts +1370 -0
- package/dist/documents/index.js +5 -0
- package/dist/documents/index.js.map +1 -0
- package/dist/documents/validate.cjs +53 -0
- package/dist/documents/validate.cjs.map +1 -0
- package/dist/documents/validate.d.cts +70 -0
- package/dist/documents/validate.d.ts +70 -0
- package/dist/documents/validate.js +4 -0
- package/dist/documents/validate.js.map +1 -0
- package/dist/index.cjs +8917 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +11088 -0
- package/dist/index.d.ts +11088 -0
- package/dist/index.js +8647 -0
- package/dist/index.js.map +1 -0
- package/dist/subgraph.cjs +891 -0
- package/dist/subgraph.cjs.map +1 -0
- package/dist/subgraph.d.cts +456 -0
- package/dist/subgraph.d.ts +456 -0
- package/dist/subgraph.js +882 -0
- package/dist/subgraph.js.map +1 -0
- package/dist/transport-0_X4HTI6.d.ts +39 -0
- package/dist/transport-uaC5Yl3p.d.cts +39 -0
- package/dist/types-B4Yi7WA4.d.cts +108 -0
- package/dist/types-B4Yi7WA4.d.ts +108 -0
- package/package.json +75 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/documents/abi.ts","../src/documents/ids.ts","../src/documents/verify.ts","../src/documents/typed-data.ts","../src/documents/transaction.ts","../src/documents/sandbox.ts","../src/deployments/sepolia-sandbox.ts","../src/documents/sandbox-deployments.ts","../src/documents/adapters.ts"],"names":["keccak256","toBytes","OpacityAttestationError","assertDocHash","assertSessionWindow","assertAddress","assertChainId","assertNonce","DOCUMENT_ATTESTOR_DOMAIN_NAME","DOCUMENT_ATTESTOR_DOMAIN_VERSION","DOCUMENT_ACCEPTANCE_TYPES","DOCUMENT_ACCEPTANCE_PRIMARY_TYPE","hashTypedData","EIP712_DOMAIN_TYPE","assertTraitId","assertServerSignature","assertUserSignature","encodeFunctionData","numberToHex","assertBoolean","encodePacked","OpacityConfigError","size","BaseError","ExecutionRevertedError","isHex","decodeFunctionResult","decodeErrorResult","getAddress","asRecord"],"mappings":"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","file":"chunk-GMPQFX25.cjs","sourcesContent":["/**\n * Minimal ABI for `DocumentAttestor`, hand-written rather than copied from a Foundry artifact.\n *\n * The contracts repo's `release-abis.yml` only syncs `AllowlistRegistry.json` downstream, so there\n * is no artifact pipeline to consume here; a hand-written `as const` array also keeps viem's type\n * inference sharp and the published bundle small.\n *\n * It covers the write path this SDK builds (`attestDocument`), the reads worth verifying a\n * deployment against, and the errors reachable from `attestDocument` — including the two from\n * `AllowlistRegistry` and `EnforcedPause`, which bubble up through `enableTraitAsWriter` and are\n * the likeliest failures in practice (writer role never granted, trait not writer-enableable,\n * registry paused). Pass this ABI to viem's revert decoding to get a named error instead of a raw\n * selector.\n *\n * Owner-only functions (`setServerSigner`, the `Ownable2Step` surface) are deliberately absent —\n * they are outside this module's scope.\n */\nexport const documentAttestorAbi = [\n {\n type: 'function',\n name: 'attestDocument',\n stateMutability: 'nonpayable',\n inputs: [\n { name: 'wallet', type: 'address' },\n { name: 'traitId', type: 'bytes32' },\n { name: 'docHash', type: 'bytes32' },\n { name: 'nonce', type: 'bytes32' },\n { name: 'issuedAt', type: 'uint256' },\n { name: 'deadline', type: 'uint256' },\n { name: 'serverSignature', type: 'bytes' },\n { name: 'userSignature', type: 'bytes' },\n ],\n outputs: [],\n },\n\n // ── Reads ────────────────────────────────────────────────────────────────────────────────────\n {\n type: 'function',\n name: 'serverSigner',\n stateMutability: 'view',\n inputs: [],\n outputs: [{ type: 'address' }],\n },\n {\n type: 'function',\n name: 'usedNonces',\n stateMutability: 'view',\n inputs: [{ name: 'nonce', type: 'bytes32' }],\n outputs: [{ type: 'bool' }],\n },\n {\n type: 'function',\n name: 'retiredSigners',\n stateMutability: 'view',\n inputs: [{ name: 'signer', type: 'address' }],\n outputs: [{ type: 'bool' }],\n },\n {\n type: 'function',\n name: 'allowlistRegistry',\n stateMutability: 'view',\n inputs: [],\n outputs: [{ type: 'address' }],\n },\n {\n type: 'function',\n name: 'MAX_ATTESTATION_LIFETIME',\n stateMutability: 'view',\n inputs: [],\n outputs: [{ type: 'uint256' }],\n },\n {\n type: 'function',\n name: 'DOCUMENT_ACCEPTANCE_TYPEHASH',\n stateMutability: 'view',\n inputs: [],\n outputs: [{ type: 'bytes32' }],\n },\n {\n type: 'function',\n name: 'ATTESTATION_AUTHORIZATION_TYPEHASH',\n stateMutability: 'view',\n inputs: [],\n outputs: [{ type: 'bytes32' }],\n },\n {\n // ERC-5267, inherited from OpenZeppelin's EIP712. Lets a consumer confirm the domain the SDK\n // builds locally matches the one the deployed contract verifies against.\n type: 'function',\n name: 'eip712Domain',\n stateMutability: 'view',\n inputs: [],\n outputs: [\n { name: 'fields', type: 'bytes1' },\n { name: 'name', type: 'string' },\n { name: 'version', type: 'string' },\n { name: 'chainId', type: 'uint256' },\n { name: 'verifyingContract', type: 'address' },\n { name: 'salt', type: 'bytes32' },\n { name: 'extensions', type: 'uint256[]' },\n ],\n },\n\n // ── Events ───────────────────────────────────────────────────────────────────────────────────\n {\n type: 'event',\n name: 'DocumentAttested',\n inputs: [\n { name: 'userId', type: 'bytes32', indexed: true },\n { name: 'wallet', type: 'address', indexed: true },\n { name: 'traitId', type: 'bytes32', indexed: true },\n { name: 'docHash', type: 'bytes32', indexed: false },\n { name: 'nonce', type: 'bytes32', indexed: false },\n ],\n anonymous: false,\n },\n\n // ── Errors: DocumentAttestor ─────────────────────────────────────────────────────────────────\n { type: 'error', name: 'ZeroAddress', inputs: [] },\n { type: 'error', name: 'InvalidTraitId', inputs: [] },\n { type: 'error', name: 'InvalidDocHash', inputs: [] },\n { type: 'error', name: 'NonceAlreadyUsed', inputs: [] },\n { type: 'error', name: 'AttestationExpired', inputs: [{ name: 'deadline', type: 'uint256' }] },\n {\n type: 'error',\n name: 'AttestationDeadlineTooFar',\n inputs: [\n { name: 'deadline', type: 'uint256' },\n { name: 'maxAllowed', type: 'uint256' },\n ],\n },\n {\n type: 'error',\n name: 'AttestationIssuedInFuture',\n inputs: [{ name: 'issuedAt', type: 'uint256' }],\n },\n { type: 'error', name: 'WalletNotOnboarded', inputs: [{ name: 'wallet', type: 'address' }] },\n { type: 'error', name: 'InvalidServerSignature', inputs: [] },\n { type: 'error', name: 'SignerRetired', inputs: [{ name: 'signer', type: 'address' }] },\n { type: 'error', name: 'InvalidUserSignature', inputs: [] },\n\n // ── Errors: OpenZeppelin ECDSA, raised while recovering the server signature ─────────────────\n { type: 'error', name: 'ECDSAInvalidSignature', inputs: [] },\n {\n type: 'error',\n name: 'ECDSAInvalidSignatureLength',\n inputs: [{ name: 'length', type: 'uint256' }],\n },\n { type: 'error', name: 'ECDSAInvalidSignatureS', inputs: [{ name: 's', type: 'bytes32' }] },\n\n // ── Errors: bubbled up from AllowlistRegistry.enableTraitAsWriter ────────────────────────────\n { type: 'error', name: 'NotTraitWriter', inputs: [] },\n { type: 'error', name: 'TraitNotWriterEnableable', inputs: [] },\n { type: 'error', name: 'EnforcedPause', inputs: [] },\n] as const;\n","import { keccak256, toBytes } from 'viem';\nimport type { Hex } from 'viem';\n\n/**\n * Derives a trait id from its canonical name: `keccak256(utf8(name))`.\n *\n * Matches the convention the contracts use verbatim — `keccak256(\"doc.offering7.subscription.v1\")`\n * in Solidity is `documentTraitId('doc.offering7.subscription.v1')` here.\n *\n * The document VERSION is part of the name, deliberately: amendments roll the id forward, so a\n * policy that requires `…v2` makes every `…v1` attestation inert without touching a contract.\n *\n * The resulting id must be writer-enableable on the registry\n * (`AllowlistRegistry.setWriterEnableableTrait`) or `attestDocument` reverts\n * `TraitNotWriterEnableable`.\n */\nexport function documentTraitId(name: string): Hex {\n return keccak256(toBytes(name));\n}\n\n/**\n * Hashes a document to the `docHash` an attestation binds to.\n *\n * Must be the EXECUTED document — the post-signature artifact — not the blank template. Pass the\n * raw bytes (e.g. a `Uint8Array` of the PDF); a `string` is hashed as UTF-8.\n */\nexport function hashDocument(content: Uint8Array | string): Hex {\n return keccak256(typeof content === 'string' ? toBytes(content) : content);\n}\n","import type { Hex } from 'viem';\n\nimport { OpacityAttestationError } from '../errors.js';\nimport { hashDocument } from './ids.js';\nimport type { ClockOptions } from './types.js';\nimport { assertDocHash, assertSessionWindow } from './validate.js';\n\n/**\n * Client-side pre-flight checks, run while the investor is still looking at the document and\n * before any wallet prompt is raised.\n *\n * **The direction matters, and it is the opposite of what a \"verify\" module usually implies: the\n * CLIENT is the source of `docHash`.** The app hashes the executed PDF it rendered during the\n * e-sign ceremony and posts that hash to `POST /attestations`. The backend signs over what the\n * client asserted; it never sees or stores the document, and there is no document URL to fetch\n * back — the client necessarily already holds the bytes.\n *\n * So what is verified here is the ROUND TRIP. The session that comes back carries a `docHash`\n * inside the typed data the wallet is about to sign, and this module re-derives the hash of the\n * bytes actually on screen and refuses to continue unless the two agree. That catches a backend\n * which echoed back a different `docHash` than the one submitted — compromised, buggy, or simply\n * crossing two users' sessions — along with any corruption in between. The wallet prompt then\n * displays the very `docHash` that was just re-verified, and that is what closes the \"investor\n * signed something they never saw\" gap.\n *\n * What none of this establishes is that the investor read or understood the document. The\n * attestor's design of record is explicit that the on-chain artifact proves *attribution + session\n * binding* only; intent-to-sign and ESIGN/UETA consent come from the off-chain e-sign ceremony,\n * of which the attestation is durable evidence rather than a substitute.\n */\n\n/**\n * Rejects content that cannot be hashed into a meaningful `docHash`.\n *\n * The empty case is worth its own error: a zero-length body is what a failed file read or a render\n * that produced nothing looks like, and letting it through would report a hash mismatch —\n * technically true, but it would send the integrator hunting for a tampered document instead of a\n * broken read.\n */\nfunction assertDocumentContent(content: Uint8Array | string): Uint8Array | string {\n if (typeof content !== 'string' && !(content instanceof Uint8Array)) {\n throw new OpacityAttestationError(\n 'MalformedInput',\n '`content` must be a `Uint8Array` of document bytes or a `string` hashed as UTF-8.',\n { field: 'content' },\n );\n }\n if (content.length === 0) {\n throw new OpacityAttestationError(\n 'MalformedInput',\n '`content` is empty. An executed document is never zero bytes, so this is a failed read or ' +\n 'a render that produced nothing, rather than a document worth hashing.',\n { field: 'content' },\n );\n }\n return content;\n}\n\n/**\n * Asserts that the bytes the app rendered still hash to the `docHash` the investor is about to\n * sign.\n *\n * **This is the single most security-relevant check the client half performs**, and the only thing\n * tying a signature to real paperwork. The 2-of-2 design defends against a compromised server\n * acting alone and against an investor acting alone; it does nothing about a client that signs\n * whatever `docHash` arrives over the wire, because the attestor never sees the document at all —\n * only its hash.\n *\n * Since the client is what produced and submitted that hash in the first place, a mismatch never\n * means \"the server sent the wrong document\" — the server has no document to send. It means one of:\n *\n * - the session echoed back a different `docHash` than the one posted to `POST /attestations`;\n * - the bytes changed between being hashed and being rendered;\n * - the wrong artifact is in hand — a blank template, or a re-encoded copy of the executed one.\n *\n * Call it before `buildDocumentAcceptanceTypedData` and refuse to raise the wallet prompt if it\n * throws. Pass the EXECUTED artifact — the same post-signature bytes that were hashed for\n * `POST /attestations` — not the blank template, and not a re-rendered or re-encoded copy of it.\n * Hashing is byte-exact: a PDF that has been through a viewer's save path will not match even\n * though it looks identical.\n *\n * The comparison is case-insensitive. `hashDocument` returns lower-case hex, but a `docHash` that\n * arrived inside a JSON session payload may be upper- or mixed-case, and rejecting a valid document\n * over hex casing would be a silent, extremely confusing failure. Constant-time comparison is not\n * warranted: both values are public, and anyone in a position to substitute the hash already knows\n * the one they substituted.\n *\n * @throws {OpacityAttestationError} `DocHashMismatch` when the content hashes to something other\n * than `expectedDocHash`; `InvalidDocHash` / `MalformedInput` when `expectedDocHash` is zero or\n * not 32 bytes of hex, or when `content` is empty or of the wrong type.\n */\nexport function assertDocumentMatchesHash(\n content: Uint8Array | string,\n expectedDocHash: Hex,\n): void {\n // Well-formedness first: a malformed or zero `docHash` is a defect in the session payload, and\n // reporting it as a mismatch would blame the document for the session's problem.\n const expected = assertDocHash(expectedDocHash);\n const actual = hashDocument(assertDocumentContent(content));\n\n if (actual.toLowerCase() !== expected.toLowerCase()) {\n // Both hashes are safe to surface — they are public, preimage-resistant, and one of them is\n // already on the wire. The document's bytes are deliberately absent: this message ends up in\n // logs and crash reports, and the content is the investor's private financial paperwork.\n throw new OpacityAttestationError(\n 'DocHashMismatch',\n 'The rendered document does not match the session `docHash`. The session commits to ' +\n `${expected}, but the supplied content hashes to ${actual}. Do not raise the wallet ` +\n 'prompt — the investor would be signing for a document they were never shown. The client ' +\n 'is the source of this hash, so either the session echoed back a different `docHash` than ' +\n 'the one posted to `POST /attestations`, or these are not the bytes that were hashed for ' +\n 'it: a template, a re-encoded PDF, or a truncated read each hash differently. Re-hash the ' +\n 'exact executed artifact that was submitted; if it still does not match, abandon the ' +\n 'session and escalate — the backend is not committing to the document being signed.',\n { field: 'docHash' },\n );\n }\n}\n\n/**\n * Coerces a unix-seconds timestamp off the wire into the `bigint` every check (and every wallet\n * stack) wants.\n *\n * The wire is deliberately inconsistent about this and it is worth naming: `POST /attestations`\n * returns `deadline` as a JSON NUMBER at the top level but as a decimal STRING inside\n * `typedData.message`, since the signed copy is the form `eth_signTypedData_v4` is specified in\n * terms of. Neither form is wrong for a wallet — viem and ethers hash the decimal string to the\n * same digest as a `bigint` — so both are accepted here, as is a `bigint` the caller already\n * holds; this is normalisation for the checks below, not repair.\n *\n * Numbers must be safe integers. Unix seconds are nowhere near 2^53, so anything larger has already\n * lost precision inside `JSON.parse` and must not be silently rounded into a deadline.\n */\nfunction toUnixSeconds(value: bigint | number | string, field: string): bigint {\n if (typeof value === 'bigint') return value;\n\n if (typeof value === 'number') {\n if (!Number.isSafeInteger(value)) {\n throw new OpacityAttestationError(\n 'MalformedInput',\n `\\`${field}\\` must be a whole number of unix seconds; received ${value}.`,\n { field },\n );\n }\n return BigInt(value);\n }\n\n if (typeof value === 'string' && /^[0-9]+$/.test(value)) {\n return BigInt(value);\n }\n\n throw new OpacityAttestationError(\n 'MalformedInput',\n `\\`${field}\\` must be unix seconds as a bigint, a whole number, or a decimal string.`,\n { field },\n );\n}\n\n/** Narrows an unknown JSON value to something with readable properties. */\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\n/** Whether a wire value is worth handing to {@link toUnixSeconds} rather than treating as absent. */\nfunction isTimestampLike(value: unknown): value is bigint | number | string {\n return typeof value === 'bigint' || typeof value === 'number' || typeof value === 'string';\n}\n\n/**\n * The parts of a `POST /attestations` response this module reads.\n *\n * Declared structurally, so the full response type — or a raw `JSON.parse` result — satisfies it\n * without conversion, and so this module does not have to move every time the rest of the response\n * grows a field.\n */\nexport interface AttestationSessionResponseLike {\n /**\n * Top-level echo of the hash the client submitted. Optional here only for tolerance; the locked\n * schema always sends it, and it is cross-checked against the signed copy when present.\n */\n docHash?: Hex | undefined;\n /** Session expiry, unix seconds. A NUMBER on the locked wire; a bigint or decimal string is fine. */\n deadline: number | bigint | string;\n /** The EIP-712 payload the wallet is about to sign. Only `message` is read. */\n typedData: {\n message: {\n /** The copy of the hash that is actually signed — this is the one that gets checked. */\n docHash: Hex;\n /** Decimal STRING on the wire, since `eth_signTypedData_v4` wants `uint256` as a string. */\n deadline?: number | bigint | string | undefined;\n };\n };\n}\n\n/**\n * Reads the two fields this module checks out of a `POST /attestations` response.\n *\n * `docHash` is taken from `typedData.message` in preference to the top-level echo: that is the copy\n * the wallet signs and the contract sees, so it is the copy that cannot drift from what the\n * investor agreed to. When both are present they must agree — a session whose two copies disagree\n * is either corrupt or is showing the UI one document while asking the wallet to sign another,\n * and neither is safe to prompt for. `deadline` is taken from the top level, where the locked\n * schema puts the number, and its signed decimal-string copy is cross-checked the same way.\n *\n * Reading is defensive rather than schema-strict: this object comes straight off `JSON.parse`, and\n * a field that is missing or of the wrong type falls back to the other copy instead of throwing on\n * a shape technicality. What is never tolerated is two copies that disagree.\n */\nfunction readSessionFields(session: AttestationSessionResponseLike): {\n docHash: Hex;\n deadline: bigint;\n} {\n const record = asRecord(session);\n if (record === undefined) {\n throw new OpacityAttestationError(\n 'MalformedInput',\n '`session` must be the object returned by `POST /attestations`.',\n { field: 'session' },\n );\n }\n\n const message = asRecord(asRecord(record['typedData'])?.['message']);\n\n return {\n docHash: readSessionDocHash(message?.['docHash'], record['docHash']),\n deadline: readSessionDeadline(record['deadline'], message?.['deadline']),\n };\n}\n\n/** The signed copy wins; a disagreement between the two copies is fatal. */\nfunction readSessionDocHash(signed: unknown, echoed: unknown): Hex {\n const signedHash = typeof signed === 'string' ? (signed as Hex) : undefined;\n const echoedHash = typeof echoed === 'string' ? (echoed as Hex) : undefined;\n\n if (\n signedHash !== undefined &&\n echoedHash !== undefined &&\n signedHash.toLowerCase() !== echoedHash.toLowerCase()\n ) {\n throw new OpacityAttestationError(\n 'DocHashMismatch',\n 'The session disagrees with itself about `docHash`: the top-level field says ' +\n `${echoedHash} while \\`typedData.message\\`, the copy the wallet actually signs, says ` +\n `${signedHash}. A UI that displays one and prompts for the other is exactly the gap this ` +\n 'check exists to close. Abandon the session and escalate.',\n { field: 'docHash' },\n );\n }\n\n const docHash = signedHash ?? echoedHash;\n if (docHash === undefined) {\n throw new OpacityAttestationError(\n 'MalformedInput',\n '`session` carries no usable `docHash`. It is read from `typedData.message.docHash`, ' +\n 'falling back to the top-level `docHash`.',\n { field: 'docHash' },\n );\n }\n return docHash;\n}\n\n/** The top-level number wins, per the locked schema; the signed string copy must agree with it. */\nfunction readSessionDeadline(top: unknown, signed: unknown): bigint {\n const topDeadline = isTimestampLike(top) ? toUnixSeconds(top, 'deadline') : undefined;\n const signedDeadline = isTimestampLike(signed) ? toUnixSeconds(signed, 'deadline') : undefined;\n\n if (topDeadline !== undefined && signedDeadline !== undefined && topDeadline !== signedDeadline) {\n throw new OpacityAttestationError(\n 'MalformedInput',\n `The session disagrees with itself about \\`deadline\\`: the top level says ${topDeadline} ` +\n `while \\`typedData.message\\`, the copy the wallet signs and the contract enforces, says ` +\n `${signedDeadline}.`,\n { field: 'deadline' },\n );\n }\n\n const deadline = topDeadline ?? signedDeadline;\n if (deadline === undefined) {\n throw new OpacityAttestationError(\n 'MalformedInput',\n '`session` carries no usable `deadline`. It is read from the top-level `deadline`, falling ' +\n 'back to `typedData.message.deadline`.',\n { field: 'deadline' },\n );\n }\n return deadline;\n}\n\n/** Shared by both shapes {@link verifyAttestationSession} accepts. */\ninterface VerifyAttestationSessionBase extends ClockOptions {\n /** The document bytes the app rendered to the investor. A `string` is hashed as UTF-8. */\n content: Uint8Array | string;\n /**\n * Optional, and normally absent: the client-facing session deliberately does not carry\n * `issuedAt` — the investor does not sign it. Supply it if you have it server-side and the\n * 30-day lifetime cap is checked too.\n */\n issuedAt?: bigint | number | string;\n}\n\n/** Pass the session's fields directly, e.g. when they were carried through your own types. */\nexport interface VerifyAttestationSessionFields extends VerifyAttestationSessionBase {\n /** `docHash` exactly as the session delivered it. Compared case-insensitively. */\n docHash: Hex;\n /** Session expiry, unix seconds, in any of the forms the wire uses. */\n deadline: bigint | number | string;\n}\n\n/** Hand over the `POST /attestations` response itself and let the SDK read it. */\nexport interface VerifyAttestationSessionResponseParams extends VerifyAttestationSessionBase {\n /** The session response as received. `docHash` is read from `typedData.message`. */\n session: AttestationSessionResponseLike;\n}\n\n/**\n * What {@link verifyAttestationSession} needs: the rendered bytes, plus either the session response\n * itself or the two fields read out of it.\n */\nexport type VerifyAttestationSessionParams =\n VerifyAttestationSessionFields | VerifyAttestationSessionResponseParams;\n\n/**\n * The one pre-flight call a UI should make before prompting the wallet.\n *\n * Combines the two questions worth asking while the investor is still looking at the document: is\n * this still the document the session commits to ({@link assertDocumentMatchesHash}), and is the\n * session still signable (`assertSessionWindow`, so the lifetime and expiry rules live in exactly\n * one place)?\n *\n * Hand it the session response as it arrived, and the fields are read from the copies that are\n * actually signed:\n *\n * ```ts\n * const session = await client.http.post('/attestations', { wallet, docHash }); // 201 body\n *\n * verifyAttestationSession({\n * content: pdfBytes, // the same executed bytes that were hashed into `docHash` above\n * session,\n * now: BigInt(Math.floor(Date.now() / 1000)), // optional; also checks expiry\n * });\n *\n * const signature = await walletClient.signTypedData({\n * account,\n * ...toViemTypedData(session.typedData, { expectedAttestor }),\n * });\n * ```\n *\n * viem would take `session.typedData` unchanged, but `toViemTypedData` is the shape to reach for:\n * it validates `primaryType`, the `DocumentAcceptance` field list and its ORDER, and the domain,\n * and `expectedAttestor` / `expectedChainId` pin the prompt to the deployment this integration\n * trusts. This function checks the document; that one checks the payload built around it.\n *\n * The fields may also be passed directly — `{ content, docHash, deadline }` — when they have been\n * carried through an app's own types. Either way `docHash` comes from `typedData.message` in\n * preference to the top-level echo, since that is the copy the wallet signs, and `deadline` is\n * coerced from the top-level number (a decimal string or a `bigint` works too).\n *\n * The document check runs first on purpose. When a session is both expired and mismatched, the\n * mismatch is the finding that matters: an expiry is a benign retry, whereas a hash that no longer\n * matches the bytes on screen means the backend is not committing to the document being signed,\n * and no amount of re-issuing sessions will fix that.\n *\n * ### Safes, ERC-1271, and the session TTL\n *\n * This is where an expired session surfaces, so it is also where too short a TTL shows up. Sessions\n * default to a 3600-second TTL (env-tunable up to the contract's 30-day `MAX_ATTESTATION_LIFETIME`\n * cap). An ERC-1271 signer — a Safe — produces no signature until enough owners have confirmed, and\n * that ceremony routinely outlasts an hour. The `deadline` must outlive it: issuers whose investors\n * sign from Safes should have the TTL raised, or the session lapses mid-ceremony and the investor\n * is asked to start over. An `AttestationExpired` from this function on a Safe flow is a TTL\n * configuration finding, not an investor mistake.\n *\n * What this does *not* do: verify the server's half of the authorization. That signature is never\n * given to the client — checking it is the attestor's job, on-chain.\n *\n * The clock checks stay opt-in — omit `now` and a skewed device clock cannot refuse a session the\n * chain would have accepted. Pass `BigInt(Math.floor(Date.now() / 1000))` to enable them.\n *\n * @throws {OpacityAttestationError} See {@link assertDocumentMatchesHash}, plus\n * `AttestationExpired`, `AttestationDeadlineTooFar`, `AttestationIssuedInFuture`, and\n * `MalformedInput` for a session whose `deadline` copies disagree or cannot be read.\n */\nexport function verifyAttestationSession(params: VerifyAttestationSessionParams): void {\n const { docHash, deadline } =\n 'session' in params\n ? readSessionFields(params.session)\n : { docHash: params.docHash, deadline: toUnixSeconds(params.deadline, 'deadline') };\n\n assertDocumentMatchesHash(params.content, docHash);\n\n assertSessionWindow(\n {\n issuedAt:\n params.issuedAt === undefined ? undefined : toUnixSeconds(params.issuedAt, 'issuedAt'),\n deadline,\n },\n params.now === undefined ? {} : { now: params.now },\n );\n}\n","import { hashTypedData } from 'viem';\nimport type { Address, Hex } from 'viem';\n\nimport {\n DOCUMENT_ACCEPTANCE_PRIMARY_TYPE,\n DOCUMENT_ACCEPTANCE_TYPES,\n DOCUMENT_ATTESTOR_DOMAIN_NAME,\n DOCUMENT_ATTESTOR_DOMAIN_VERSION,\n EIP712_DOMAIN_TYPE,\n} from './constants.js';\nimport type { BuildDocumentAcceptanceTypedDataParams } from './types.js';\nimport {\n assertAddress,\n assertChainId,\n assertDocHash,\n assertNonce,\n assertSessionWindow,\n} from './validate.js';\n\n/** The EIP-712 domain of a `DocumentAttestor` deployment. No `salt` — see `constants.ts`. */\nexport interface DocumentAttestorDomain {\n name: typeof DOCUMENT_ATTESTOR_DOMAIN_NAME;\n version: typeof DOCUMENT_ATTESTOR_DOMAIN_VERSION;\n chainId: number;\n verifyingContract: Address;\n}\n\n/** What the investor's wallet is asked to sign. */\nexport interface DocumentAcceptanceMessage {\n nonce: Hex;\n docHash: Hex;\n deadline: bigint;\n}\n\n/**\n * A viem/wagmi-native EIP-712 payload.\n *\n * `types` deliberately omits `EIP712Domain`: viem derives the domain type from the `domain` object\n * when the entry is absent, and ethers v6 throws if it is present. Omitting it is only safe\n * *because* those two derive it — a raw `eth_signTypedData_v4` provider does not, so use\n * {@link toEip712JsonPayload} / {@link toEip712Json} for that path. Never hand this shape to\n * `eth_signTypedData_v4` directly; see {@link toEip712JsonPayload} for what silently goes wrong.\n */\nexport interface DocumentAcceptanceTypedData {\n domain: DocumentAttestorDomain;\n types: typeof DOCUMENT_ACCEPTANCE_TYPES;\n primaryType: typeof DOCUMENT_ACCEPTANCE_PRIMARY_TYPE;\n message: DocumentAcceptanceMessage;\n}\n\n/**\n * Builds the EIP-712 payload the investor's wallet signs to accept a document.\n *\n * This is a signature prompt, not a transaction: it costs no gas and broadcasts nothing. It is\n * also the investor's *only* wallet interaction — the resulting signature is posted back to the\n * backend, which pairs it with the server's half and relays `buildAttestDocumentTransaction` from\n * a gas-sponsor key. The investor never sends a transaction and never needs to hold gas.\n *\n * The returned object is what viem and wagmi want as-is:\n *\n * ```ts\n * const typedData = buildDocumentAcceptanceTypedData({\n * attestorAddress, chainId, nonce, docHash, deadline, issuedAt,\n * });\n *\n * const signature = await walletClient.signTypedData({ account, ...typedData }); // viem\n * const signature = await signTypedDataAsync(typedData); // wagmi\n * ```\n *\n * For other stacks, pass it through {@link toEthersTypedData} or {@link toEip712JsonPayload}.\n *\n * @throws {import('../errors.js').OpacityAttestationError} when a parameter would produce a\n * signature the attestor is guaranteed to reject.\n */\nexport function buildDocumentAcceptanceTypedData(\n params: BuildDocumentAcceptanceTypedDataParams,\n): DocumentAcceptanceTypedData {\n const verifyingContract = assertAddress(params.attestorAddress, 'attestorAddress');\n const chainId = assertChainId(params.chainId);\n const nonce = assertNonce(params.nonce);\n const docHash = assertDocHash(params.docHash);\n\n // `issuedAt` is not signed by the investor, but when the caller has it we can refuse to raise a\n // prompt for a session that would be rejected at redemption anyway.\n assertSessionWindow(\n { issuedAt: params.issuedAt, deadline: params.deadline },\n params.now === undefined ? {} : { now: params.now },\n );\n\n return {\n domain: {\n name: DOCUMENT_ATTESTOR_DOMAIN_NAME,\n version: DOCUMENT_ATTESTOR_DOMAIN_VERSION,\n chainId,\n verifyingContract,\n },\n types: DOCUMENT_ACCEPTANCE_TYPES,\n primaryType: DOCUMENT_ACCEPTANCE_PRIMARY_TYPE,\n message: { nonce, docHash, deadline: params.deadline },\n };\n}\n\n/**\n * The EIP-712 digest the wallet actually signs.\n *\n * Useful for logging or for checking a returned signature offline. Note that an ERC-1271 wallet's\n * signature is not recoverable to an address, so digest comparison is not a substitute for the\n * on-chain `SignatureChecker` result.\n */\nexport function hashDocumentAcceptance(typedData: DocumentAcceptanceTypedData): Hex {\n return hashTypedData(typedData);\n}\n\n/** ethers v6 `signer.signTypedData(domain, types, value)` takes three positional arguments. */\nexport interface EthersTypedData {\n domain: DocumentAttestorDomain;\n /**\n * A MUTABLE copy of {@link DOCUMENT_ACCEPTANCE_TYPES}, not the readonly constant itself:\n * ethers v6 types `signTypedData`'s second argument as `Record<string, TypedDataField[]>`\n * (mutable arrays), so the SDK's deeply-readonly `as const` shape fails TS2345 when passed\n * directly. Structurally typed rather than importing ethers' `TypedDataField` — ethers is not\n * a dependency of this package, and its types must not leak into the published declarations.\n */\n types: { DocumentAcceptance: { name: string; type: string }[] };\n value: DocumentAcceptanceMessage;\n}\n\n/**\n * Reshapes the payload for ethers v6.\n *\n * ```ts\n * const { domain, types, value } = toEthersTypedData(typedData);\n * const signature = await signer.signTypedData(domain, types, value);\n * ```\n *\n * `types` still omits `EIP712Domain` — ethers infers the domain from its first argument and throws\n * if the type is also declared.\n */\nexport function toEthersTypedData(typedData: DocumentAcceptanceTypedData): EthersTypedData {\n return {\n domain: typedData.domain,\n types: {\n DocumentAcceptance: typedData.types.DocumentAcceptance.map((field) => ({ ...field })),\n },\n value: typedData.message,\n };\n}\n\n/** A JSON-safe `eth_signTypedData_v4` payload: no bigints, `EIP712Domain` declared. */\nexport interface Eip712JsonPayload {\n types: Record<string, ReadonlyArray<{ readonly name: string; readonly type: string }>>;\n primaryType: string;\n domain: {\n name: string;\n version: string;\n chainId: number;\n verifyingContract: Address;\n };\n /** `deadline` is a decimal string, not a bigint — JSON cannot carry one. */\n message: {\n nonce: Hex;\n docHash: Hex;\n deadline: string;\n };\n}\n\n/**\n * Reshapes the payload for a raw EIP-1193 provider.\n *\n * This is the lowest common denominator every wallet connection service bottoms out at — MetaMask,\n * WalletConnect, Coinbase Wallet, Privy, Dynamic, and the Safe Apps SDK all accept it:\n *\n * ```ts\n * const signature = await provider.request({\n * method: 'eth_signTypedData_v4',\n * params: [account, toEip712Json(typedData)],\n * });\n * ```\n *\n * Two differences from the viem shape are required by the JSON-RPC method, not stylistic:\n * `EIP712Domain` must be declared in `types`, and `uint256` values are decimal strings because JSON\n * cannot carry a bigint.\n *\n * **Declaring `EIP712Domain` is load-bearing, and its absence fails SILENTLY.** MetaMask's\n * `eth-sig-util` sanitises the payload with `{ EIP712Domain: [], ...types }`, so a payload that\n * omits the entry does not error — it hashes the domain as `keccak256(\"EIP712Domain()\")`, a type\n * with NO fields, and the digest moves:\n *\n * ```text\n * EIP712Domain declared 0x91feb0709c4ebdff9ccc57b12b26c50936eae7973f67c6d23780fcfdbda3f410 ✓\n * EIP712Domain defaulted [] 0x82ada7044278f3b529058b2dac44bb987f078c23b15195e1dca77110f0c91691 ✗\n * ```\n *\n * The wallet then returns a perfectly well-formed signature over the WRONG digest, which the\n * backend rejects at its simulate step with `InvalidUserSignature` — far from the cause, and\n * indistinguishable to the investor from \"the wallet is broken\". Declaring the type does not touch\n * the `DocumentAcceptance` struct hash; it only makes the DOMAIN hash correct. So this is strictly\n * a fix, never a behaviour change, and the `EIP712Domain` entry must not be removed from this\n * function on the theory that the wallet will derive it.\n */\nexport function toEip712JsonPayload(typedData: DocumentAcceptanceTypedData): Eip712JsonPayload {\n return {\n types: {\n EIP712Domain: EIP712_DOMAIN_TYPE,\n ...typedData.types,\n },\n primaryType: typedData.primaryType,\n domain: {\n name: typedData.domain.name,\n version: typedData.domain.version,\n chainId: typedData.domain.chainId,\n verifyingContract: typedData.domain.verifyingContract,\n },\n message: {\n nonce: typedData.message.nonce,\n docHash: typedData.message.docHash,\n deadline: typedData.message.deadline.toString(),\n },\n };\n}\n\n/**\n * {@link toEip712JsonPayload}, serialised — the second `eth_signTypedData_v4` parameter.\n *\n * A backend-issued payload reaches this through `toEip712Json(toViemTypedData(session.typedData))`:\n * `toViemTypedData` validates and normalises the server's JSON, and this re-serialises it with\n * `EIP712Domain` declared.\n *\n * That round trip is optional on this path. mobile-api already declares `EIP712Domain` and already\n * sends `deadline` as a decimal string, so `session.typedData` is a correct\n * `eth_signTypedData_v4` payload exactly as it arrives — nothing is corrupted by sending it\n * directly. Going through `toViemTypedData` buys validation (`primaryType`, the field list and its\n * ORDER, the domain) and `expectedAttestor` / `expectedChainId` pinning, and it re-declares\n * `EIP712Domain` from this SDK's own constant rather than trusting the wire's copy. Prefer it, but\n * do not treat the direct route as broken.\n */\nexport function toEip712Json(typedData: DocumentAcceptanceTypedData): string {\n return JSON.stringify(toEip712JsonPayload(typedData));\n}\n","import { encodeFunctionData, numberToHex } from 'viem';\nimport type { Address, Hex } from 'viem';\n\nimport { documentAttestorAbi } from './abi.js';\nimport type { BuildAttestDocumentTransactionParams, TransactionRequest } from './types.js';\nimport {\n assertAddress,\n assertChainId,\n assertDocHash,\n assertNonce,\n assertServerSignature,\n assertSessionWindow,\n assertTraitId,\n assertUserSignature,\n} from './validate.js';\n\n/** `attestDocument` arguments, in the contract's positional order. */\ntype AttestDocumentArgs = readonly [\n wallet: Address,\n traitId: Hex,\n docHash: Hex,\n nonce: Hex,\n issuedAt: bigint,\n deadline: bigint,\n serverSignature: Hex,\n userSignature: Hex,\n];\n\n/**\n * Validates and orders the `attestDocument` arguments.\n *\n * The ordering is the reason this is centralised: the function's parameter order\n * (`wallet, traitId, docHash, nonce, …`) is NOT the order of the EIP-712 type\n * (`nonce, docHash, wallet, traitId, …`), and the first four are all `bytes32`/`address`, so a\n * transposition encodes cleanly and fails only on-chain.\n */\nfunction toArgs(params: BuildAttestDocumentTransactionParams): AttestDocumentArgs {\n const wallet = assertAddress(params.wallet, 'wallet');\n const traitId = assertTraitId(params.traitId);\n const docHash = assertDocHash(params.docHash);\n const nonce = assertNonce(params.nonce);\n const serverSignature = assertServerSignature(params.serverSignature);\n const userSignature = assertUserSignature(params.userSignature);\n\n assertSessionWindow(\n { issuedAt: params.issuedAt, deadline: params.deadline },\n params.now === undefined ? {} : { now: params.now },\n );\n\n return [\n wallet,\n traitId,\n docHash,\n nonce,\n params.issuedAt,\n params.deadline,\n serverSignature,\n userSignature,\n ];\n}\n\n/**\n * Builds the `attestDocument` transaction that redeems a signed session on-chain.\n *\n * This is the relay half of the flow, so its consumer is the backend, not the browser. The\n * investor's entire involvement is the off-chain signature from\n * {@link import('./typed-data.js').buildDocumentAcceptanceTypedData} — one wallet prompt, no\n * transaction, no gas. The relayer pairs that signature with the server's half and broadcasts this\n * call from a gas-sponsor key.\n *\n * The call is permissionless — `msg.sender` is never trusted and never recorded — so `from` is\n * optional, and when supplied it names the sponsor account paying for gas. The descriptor works\n * as-is with viem, wagmi and ethers v6:\n *\n * ```ts\n * const tx = buildAttestDocumentTransaction({ ... });\n *\n * await walletClient.sendTransaction({ account, ...tx }); // viem\n * sendTransaction(tx); // wagmi\n * await signer.sendTransaction(tx); // ethers v6\n * ```\n *\n * See {@link toWriteContractRequest} for wagmi's `useWriteContract`, and\n * {@link toJsonRpcTransaction} for a raw EIP-1193 provider.\n *\n * @throws {import('../errors.js').OpacityAttestationError} when a parameter would produce a\n * transaction the attestor is guaranteed to revert.\n */\nexport function buildAttestDocumentTransaction(\n params: BuildAttestDocumentTransactionParams,\n): TransactionRequest {\n const to = assertAddress(params.attestorAddress, 'attestorAddress');\n const chainId = assertChainId(params.chainId);\n const from = params.from === undefined ? undefined : assertAddress(params.from, 'from');\n\n const request: TransactionRequest = {\n to,\n data: encodeFunctionData({\n abi: documentAttestorAbi,\n functionName: 'attestDocument',\n args: toArgs(params),\n }),\n value: 0n,\n chainId,\n };\n\n return from === undefined ? request : { ...request, from };\n}\n\n/** The ABI-level form of the same call, for viem `writeContract` / wagmi `useWriteContract`. */\nexport interface WriteContractRequest {\n address: Address;\n abi: typeof documentAttestorAbi;\n functionName: 'attestDocument';\n args: AttestDocumentArgs;\n chainId: number;\n}\n\n/**\n * The same call expressed as contract arguments rather than calldata.\n *\n * Preferred by wagmi users, and it gives viem the ABI it needs to decode a revert into a named\n * error (`NotTraitWriter`, `NonceAlreadyUsed`, …) instead of a bare selector.\n *\n * ```ts\n * writeContract(toWriteContractRequest(params));\n * ```\n */\nexport function toWriteContractRequest(\n params: BuildAttestDocumentTransactionParams,\n): WriteContractRequest {\n return {\n address: assertAddress(params.attestorAddress, 'attestorAddress'),\n abi: documentAttestorAbi,\n functionName: 'attestDocument',\n args: toArgs(params),\n chainId: assertChainId(params.chainId),\n };\n}\n\n/** An `eth_sendTransaction` parameter object — every numeric field hex-encoded. */\nexport interface JsonRpcTransaction {\n from: Address;\n to: Address;\n data: Hex;\n value: Hex;\n chainId: Hex;\n}\n\n/**\n * Reshapes the descriptor for a raw EIP-1193 provider.\n *\n * `eth_sendTransaction` demands a mandatory `from` and hex-quantity encoding; the chain-agnostic\n * descriptor has neither (its own `from` is optional and its quantities are bigints), so the\n * sending account is passed explicitly here — under relay, that is the gas sponsor:\n *\n * ```ts\n * const hash = await provider.request({\n * method: 'eth_sendTransaction',\n * params: [toJsonRpcTransaction(tx, { from: relayer })],\n * });\n * ```\n */\nexport function toJsonRpcTransaction(\n transaction: TransactionRequest,\n options: { from: Address },\n): JsonRpcTransaction {\n return {\n from: assertAddress(options.from, 'from'),\n to: transaction.to,\n data: transaction.data,\n value: numberToHex(transaction.value),\n chainId: numberToHex(transaction.chainId),\n };\n}\n","import {\n BaseError,\n decodeErrorResult,\n decodeFunctionResult,\n encodeFunctionData,\n encodePacked,\n ExecutionRevertedError,\n isHex,\n keccak256,\n size,\n toBytes,\n} from 'viem';\nimport type { Address, Hex } from 'viem';\n\nimport { OpacityConfigError } from '../errors.js';\nimport type { TransactionRequest } from './types.js';\nimport { assertAddress, assertBoolean, assertChainId, assertTraitId } from './validate.js';\n\n/**\n * Minimal ABI for `SandboxAllowlistRegistry` — the SANDBOX-ONLY registry implementation.\n *\n * The sandbox implementation is the stock `AllowlistRegistry` plus permissionless, sandbox-only\n * helpers (`sandboxAddSelf()`, v2's `sandboxSetSelfTrait()`, and v3's `sandboxRegisterIssuer()`).\n * It runs behind the registry proxy in a sandbox deployment, so there is no separate helper address: this ABI is used against\n * the `allowlistRegistry` address from discovery or the built-in `SANDBOX_DEPLOYMENTS` entry, and\n * only works while that proxy exposes the sandbox implementation.\n *\n * Covers the writes this module builds (`sandboxAddSelf`, `sandboxSetSelfTrait`), the marker view\n * that identifies the sandbox implementation behind a proxy (`sandboxVersion`), the reads a\n * consumer verifies results with (`isAllowed`, `getUserId`, `hasGlobalTrait`), their emitted trait\n * event, and every error reachable from those writes:\n *\n * - `EnforcedPause()` — the `whenNotPaused` modifier (OpenZeppelin `PausableUpgradeable`) when the\n * registry is paused.\n * - `AddressNotEligible(address)` — the parent `_addToAllowlist` when the sender's entry is in a\n * TERMINAL status (`COMPLIANCE_REMOVAL` or `MIGRATED`); those cannot be re-added by any path.\n * - `AddressNotVerified(address)` — `sandboxSetSelfTrait` requires its caller to be verified first.\n * - `InvalidUserId()` — the caller has no usable userId binding.\n * - `InvalidTraitId()` — `traitId` is zero.\n */\nexport const sandboxAllowlistRegistryAbi = [\n {\n type: 'function',\n name: 'sandboxRegisterIssuer',\n stateMutability: 'nonpayable',\n inputs: [],\n outputs: [],\n },\n {\n type: 'function',\n name: 'sandboxAddSelf',\n stateMutability: 'nonpayable',\n inputs: [],\n outputs: [],\n },\n {\n type: 'function',\n name: 'sandboxSetSelfTrait',\n stateMutability: 'nonpayable',\n inputs: [\n { name: 'traitId', type: 'bytes32' },\n { name: 'enabled', type: 'bool' },\n ],\n outputs: [],\n },\n\n // ── Marker ───────────────────────────────────────────────────────────────────────────────────\n //\n // Present ONLY on the sandbox implementation, so tooling can tell it apart from the stock\n // `AllowlistRegistry` behind a proxy with one staticcall instead of a storage probe. The marker\n // landed as version 1 in contracts commit 281e9c5; the self-trait surface advances it to 2.\n // Sandbox v3 adds issuer self-registration. Older implementations deployed before the marker\n // revert on it while `sandboxAddSelf()` works; `probeSandboxRegistry` copes with both.\n {\n type: 'function',\n name: 'sandboxVersion',\n stateMutability: 'pure',\n inputs: [],\n outputs: [{ type: 'uint256' }],\n },\n\n // ── Reads ────────────────────────────────────────────────────────────────────────────────────\n {\n type: 'function',\n name: 'isAllowed',\n stateMutability: 'view',\n inputs: [{ name: 'account', type: 'address' }],\n outputs: [{ type: 'bool' }],\n },\n {\n type: 'function',\n name: 'getUserId',\n stateMutability: 'view',\n inputs: [{ name: 'account', type: 'address' }],\n outputs: [{ type: 'bytes32' }],\n },\n {\n type: 'function',\n name: 'hasGlobalTrait',\n stateMutability: 'view',\n inputs: [\n { name: 'userId', type: 'bytes32' },\n { name: 'traitId', type: 'bytes32' },\n ],\n outputs: [{ type: 'bool' }],\n },\n\n // ── Events ───────────────────────────────────────────────────────────────────────────────────\n {\n type: 'event',\n name: 'GlobalTraitSet',\n anonymous: false,\n inputs: [\n { name: 'userId', type: 'bytes32', indexed: true },\n { name: 'traitId', type: 'bytes32', indexed: true },\n { name: 'enabled', type: 'bool', indexed: false },\n { name: 'updatedBy', type: 'address', indexed: false },\n ],\n },\n\n // ── Errors reachable from the sandbox writes ─────────────────────────────────────────────────\n { type: 'error', name: 'EnforcedPause', inputs: [] },\n { type: 'error', name: 'AddressNotEligible', inputs: [{ name: 'account', type: 'address' }] },\n { type: 'error', name: 'AddressNotVerified', inputs: [{ name: 'account', type: 'address' }] },\n { type: 'error', name: 'InvalidUserId', inputs: [] },\n { type: 'error', name: 'InvalidTraitId', inputs: [] },\n] as const;\n\n/**\n * What `sandboxVersion()` returns on the SDK's target sandbox implementation source.\n *\n * Mirrors the `return 3` in the deployed `SandboxAllowlistRegistry.sol`. A lower live version\n * exposes fewer sandbox capabilities; a higher one is a newer surface this SDK may not know yet.\n */\nexport const SANDBOX_IMPLEMENTATION_VERSION = 3n;\n\n/**\n * Named trait ids used by the current sandbox product flow.\n *\n * `sandboxSetSelfTrait` itself accepts ANY non-zero `bytes32`; these are conveniences, not an\n * allowlist. `mmfDocumentSigned` is specifically the current MMF subscription document version.\n * Use `documentTraitId(<versioned canonical name>)` for another document or offering.\n */\nexport const SANDBOX_TRAIT_IDS = Object.freeze({\n /** `keccak256(\"trait.accredited\")` — the contracts' canonical accredited-investor trait. */\n accreditedInvestor: keccak256(toBytes('trait.accredited')),\n /** `keccak256(\"doc.mmf.subscription.v1\")` — the current MMF subscription document trait. */\n mmfDocumentSigned: keccak256(toBytes('doc.mmf.subscription.v1')),\n} as const);\n\n/**\n * Which registry proxy, on which chain, and optionally which wallet sends.\n *\n * Unlike the attestation flow there is no separate helper contract to point at: `registryAddress`\n * is exactly the sandbox deployment's `allowlistRegistry` proxy returned by the discovery endpoint\n * (`GET /chains/:chain_id/attestor`) — or, for a chain with a built-in entry,\n * `SANDBOX_DEPLOYMENTS[chainId].allowlistRegistry`.\n */\nexport interface BuildSandboxAddSelfTransactionParams {\n /** The allowlist-registry PROXY address — the same one discovery returns. */\n registryAddress: Address;\n /** Chain the registry proxy is deployed on. */\n chainId: number;\n /**\n * Optional expected sender recorded as JSON-RPC `from`. If supplied it MUST be the investor's\n * own wallet. A viem caller must ALSO pass the same wallet as `account`; prefer the ABI-level\n * builder when account binding is desired.\n */\n from?: Address;\n}\n\n/**\n * Builds the `sandboxAddSelf()` transaction — a SANDBOX-ONLY, permissionless KYC bypass.\n *\n * **SANDBOX ONLY.** `sandboxAddSelf` exists only on the `SandboxAllowlistRegistry` implementation,\n * a deliberate, total KYC bypass for throwaway sandbox deployments. It must NEVER point at a\n * production registry; on production implementations this calldata reverts with an unknown\n * selector.\n *\n * **The SENDER is who gets allowlisted.** This is the exact opposite of `attestDocument`'s\n * permissionless relay: the contract allowlists `msg.sender`, so this transaction CANNOT be\n * relayed on an investor's behalf. The investor's own wallet must send it, and that wallet pays\n * the gas.\n *\n * `registryAddress` is the same allowlist-registry proxy discovery returns (`allowlistRegistry`\n * from `GET /chains/:chain_id/attestor`) — same address, same events.\n *\n * On success the sender holds a VERIFIED allowlist entry stamped with the registry's default\n * expiry window, and on the FIRST call the wallet is bound to the deterministic userId\n * {@link sandboxUserId} computes. With viem, pass the investor explicitly as `account` when\n * sending; the raw descriptor's `from` is not an account-selection mechanism. See\n * {@link toSandboxAddSelfWriteContractRequest} for an ABI-level request whose `account` is bound,\n * and `toJsonRpcTransaction` from `transaction.ts` for a raw EIP-1193 provider.\n *\n * @throws {import('../errors.js').OpacityAttestationError} when `registryAddress`, `chainId` or\n * `from` is malformed or zero.\n */\nexport function buildSandboxAddSelfTransaction(\n params: BuildSandboxAddSelfTransactionParams,\n): TransactionRequest {\n const to = assertAddress(params.registryAddress, 'registryAddress');\n const chainId = assertChainId(params.chainId);\n const from = params.from === undefined ? undefined : assertAddress(params.from, 'from');\n\n const request: TransactionRequest = {\n to,\n data: SANDBOX_ADD_SELF_CALLDATA,\n value: 0n,\n chainId,\n };\n\n return from === undefined ? request : { ...request, from };\n}\n\n/** The ABI-level form of the same call, for viem `writeContract` / wagmi `useWriteContract`. */\nexport interface SandboxAddSelfWriteContractRequest {\n address: Address;\n abi: typeof sandboxAllowlistRegistryAbi;\n functionName: 'sandboxAddSelf';\n args: readonly [];\n chainId: number;\n /** Present only when the caller pinned a `from` — the investor wallet that must send. */\n account?: Address;\n}\n\n/**\n * The same SANDBOX-ONLY call expressed as contract arguments rather than calldata.\n *\n * Preferred by wagmi users, and it gives viem the ABI it needs to decode a revert into a named\n * error (`EnforcedPause`, `AddressNotEligible`) instead of a bare selector. All the warnings on\n * {@link buildSandboxAddSelfTransaction} apply verbatim — sandbox only, and whichever account\n * sends this request is the one that gets allowlisted; a supplied `from` becomes `account`.\n *\n * ```ts\n * writeContract(toSandboxAddSelfWriteContractRequest({ registryAddress, chainId }));\n * ```\n */\nexport function toSandboxAddSelfWriteContractRequest(\n params: BuildSandboxAddSelfTransactionParams,\n): SandboxAddSelfWriteContractRequest {\n const address = assertAddress(params.registryAddress, 'registryAddress');\n const chainId = assertChainId(params.chainId);\n const account = params.from === undefined ? undefined : assertAddress(params.from, 'from');\n\n const request: SandboxAddSelfWriteContractRequest = {\n address,\n abi: sandboxAllowlistRegistryAbi,\n functionName: 'sandboxAddSelf',\n args: [],\n chainId,\n };\n\n return account === undefined ? request : { ...request, account };\n}\n\n/** Sandbox v3 issuer registration uses the same caller/registry binding as self-onboarding. */\nexport type BuildSandboxRegisterIssuerTransactionParams = BuildSandboxAddSelfTransactionParams;\n\n/** Onboard and authorize the sending wallet as an issuer, without an operator transaction. */\nexport function buildSandboxRegisterIssuerTransaction(\n params: BuildSandboxRegisterIssuerTransactionParams,\n): TransactionRequest {\n return {\n ...buildSandboxAddSelfTransaction(params),\n data: encodeFunctionData({\n abi: sandboxAllowlistRegistryAbi,\n functionName: 'sandboxRegisterIssuer',\n }),\n };\n}\n\n/** ABI-level registration request for the issuer's own wallet. Requires a v3 registry. */\nexport type SandboxRegisterIssuerWriteContractRequest = Omit<\n SandboxAddSelfWriteContractRequest,\n 'functionName'\n> & { functionName: 'sandboxRegisterIssuer' };\n\nexport function toSandboxRegisterIssuerWriteContractRequest(\n params: BuildSandboxRegisterIssuerTransactionParams,\n): SandboxRegisterIssuerWriteContractRequest {\n return { ...toSandboxAddSelfWriteContractRequest(params), functionName: 'sandboxRegisterIssuer' };\n}\n\n/** Inputs shared by the calldata and ABI-level `sandboxSetSelfTrait` builders. */\nexport interface BuildSandboxSetSelfTraitTransactionParams {\n /** The allowlist-registry PROXY running `SandboxAllowlistRegistry` v2 or newer. */\n registryAddress: Address;\n /** Chain the registry proxy is deployed on. */\n chainId: number;\n /** Any non-zero global trait id. See {@link SANDBOX_TRAIT_IDS} for current presets. */\n traitId: Hex;\n /** `true` grants the trait; `false` clears it. */\n enabled: boolean;\n /**\n * Optional expected sender as JSON-RPC `from`; viem callers must also select it as `account`.\n * This wallet's own userId receives (or loses) the trait.\n */\n from?: Address;\n}\n\n/**\n * Builds a `sandboxSetSelfTrait(bytes32,bool)` transaction for the caller's own global trait.\n *\n * **SANDBOX v2 OR NEWER.** This is a deliberate KYC/document/compliance bypass and is absent from the\n * production registry and sandbox v1. The sending wallet must already have VERIFIED status —\n * normally by sending {@link buildSandboxAddSelfTransaction} first — and the trait is written to\n * that wallet's existing userId. There is deliberately no combined add+trait transaction.\n *\n * `traitId` can be any non-zero `bytes32`. `enabled: true` grants it; `enabled: false` clears it.\n * Both directions emit `GlobalTraitSet` with `updatedBy` equal to the sending wallet.\n *\n * @throws {import('../errors.js').OpacityAttestationError} when an address, `chainId`, `traitId`,\n * or `enabled` is malformed; zero `traitId` is rejected locally as `InvalidTraitId`.\n */\nexport function buildSandboxSetSelfTraitTransaction(\n params: BuildSandboxSetSelfTraitTransactionParams,\n): TransactionRequest {\n const to = assertAddress(params.registryAddress, 'registryAddress');\n const chainId = assertChainId(params.chainId);\n const traitId = assertTraitId(params.traitId);\n const enabled = assertBoolean(params.enabled, 'enabled');\n const from = params.from === undefined ? undefined : assertAddress(params.from, 'from');\n\n const request: TransactionRequest = {\n to,\n data: encodeFunctionData({\n abi: sandboxAllowlistRegistryAbi,\n functionName: 'sandboxSetSelfTrait',\n args: [traitId, enabled],\n }),\n value: 0n,\n chainId,\n };\n\n return from === undefined ? request : { ...request, from };\n}\n\n/** ABI-level form of `sandboxSetSelfTrait`, for viem/wagmi `writeContract`. */\nexport interface SandboxSetSelfTraitWriteContractRequest {\n address: Address;\n abi: typeof sandboxAllowlistRegistryAbi;\n functionName: 'sandboxSetSelfTrait';\n args: readonly [traitId: Hex, enabled: boolean];\n chainId: number;\n /** Present only when the caller pins the wallet whose own trait will change. */\n account?: Address;\n}\n\n/**\n * Expresses the same sandbox-v2 trait write as ABI + args for viem/wagmi.\n *\n * All warnings and validation on {@link buildSandboxSetSelfTraitTransaction} apply. A supplied\n * `from` becomes `account`; that account must send the transaction and is the identity modified.\n */\nexport function toSandboxSetSelfTraitWriteContractRequest(\n params: BuildSandboxSetSelfTraitTransactionParams,\n): SandboxSetSelfTraitWriteContractRequest {\n const address = assertAddress(params.registryAddress, 'registryAddress');\n const chainId = assertChainId(params.chainId);\n const traitId = assertTraitId(params.traitId);\n const enabled = assertBoolean(params.enabled, 'enabled');\n const account = params.from === undefined ? undefined : assertAddress(params.from, 'from');\n\n const request: SandboxSetSelfTraitWriteContractRequest = {\n address,\n abi: sandboxAllowlistRegistryAbi,\n functionName: 'sandboxSetSelfTrait',\n args: [traitId, enabled],\n chainId,\n };\n\n return account === undefined ? request : { ...request, account };\n}\n\n/**\n * The deterministic userId `sandboxAddSelf` binds a wallet to on its FIRST call:\n * `keccak256(abi.encodePacked(\"sandbox.user.\", wallet))` — the 13 UTF-8 bytes of the prefix\n * concatenated with the 20 address bytes, PACKED, not ABI-padded.\n *\n * Checksum-insensitive: the address is normalised before hashing, so any casing of the same\n * address produces the same id.\n *\n * This predicts the userId ONLY for the first-call binding. A wallet previously onboarded through\n * another path (TEE batch, compliance admin, …) already has a userId, and `sandboxAddSelf` keeps\n * that existing binding — read the real one back with `getUserId(wallet)` rather than assuming\n * this value.\n *\n * @throws {import('../errors.js').OpacityAttestationError} when `wallet` is malformed or zero.\n */\nexport function sandboxUserId(wallet: Address): Hex {\n const normalized = assertAddress(wallet, 'wallet');\n return keccak256(encodePacked(['string', 'address'], ['sandbox.user.', normalized]));\n}\n\n// ─── Detection: is the sandbox implementation attached behind a registry proxy? ───────────────\n\n/** `sandboxAddSelf()` takes no arguments, so its selector is the whole calldata. */\nconst SANDBOX_ADD_SELF_CALLDATA: Hex = encodeFunctionData({\n abi: sandboxAllowlistRegistryAbi,\n functionName: 'sandboxAddSelf',\n args: [],\n});\n\n/** Likewise for the marker view. */\nconst SANDBOX_VERSION_CALLDATA: Hex = encodeFunctionData({\n abi: sandboxAllowlistRegistryAbi,\n functionName: 'sandboxVersion',\n args: [],\n});\n\n/**\n * The `eth_call` sender the legacy probe impersonates when the caller pins none. An `eth_call`\n * sends nothing and changes nothing, so any address will do; this one is chosen to be nobody's,\n * so its allowlist entry cannot be in a terminal status that would skew the answer.\n */\nconst PROBE_SENDER: Address = '0x1000000000000000000000000000000000000001';\n\n/**\n * The RPC capabilities {@link probeSandboxRegistry} needs: bytecode lookup, chain identity, and\n * `eth_call`.\n *\n * A structural subset of viem's `PublicClient` — pass the public client your app already has\n * (wagmi's `usePublicClient()`, or `createPublicClient`). The SDK never opens an RPC connection\n * of its own, which is why this is a parameter and not configuration it resolves.\n */\nexport interface SandboxProbeClient {\n /** Named `getBytecode` for compatibility with the full declared viem v2 peer range. */\n getBytecode(args: { address: Address }): Promise<Hex | undefined>;\n getChainId(): Promise<number>;\n call(args: { to: Address; data: Hex; account?: Address }): Promise<{ data?: Hex | undefined }>;\n}\n\nexport interface ProbeSandboxRegistryParams {\n /** The allowlist-registry PROXY to inspect. */\n registryAddress: Address;\n /** Expected RPC chain. Required so a wrong-network reader can never produce a verdict. */\n chainId: number;\n /**\n * Sender to impersonate in the legacy `sandboxAddSelf()` `eth_call` — the investor's wallet,\n * typically, so a `self_add_revert` verdict is about THEIR entry. Defaults to a nobody address.\n * Nothing is sent either way.\n */\n from?: Address;\n}\n\n/**\n * How {@link probeSandboxRegistry} reached its verdict, most to least direct.\n *\n * - `marker` — `sandboxVersion()` answered. A sandbox implementation with the marker (source from\n * 2026-09-01 on) is attached; `version` carries the answer.\n * - `self_add_call` — the marker reverted, but an `eth_call` of `sandboxAddSelf()` from `from`\n * returned the empty data its no-output ABI requires. This is compatibility evidence for an\n * older, PRE-marker sandbox implementation, but is necessarily heuristic because a foreign\n * contract can have a permissive empty fallback.\n * - `self_add_revert` — `sandboxAddSelf()` exists but refused the probe sender with one of its own\n * errors (`EnforcedPause`, `AddressNotEligible`). The sandbox IS attached; the real transaction\n * from that sender would revert the same way right now.\n * - `not_sandbox` — the marker returned an invalid/empty answer, or both selectors reverted with no\n * sandbox registry error. A stock `AllowlistRegistry` (or something else) answers here.\n * - `no_code` — bytecode lookup proved nothing is deployed at the address.\n */\nexport type SandboxProbeEvidence =\n 'marker' | 'self_add_call' | 'self_add_revert' | 'not_sandbox' | 'no_code';\n\n/** The verdict of {@link probeSandboxRegistry}. */\nexport interface SandboxRegistryProbe {\n /** The registry that was inspected, checksummed. */\n registryAddress: Address;\n /** Whether a `SandboxAllowlistRegistry` implementation answers behind the proxy. */\n attached: boolean;\n /**\n * `sandboxVersion()` when the implementation exposes it; `null` for a pre-marker sandbox\n * implementation and for anything that is not the sandbox. Version 2 or newer is required for\n * `sandboxSetSelfTrait`.\n */\n version: bigint | null;\n /** How the verdict was reached. See {@link SandboxProbeEvidence}. */\n evidence: SandboxProbeEvidence;\n}\n\n/**\n * Asks a registry proxy, on-chain, whether the sandbox implementation is attached — BEFORE an\n * investor is prompted to send `sandboxAddSelf()`.\n *\n * The sandbox registry is upgradeable, so an address alone does not prove which implementation\n * currently answers behind it. Two read-only `eth_call`s settle it:\n *\n * 1. `sandboxVersion()` — the marker the contracts added for exactly this purpose. Present, and\n * the answer is the verdict (`marker`).\n * 2. Otherwise `sandboxAddSelf()` itself, simulated from `from`. Older sandbox implementations\n * deployed before the marker existed have the function but not the view. Its expected empty\n * return (or a sandbox-specific revert) is a compatibility signal (`self_add_call` /\n * `self_add_revert`), not cryptographic proof: a permissive fallback can imitate empty success.\n * Marker-based version detection is authoritative for v1+.\n *\n * The reader's chain is checked first, then bytecode, because a wrong network or an empty account\n * must never produce a verdict. Only an execution REVERT is treated as an answer; a transport\n * failure propagates as thrown by the client, so a flaky node never reads as \"not a sandbox\".\n *\n * ```ts\n * const probe = await probeSandboxRegistry(publicClient, {\n * registryAddress,\n * chainId: 11155111,\n * from: investor,\n * });\n * if (!probe.attached) showError('This registry is not running the sandbox implementation.');\n * ```\n *\n * @throws {import('../errors.js').OpacityAttestationError} when `registryAddress`, `chainId`, or\n * `from` is malformed or zero.\n * @throws {import('../errors.js').OpacityConfigError} when the reader is connected to a different\n * chain than `chainId`.\n * @throws whatever the RPC client throws for a non-revert failure, untouched.\n */\nexport async function probeSandboxRegistry(\n client: SandboxProbeClient,\n params: ProbeSandboxRegistryParams,\n): Promise<SandboxRegistryProbe> {\n const registryAddress = assertAddress(params.registryAddress, 'registryAddress');\n const expectedChainId = assertChainId(params.chainId);\n const from = params.from === undefined ? PROBE_SENDER : assertAddress(params.from, 'from');\n\n const actualChainId = await client.getChainId();\n if (actualChainId !== expectedChainId) {\n throw new OpacityConfigError(\n `Sandbox registry ${registryAddress} was resolved for chain ${expectedChainId}, but the ` +\n `probe RPC client is connected to chain ${actualChainId}. Pass a public client for ` +\n `chain ${expectedChainId}.`,\n );\n }\n\n const code = await client.getBytecode({ address: registryAddress });\n if (code === undefined || size(code) === 0) {\n return { registryAddress, attached: false, version: null, evidence: 'no_code' };\n }\n\n const marker = await tryCall(client, { to: registryAddress, data: SANDBOX_VERSION_CALLDATA });\n if (marker.outcome === 'returned') {\n if (marker.data === undefined || size(marker.data) === 0) {\n return { registryAddress, attached: false, version: null, evidence: 'not_sandbox' };\n }\n const version = decodeVersion(marker.data);\n return version === undefined\n ? { registryAddress, attached: false, version: null, evidence: 'not_sandbox' }\n : { registryAddress, attached: true, version, evidence: 'marker' };\n }\n\n const legacy = await tryCall(client, {\n to: registryAddress,\n data: SANDBOX_ADD_SELF_CALLDATA,\n account: from,\n });\n if (legacy.outcome === 'returned') {\n // A no-output Solidity function returns empty bytes. Non-empty data is evidence of a\n // selector-aware/permissive fallback, not `sandboxAddSelf` itself.\n return legacy.data === undefined || size(legacy.data) === 0\n ? { registryAddress, attached: true, version: null, evidence: 'self_add_call' }\n : { registryAddress, attached: false, version: null, evidence: 'not_sandbox' };\n }\n if (legacy.data !== undefined && isSandboxRegistryError(legacy.data)) {\n return { registryAddress, attached: true, version: null, evidence: 'self_add_revert' };\n }\n return { registryAddress, attached: false, version: null, evidence: 'not_sandbox' };\n}\n\ntype CallOutcome =\n { outcome: 'returned'; data: Hex | undefined } | { outcome: 'reverted'; data: Hex | undefined };\n\n/** One `eth_call`, with an execution revert folded into the result and everything else thrown. */\nasync function tryCall(\n client: SandboxProbeClient,\n args: { to: Address; data: Hex; account?: Address },\n): Promise<CallOutcome> {\n try {\n const { data } = await client.call(args);\n return { outcome: 'returned', data };\n } catch (error) {\n const revert = asExecutionRevert(error);\n if (revert === undefined) throw error;\n return { outcome: 'reverted', data: revert.data };\n }\n}\n\n/**\n * Recognises an execution revert however the client reports it, and digs out its return data.\n *\n * viem wraps a reverted `eth_call` as `CallExecutionError` → `ExecutionRevertedError` →\n * `RpcRequestError` → the raw JSON-RPC error (`code: 3`, `message: \"execution reverted\"`, and\n * `data` when the contract returned any), so the chain is walked for the class, then the deepest\n * cause is checked for the node's own code and message, so a non-viem client that surfaces the\n * raw RPC error is recognised too. Anything else — HTTP failures, timeouts, a wrong chain — is\n * NOT a revert and returns `undefined` so the caller rethrows it.\n */\nfunction asExecutionRevert(error: unknown): { data: Hex | undefined } | undefined {\n const root: unknown = error instanceof BaseError ? error.walk() : error;\n const reverted =\n (error instanceof BaseError &&\n error.walk((e) => e instanceof ExecutionRevertedError) !== null) ||\n hasRevertCode(root) ||\n hasRevertMessage(root) ||\n hasRevertMessage(error);\n if (!reverted) return undefined;\n return { data: revertData(root) ?? revertData(error) };\n}\n\n/** JSON-RPC error code 3 is `execution reverted` on every major node. */\nfunction hasRevertCode(value: unknown): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { code?: unknown }).code === ExecutionRevertedError.code\n );\n}\n\n/** The node's message, or viem's `details`/`shortMessage` copy of it. */\nfunction hasRevertMessage(value: unknown): boolean {\n if (typeof value !== 'object' || value === null) return false;\n const record = value as { message?: unknown; details?: unknown; shortMessage?: unknown };\n return [record.message, record.details, record.shortMessage].some(\n (text) =>\n typeof text === 'string' && ExecutionRevertedError.nodeMessage.test(text.toLowerCase()),\n );\n}\n\n/** The revert payload, as either a hex string or a nested `{ data }` — both shapes occur. */\nfunction revertData(value: unknown): Hex | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const data = (value as { data?: unknown }).data;\n if (typeof data === 'string' && isHex(data)) return data;\n if (typeof data === 'object' && data !== null) {\n const nested = (data as { data?: unknown }).data;\n if (typeof nested === 'string' && isHex(nested)) return nested;\n }\n return undefined;\n}\n\n/** `sandboxVersion()` returns one `uint256`: exactly 32 bytes, or it is not the marker. */\nfunction decodeVersion(data: Hex): bigint | undefined {\n if (size(data) !== 32) return undefined;\n try {\n const version = decodeFunctionResult({\n abi: sandboxAllowlistRegistryAbi,\n functionName: 'sandboxVersion',\n data,\n });\n return version > 0n ? version : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** True when the revert data decodes to one of the errors only `sandboxAddSelf()` can raise. */\nfunction isSandboxRegistryError(data: Hex): boolean {\n try {\n const decoded = decodeErrorResult({ abi: sandboxAllowlistRegistryAbi, data });\n return decoded.errorName === 'EnforcedPause' || decoded.errorName === 'AddressNotEligible';\n } catch {\n return false;\n }\n}\n","import { getAddress } from 'viem';\n\n/**\n * Sepolia sandbox v3, verified after DeployMmfSandbox + SeedMmfDemoData on 2026-09-14.\n * All 76 receipts succeeded. Public evidence: deployments/sepolia-sandbox-v3.json.\n * Proxy addresses are used for calls. This is a pinned snapshot; use live preflight.\n * Backend discovery/indexing needs the matching subgraph rollout before it agrees.\n */\nexport const SEPOLIA_SANDBOX_MANIFEST = Object.freeze({\n chainId: 11155111,\n contractsCommit: 'ee48b026312447f4b98259c5b69c5b3dd909e7ac',\n startBlock: 11704186,\n deploymentEndBlock: 11704251,\n seedEndBlock: 11704261,\n verifiedAtBlock: 11704261,\n verifiedAtBlockHash: '0x2be898f65c42951b74f5638840b580f50a3d67e6a3fdacb23a93c91d5d30e584',\n sandboxVersion: 3,\n contractsPr: 'https://github.com/OpacityLabs/pilot-evm/pull/163',\n mmfTokenId: 1n,\n defaultBeaconVariant:\n '0x9710c10589ba16449491db61cd49910e5850d89fd101354fd502e443315ef1a7' as const,\n documentTraitId: '0x07a0e2ce63cbf806e2e785550e9037052acefbf71086a0b714149f62d2511603' as const,\n addresses: Object.freeze({\n registry: getAddress('0x4f471f8719192965c7ee1c3ab460d55d9734ac17'),\n registryImplementation: getAddress('0x580ee27e862052c3454e99be374785394b490e5c'),\n securityTokenImplementation: getAddress('0xf388b72cc6043c97f33e2bd74c73b102efc0540a'),\n timelockBeacon: getAddress('0x8362deb9ddde9a37cc104ac5f567596d295e9f2f'),\n beaconRegistry: getAddress('0xc7e3f9802e637cd63096008cc2fb0e4b5da91c79'),\n factoryImplementation: getAddress('0x5b0db45654ac926405c270de0947767ef8edde12'),\n policyRegistry: getAddress('0x23f059b4a2962b2801804b69db78200cc4ca5308'),\n policyEngineImplementation: getAddress('0x7b1bc77a3934b7c04aebfa783ae1c9047962fe80'),\n orchestratorImplementation: getAddress('0x1c3dc8c8e87a1e2840283f1418b3787d3825f492'),\n securityTokenLens: getAddress('0xa3d006def1b1330a52776271cc43e1c76d505c59'),\n overrideHelperImplementation: getAddress('0x0d9c174129bab0c6005ad228a5457f53dcebf3c5'),\n tokenTraitRegistry: getAddress('0x5d491bc34df171e0657e26911bd6821b8257d139'),\n documentAttestor: getAddress('0x0de5ac323a4756e44620b2da5845fe8c3bdcc229'),\n mockUSDC: getAddress('0x88043845880c5a23ba54bcbf68570c882d3e6ae5'),\n vault: getAddress('0xfb8a78e328c0d8894cd3c87244d67e79e7d0c6af'),\n factory: getAddress('0xb5554c9ea27d3797cdd7b9582098bedd8e487213'),\n policyEngine: getAddress('0x1fc164c13cdd0fb72a68b7ab29f141446613b691'),\n orchestrator: getAddress('0x6378a86ff255107df40a8c442710a3f2dea14ded'),\n overrideHelper: getAddress('0x47f535716d1115bb5416317b784819c934c3ced5'),\n helperTimelock: getAddress('0xcca60edb282d18dec3d92515d2fc328e981cf56e'),\n engineTimelock: getAddress('0x74d8a771245b836b1bf5811812025d11d056e371'),\n orchestratorTimelock: getAddress('0x48d66185eb49999d21db44ccf5a67dc81ace2953'),\n factoryTimelock: getAddress('0x70b081d01b7dda17e5beaf66b006e58dc18911a1'),\n registryProxyAdmin: getAddress('0x6bd7489a9882dbf7102dc173e770963ba626f179'),\n innerBeacon: getAddress('0x5d0d62913f3e347bfbb3289b1e74c8a3a2823201'),\n mmfToken: getAddress('0x490b0b9396cb1b1ee717acd1376c3f21de4ee808'),\n }),\n policies: Object.freeze({\n TradingDisabledPolicy: getAddress('0xba5798564c819f886f93aad71a074ebc874a19e3'),\n AllowedTransfereeTypePolicy: getAddress('0x2645026dc2eb3233bce7ead874715a485984bbc6'),\n HolderCountCapPolicy: getAddress('0x631ccf8d3a44e5b03df176d915b09d30f34c94c3'),\n FloorBalancePolicy: getAddress('0xcc33aa099db0cdadf0e124f9aa64cb130f0bf513'),\n CeilingBalancePolicy: getAddress('0xb4806408c9a80442ed277df4cb33a7e6b69d1d08'),\n DenylistPolicy: getAddress('0xfedf6f0df8473ba96bc2c379f9a41b1947a53af7'),\n InsiderTradingFreezePolicy: getAddress('0xd560c8fb46f9d61e1067177c9ccb09ba0a4c4489'),\n SelfTransferOnlyPolicy: getAddress('0xc1bf4aad716407984e020b38c27b165f0716265a'),\n }),\n});\n","import { SEPOLIA_SANDBOX_MANIFEST } from '../deployments/sepolia-sandbox.js';\nimport type { Address } from 'viem';\n\nimport { OpacityConfigError } from '../errors.js';\n\n/**\n * Sepolia's chain id — the one chain the shared Opacity sandbox is deployed on today.\n */\nexport const SEPOLIA_CHAIN_ID = 11155111;\n\n/**\n * The chain `client.sandbox` assumes when the client has no `chainId` configured and none is\n * passed per call. Sepolia, for now: it is the only chain with a sandbox deployment, so it is the\n * only honest default. `client.documents` deliberately does NOT inherit this default — the\n * attestation flow is chain-agnostic and refuses to guess.\n */\nexport const SANDBOX_CHAIN_ID = SEPOLIA_CHAIN_ID;\n\n/**\n * The document/onboarding addresses of one sandbox deployment. Purchase vault/token/payment\n * addresses are separately pinned in `SANDBOX_PURCHASE_DEPLOYMENT`.\n *\n * The sandbox registry is upgradeable, so `allowlistRegistry` is the proxy address rather than\n * its current implementation. The Sepolia sandbox is a dedicated deployment initialized with\n * `SandboxAllowlistRegistry`; whether that implementation still answers is a live question — see\n * `probeSandboxRegistry`.\n */\nexport interface SandboxDeployment {\n /** The chain these addresses live on. */\n chainId: number;\n /** The allowlist-registry PROXY running `SandboxAllowlistRegistry`. The target of `sandboxAddSelf()`. */\n allowlistRegistry: Address;\n /**\n * The `DocumentAttestor` wired as that registry's trait writer — the EIP-712 `verifyingContract`\n * of every session the sandbox backend issues. Pin it as `expectedAttestor` when you want the\n * wallet prompt refused if discovery ever disagrees.\n */\n documentAttestor: Address;\n}\n\n/**\n * Built-in sandbox deployments, keyed by chain id. Sepolia only, today.\n *\n * These and `SANDBOX_PURCHASE_DEPLOYMENT` are testnet-only constants; production addresses are\n * never baked in. They serve as\n * the FALLBACK for `client.sandbox` when discovery cannot answer, and as constants a consumer can\n * pin (`expectedAttestor`) or use with the pure builders without a backend at all.\n *\n * Source and receipt provenance: SEPOLIA_SANDBOX_MANIFEST and\n * deployments/sepolia-sandbox-v3.json. Verified sandboxVersion() = 3 after all\n * deployment and MMF seed transactions confirmed. Discovery remains backend-owned;\n * pin these addresses explicitly during the subgraph/backend cutover.\n */\nexport const SANDBOX_DEPLOYMENTS: Readonly<Partial<Record<number, SandboxDeployment>>> =\n Object.freeze({\n [SEPOLIA_CHAIN_ID]: Object.freeze({\n chainId: SEPOLIA_CHAIN_ID,\n allowlistRegistry: SEPOLIA_SANDBOX_MANIFEST.addresses.registry,\n documentAttestor: SEPOLIA_SANDBOX_MANIFEST.addresses.documentAttestor,\n }),\n });\n\n/** The built-in sandbox deployment for a chain, or `undefined` when the SDK ships none for it. */\nexport function getSandboxDeployment(chainId: number): SandboxDeployment | undefined {\n return SANDBOX_DEPLOYMENTS[chainId];\n}\n\n/**\n * The built-in sandbox deployment for a chain, or an error naming the chains that have one.\n *\n * @throws {OpacityConfigError} when no built-in deployment exists for `chainId`.\n */\nexport function requireSandboxDeployment(chainId: number): SandboxDeployment {\n const deployment = getSandboxDeployment(chainId);\n if (deployment !== undefined) return deployment;\n\n const known = Object.keys(SANDBOX_DEPLOYMENTS).join(', ');\n throw new OpacityConfigError(\n `No built-in sandbox deployment for chain ${chainId}. This SDK ships sandbox addresses for ` +\n `chain(s) ${known} only. Point the client at one of those, pass \\`registryAddress\\` ` +\n 'explicitly, or rely on discovery (`GET /chains/:chain_id/attestor`) for a chain whose ' +\n 'backend serves one.',\n );\n}\n","import type { Address, Hex } from 'viem';\nimport { OpacityAttestationError } from '../errors.js';\nimport {\n DOCUMENT_ACCEPTANCE_PRIMARY_TYPE,\n DOCUMENT_ACCEPTANCE_TYPES,\n DOCUMENT_ATTESTOR_DOMAIN_NAME,\n DOCUMENT_ATTESTOR_DOMAIN_VERSION,\n EIP712_DOMAIN_TYPE,\n} from './constants.js';\nimport { toEip712Json, toEip712JsonPayload } from './typed-data.js';\nimport type { DocumentAcceptanceTypedData, Eip712JsonPayload } from './typed-data.js';\nimport { assertAddress, assertChainId, assertDocHash, assertNonce } from './validate.js';\n\n/** One entry of an EIP-712 struct definition, as it arrives over the wire. */\nexport interface Eip712TypeField {\n name: string;\n type: string;\n}\n\n/**\n * The `typedData` block of a create response, exactly as the backend sends it.\n *\n * JSON-shaped: `deadline` is a decimal STRING because JSON cannot carry a `bigint`, and `types`\n * declares `EIP712Domain` alongside `DocumentAcceptance`.\n *\n * **Signable as it arrives on a raw `eth_signTypedData_v4` provider.** That method wants exactly\n * this JSON form, and mobile-api already declares `EIP712Domain` in `types`, so no reshaping is\n * needed. {@link toEip1193Json} / {@link toEip1193TypedData} remain worthwhile there for their\n * validation and attestor pinning, not because the payload needs repair.\n *\n * **viem and wagmi also take it as it arrives.** viem parses the decimal-string `uint256` to the\n * same digest a `bigint` produces, and ignores the extra `EIP712Domain` entry. Run it through\n * {@link toViemTypedData} anyway — for the validation and the `expectedAttestor` /\n * `expectedChainId` pinning, not for correctness.\n *\n * **ethers v6 is the one stack that cannot take it**, and that is the hard requirement\n * {@link toViemTypedData} exists to satisfy. `TypedDataEncoder` rejects a `types` map that declares\n * the domain, throwing `ambiguous primary types or unused types: \"EIP712Domain\",\n * \"DocumentAcceptance\"` — so the raw payload never reaches an ethers signer at all. Route it\n * through {@link toViemTypedData} (whose `types` is this SDK's constant, with no `EIP712Domain`\n * entry) and then `toEthersTypedData`.\n */\nexport interface ServerAttestationTypedData {\n domain: {\n name: string;\n version: string;\n chainId: number;\n verifyingContract: Address;\n };\n types: Record<string, readonly Eip712TypeField[]>;\n primaryType: string;\n message: {\n nonce: Hex;\n docHash: Hex;\n /** Decimal string of unix seconds. NOT a number, and NOT a bigint. */\n deadline: string;\n };\n}\n\n/** Optional domain pinning for {@link toViemTypedData}. */\nexport interface ToViemTypedDataOptions {\n /**\n * The `DocumentAttestor` address this client will accept, checked against\n * `typedData.domain.verifyingContract`.\n *\n * Supplying it is defence in depth and costs nothing: a client that blindly signs whatever\n * domain arrives over the wire has no independent anchor on which contract it is authorising, so\n * a compromised or merely misconfigured backend could aim a valid-looking prompt at a different\n * deployment. The investor cannot tell those apart; a pinned constant can.\n */\n expectedAttestor?: Address;\n /** The chain id this client will accept, checked against `typedData.domain.chainId`. */\n expectedChainId?: number;\n}\n\n/**\n * Validates the backend's JSON `typedData` and returns it in this SDK's own viem-shaped form — the\n * one `toEthersTypedData`, `toEip712JsonPayload` and `hashDocumentAcceptance` all take.\n *\n * **Only ethers strictly needs it, and not for the reason you would guess.** The `deadline`\n * reshaping is cosmetic: viem and ethers both hash the wire's decimal-string `uint256` to the same\n * digest as the `bigint` this returns. What ethers v6 will NOT accept is the `EIP712Domain` entry\n * mobile-api declares in `types` — `TypedDataEncoder` throws `ambiguous primary types or unused\n * types: \"EIP712Domain\", \"DocumentAcceptance\"` — so the server's payload cannot reach an ethers\n * signer at all. This function's `types` is the SDK's own constant, which omits that entry, which\n * is what makes the `toEthersTypedData` hand-off work.\n *\n * **viem, wagmi and a raw `eth_signTypedData_v4` provider all accept `session.typedData` as it\n * arrives.** viem tolerates both the decimal string and the extra `EIP712Domain` entry;\n * `eth_signTypedData_v4` is specified in terms of exactly that JSON shape. Use this function on\n * those paths for what it validates and pins, not because the payload needs repair — and use\n * {@link toEip1193Json} for the EIP-1193 one, which runs these same checks and re-serialises.\n *\n * Everything else this function does is validation, because the payload it is handed decides what\n * a human is about to authorise:\n *\n * - `primaryType` must be `DocumentAcceptance`.\n * - The `DocumentAcceptance` field list must match {@link DOCUMENT_ACCEPTANCE_TYPES} exactly —\n * same names, same types, same ORDER. Order is consensus-critical: it is part of the type hash,\n * and a reordered list produces a valid signature over a different struct. Unreferenced extra\n * entries in `types` are ignored: the encoding of this payload is fully determined by the primary\n * type's field list, all of which are atomic, so an unused extra type cannot change the digest.\n * - `EIP712Domain` is the one exception to that, and mobile-api declares it on EVERY session — so\n * this check runs on the normal path, not on a hypothetical future one. A declaration matching\n * {@link EIP712_DOMAIN_TYPE} is accepted; any other declaration — including the empty list — is\n * rejected, because that entry is not inert. It replaces the domain type a wallet would otherwise\n * derive, so a wrong one re-hashes the domain and moves the digest. An absent entry is tolerated\n * too, since viem and ethers derive the type themselves and this SDK re-declares it on the\n * EIP-1193 path.\n * - The domain `name`/`version` must be `DocumentAttestor`/`1`, and `chainId` /\n * `verifyingContract` must be well-formed.\n * - `nonce` and `docHash` must be well-formed `bytes32`, and `docHash` non-zero.\n *\n * Pass {@link ToViemTypedDataOptions} to additionally pin the domain to a deployment this client\n * already knows about. Optional, and worth taking: see the field docs for why blind signing leaves\n * the client with no independent anchor.\n *\n * The returned `types` object is this SDK's own constant rather than the server's array. That is\n * safe precisely because the check above proved the two are identical field for field, and it\n * means the result is the same `DocumentAcceptanceTypedData` the local builder produces — so\n * `toEthersTypedData`, `toEip712JsonPayload` and `hashDocumentAcceptance` all accept it.\n *\n * @throws {import('../errors.js').OpacityAttestationError} on any mismatch. Nothing is coerced\n * silently; a payload that does not validate must not reach a wallet.\n */\nexport function toViemTypedData(\n typedData: ServerAttestationTypedData,\n options: ToViemTypedDataOptions = {},\n): DocumentAcceptanceTypedData {\n const record = asRecord(typedData);\n if (record === undefined) {\n throw typedDataError('`typedData` is not an object.', 'typedData');\n }\n\n if (record['primaryType'] !== DOCUMENT_ACCEPTANCE_PRIMARY_TYPE) {\n throw typedDataError(\n `\\`primaryType\\` must be \\`${DOCUMENT_ACCEPTANCE_PRIMARY_TYPE}\\`; received ` +\n `${describe(record['primaryType'])}.`,\n 'typedData.primaryType',\n );\n }\n\n const types = asRecord(record['types']);\n assertAcceptanceFields(types?.[DOCUMENT_ACCEPTANCE_PRIMARY_TYPE]);\n assertDomainFieldsIfDeclared(types?.[EIP712_DOMAIN_TYPE_NAME]);\n\n const domain = asRecord(record['domain']);\n if (domain === undefined) {\n throw typedDataError('`domain` is missing or is not an object.', 'typedData.domain');\n }\n if (domain['name'] !== DOCUMENT_ATTESTOR_DOMAIN_NAME) {\n throw typedDataError(\n `\\`domain.name\\` must be \\`${DOCUMENT_ATTESTOR_DOMAIN_NAME}\\`; received ` +\n `${describe(domain['name'])}. A different domain name is a different contract.`,\n 'typedData.domain.name',\n );\n }\n if (domain['version'] !== DOCUMENT_ATTESTOR_DOMAIN_VERSION) {\n throw typedDataError(\n `\\`domain.version\\` must be \\`${DOCUMENT_ATTESTOR_DOMAIN_VERSION}\\`; received ` +\n `${describe(domain['version'])}.`,\n 'typedData.domain.version',\n );\n }\n\n const chainId = assertChainId(asNumber(domain['chainId']) ?? Number.NaN);\n const verifyingContract = assertAddress(\n domain['verifyingContract'] as Address,\n 'domain.verifyingContract',\n );\n\n if (options.expectedChainId !== undefined) {\n const expected = assertChainId(options.expectedChainId);\n if (expected !== chainId) {\n throw typedDataError(\n `\\`domain.chainId\\` is ${chainId}, but this client is pinned to ${expected}. ` +\n 'Refusing to prompt: a signature for another chain is not the one you asked for.',\n 'typedData.domain.chainId',\n );\n }\n }\n if (options.expectedAttestor !== undefined) {\n const expected = assertAddress(options.expectedAttestor, 'expectedAttestor');\n if (expected !== verifyingContract) {\n throw typedDataError(\n `\\`domain.verifyingContract\\` is ${verifyingContract}, but this client is pinned to ` +\n `${expected}. Refusing to prompt: the investor would be authorising a different ` +\n '`DocumentAttestor` deployment than the one this integration trusts.',\n 'typedData.domain.verifyingContract',\n );\n }\n }\n\n const message = asRecord(record['message']);\n if (message === undefined) {\n throw typedDataError('`message` is missing or is not an object.', 'typedData.message');\n }\n\n return {\n domain: {\n name: DOCUMENT_ATTESTOR_DOMAIN_NAME,\n version: DOCUMENT_ATTESTOR_DOMAIN_VERSION,\n chainId,\n verifyingContract,\n },\n types: DOCUMENT_ACCEPTANCE_TYPES,\n primaryType: DOCUMENT_ACCEPTANCE_PRIMARY_TYPE,\n message: {\n nonce: assertNonce(message['nonce'] as Hex),\n docHash: assertDocHash(message['docHash'] as Hex),\n deadline: toDeadlineBigInt(message['deadline']),\n },\n };\n}\n\n/**\n * Converts the backend's JSON `typedData` into a payload a raw EIP-1193 provider can sign, and\n * validates it on the way through.\n *\n * ```ts\n * const signature = await provider.request({\n * method: 'eth_signTypedData_v4',\n * params: [account, toEip1193Json(session.typedData, { expectedAttestor, expectedChainId })],\n * });\n * ```\n *\n * Sending `session.typedData` as it arrives is FINE — mobile-api declares `EIP712Domain`\n * alongside `DocumentAcceptance`, which is what makes it safe. This function is the belt-and-braces\n * route: it validates and pins the payload before a wallet ever sees it.\n *\n * What it guards against is a `types` map that declares `EIP712Domain` INCORRECTLY, or omits it.\n * `eth_signTypedData_v4` implementations built on MetaMask's `eth-sig-util` sanitise with\n * `{ EIP712Domain: [], ...types }`, so a missing entry becomes an EMPTY field list rather than an\n * error. The domain then hashes as `keccak256(\"EIP712Domain()\")` — no `name`, no `version`, no\n * `chainId`, no `verifyingContract` — and the digest changes:\n *\n * ```text\n * EIP712Domain declared 0x91feb0709c4ebdff9ccc57b12b26c50936eae7973f67c6d23780fcfdbda3f410 ✓\n * EIP712Domain defaulted [] 0x82ada7044278f3b529058b2dac44bb987f078c23b15195e1dca77110f0c91691 ✗\n * ```\n *\n * Nothing throws. The wallet shows the right prompt and returns a well-formed signature over a\n * digest the contract has never heard of, and the failure surfaces much later as an\n * `InvalidUserSignature` from the relay's simulate step — which reads like \"your wallet is\n * broken\", not \"the payload was missing a type\". That is why {@link assertDomainFieldsIfDeclared}\n * rejects a MALFORMED `EIP712Domain` rather than quietly replacing it: the SDK will not hand a\n * wallet a payload whose domain type it cannot vouch for.\n *\n * The conversion runs {@link toViemTypedData} first, so every check listed there applies — the\n * primary type, the field list and its ORDER, the domain, and the optional\n * {@link ToViemTypedDataOptions} pinning — and then {@link toEip712JsonPayload} re-serialises with\n * `EIP712Domain` declared and `deadline` back to a decimal string. That round trip through a\n * `bigint` is deliberate: it is what proves the string the wallet receives is a well-formed\n * `uint256` rather than whatever the wire happened to carry.\n *\n * @throws {import('../errors.js').OpacityAttestationError} on any mismatch, exactly as\n * {@link toViemTypedData} does. A payload that does not validate must not reach a wallet.\n */\nexport function toEip1193TypedData(\n typedData: ServerAttestationTypedData,\n options: ToViemTypedDataOptions = {},\n): Eip712JsonPayload {\n return toEip712JsonPayload(toViemTypedData(typedData, options));\n}\n\n/**\n * {@link toEip1193TypedData}, serialised — the second `eth_signTypedData_v4` parameter.\n *\n * Providers differ on whether they want the object or the JSON string; the string is accepted\n * everywhere, so this is the safer default. Same validation, same reason for existing: see\n * {@link toEip1193TypedData} for the digest that silently changes without it.\n *\n * @throws {import('../errors.js').OpacityAttestationError} on any mismatch.\n */\nexport function toEip1193Json(\n typedData: ServerAttestationTypedData,\n options: ToViemTypedDataOptions = {},\n): string {\n return toEip712Json(toViemTypedData(typedData, options));\n}\n\n/** Field-for-field comparison against the canonical `DocumentAcceptance` definition. */\nfunction assertAcceptanceFields(fields: unknown): void {\n const expected = DOCUMENT_ACCEPTANCE_TYPES.DocumentAcceptance;\n\n if (!Array.isArray(fields)) {\n throw typedDataError(\n `\\`types.${DOCUMENT_ACCEPTANCE_PRIMARY_TYPE}\\` is missing or is not an array.`,\n `typedData.types.${DOCUMENT_ACCEPTANCE_PRIMARY_TYPE}`,\n );\n }\n if (fields.length !== expected.length) {\n throw typedDataError(\n `\\`types.${DOCUMENT_ACCEPTANCE_PRIMARY_TYPE}\\` must declare exactly ${expected.length} ` +\n `fields; received ${fields.length}. The field list is part of the type hash.`,\n `typedData.types.${DOCUMENT_ACCEPTANCE_PRIMARY_TYPE}`,\n );\n }\n\n for (const [index, want] of expected.entries()) {\n const got = asRecord(fields[index]);\n if (got?.['name'] !== want.name || got?.['type'] !== want.type) {\n throw typedDataError(\n `\\`types.${DOCUMENT_ACCEPTANCE_PRIMARY_TYPE}[${index}]\\` must be ` +\n `\\`${want.type} ${want.name}\\`; received ` +\n `\\`${describe(got?.['type'])} ${describe(got?.['name'])}\\`. Names, types and ORDER are ` +\n 'all part of the type hash, so a reordered list signs a different struct.',\n `typedData.types.${DOCUMENT_ACCEPTANCE_PRIMARY_TYPE}[${index}]`,\n );\n }\n }\n}\n\n/** The reserved `types` key EIP-712 gives the domain struct. */\nconst EIP712_DOMAIN_TYPE_NAME = 'EIP712Domain';\n\n/**\n * Checks an `EIP712Domain` entry, if the server sent one.\n *\n * **PRESENT is the normal case.** mobile-api's `buildDocumentAcceptanceTypedData` returns\n * `{ EIP712Domain, DocumentAcceptance }` unconditionally, so every real session declares it and\n * this comparison is the hot path rather than a forward-compatibility hedge.\n *\n * Absent is tolerated but is not what the backend sends: viem and ethers derive the domain type\n * from the `domain` object, and the EIP-1193 path re-declares it from {@link EIP712_DOMAIN_TYPE}\n * anyway. Treat a missing entry as a signal the payload did not come from this backend, not as\n * business as usual.\n *\n * What must never pass is a DIFFERENT declaration, because unlike every other extra entry in\n * `types` this one is not inert: it overrides the domain type a wallet would otherwise derive, so\n * the domain re-hashes and the digest moves. The empty list is the specific shape to fear, since it\n * is what MetaMask's `sanitizeData` substitutes for a missing entry, and it hashes the domain as\n * the field-less `keccak256(\"EIP712Domain()\")` — silently, with no error anywhere.\n */\nfunction assertDomainFieldsIfDeclared(fields: unknown): void {\n if (fields === undefined) return;\n\n const detail =\n 'Declaring it differently is not additive: it replaces the domain type the wallet would ' +\n 'derive, which changes the domain hash and therefore the digest — a well-formed signature ' +\n 'over the wrong message, caught only when the relay simulates the attestation.';\n\n const matches =\n Array.isArray(fields) &&\n fields.length === EIP712_DOMAIN_TYPE.length &&\n EIP712_DOMAIN_TYPE.every((want, index) => {\n const got = asRecord(fields[index]);\n return got?.['name'] === want.name && got?.['type'] === want.type;\n });\n\n if (!matches) {\n const encoded = EIP712_DOMAIN_TYPE.map((field) => `${field.type} ${field.name}`).join(',');\n throw typedDataError(\n `\\`types.${EIP712_DOMAIN_TYPE_NAME}\\`, when present, must be exactly ` +\n `\\`${encoded}\\`; received ${describeFieldList(fields)}. ${detail}`,\n `typedData.types.${EIP712_DOMAIN_TYPE_NAME}`,\n );\n }\n}\n\n/** Renders a `types` entry compactly for an error message: `[]`, `bytes32 salt`, or a type name. */\nfunction describeFieldList(fields: unknown): string {\n if (!Array.isArray(fields)) return describe(fields);\n if (fields.length === 0) return 'an EMPTY field list';\n\n return `\\`${fields\n .map((field) => {\n const got = asRecord(field);\n return `${String(got?.['type'])} ${String(got?.['name'])}`;\n })\n .join(',')}\\``;\n}\n\n/**\n * Normalises a JSON `uint256` to a `bigint`.\n *\n * Not a repair — viem and ethers hash the decimal string to the same digest — but it is a\n * well-formedness proof: whatever the wire carried, what leaves here is a non-negative integer of\n * unix seconds, and the result is interchangeable with a locally built payload.\n *\n * A decimal string is the documented form. A `number` or `bigint` is accepted too — some stacks\n * re-serialise the payload before it gets here — but a float, a negative, or anything else is\n * rejected rather than coerced, because a silently wrong deadline produces a signature that fails\n * on-chain long after the investor has walked away.\n */\nfunction toDeadlineBigInt(value: unknown): bigint {\n if (typeof value === 'bigint' && value >= 0n) return value;\n if (typeof value === 'number' && Number.isSafeInteger(value) && value >= 0) return BigInt(value);\n if (typeof value === 'string' && /^\\d+$/.test(value.trim())) return BigInt(value.trim());\n\n throw typedDataError(\n `\\`message.deadline\\` must be a non-negative integer of unix seconds; received ` +\n `${describe(value)}. The backend sends it as a DECIMAL STRING — that is the form ` +\n '`eth_signTypedData_v4` is specified in terms of — and this is where it is checked and ' +\n 'normalised into the `bigint` the viem-shaped payload carries.',\n 'typedData.message.deadline',\n );\n}\n\nfunction typedDataError(detail: string, field: string): OpacityAttestationError {\n return new OpacityAttestationError(\n 'MalformedInput',\n `The server's \\`typedData\\` cannot be trusted: ${detail} Refusing to hand it to a wallet.`,\n { field },\n );\n}\n\n/** Renders an unexpected value for an error message without dumping a whole payload into logs. */\nfunction describe(value: unknown): string {\n if (typeof value === 'string') return `\\`${value}\\``;\n if (value === undefined) return 'nothing';\n if (value === null) return 'null';\n if (typeof value === 'object') return Array.isArray(value) ? 'an array' : 'an object';\n return `\\`${String(value)}\\``;\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return undefined;\n return value as Record<string, unknown>;\n}\n\n/** Accepts a number, a bigint, or a decimal/hex string — backends disagree on how to send one. */\nfunction asNumber(value: unknown): number | undefined {\n if (typeof value === 'number') return Number.isFinite(value) ? value : undefined;\n if (typeof value === 'bigint') return Number(value);\n if (typeof value === 'string' && value.trim() !== '') {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return undefined;\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/errors.ts
|
|
4
|
+
var OpacityIssuerError = class extends Error {
|
|
5
|
+
constructor(message, options) {
|
|
6
|
+
super(message, options);
|
|
7
|
+
this.name = "OpacityIssuerError";
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
var OpacityConfigError = class extends OpacityIssuerError {
|
|
11
|
+
constructor(message, options) {
|
|
12
|
+
super(message, options);
|
|
13
|
+
this.name = "OpacityConfigError";
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
var OpacityAttestationError = class extends OpacityIssuerError {
|
|
17
|
+
/** Which check failed. Mirrors a contract error name where one exists. */
|
|
18
|
+
code;
|
|
19
|
+
/** The offending parameter, when the failure is attributable to a single one. */
|
|
20
|
+
field;
|
|
21
|
+
constructor(code, message, options) {
|
|
22
|
+
super(message, options?.cause === void 0 ? void 0 : { cause: options.cause });
|
|
23
|
+
this.name = "OpacityAttestationError";
|
|
24
|
+
this.code = code;
|
|
25
|
+
this.field = options?.field;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
exports.OpacityAttestationError = OpacityAttestationError;
|
|
30
|
+
exports.OpacityConfigError = OpacityConfigError;
|
|
31
|
+
exports.OpacityIssuerError = OpacityIssuerError;
|
|
32
|
+
//# sourceMappingURL=chunk-HJQZWNZJ.cjs.map
|
|
33
|
+
//# sourceMappingURL=chunk-HJQZWNZJ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts"],"names":[],"mappings":";;;AAmBO,IAAM,kBAAA,GAAN,cAAiC,KAAA,CAAM;AAAA,EAC5C,WAAA,CAAY,SAAiB,OAAA,EAA+B;AAC1D,IAAA,KAAA,CAAM,SAAS,OAAO,CAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AAAA,EACd;AACF;AAGO,IAAM,kBAAA,GAAN,cAAiC,kBAAA,CAAmB;AAAA,EACzD,WAAA,CAAY,SAAiB,OAAA,EAA+B;AAC1D,IAAA,KAAA,CAAM,SAAS,OAAO,CAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AAAA,EACd;AACF;AASO,IAAM,uBAAA,GAAN,cAAsC,kBAAA,CAAmB;AAAA;AAAA,EAErD,IAAA;AAAA;AAAA,EAEA,KAAA;AAAA,EAET,WAAA,CACE,IAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,OAAA,EAAS,SAAS,KAAA,KAAU,MAAA,GAAY,SAAY,EAAE,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAO,CAAA;AAClF,IAAA,IAAA,CAAK,IAAA,GAAO,yBAAA;AACZ,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,QAAQ,OAAA,EAAS,KAAA;AAAA,EACxB;AACF","file":"chunk-HJQZWNZJ.cjs","sourcesContent":["import type { AttestationErrorCode } from './documents/types.js';\n\n// `OpacityDiscoveryError` is deliberately NOT re-exported from here, even though it belongs to\n// this hierarchy and is exported from the package root (via `documents/index.ts`).\n//\n// A value re-export — `export { OpacityDiscoveryError } from './documents/discovery.js'` — is a\n// RUNTIME edge, and `discovery.ts` already imports this module for `OpacityIssuerError`. The cycle\n// is fatal, not benign: `config.ts` imports `errors.js` first, so `errors.js` starts evaluating,\n// the re-export pulls in `discovery.js`, and `class OpacityDiscoveryError extends\n// OpacityIssuerError` runs while `OpacityIssuerError` is still in its temporal dead zone —\n// `TypeError: Class extends value undefined`. Verified, not theorised.\n//\n// The type-only imports above are safe for the opposite reason: `verbatimModuleSyntax` erases\n// them, so they create no runtime edge at all.\n\n/**\n * Base class for every error thrown by this SDK, so consumers can do a single\n * `instanceof OpacityIssuerError` check at their integration boundary.\n */\nexport class OpacityIssuerError extends Error {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = 'OpacityIssuerError';\n }\n}\n\n/** Thrown when `createOpacityIssuerClient` is called with invalid configuration. */\nexport class OpacityConfigError extends OpacityIssuerError {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = 'OpacityConfigError';\n }\n}\n\n/**\n * Thrown by the document-attestation builders when a parameter would produce a transaction the\n * `DocumentAttestor` is guaranteed to reject, or is too malformed to encode.\n *\n * Branch on {@link code}, not on the message: each value names the on-chain error it stands in for,\n * so a pre-flight rejection is legible in the same terms as the revert it saved.\n */\nexport class OpacityAttestationError extends OpacityIssuerError {\n /** Which check failed. Mirrors a contract error name where one exists. */\n readonly code: AttestationErrorCode;\n /** The offending parameter, when the failure is attributable to a single one. */\n readonly field: string | undefined;\n\n constructor(\n code: AttestationErrorCode,\n message: string,\n options?: { field?: string; cause?: unknown },\n ) {\n super(message, options?.cause === undefined ? undefined : { cause: options.cause });\n this.name = 'OpacityAttestationError';\n this.code = code;\n this.field = options?.field;\n }\n}\n"]}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkGMPQFX25_cjs = require('../chunk-GMPQFX25.cjs');
|
|
4
|
+
var chunk3L7NNVUV_cjs = require('../chunk-3L7NNVUV.cjs');
|
|
5
|
+
require('../chunk-HJQZWNZJ.cjs');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
Object.defineProperty(exports, "SANDBOX_CHAIN_ID", {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
get: function () { return chunkGMPQFX25_cjs.SANDBOX_CHAIN_ID; }
|
|
12
|
+
});
|
|
13
|
+
Object.defineProperty(exports, "SANDBOX_DEPLOYMENTS", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () { return chunkGMPQFX25_cjs.SANDBOX_DEPLOYMENTS; }
|
|
16
|
+
});
|
|
17
|
+
Object.defineProperty(exports, "SANDBOX_IMPLEMENTATION_VERSION", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
get: function () { return chunkGMPQFX25_cjs.SANDBOX_IMPLEMENTATION_VERSION; }
|
|
20
|
+
});
|
|
21
|
+
Object.defineProperty(exports, "SANDBOX_TRAIT_IDS", {
|
|
22
|
+
enumerable: true,
|
|
23
|
+
get: function () { return chunkGMPQFX25_cjs.SANDBOX_TRAIT_IDS; }
|
|
24
|
+
});
|
|
25
|
+
Object.defineProperty(exports, "SEPOLIA_CHAIN_ID", {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
get: function () { return chunkGMPQFX25_cjs.SEPOLIA_CHAIN_ID; }
|
|
28
|
+
});
|
|
29
|
+
Object.defineProperty(exports, "assertDocumentMatchesHash", {
|
|
30
|
+
enumerable: true,
|
|
31
|
+
get: function () { return chunkGMPQFX25_cjs.assertDocumentMatchesHash; }
|
|
32
|
+
});
|
|
33
|
+
Object.defineProperty(exports, "buildAttestDocumentTransaction", {
|
|
34
|
+
enumerable: true,
|
|
35
|
+
get: function () { return chunkGMPQFX25_cjs.buildAttestDocumentTransaction; }
|
|
36
|
+
});
|
|
37
|
+
Object.defineProperty(exports, "buildDocumentAcceptanceTypedData", {
|
|
38
|
+
enumerable: true,
|
|
39
|
+
get: function () { return chunkGMPQFX25_cjs.buildDocumentAcceptanceTypedData; }
|
|
40
|
+
});
|
|
41
|
+
Object.defineProperty(exports, "buildSandboxAddSelfTransaction", {
|
|
42
|
+
enumerable: true,
|
|
43
|
+
get: function () { return chunkGMPQFX25_cjs.buildSandboxAddSelfTransaction; }
|
|
44
|
+
});
|
|
45
|
+
Object.defineProperty(exports, "buildSandboxRegisterIssuerTransaction", {
|
|
46
|
+
enumerable: true,
|
|
47
|
+
get: function () { return chunkGMPQFX25_cjs.buildSandboxRegisterIssuerTransaction; }
|
|
48
|
+
});
|
|
49
|
+
Object.defineProperty(exports, "buildSandboxSetSelfTraitTransaction", {
|
|
50
|
+
enumerable: true,
|
|
51
|
+
get: function () { return chunkGMPQFX25_cjs.buildSandboxSetSelfTraitTransaction; }
|
|
52
|
+
});
|
|
53
|
+
Object.defineProperty(exports, "documentAttestorAbi", {
|
|
54
|
+
enumerable: true,
|
|
55
|
+
get: function () { return chunkGMPQFX25_cjs.documentAttestorAbi; }
|
|
56
|
+
});
|
|
57
|
+
Object.defineProperty(exports, "documentTraitId", {
|
|
58
|
+
enumerable: true,
|
|
59
|
+
get: function () { return chunkGMPQFX25_cjs.documentTraitId; }
|
|
60
|
+
});
|
|
61
|
+
Object.defineProperty(exports, "getSandboxDeployment", {
|
|
62
|
+
enumerable: true,
|
|
63
|
+
get: function () { return chunkGMPQFX25_cjs.getSandboxDeployment; }
|
|
64
|
+
});
|
|
65
|
+
Object.defineProperty(exports, "hashDocument", {
|
|
66
|
+
enumerable: true,
|
|
67
|
+
get: function () { return chunkGMPQFX25_cjs.hashDocument; }
|
|
68
|
+
});
|
|
69
|
+
Object.defineProperty(exports, "hashDocumentAcceptance", {
|
|
70
|
+
enumerable: true,
|
|
71
|
+
get: function () { return chunkGMPQFX25_cjs.hashDocumentAcceptance; }
|
|
72
|
+
});
|
|
73
|
+
Object.defineProperty(exports, "probeSandboxRegistry", {
|
|
74
|
+
enumerable: true,
|
|
75
|
+
get: function () { return chunkGMPQFX25_cjs.probeSandboxRegistry; }
|
|
76
|
+
});
|
|
77
|
+
Object.defineProperty(exports, "requireSandboxDeployment", {
|
|
78
|
+
enumerable: true,
|
|
79
|
+
get: function () { return chunkGMPQFX25_cjs.requireSandboxDeployment; }
|
|
80
|
+
});
|
|
81
|
+
Object.defineProperty(exports, "sandboxAllowlistRegistryAbi", {
|
|
82
|
+
enumerable: true,
|
|
83
|
+
get: function () { return chunkGMPQFX25_cjs.sandboxAllowlistRegistryAbi; }
|
|
84
|
+
});
|
|
85
|
+
Object.defineProperty(exports, "sandboxUserId", {
|
|
86
|
+
enumerable: true,
|
|
87
|
+
get: function () { return chunkGMPQFX25_cjs.sandboxUserId; }
|
|
88
|
+
});
|
|
89
|
+
Object.defineProperty(exports, "toEip1193Json", {
|
|
90
|
+
enumerable: true,
|
|
91
|
+
get: function () { return chunkGMPQFX25_cjs.toEip1193Json; }
|
|
92
|
+
});
|
|
93
|
+
Object.defineProperty(exports, "toEip1193TypedData", {
|
|
94
|
+
enumerable: true,
|
|
95
|
+
get: function () { return chunkGMPQFX25_cjs.toEip1193TypedData; }
|
|
96
|
+
});
|
|
97
|
+
Object.defineProperty(exports, "toEip712Json", {
|
|
98
|
+
enumerable: true,
|
|
99
|
+
get: function () { return chunkGMPQFX25_cjs.toEip712Json; }
|
|
100
|
+
});
|
|
101
|
+
Object.defineProperty(exports, "toEip712JsonPayload", {
|
|
102
|
+
enumerable: true,
|
|
103
|
+
get: function () { return chunkGMPQFX25_cjs.toEip712JsonPayload; }
|
|
104
|
+
});
|
|
105
|
+
Object.defineProperty(exports, "toEthersTypedData", {
|
|
106
|
+
enumerable: true,
|
|
107
|
+
get: function () { return chunkGMPQFX25_cjs.toEthersTypedData; }
|
|
108
|
+
});
|
|
109
|
+
Object.defineProperty(exports, "toJsonRpcTransaction", {
|
|
110
|
+
enumerable: true,
|
|
111
|
+
get: function () { return chunkGMPQFX25_cjs.toJsonRpcTransaction; }
|
|
112
|
+
});
|
|
113
|
+
Object.defineProperty(exports, "toSandboxAddSelfWriteContractRequest", {
|
|
114
|
+
enumerable: true,
|
|
115
|
+
get: function () { return chunkGMPQFX25_cjs.toSandboxAddSelfWriteContractRequest; }
|
|
116
|
+
});
|
|
117
|
+
Object.defineProperty(exports, "toSandboxRegisterIssuerWriteContractRequest", {
|
|
118
|
+
enumerable: true,
|
|
119
|
+
get: function () { return chunkGMPQFX25_cjs.toSandboxRegisterIssuerWriteContractRequest; }
|
|
120
|
+
});
|
|
121
|
+
Object.defineProperty(exports, "toSandboxSetSelfTraitWriteContractRequest", {
|
|
122
|
+
enumerable: true,
|
|
123
|
+
get: function () { return chunkGMPQFX25_cjs.toSandboxSetSelfTraitWriteContractRequest; }
|
|
124
|
+
});
|
|
125
|
+
Object.defineProperty(exports, "toViemTypedData", {
|
|
126
|
+
enumerable: true,
|
|
127
|
+
get: function () { return chunkGMPQFX25_cjs.toViemTypedData; }
|
|
128
|
+
});
|
|
129
|
+
Object.defineProperty(exports, "toWriteContractRequest", {
|
|
130
|
+
enumerable: true,
|
|
131
|
+
get: function () { return chunkGMPQFX25_cjs.toWriteContractRequest; }
|
|
132
|
+
});
|
|
133
|
+
Object.defineProperty(exports, "verifyAttestationSession", {
|
|
134
|
+
enumerable: true,
|
|
135
|
+
get: function () { return chunkGMPQFX25_cjs.verifyAttestationSession; }
|
|
136
|
+
});
|
|
137
|
+
Object.defineProperty(exports, "DOCUMENT_ACCEPTANCE_PRIMARY_TYPE", {
|
|
138
|
+
enumerable: true,
|
|
139
|
+
get: function () { return chunk3L7NNVUV_cjs.DOCUMENT_ACCEPTANCE_PRIMARY_TYPE; }
|
|
140
|
+
});
|
|
141
|
+
Object.defineProperty(exports, "DOCUMENT_ACCEPTANCE_TYPEHASH", {
|
|
142
|
+
enumerable: true,
|
|
143
|
+
get: function () { return chunk3L7NNVUV_cjs.DOCUMENT_ACCEPTANCE_TYPEHASH; }
|
|
144
|
+
});
|
|
145
|
+
Object.defineProperty(exports, "DOCUMENT_ACCEPTANCE_TYPES", {
|
|
146
|
+
enumerable: true,
|
|
147
|
+
get: function () { return chunk3L7NNVUV_cjs.DOCUMENT_ACCEPTANCE_TYPES; }
|
|
148
|
+
});
|
|
149
|
+
Object.defineProperty(exports, "DOCUMENT_ATTESTOR_DOMAIN_NAME", {
|
|
150
|
+
enumerable: true,
|
|
151
|
+
get: function () { return chunk3L7NNVUV_cjs.DOCUMENT_ATTESTOR_DOMAIN_NAME; }
|
|
152
|
+
});
|
|
153
|
+
Object.defineProperty(exports, "DOCUMENT_ATTESTOR_DOMAIN_VERSION", {
|
|
154
|
+
enumerable: true,
|
|
155
|
+
get: function () { return chunk3L7NNVUV_cjs.DOCUMENT_ATTESTOR_DOMAIN_VERSION; }
|
|
156
|
+
});
|
|
157
|
+
Object.defineProperty(exports, "ECDSA_SIGNATURE_BYTES", {
|
|
158
|
+
enumerable: true,
|
|
159
|
+
get: function () { return chunk3L7NNVUV_cjs.ECDSA_SIGNATURE_BYTES; }
|
|
160
|
+
});
|
|
161
|
+
Object.defineProperty(exports, "EIP712_DOMAIN_TYPE", {
|
|
162
|
+
enumerable: true,
|
|
163
|
+
get: function () { return chunk3L7NNVUV_cjs.EIP712_DOMAIN_TYPE; }
|
|
164
|
+
});
|
|
165
|
+
Object.defineProperty(exports, "MAX_ATTESTATION_LIFETIME_SECONDS", {
|
|
166
|
+
enumerable: true,
|
|
167
|
+
get: function () { return chunk3L7NNVUV_cjs.MAX_ATTESTATION_LIFETIME_SECONDS; }
|
|
168
|
+
});
|
|
169
|
+
//# sourceMappingURL=index.cjs.map
|
|
170
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.cjs"}
|