Repository navigation
TypeScript integration gaps found while building the live bind app #116
Description
Building the live end-to-end bind app (#72, ts/apps/bind) meant writing everything an outside application needs to get from a ceremony result to a mined IdentityRegistry.bind. These are the TypeScript gaps that work turned up.
Packages
@libid/ceremony,@libid/ledgerand@libid/popupare private. An application outside this monorepo can't install them.- The ceremony pins a
@libid/contractsversion that can lag the deployed chain. Nothing tells an integrator which contracts, circuits and verifiers a ceremony build needs (see "Versions" below).
From a ceremony result to a bind transaction
-
There is no EVM
LedgerId. Every application rebuilds the Chain ID hash (keccak256(U256BE(chainId)), chain-profiles §3.1) by hand. -
There is no payload encoder. The application must know each verifier's struct and encode it as one ABI tuple:
TlsNotaryProoffor GitHub and X;GoogleProoffor Google.
docs/client.mdstops at "hand to your ledger adapter".ts/apps/bind/src/evm.tshas working encoders that could be published. -
Nothing dispatches on the platform. Each platform family needs its own encoder, and there is no single "result to payload" function.
-
One payload's fields come from three places:
- most of it from
oauthProof; - Google's client identifier from
identity.oauthClientId; - the operation domain and transaction data, which
oauthProofdoes not carry, so the application must keep them itself.
None of this is documented.
- most of it from
-
Naming mismatch: an attestation's
signaturein TypeScript isproofin the Solidity struct. -
Narrowing doesn't work: checking
result.identity.platformIddoes not narrowresult.oauthProof's type, so the application needs casts. -
bind'sverifierVersionis easy to confuse. It is the registry's verifier slot, not the proof'splatformCeremonyVersion. The two are both 1 today, so mixing them up works until it doesn't. -
The Authorization Digest helper is not exported, so an application cannot check a proof against its inputs before submitting.
Errors
- The verifiers' error ABIs are not exported. A failed
bindshows a bare selector, such as0xa493bc37(AttestationAhead) orSumcheckFailed(), that viem cannot decode.
Versions
- No compatibility signal between a ceremony build and the verifier artifacts it needs.
- Main's ceremony proves with the libid-circuits v0.6.0 circuits. A chain deployed with an older
libid-deployreverts every bind withSumcheckFailed(). - Nothing checks or states the pairing up front.
- Main's ceremony proves with the libid-circuits v0.6.0 circuits. A chain deployed with an older
- Breaking client API changes arrive without a signal.
client.connectnow generates the connection id andclient.newtakes none; we found it through a broken build.
Already addressed elsewhere
- viem at load time:
@libid/contractsalways loaded viem, even for handle normalization. Fixed by@libid/contracts/handlein libID-contracts popup: mobile-WebKit flake in close-right-after-navigate (CI only) #86. - Two copies of
@libid/contracts: different version pins brokeinstanceof HandleError. One catalog pin, andHandleErrorre-exported from@libid/ens(feat(ens): @libid/ens, the ENS name of a handle #109). - Handle → ENS name:
@libid/ens(feat(ens): @libid/ens, the ENS name of a handle #109).
Suggested first steps
- Publish the packages, or say which ones are meant for integrators.
- An EVM ledger adapter:
evmLedger(chainId, notary)plusencodeBindPayload(result, operationDomain, transactionData)for every platform, built from the generated verifier ABIs so it can't drift. - Export the digest helper and the verifier error ABIs.
- State the circuit and verifier version a ceremony build requires, and check it against the chain before proving.
Activity