@bsv/sdk 2.1.0 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/src/auth/Peer.js +8 -13
- package/dist/cjs/src/auth/Peer.js.map +1 -1
- package/dist/cjs/src/auth/SessionManager.js +4 -7
- package/dist/cjs/src/auth/SessionManager.js.map +1 -1
- package/dist/cjs/src/auth/certificates/MasterCertificate.js +1 -1
- package/dist/cjs/src/auth/certificates/MasterCertificate.js.map +1 -1
- package/dist/cjs/src/auth/certificates/__tests/CompletedProtoWallet.js +1 -1
- package/dist/cjs/src/auth/certificates/__tests/CompletedProtoWallet.js.map +1 -1
- package/dist/cjs/src/auth/clients/AuthFetch.js +32 -32
- package/dist/cjs/src/auth/clients/AuthFetch.js.map +1 -1
- package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js +4 -4
- package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
- package/dist/cjs/src/compat/ECIES.js +29 -34
- package/dist/cjs/src/compat/ECIES.js.map +1 -1
- package/dist/cjs/src/compat/HD.js +9 -4
- package/dist/cjs/src/compat/HD.js.map +1 -1
- package/dist/cjs/src/compat/Mnemonic.js +12 -12
- package/dist/cjs/src/compat/Mnemonic.js.map +1 -1
- package/dist/cjs/src/identity/ContactsManager.js +212 -234
- package/dist/cjs/src/identity/ContactsManager.js.map +1 -1
- package/dist/cjs/src/identity/IdentityClient.js +199 -63
- package/dist/cjs/src/identity/IdentityClient.js.map +1 -1
- package/dist/cjs/src/kvstore/GlobalKVStore.js +30 -31
- package/dist/cjs/src/kvstore/GlobalKVStore.js.map +1 -1
- package/dist/cjs/src/kvstore/LocalKVStore.js +9 -9
- package/dist/cjs/src/kvstore/LocalKVStore.js.map +1 -1
- package/dist/cjs/src/kvstore/kvStoreInterpreter.js +2 -2
- package/dist/cjs/src/kvstore/kvStoreInterpreter.js.map +1 -1
- package/dist/cjs/src/messages/SignedMessage.js +1 -1
- package/dist/cjs/src/messages/SignedMessage.js.map +1 -1
- package/dist/cjs/src/overlay-tools/Historian.js +1 -1
- package/dist/cjs/src/overlay-tools/Historian.js.map +1 -1
- package/dist/cjs/src/overlay-tools/LookupResolver.js +213 -93
- package/dist/cjs/src/overlay-tools/LookupResolver.js.map +1 -1
- package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js +75 -146
- package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js.map +1 -1
- package/dist/cjs/src/primitives/AESGCM.js +2 -2
- package/dist/cjs/src/primitives/AESGCM.js.map +1 -1
- package/dist/cjs/src/primitives/BigNumber.js +164 -148
- package/dist/cjs/src/primitives/BigNumber.js.map +1 -1
- package/dist/cjs/src/primitives/Curve.js +17 -15
- package/dist/cjs/src/primitives/Curve.js.map +1 -1
- package/dist/cjs/src/primitives/ECDSA.js +12 -7
- package/dist/cjs/src/primitives/ECDSA.js.map +1 -1
- package/dist/cjs/src/primitives/Hash.js +312 -105
- package/dist/cjs/src/primitives/Hash.js.map +1 -1
- package/dist/cjs/src/primitives/JacobianPoint.js +8 -8
- package/dist/cjs/src/primitives/JacobianPoint.js.map +1 -1
- package/dist/cjs/src/primitives/K256.js +3 -3
- package/dist/cjs/src/primitives/K256.js.map +1 -1
- package/dist/cjs/src/primitives/Point.js +36 -40
- package/dist/cjs/src/primitives/Point.js.map +1 -1
- package/dist/cjs/src/primitives/PrivateKey.js +4 -4
- package/dist/cjs/src/primitives/PrivateKey.js.map +1 -1
- package/dist/cjs/src/primitives/PublicKey.js +4 -4
- package/dist/cjs/src/primitives/PublicKey.js.map +1 -1
- package/dist/cjs/src/primitives/Random.js +10 -14
- package/dist/cjs/src/primitives/Random.js.map +1 -1
- package/dist/cjs/src/primitives/ReaderUint8Array.js +6 -6
- package/dist/cjs/src/primitives/ReaderUint8Array.js.map +1 -1
- package/dist/cjs/src/primitives/Schnorr.js +2 -2
- package/dist/cjs/src/primitives/Schnorr.js.map +1 -1
- package/dist/cjs/src/primitives/Secp256r1.js +2 -1
- package/dist/cjs/src/primitives/Secp256r1.js.map +1 -1
- package/dist/cjs/src/primitives/Signature.js +8 -8
- package/dist/cjs/src/primitives/Signature.js.map +1 -1
- package/dist/cjs/src/primitives/SymmetricKey.js +123 -1
- package/dist/cjs/src/primitives/SymmetricKey.js.map +1 -1
- package/dist/cjs/src/primitives/TransactionSignature.js +20 -21
- package/dist/cjs/src/primitives/TransactionSignature.js.map +1 -1
- package/dist/cjs/src/primitives/utils.js +39 -46
- package/dist/cjs/src/primitives/utils.js.map +1 -1
- package/dist/cjs/src/registry/RegistryClient.js +31 -23
- package/dist/cjs/src/registry/RegistryClient.js.map +1 -1
- package/dist/cjs/src/remittance/RemittanceManager.js +19 -18
- package/dist/cjs/src/remittance/RemittanceManager.js.map +1 -1
- package/dist/cjs/src/remittance/modules/BasicBRC29.js.map +1 -1
- package/dist/cjs/src/script/Script.js +93 -170
- package/dist/cjs/src/script/Script.js.map +1 -1
- package/dist/cjs/src/script/ScriptEvaluationError.js +2 -2
- package/dist/cjs/src/script/ScriptEvaluationError.js.map +1 -1
- package/dist/cjs/src/script/Spend.js +14 -12
- package/dist/cjs/src/script/Spend.js.map +1 -1
- package/dist/cjs/src/script/templates/PushDrop.js +22 -18
- package/dist/cjs/src/script/templates/PushDrop.js.map +1 -1
- package/dist/cjs/src/script/templates/RPuzzle.js +2 -4
- package/dist/cjs/src/script/templates/RPuzzle.js.map +1 -1
- package/dist/cjs/src/storage/StorageDownloader.js +42 -9
- package/dist/cjs/src/storage/StorageDownloader.js.map +1 -1
- package/dist/cjs/src/totp/totp.js +1 -1
- package/dist/cjs/src/totp/totp.js.map +1 -1
- package/dist/cjs/src/transaction/Beef.js +239 -192
- package/dist/cjs/src/transaction/Beef.js.map +1 -1
- package/dist/cjs/src/transaction/BeefConstants.js +19 -0
- package/dist/cjs/src/transaction/BeefConstants.js.map +1 -0
- package/dist/cjs/src/transaction/BeefTx.js +12 -12
- package/dist/cjs/src/transaction/BeefTx.js.map +1 -1
- package/dist/cjs/src/transaction/MerklePath.js +4 -4
- package/dist/cjs/src/transaction/MerklePath.js.map +1 -1
- package/dist/cjs/src/transaction/Transaction.js +49 -52
- package/dist/cjs/src/transaction/Transaction.js.map +1 -1
- package/dist/cjs/src/transaction/fee-models/SatoshisPerKilobyte.js +1 -1
- package/dist/cjs/src/transaction/fee-models/SatoshisPerKilobyte.js.map +1 -1
- package/dist/cjs/src/transaction/http/BinaryFetchClient.js +9 -9
- package/dist/cjs/src/transaction/http/BinaryFetchClient.js.map +1 -1
- package/dist/cjs/src/transaction/http/DefaultHttpClient.js +9 -9
- package/dist/cjs/src/transaction/http/DefaultHttpClient.js.map +1 -1
- package/dist/cjs/src/wallet/CachedKeyDeriver.js +1 -1
- package/dist/cjs/src/wallet/CachedKeyDeriver.js.map +1 -1
- package/dist/cjs/src/wallet/WalletClient.js.map +1 -1
- package/dist/cjs/src/wallet/WalletError.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/HTTPWalletJSON.js +5 -4
- package/dist/cjs/src/wallet/substrates/HTTPWalletJSON.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/ReactNativeWebView.js +9 -9
- package/dist/cjs/src/wallet/substrates/ReactNativeWebView.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js +92 -92
- package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js +387 -711
- package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/XDM.js +4 -4
- package/dist/cjs/src/wallet/substrates/XDM.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/window.CWI.js +2 -2
- package/dist/cjs/src/wallet/substrates/window.CWI.js.map +1 -1
- package/dist/cjs/src/wallet/validationHelpers.js +9 -9
- package/dist/cjs/src/wallet/validationHelpers.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/auth/Peer.js +25 -13
- package/dist/esm/src/auth/Peer.js.map +1 -1
- package/dist/esm/src/auth/SessionManager.js +4 -7
- package/dist/esm/src/auth/SessionManager.js.map +1 -1
- package/dist/esm/src/auth/certificates/MasterCertificate.js +1 -1
- package/dist/esm/src/auth/certificates/MasterCertificate.js.map +1 -1
- package/dist/esm/src/auth/certificates/__tests/CompletedProtoWallet.js +1 -1
- package/dist/esm/src/auth/certificates/__tests/CompletedProtoWallet.js.map +1 -1
- package/dist/esm/src/auth/clients/AuthFetch.js +32 -32
- package/dist/esm/src/auth/clients/AuthFetch.js.map +1 -1
- package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js +4 -4
- package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
- package/dist/esm/src/compat/ECIES.js +29 -34
- package/dist/esm/src/compat/ECIES.js.map +1 -1
- package/dist/esm/src/compat/HD.js +9 -4
- package/dist/esm/src/compat/HD.js.map +1 -1
- package/dist/esm/src/compat/Mnemonic.js +12 -12
- package/dist/esm/src/compat/Mnemonic.js.map +1 -1
- package/dist/esm/src/identity/ContactsManager.js +212 -234
- package/dist/esm/src/identity/ContactsManager.js.map +1 -1
- package/dist/esm/src/identity/IdentityClient.js +199 -63
- package/dist/esm/src/identity/IdentityClient.js.map +1 -1
- package/dist/esm/src/kvstore/GlobalKVStore.js +30 -31
- package/dist/esm/src/kvstore/GlobalKVStore.js.map +1 -1
- package/dist/esm/src/kvstore/LocalKVStore.js +9 -9
- package/dist/esm/src/kvstore/LocalKVStore.js.map +1 -1
- package/dist/esm/src/kvstore/kvStoreInterpreter.js +2 -2
- package/dist/esm/src/kvstore/kvStoreInterpreter.js.map +1 -1
- package/dist/esm/src/messages/SignedMessage.js +1 -1
- package/dist/esm/src/messages/SignedMessage.js.map +1 -1
- package/dist/esm/src/overlay-tools/Historian.js +1 -1
- package/dist/esm/src/overlay-tools/Historian.js.map +1 -1
- package/dist/esm/src/overlay-tools/LookupResolver.js +213 -93
- package/dist/esm/src/overlay-tools/LookupResolver.js.map +1 -1
- package/dist/esm/src/overlay-tools/SHIPBroadcaster.js +74 -146
- package/dist/esm/src/overlay-tools/SHIPBroadcaster.js.map +1 -1
- package/dist/esm/src/primitives/AESGCM.js +2 -2
- package/dist/esm/src/primitives/AESGCM.js.map +1 -1
- package/dist/esm/src/primitives/BigNumber.js +167 -154
- package/dist/esm/src/primitives/BigNumber.js.map +1 -1
- package/dist/esm/src/primitives/Curve.js +17 -15
- package/dist/esm/src/primitives/Curve.js.map +1 -1
- package/dist/esm/src/primitives/ECDSA.js +12 -7
- package/dist/esm/src/primitives/ECDSA.js.map +1 -1
- package/dist/esm/src/primitives/Hash.js +316 -105
- package/dist/esm/src/primitives/Hash.js.map +1 -1
- package/dist/esm/src/primitives/JacobianPoint.js +8 -8
- package/dist/esm/src/primitives/JacobianPoint.js.map +1 -1
- package/dist/esm/src/primitives/K256.js +3 -3
- package/dist/esm/src/primitives/K256.js.map +1 -1
- package/dist/esm/src/primitives/Point.js +36 -40
- package/dist/esm/src/primitives/Point.js.map +1 -1
- package/dist/esm/src/primitives/PrivateKey.js +4 -4
- package/dist/esm/src/primitives/PrivateKey.js.map +1 -1
- package/dist/esm/src/primitives/PublicKey.js +4 -4
- package/dist/esm/src/primitives/PublicKey.js.map +1 -1
- package/dist/esm/src/primitives/Random.js +10 -14
- package/dist/esm/src/primitives/Random.js.map +1 -1
- package/dist/esm/src/primitives/ReaderUint8Array.js +6 -6
- package/dist/esm/src/primitives/ReaderUint8Array.js.map +1 -1
- package/dist/esm/src/primitives/Schnorr.js +1 -1
- package/dist/esm/src/primitives/Schnorr.js.map +1 -1
- package/dist/esm/src/primitives/Secp256r1.js +2 -1
- package/dist/esm/src/primitives/Secp256r1.js.map +1 -1
- package/dist/esm/src/primitives/Signature.js +8 -8
- package/dist/esm/src/primitives/Signature.js.map +1 -1
- package/dist/esm/src/primitives/SymmetricKey.js +123 -1
- package/dist/esm/src/primitives/SymmetricKey.js.map +1 -1
- package/dist/esm/src/primitives/TransactionSignature.js +20 -21
- package/dist/esm/src/primitives/TransactionSignature.js.map +1 -1
- package/dist/esm/src/primitives/utils.js +39 -48
- package/dist/esm/src/primitives/utils.js.map +1 -1
- package/dist/esm/src/registry/RegistryClient.js +31 -23
- package/dist/esm/src/registry/RegistryClient.js.map +1 -1
- package/dist/esm/src/remittance/RemittanceManager.js +19 -18
- package/dist/esm/src/remittance/RemittanceManager.js.map +1 -1
- package/dist/esm/src/remittance/modules/BasicBRC29.js.map +1 -1
- package/dist/esm/src/script/Script.js +93 -170
- package/dist/esm/src/script/Script.js.map +1 -1
- package/dist/esm/src/script/ScriptEvaluationError.js +2 -2
- package/dist/esm/src/script/ScriptEvaluationError.js.map +1 -1
- package/dist/esm/src/script/Spend.js +14 -12
- package/dist/esm/src/script/Spend.js.map +1 -1
- package/dist/esm/src/script/templates/PushDrop.js +4 -3
- package/dist/esm/src/script/templates/PushDrop.js.map +1 -1
- package/dist/esm/src/script/templates/RPuzzle.js +2 -4
- package/dist/esm/src/script/templates/RPuzzle.js.map +1 -1
- package/dist/esm/src/storage/StorageDownloader.js +1 -1
- package/dist/esm/src/storage/StorageDownloader.js.map +1 -1
- package/dist/esm/src/totp/totp.js +1 -1
- package/dist/esm/src/totp/totp.js.map +1 -1
- package/dist/esm/src/transaction/Beef.js +229 -186
- package/dist/esm/src/transaction/Beef.js.map +1 -1
- package/dist/esm/src/transaction/BeefConstants.js +16 -0
- package/dist/esm/src/transaction/BeefConstants.js.map +1 -0
- package/dist/esm/src/transaction/BeefTx.js +3 -3
- package/dist/esm/src/transaction/BeefTx.js.map +1 -1
- package/dist/esm/src/transaction/MerklePath.js +4 -4
- package/dist/esm/src/transaction/MerklePath.js.map +1 -1
- package/dist/esm/src/transaction/Transaction.js +49 -52
- package/dist/esm/src/transaction/Transaction.js.map +1 -1
- package/dist/esm/src/transaction/fee-models/SatoshisPerKilobyte.js +1 -1
- package/dist/esm/src/transaction/fee-models/SatoshisPerKilobyte.js.map +1 -1
- package/dist/esm/src/transaction/http/BinaryFetchClient.js +9 -9
- package/dist/esm/src/transaction/http/BinaryFetchClient.js.map +1 -1
- package/dist/esm/src/transaction/http/DefaultHttpClient.js +9 -9
- package/dist/esm/src/transaction/http/DefaultHttpClient.js.map +1 -1
- package/dist/esm/src/wallet/CachedKeyDeriver.js +1 -1
- package/dist/esm/src/wallet/CachedKeyDeriver.js.map +1 -1
- package/dist/esm/src/wallet/WalletClient.js.map +1 -1
- package/dist/esm/src/wallet/WalletError.js.map +1 -1
- package/dist/esm/src/wallet/substrates/HTTPWalletJSON.js +5 -4
- package/dist/esm/src/wallet/substrates/HTTPWalletJSON.js.map +1 -1
- package/dist/esm/src/wallet/substrates/ReactNativeWebView.js +9 -9
- package/dist/esm/src/wallet/substrates/ReactNativeWebView.js.map +1 -1
- package/dist/esm/src/wallet/substrates/WalletWireProcessor.js +92 -92
- package/dist/esm/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
- package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js +387 -711
- package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
- package/dist/esm/src/wallet/substrates/XDM.js +4 -4
- package/dist/esm/src/wallet/substrates/XDM.js.map +1 -1
- package/dist/esm/src/wallet/substrates/window.CWI.js +2 -2
- package/dist/esm/src/wallet/substrates/window.CWI.js.map +1 -1
- package/dist/esm/src/wallet/validationHelpers.js +9 -9
- package/dist/esm/src/wallet/validationHelpers.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/auth/Peer.d.ts +13 -0
- package/dist/types/src/auth/Peer.d.ts.map +1 -1
- package/dist/types/src/auth/SessionManager.d.ts.map +1 -1
- package/dist/types/src/auth/clients/AuthFetch.d.ts.map +1 -1
- package/dist/types/src/compat/ECIES.d.ts.map +1 -1
- package/dist/types/src/compat/HD.d.ts.map +1 -1
- package/dist/types/src/identity/ContactsManager.d.ts +31 -2
- package/dist/types/src/identity/ContactsManager.d.ts.map +1 -1
- package/dist/types/src/identity/IdentityClient.d.ts +75 -10
- package/dist/types/src/identity/IdentityClient.d.ts.map +1 -1
- package/dist/types/src/kvstore/GlobalKVStore.d.ts.map +1 -1
- package/dist/types/src/overlay-tools/LookupResolver.d.ts +73 -2
- package/dist/types/src/overlay-tools/LookupResolver.d.ts.map +1 -1
- package/dist/types/src/overlay-tools/SHIPBroadcaster.d.ts +18 -3
- package/dist/types/src/overlay-tools/SHIPBroadcaster.d.ts.map +1 -1
- package/dist/types/src/primitives/BigNumber.d.ts +13 -3
- package/dist/types/src/primitives/BigNumber.d.ts.map +1 -1
- package/dist/types/src/primitives/Curve.d.ts.map +1 -1
- package/dist/types/src/primitives/ECDSA.d.ts.map +1 -1
- package/dist/types/src/primitives/Hash.d.ts +22 -17
- package/dist/types/src/primitives/Hash.d.ts.map +1 -1
- package/dist/types/src/primitives/JacobianPoint.d.ts +3 -1
- package/dist/types/src/primitives/JacobianPoint.d.ts.map +1 -1
- package/dist/types/src/primitives/Point.d.ts.map +1 -1
- package/dist/types/src/primitives/Random.d.ts +2 -2
- package/dist/types/src/primitives/Random.d.ts.map +1 -1
- package/dist/types/src/primitives/ReaderUint8Array.d.ts.map +1 -1
- package/dist/types/src/primitives/Schnorr.d.ts +2 -1
- package/dist/types/src/primitives/Schnorr.d.ts.map +1 -1
- package/dist/types/src/primitives/Secp256r1.d.ts.map +1 -1
- package/dist/types/src/primitives/SymmetricKey.d.ts.map +1 -1
- package/dist/types/src/primitives/utils.d.ts +2 -4
- package/dist/types/src/primitives/utils.d.ts.map +1 -1
- package/dist/types/src/registry/RegistryClient.d.ts.map +1 -1
- package/dist/types/src/remittance/RemittanceManager.d.ts.map +1 -1
- package/dist/types/src/remittance/modules/BasicBRC29.d.ts.map +1 -1
- package/dist/types/src/script/Script.d.ts +15 -8
- package/dist/types/src/script/Script.d.ts.map +1 -1
- package/dist/types/src/script/Spend.d.ts.map +1 -1
- package/dist/types/src/script/templates/PushDrop.d.ts +3 -1
- package/dist/types/src/script/templates/PushDrop.d.ts.map +1 -1
- package/dist/types/src/script/templates/RPuzzle.d.ts.map +1 -1
- package/dist/types/src/transaction/Beef.d.ts +46 -8
- package/dist/types/src/transaction/Beef.d.ts.map +1 -1
- package/dist/types/src/transaction/BeefConstants.d.ts +15 -0
- package/dist/types/src/transaction/BeefConstants.d.ts.map +1 -0
- package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
- package/dist/types/src/wallet/CachedKeyDeriver.d.ts.map +1 -1
- package/dist/types/src/wallet/KeyDeriver.d.ts +1 -1
- package/dist/types/src/wallet/KeyDeriver.d.ts.map +1 -1
- package/dist/types/src/wallet/Wallet.interfaces.d.ts +18 -3
- package/dist/types/src/wallet/Wallet.interfaces.d.ts.map +1 -1
- package/dist/types/src/wallet/WalletClient.d.ts +8 -8
- package/dist/types/src/wallet/WalletClient.d.ts.map +1 -1
- package/dist/types/src/wallet/substrates/HTTPWalletJSON.d.ts +7 -7
- package/dist/types/src/wallet/substrates/HTTPWalletJSON.d.ts.map +1 -1
- package/dist/types/src/wallet/substrates/WalletWireTransceiver.d.ts +36 -7
- package/dist/types/src/wallet/substrates/WalletWireTransceiver.d.ts.map +1 -1
- package/dist/types/src/wallet/substrates/window.CWI.d.ts +9 -9
- package/dist/types/src/wallet/substrates/window.CWI.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +3 -3
- package/package.json +1 -1
- package/src/auth/Peer.ts +26 -13
- package/src/auth/SessionManager.ts +4 -7
- package/src/auth/certificates/MasterCertificate.ts +1 -1
- package/src/auth/certificates/__tests/CompletedProtoWallet.ts +1 -1
- package/src/auth/clients/AuthFetch.ts +41 -41
- package/src/auth/transports/SimplifiedFetchTransport.ts +4 -4
- package/src/compat/ECIES.ts +29 -34
- package/src/compat/HD.ts +10 -5
- package/src/compat/Mnemonic.ts +11 -11
- package/src/compat/__tests/HD.test.ts +19 -0
- package/src/identity/ContactsManager.ts +236 -258
- package/src/identity/IdentityClient.ts +244 -71
- package/src/identity/__tests/IdentityClient.additional.test.ts +150 -1
- package/src/identity/__tests/IdentityClient.test.ts +27 -3
- package/src/kvstore/GlobalKVStore.ts +31 -32
- package/src/kvstore/LocalKVStore.ts +8 -8
- package/src/kvstore/kvStoreInterpreter.ts +2 -2
- package/src/messages/SignedMessage.ts +1 -1
- package/src/overlay-tools/Historian.ts +1 -1
- package/src/overlay-tools/LookupResolver.ts +264 -90
- package/src/overlay-tools/SHIPBroadcaster.ts +92 -168
- package/src/primitives/AESGCM.ts +2 -2
- package/src/primitives/BigNumber.ts +122 -113
- package/src/primitives/Curve.ts +16 -15
- package/src/primitives/ECDSA.ts +10 -8
- package/src/primitives/Hash.ts +381 -146
- package/src/primitives/JacobianPoint.ts +13 -11
- package/src/primitives/K256.ts +3 -3
- package/src/primitives/Point.ts +35 -38
- package/src/primitives/PrivateKey.ts +3 -3
- package/src/primitives/PublicKey.ts +3 -3
- package/src/primitives/Random.ts +11 -14
- package/src/primitives/ReaderUint8Array.ts +7 -7
- package/src/primitives/Schnorr.ts +2 -1
- package/src/primitives/Secp256r1.ts +2 -1
- package/src/primitives/Signature.ts +8 -8
- package/src/primitives/SymmetricKey.ts +145 -1
- package/src/primitives/TransactionSignature.ts +16 -16
- package/src/primitives/__tests/Hash.additional.test.ts +65 -0
- package/src/primitives/__tests/Hash.test.ts +6 -1
- package/src/primitives/utils.ts +37 -47
- package/src/registry/RegistryClient.ts +25 -25
- package/src/remittance/RemittanceManager.ts +17 -18
- package/src/remittance/modules/BasicBRC29.ts +2 -5
- package/src/script/Script.ts +114 -170
- package/src/script/ScriptEvaluationError.ts +2 -2
- package/src/script/Spend.ts +14 -15
- package/src/script/templates/PushDrop.ts +5 -3
- package/src/script/templates/RPuzzle.ts +2 -4
- package/src/storage/StorageDownloader.ts +1 -1
- package/src/totp/totp.ts +1 -1
- package/src/transaction/Beef.ts +241 -203
- package/src/transaction/BeefConstants.ts +16 -0
- package/src/transaction/BeefTx.ts +3 -3
- package/src/transaction/MerklePath.ts +4 -4
- package/src/transaction/Transaction.ts +48 -51
- package/src/transaction/fee-models/SatoshisPerKilobyte.ts +1 -1
- package/src/transaction/http/BinaryFetchClient.ts +8 -8
- package/src/transaction/http/DefaultHttpClient.ts +8 -8
- package/src/wallet/CachedKeyDeriver.ts +8 -6
- package/src/wallet/KeyDeriver.ts +1 -1
- package/src/wallet/Wallet.interfaces.ts +18 -5
- package/src/wallet/WalletClient.ts +9 -9
- package/src/wallet/WalletError.ts +1 -1
- package/src/wallet/__tests/WalletClient.substrate.test.ts +10 -6
- package/src/wallet/substrates/HTTPWalletJSON.ts +22 -21
- package/src/wallet/substrates/ReactNativeWebView.ts +9 -9
- package/src/wallet/substrates/WalletWireProcessor.ts +83 -83
- package/src/wallet/substrates/WalletWireTransceiver.ts +528 -938
- package/src/wallet/substrates/XDM.ts +4 -4
- package/src/wallet/substrates/__tests/HTTPWalletJSON.test.ts +38 -25
- package/src/wallet/substrates/__tests/ReactNativeWebView.test.ts +174 -0
- package/src/wallet/substrates/__tests/window.CWI.test.ts +256 -0
- package/src/wallet/substrates/window.CWI.ts +11 -11
- package/src/wallet/validationHelpers.ts +9 -9
|
@@ -18,6 +18,74 @@ import { PrivateKey, Utils } from '../primitives/index.js'
|
|
|
18
18
|
import { LookupResolver, SHIPBroadcaster, TopicBroadcaster, withDoubleSpendRetry } from '../overlay-tools/index.js'
|
|
19
19
|
import { ContactsManager, Contact } from './ContactsManager.js'
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Maximum number of identity certificates to parse synchronously before yielding to the
|
|
23
|
+
* event loop. Keeps the main thread responsive when an overlay query returns many results
|
|
24
|
+
* (e.g. a bulk enrichment of N identityKeys).
|
|
25
|
+
*/
|
|
26
|
+
const PARSE_BATCH_SIZE = 32
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Yield control to the event loop so queued microtasks / timers can run. Uses
|
|
30
|
+
* `scheduler.yield()` when available (Chromium) or a 0ms macrotask fallback.
|
|
31
|
+
*/
|
|
32
|
+
async function yieldToEventLoop (): Promise<void> {
|
|
33
|
+
const sched = (globalThis as any).scheduler
|
|
34
|
+
if (sched != null && typeof sched.yield === 'function') {
|
|
35
|
+
return await sched.yield()
|
|
36
|
+
}
|
|
37
|
+
return await new Promise<void>((resolve) => setTimeout(resolve, 0))
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Options for {@link IdentityClient.resolveByIdentityKey}. */
|
|
41
|
+
export interface ResolveByIdentityKeyOptions {
|
|
42
|
+
/**
|
|
43
|
+
* Opt-in to consulting personal contacts before/alongside the overlay. Default `false`.
|
|
44
|
+
*
|
|
45
|
+
* Most callers (including any client without a populated contacts basket) pay no benefit
|
|
46
|
+
* from the contacts path and incur its setup cost. Set `true` only in UI contexts where
|
|
47
|
+
* the user has likely saved contacts and a local cache hit is preferable to a fresh overlay
|
|
48
|
+
* answer.
|
|
49
|
+
*/
|
|
50
|
+
useContacts?: boolean
|
|
51
|
+
/**
|
|
52
|
+
* Legacy alias for {@link useContacts}. When provided, takes precedence over the new flag.
|
|
53
|
+
* Kept for binary compatibility — new code should use `useContacts`.
|
|
54
|
+
*/
|
|
55
|
+
overrideWithContacts?: boolean
|
|
56
|
+
/**
|
|
57
|
+
* When `true` (and {@link useContacts} is also true), fire contacts and overlay in parallel
|
|
58
|
+
* rather than short-circuiting on a contacts hit. Use only when callers specifically need a
|
|
59
|
+
* fresh overlay answer alongside any cached contact record.
|
|
60
|
+
*/
|
|
61
|
+
parallel?: boolean
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Options for {@link IdentityClient.resolveByAttributes}. */
|
|
65
|
+
export interface ResolveByAttributesOptions {
|
|
66
|
+
/**
|
|
67
|
+
* Opt-in to consulting personal contacts before/alongside the overlay. Default `false`.
|
|
68
|
+
* See {@link ResolveByIdentityKeyOptions.useContacts}.
|
|
69
|
+
*/
|
|
70
|
+
useContacts?: boolean
|
|
71
|
+
/** Legacy alias for {@link useContacts}. Takes precedence when provided. */
|
|
72
|
+
overrideWithContacts?: boolean
|
|
73
|
+
/**
|
|
74
|
+
* When `true` (and {@link useContacts} is also true), fire contacts and overlay in parallel.
|
|
75
|
+
*/
|
|
76
|
+
parallel?: boolean
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Normalize either legacy boolean / new options object into a canonical { useContacts, parallel }. */
|
|
80
|
+
function normalizeOpts (
|
|
81
|
+
raw: boolean | ResolveByIdentityKeyOptions | ResolveByAttributesOptions | undefined
|
|
82
|
+
): { useContacts: boolean, parallel: boolean } {
|
|
83
|
+
if (raw === undefined) return { useContacts: false, parallel: false }
|
|
84
|
+
if (typeof raw === 'boolean') return { useContacts: raw, parallel: false }
|
|
85
|
+
const useContacts = raw.overrideWithContacts ?? raw.useContacts ?? false
|
|
86
|
+
return { useContacts, parallel: raw.parallel === true }
|
|
87
|
+
}
|
|
88
|
+
|
|
21
89
|
/**
|
|
22
90
|
* IdentityClient lets you discover who others are, and let the world know who you are.
|
|
23
91
|
*/
|
|
@@ -69,7 +137,8 @@ export class IdentityClient {
|
|
|
69
137
|
certificate.signature
|
|
70
138
|
)
|
|
71
139
|
await masterCert.verify()
|
|
72
|
-
} catch (
|
|
140
|
+
} catch (_certVerificationError) {
|
|
141
|
+
// Low-level cert error details are suppressed — surface a user-facing message only
|
|
73
142
|
throw new Error('Public reveal failed: Certificate verification failed!')
|
|
74
143
|
}
|
|
75
144
|
|
|
@@ -97,7 +166,7 @@ export class IdentityClient {
|
|
|
97
166
|
true,
|
|
98
167
|
true
|
|
99
168
|
)
|
|
100
|
-
//
|
|
169
|
+
// Consider verification and if this is necessary
|
|
101
170
|
// counterpartyCanVerifyMyOwnership: true
|
|
102
171
|
|
|
103
172
|
const { tx } = await this.wallet.createAction(
|
|
@@ -128,67 +197,125 @@ export class IdentityClient {
|
|
|
128
197
|
}
|
|
129
198
|
|
|
130
199
|
/**
|
|
131
|
-
* Resolves displayable identity certificates
|
|
200
|
+
* Resolves displayable identity certificates issued to a given identity key.
|
|
201
|
+
*
|
|
202
|
+
* **Default behavior (changed): contacts are NOT consulted.** Most clients have no
|
|
203
|
+
* contacts saved locally, so the previous "contacts-first" default paid setup cost for no
|
|
204
|
+
* gain. Pass `{ useContacts: true }` to opt in — appropriate when you know the user has
|
|
205
|
+
* saved contacts and prefers a local hit over a fresh overlay answer.
|
|
206
|
+
*
|
|
207
|
+
* When `useContacts: true`:
|
|
208
|
+
* - Default short-circuits: if a contact matches, the overlay is skipped entirely.
|
|
209
|
+
* - `{ parallel: true }` fires contacts and overlay in parallel; contact wins on hit.
|
|
132
210
|
*
|
|
133
|
-
* @param
|
|
134
|
-
* @param
|
|
135
|
-
* @returns {Promise<DisplayableIdentity[]>} The promise resolves to displayable identities.
|
|
211
|
+
* @param args - Arguments for requesting the discovery based on the identity key.
|
|
212
|
+
* @param opts - Boolean (legacy) or options object. Boolean `true` ≡ `{ useContacts: true }`.
|
|
136
213
|
*/
|
|
137
214
|
async resolveByIdentityKey (
|
|
138
215
|
args: DiscoverByIdentityKeyArgs,
|
|
139
|
-
|
|
216
|
+
opts: boolean | ResolveByIdentityKeyOptions = false
|
|
140
217
|
): Promise<DisplayableIdentity[]> {
|
|
141
|
-
|
|
218
|
+
const { useContacts, parallel } = normalizeOpts(opts)
|
|
219
|
+
|
|
220
|
+
// Fast path: skip contacts entirely. Default — straight overlay query,
|
|
221
|
+
// no listOutputs / decrypt / cache churn.
|
|
222
|
+
if (!useContacts) {
|
|
223
|
+
const certificatesResult = await this.wallet.discoverByIdentityKey(args, this.originator)
|
|
224
|
+
const certs = certificatesResult?.certificates ?? []
|
|
225
|
+
return await IdentityClient.parseIdentities(certs)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (!parallel) {
|
|
229
|
+
const contacts = await this.contactsManager.getContacts(args.identityKey)
|
|
230
|
+
if (contacts.length > 0) return contacts
|
|
231
|
+
|
|
232
|
+
const certificatesResult = await this.wallet.discoverByIdentityKey(args, this.originator)
|
|
233
|
+
const certs = certificatesResult?.certificates ?? []
|
|
234
|
+
return await IdentityClient.parseIdentities(certs)
|
|
235
|
+
}
|
|
236
|
+
|
|
142
237
|
const [contacts, certificatesResult] = await Promise.all([
|
|
143
|
-
|
|
144
|
-
? this.contactsManager.getContacts(args.identityKey)
|
|
145
|
-
: Promise.resolve([]),
|
|
238
|
+
this.contactsManager.getContacts(args.identityKey),
|
|
146
239
|
this.wallet.discoverByIdentityKey(args, this.originator)
|
|
147
240
|
])
|
|
148
241
|
|
|
149
|
-
|
|
150
|
-
if (contacts.length > 0) {
|
|
151
|
-
return contacts
|
|
152
|
-
}
|
|
153
|
-
|
|
242
|
+
if (contacts.length > 0) return contacts
|
|
154
243
|
const certs = certificatesResult?.certificates ?? []
|
|
155
|
-
return
|
|
156
|
-
return IdentityClient.parseIdentity(cert)
|
|
157
|
-
})
|
|
244
|
+
return await IdentityClient.parseIdentities(certs)
|
|
158
245
|
}
|
|
159
246
|
|
|
160
247
|
/**
|
|
161
|
-
* Resolves displayable identity certificates by specific identity attributes
|
|
248
|
+
* Resolves displayable identity certificates by specific identity attributes.
|
|
162
249
|
*
|
|
163
|
-
*
|
|
164
|
-
* @
|
|
165
|
-
*
|
|
250
|
+
* **Default behavior (changed): contacts are NOT consulted.** See
|
|
251
|
+
* {@link resolveByIdentityKey} for the reasoning. Pass `{ useContacts: true }` to opt in.
|
|
252
|
+
*
|
|
253
|
+
* @param args - Attributes and optional parameters used to discover certificates.
|
|
254
|
+
* @param opts - Boolean (legacy) or options object. Boolean `true` ≡ `{ useContacts: true }`.
|
|
166
255
|
*/
|
|
167
256
|
async resolveByAttributes (
|
|
168
257
|
args: DiscoverByAttributesArgs,
|
|
169
|
-
|
|
258
|
+
opts: boolean | ResolveByAttributesOptions = false
|
|
170
259
|
): Promise<DisplayableIdentity[]> {
|
|
171
|
-
|
|
260
|
+
const { useContacts, parallel } = normalizeOpts(opts)
|
|
261
|
+
|
|
262
|
+
// Fast path: skip contacts entirely.
|
|
263
|
+
if (!useContacts) {
|
|
264
|
+
const certificatesResult = await this.wallet.discoverByAttributes(args, this.originator)
|
|
265
|
+
const certs = certificatesResult?.certificates ?? []
|
|
266
|
+
return await IdentityClient.parseIdentities(certs)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (!parallel) {
|
|
270
|
+
const contacts = await this.contactsManager.getContacts()
|
|
271
|
+
const matches = this.matchContactsByAttributes(contacts, args)
|
|
272
|
+
if (matches.length > 0) return matches
|
|
273
|
+
|
|
274
|
+
const certificatesResult = await this.wallet.discoverByAttributes(args, this.originator)
|
|
275
|
+
const certs = certificatesResult?.certificates ?? []
|
|
276
|
+
if (contacts.length === 0) return await IdentityClient.parseIdentities(certs)
|
|
277
|
+
const contactByKey = new Map<PubKeyHex, Contact>(
|
|
278
|
+
contacts.map((contact) => [contact.identityKey, contact] as const)
|
|
279
|
+
)
|
|
280
|
+
return await IdentityClient.parseIdentitiesWithOverrides(certs, contactByKey)
|
|
281
|
+
}
|
|
282
|
+
|
|
172
283
|
const [contacts, certificatesResult] = await Promise.all([
|
|
173
|
-
|
|
174
|
-
? this.contactsManager.getContacts()
|
|
175
|
-
: Promise.resolve([]),
|
|
284
|
+
this.contactsManager.getContacts(),
|
|
176
285
|
this.wallet.discoverByAttributes(args, this.originator)
|
|
177
286
|
])
|
|
178
287
|
|
|
179
|
-
|
|
288
|
+
const certs = certificatesResult?.certificates ?? []
|
|
289
|
+
if (contacts.length === 0) return await IdentityClient.parseIdentities(certs)
|
|
180
290
|
const contactByKey = new Map<PubKeyHex, Contact>(
|
|
181
291
|
contacts.map((contact) => [contact.identityKey, contact] as const)
|
|
182
292
|
)
|
|
293
|
+
return await IdentityClient.parseIdentitiesWithOverrides(certs, contactByKey)
|
|
294
|
+
}
|
|
183
295
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
296
|
+
/**
|
|
297
|
+
* Best-effort match of contacts against a `DiscoverByAttributesArgs.attributes` shape.
|
|
298
|
+
* Used by the contacts-first path of {@link resolveByAttributes} to decide whether the overlay
|
|
299
|
+
* can be skipped. Compares string-valued attributes against same-named fields on the contact's
|
|
300
|
+
* decrypted record. Returns the subset of contacts that match every supplied attribute.
|
|
301
|
+
*/
|
|
302
|
+
private matchContactsByAttributes (
|
|
303
|
+
contacts: Contact[],
|
|
304
|
+
args: DiscoverByAttributesArgs
|
|
305
|
+
): Contact[] {
|
|
306
|
+
const attrs = (args).attributes
|
|
307
|
+
if (attrs == null || typeof attrs !== 'object' || Array.isArray(attrs)) return []
|
|
308
|
+
const entries = Object.entries(attrs as Record<string, unknown>).filter(
|
|
309
|
+
([, v]) => typeof v === 'string' && v.length > 0
|
|
310
|
+
) as Array<[string, string]>
|
|
311
|
+
if (entries.length === 0) return []
|
|
312
|
+
return contacts.filter((contact) => {
|
|
313
|
+
const bag: Record<string, unknown> = {
|
|
314
|
+
name: contact.name,
|
|
315
|
+
identityKey: contact.identityKey
|
|
316
|
+
}
|
|
317
|
+
return entries.every(([k, v]) => typeof bag[k] === 'string' && (bag[k] as string).toLowerCase() === v.toLowerCase())
|
|
318
|
+
})
|
|
192
319
|
}
|
|
193
320
|
|
|
194
321
|
/**
|
|
@@ -328,6 +455,45 @@ export class IdentityClient {
|
|
|
328
455
|
return await this.contactsManager.removeContact(identityKey)
|
|
329
456
|
}
|
|
330
457
|
|
|
458
|
+
/**
|
|
459
|
+
* Parse an array of certificates into DisplayableIdentity records, yielding to the
|
|
460
|
+
* event loop every {@link PARSE_BATCH_SIZE} entries so large result sets don't hog
|
|
461
|
+
* the main thread. Equivalent to `certs.map(parseIdentity)` for small inputs.
|
|
462
|
+
*/
|
|
463
|
+
static async parseIdentities (certs: IdentityCertificate[]): Promise<DisplayableIdentity[]> {
|
|
464
|
+
const n = certs.length
|
|
465
|
+
if (n <= PARSE_BATCH_SIZE) {
|
|
466
|
+
return certs.map((c) => IdentityClient.parseIdentity(c))
|
|
467
|
+
}
|
|
468
|
+
const out: DisplayableIdentity[] = new Array(n)
|
|
469
|
+
for (let i = 0; i < n; i++) {
|
|
470
|
+
out[i] = IdentityClient.parseIdentity(certs[i])
|
|
471
|
+
if ((i + 1) % PARSE_BATCH_SIZE === 0) await yieldToEventLoop()
|
|
472
|
+
}
|
|
473
|
+
return out
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Same as {@link parseIdentities} but consults a contact override map keyed by subject
|
|
478
|
+
* identity key. Used by `resolveByAttributes` when contacts are loaded.
|
|
479
|
+
*/
|
|
480
|
+
static async parseIdentitiesWithOverrides (
|
|
481
|
+
certs: IdentityCertificate[],
|
|
482
|
+
contactByKey: Map<PubKeyHex, Contact>
|
|
483
|
+
): Promise<DisplayableIdentity[]> {
|
|
484
|
+
const n = certs.length
|
|
485
|
+
if (n <= PARSE_BATCH_SIZE) {
|
|
486
|
+
return certs.map((cert) => contactByKey.get(cert.subject) ?? IdentityClient.parseIdentity(cert))
|
|
487
|
+
}
|
|
488
|
+
const out: DisplayableIdentity[] = new Array(n)
|
|
489
|
+
for (let i = 0; i < n; i++) {
|
|
490
|
+
const cert = certs[i]
|
|
491
|
+
out[i] = contactByKey.get(cert.subject) ?? IdentityClient.parseIdentity(cert)
|
|
492
|
+
if ((i + 1) % PARSE_BATCH_SIZE === 0) await yieldToEventLoop()
|
|
493
|
+
}
|
|
494
|
+
return out
|
|
495
|
+
}
|
|
496
|
+
|
|
331
497
|
/**
|
|
332
498
|
* Parse out identity and certifier attributes to display from an IdentityCertificate
|
|
333
499
|
* @param identityToParse - The Identity Certificate to parse
|
|
@@ -346,42 +512,42 @@ export class IdentityClient {
|
|
|
346
512
|
avatarURL = decryptedFields.profilePhoto
|
|
347
513
|
badgeLabel = `X account certified by ${certifierInfo.name}`
|
|
348
514
|
badgeIconURL = certifierInfo.iconUrl
|
|
349
|
-
badgeClickURL = 'https://socialcert.net' //
|
|
515
|
+
badgeClickURL = 'https://socialcert.net' // (no dedicated page yet)
|
|
350
516
|
break
|
|
351
517
|
case KNOWN_IDENTITY_TYPES.discordCert:
|
|
352
518
|
name = decryptedFields.userName
|
|
353
519
|
avatarURL = decryptedFields.profilePhoto
|
|
354
520
|
badgeLabel = `Discord account certified by ${certifierInfo.name}`
|
|
355
521
|
badgeIconURL = certifierInfo.iconUrl
|
|
356
|
-
badgeClickURL = 'https://socialcert.net' //
|
|
522
|
+
badgeClickURL = 'https://socialcert.net' // (no dedicated page yet)
|
|
357
523
|
break
|
|
358
524
|
case KNOWN_IDENTITY_TYPES.emailCert:
|
|
359
525
|
name = decryptedFields.email
|
|
360
526
|
avatarURL = 'XUTZxep7BBghAJbSBwTjNfmcsDdRFs5EaGEgkESGSgjJVYgMEizu'
|
|
361
527
|
badgeLabel = `Email certified by ${certifierInfo.name}`
|
|
362
528
|
badgeIconURL = certifierInfo.iconUrl
|
|
363
|
-
badgeClickURL = 'https://socialcert.net' //
|
|
529
|
+
badgeClickURL = 'https://socialcert.net' // (no dedicated page yet)
|
|
364
530
|
break
|
|
365
531
|
case KNOWN_IDENTITY_TYPES.phoneCert:
|
|
366
532
|
name = decryptedFields.phoneNumber
|
|
367
533
|
avatarURL = 'XUTLxtX3ELNUwRhLwL7kWNGbdnFM8WG2eSLv84J7654oH8HaJWrU'
|
|
368
534
|
badgeLabel = `Phone certified by ${certifierInfo.name}`
|
|
369
535
|
badgeIconURL = certifierInfo.iconUrl
|
|
370
|
-
badgeClickURL = 'https://socialcert.net' //
|
|
536
|
+
badgeClickURL = 'https://socialcert.net' // (no dedicated page yet)
|
|
371
537
|
break
|
|
372
538
|
case KNOWN_IDENTITY_TYPES.identiCert:
|
|
373
539
|
name = `${decryptedFields.firstName} ${decryptedFields.lastName}`
|
|
374
540
|
avatarURL = decryptedFields.profilePhoto
|
|
375
541
|
badgeLabel = `Government ID certified by ${certifierInfo.name}`
|
|
376
542
|
badgeIconURL = certifierInfo.iconUrl
|
|
377
|
-
badgeClickURL = 'https://identicert.me' //
|
|
543
|
+
badgeClickURL = 'https://identicert.me' // (no dedicated page yet)
|
|
378
544
|
break
|
|
379
545
|
case KNOWN_IDENTITY_TYPES.registrant:
|
|
380
546
|
name = decryptedFields.name
|
|
381
547
|
avatarURL = decryptedFields.icon
|
|
382
548
|
badgeLabel = `Entity certified by ${certifierInfo.name}`
|
|
383
549
|
badgeIconURL = certifierInfo.iconUrl
|
|
384
|
-
badgeClickURL = 'https://bsv-blockchain.github.io/ts-sdk/reference/identity/' //
|
|
550
|
+
badgeClickURL = 'https://bsv-blockchain.github.io/ts-sdk/reference/identity/' // (no dedicated page yet)
|
|
385
551
|
break
|
|
386
552
|
case KNOWN_IDENTITY_TYPES.coolCert:
|
|
387
553
|
name = decryptedFields.cool === 'true' ? 'Cool Person!' : 'Not cool!'
|
|
@@ -392,14 +558,14 @@ export class IdentityClient {
|
|
|
392
558
|
badgeLabel =
|
|
393
559
|
'Represents the ability for anyone to access this information.'
|
|
394
560
|
badgeIconURL = 'XUUV39HVPkpmMzYNTx7rpKzJvXfeiVyQWg2vfSpjBAuhunTCA9uG'
|
|
395
|
-
badgeClickURL = 'https://bsv-blockchain.github.io/ts-sdk/reference/identity/' //
|
|
561
|
+
badgeClickURL = 'https://bsv-blockchain.github.io/ts-sdk/reference/identity/' // (no dedicated page yet)
|
|
396
562
|
break
|
|
397
563
|
case KNOWN_IDENTITY_TYPES.self:
|
|
398
564
|
name = 'You'
|
|
399
565
|
avatarURL = 'XUT9jHGk2qace148jeCX5rDsMftkSGYKmigLwU2PLLBc7Hm63VYR'
|
|
400
566
|
badgeLabel = 'Represents your ability to access this information.'
|
|
401
567
|
badgeIconURL = 'XUUV39HVPkpmMzYNTx7rpKzJvXfeiVyQWg2vfSpjBAuhunTCA9uG'
|
|
402
|
-
badgeClickURL = 'https://bsv-blockchain.github.io/ts-sdk/reference/identity/' //
|
|
568
|
+
badgeClickURL = 'https://bsv-blockchain.github.io/ts-sdk/reference/identity/' // (no dedicated page yet)
|
|
403
569
|
break
|
|
404
570
|
default: {
|
|
405
571
|
const parsed = IdentityClient.tryToParseGenericIdentity(
|
|
@@ -455,34 +621,41 @@ export class IdentityClient {
|
|
|
455
621
|
// Try to construct a name from common field patterns
|
|
456
622
|
const firstName = decryptedFields.firstName
|
|
457
623
|
const lastName = decryptedFields.lastName
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
624
|
+
let fullName: string | undefined
|
|
625
|
+
if (IdentityClient.hasValue(firstName) && IdentityClient.hasValue(lastName)) {
|
|
626
|
+
fullName = `${firstName} ${lastName}`
|
|
627
|
+
} else if (IdentityClient.hasValue(firstName)) {
|
|
628
|
+
fullName = firstName
|
|
629
|
+
} else if (IdentityClient.hasValue(lastName)) {
|
|
630
|
+
fullName = lastName
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
let name: string | undefined
|
|
634
|
+
if (IdentityClient.hasValue(decryptedFields.name)) {
|
|
635
|
+
name = decryptedFields.name
|
|
636
|
+
} else if (IdentityClient.hasValue(decryptedFields.userName)) {
|
|
637
|
+
name = decryptedFields.userName
|
|
638
|
+
} else if (fullName !== undefined) {
|
|
639
|
+
name = fullName
|
|
640
|
+
} else if (IdentityClient.hasValue(decryptedFields.email)) {
|
|
641
|
+
name = decryptedFields.email
|
|
642
|
+
} else {
|
|
643
|
+
name = defaultIdentity.name
|
|
644
|
+
}
|
|
475
645
|
|
|
476
646
|
// Try to find an avatar/photo from common field names
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
647
|
+
let avatarURL: string | undefined
|
|
648
|
+
if (IdentityClient.hasValue(decryptedFields.profilePhoto)) {
|
|
649
|
+
avatarURL = decryptedFields.profilePhoto
|
|
650
|
+
} else if (IdentityClient.hasValue(decryptedFields.avatar)) {
|
|
651
|
+
avatarURL = decryptedFields.avatar
|
|
652
|
+
} else if (IdentityClient.hasValue(decryptedFields.icon)) {
|
|
653
|
+
avatarURL = decryptedFields.icon
|
|
654
|
+
} else if (IdentityClient.hasValue(decryptedFields.photo)) {
|
|
655
|
+
avatarURL = decryptedFields.photo
|
|
656
|
+
} else {
|
|
657
|
+
avatarURL = defaultIdentity.avatarURL
|
|
658
|
+
}
|
|
486
659
|
|
|
487
660
|
// Generate badge information
|
|
488
661
|
const badgeLabel = IdentityClient.hasValue(certifierInfo?.name)
|
|
@@ -571,7 +571,7 @@ describe('IdentityClient (additional coverage)', () => {
|
|
|
571
571
|
mockContactsManager.getContacts = jest.fn().mockResolvedValue([contact])
|
|
572
572
|
walletMock.discoverByAttributes = jest.fn().mockResolvedValue({ certificates: [discoveredCertificate] })
|
|
573
573
|
|
|
574
|
-
const result = await identityClient.resolveByAttributes({ attributes: { email: 'alice@example.com' } })
|
|
574
|
+
const result = await identityClient.resolveByAttributes({ attributes: { email: 'alice@example.com' } }, { useContacts: true })
|
|
575
575
|
expect(result[0].name).toBe('Alice From Contact')
|
|
576
576
|
})
|
|
577
577
|
|
|
@@ -764,4 +764,153 @@ describe('IdentityClient (additional coverage)', () => {
|
|
|
764
764
|
expect(mockContactsManager.removeContact).toHaveBeenCalledWith('key-to-remove')
|
|
765
765
|
})
|
|
766
766
|
})
|
|
767
|
+
|
|
768
|
+
// ─── useContacts branches in resolveByIdentityKey / resolveByAttributes ─────
|
|
769
|
+
|
|
770
|
+
// Shared helpers — extracted to keep new tests DRY (avoid Sonar duplication gate).
|
|
771
|
+
const xCert = (subject: string, userName: string): any => ({
|
|
772
|
+
type: KNOWN_IDENTITY_TYPES.xCert,
|
|
773
|
+
subject,
|
|
774
|
+
decryptedFields: { userName, profilePhoto: '' },
|
|
775
|
+
certifierInfo: { name: 'CX', iconUrl: '' }
|
|
776
|
+
})
|
|
777
|
+
const emailCertOf = (subject: string, email: string): any => ({
|
|
778
|
+
type: KNOWN_IDENTITY_TYPES.emailCert,
|
|
779
|
+
subject,
|
|
780
|
+
decryptedFields: { email },
|
|
781
|
+
certifierInfo: { name: 'EC', iconUrl: '' }
|
|
782
|
+
})
|
|
783
|
+
const contactOf = (name: string, identityKey: string): any => ({
|
|
784
|
+
name, identityKey, avatarURL: '', abbreviatedKey: '', badgeIconURL: '', badgeLabel: '', badgeClickURL: ''
|
|
785
|
+
})
|
|
786
|
+
const stubDiscoveryByKey = (contacts: any[], certificates: any[]): void => {
|
|
787
|
+
identityClient['contactsManager'].getContacts = jest.fn().mockResolvedValue(contacts)
|
|
788
|
+
walletMock.discoverByIdentityKey = jest.fn().mockResolvedValue({ certificates })
|
|
789
|
+
}
|
|
790
|
+
const stubDiscoveryByAttr = (contacts: any[], certificates: any[]): void => {
|
|
791
|
+
identityClient['contactsManager'].getContacts = jest.fn().mockResolvedValue(contacts)
|
|
792
|
+
walletMock.discoverByAttributes = jest.fn().mockResolvedValue({ certificates })
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
describe('resolveByIdentityKey with useContacts opt-in', () => {
|
|
796
|
+
it('contacts miss falls through to overlay (sequential)', async () => {
|
|
797
|
+
stubDiscoveryByKey([], [xCert('k1', 'XUser')])
|
|
798
|
+
const result = await identityClient.resolveByIdentityKey({ identityKey: 'k1' }, { useContacts: true })
|
|
799
|
+
expect(walletMock.discoverByIdentityKey).toHaveBeenCalled()
|
|
800
|
+
expect(result[0].name).toBe('XUser')
|
|
801
|
+
})
|
|
802
|
+
|
|
803
|
+
it('parallel mode returns contact on hit even though overlay runs', async () => {
|
|
804
|
+
const contact = contactOf('Cached Alice', 'k2')
|
|
805
|
+
stubDiscoveryByKey([contact], [])
|
|
806
|
+
const result = await identityClient.resolveByIdentityKey({ identityKey: 'k2' }, { useContacts: true, parallel: true })
|
|
807
|
+
expect(walletMock.discoverByIdentityKey).toHaveBeenCalled()
|
|
808
|
+
expect(result).toEqual([contact])
|
|
809
|
+
})
|
|
810
|
+
|
|
811
|
+
it('parallel mode contacts miss returns parsed overlay results', async () => {
|
|
812
|
+
stubDiscoveryByKey([], [xCert('k3', 'XOnly')])
|
|
813
|
+
const result = await identityClient.resolveByIdentityKey({ identityKey: 'k3' }, { useContacts: true, parallel: true })
|
|
814
|
+
expect(result[0].name).toBe('XOnly')
|
|
815
|
+
})
|
|
816
|
+
|
|
817
|
+
it('legacy boolean opt-in (true) consults contacts', async () => {
|
|
818
|
+
stubDiscoveryByKey([contactOf('Legacy True', 'k4')], [])
|
|
819
|
+
const result = await identityClient.resolveByIdentityKey({ identityKey: 'k4' }, true)
|
|
820
|
+
expect(result[0].name).toBe('Legacy True')
|
|
821
|
+
expect(walletMock.discoverByIdentityKey).not.toHaveBeenCalled()
|
|
822
|
+
})
|
|
823
|
+
|
|
824
|
+
it('overrideWithContacts legacy alias takes precedence over useContacts', async () => {
|
|
825
|
+
stubDiscoveryByKey([contactOf('Override Wins', 'k5')], [])
|
|
826
|
+
const result = await identityClient.resolveByIdentityKey(
|
|
827
|
+
{ identityKey: 'k5' },
|
|
828
|
+
{ useContacts: false, overrideWithContacts: true }
|
|
829
|
+
)
|
|
830
|
+
expect(result[0].name).toBe('Override Wins')
|
|
831
|
+
})
|
|
832
|
+
})
|
|
833
|
+
|
|
834
|
+
describe('resolveByAttributes with useContacts opt-in', () => {
|
|
835
|
+
it('contacts no-match falls through to overlay with contact overrides applied', async () => {
|
|
836
|
+
stubDiscoveryByAttr([contactOf('Override Alice', 'k-over')], [emailCertOf('k-over', 'alice@example.com')])
|
|
837
|
+
const result = await identityClient.resolveByAttributes(
|
|
838
|
+
{ attributes: { email: 'alice@example.com' } },
|
|
839
|
+
{ useContacts: true }
|
|
840
|
+
)
|
|
841
|
+
expect(result[0].name).toBe('Override Alice')
|
|
842
|
+
})
|
|
843
|
+
|
|
844
|
+
it('contacts empty + overlay miss returns empty', async () => {
|
|
845
|
+
stubDiscoveryByAttr([], [])
|
|
846
|
+
const result = await identityClient.resolveByAttributes(
|
|
847
|
+
{ attributes: { email: 'nobody@example.com' } },
|
|
848
|
+
{ useContacts: true }
|
|
849
|
+
)
|
|
850
|
+
expect(result).toEqual([])
|
|
851
|
+
})
|
|
852
|
+
|
|
853
|
+
it('parallel mode with no contacts parses overlay only', async () => {
|
|
854
|
+
stubDiscoveryByAttr([], [emailCertOf('no-contact-key', 'lone@example.com')])
|
|
855
|
+
const result = await identityClient.resolveByAttributes(
|
|
856
|
+
{ attributes: { email: 'lone@example.com' } },
|
|
857
|
+
{ useContacts: true, parallel: true }
|
|
858
|
+
)
|
|
859
|
+
expect(result[0].name).toBe('lone@example.com')
|
|
860
|
+
})
|
|
861
|
+
|
|
862
|
+
it('parallel mode with contacts applies overrides on overlay results', async () => {
|
|
863
|
+
stubDiscoveryByAttr([contactOf('Parallel Contact', 'pk')], [emailCertOf('pk', 'p@example.com')])
|
|
864
|
+
const result = await identityClient.resolveByAttributes(
|
|
865
|
+
{ attributes: { email: 'p@example.com' } },
|
|
866
|
+
{ useContacts: true, parallel: true }
|
|
867
|
+
)
|
|
868
|
+
expect(result[0].name).toBe('Parallel Contact')
|
|
869
|
+
})
|
|
870
|
+
|
|
871
|
+
it('matchContactsByAttributes ignores non-string attribute values', async () => {
|
|
872
|
+
stubDiscoveryByAttr([contactOf('X', 'kkkk')], [])
|
|
873
|
+
const result = await identityClient.resolveByAttributes(
|
|
874
|
+
{ attributes: { count: 5 as unknown as string } },
|
|
875
|
+
{ useContacts: true }
|
|
876
|
+
)
|
|
877
|
+
// No string-valued attrs → matchContactsByAttributes returns [] → overlay path
|
|
878
|
+
expect(walletMock.discoverByAttributes).toHaveBeenCalled()
|
|
879
|
+
expect(result).toEqual([])
|
|
880
|
+
})
|
|
881
|
+
})
|
|
882
|
+
|
|
883
|
+
describe('parseIdentities batched path', () => {
|
|
884
|
+
it('yields to event loop when batch > PARSE_BATCH_SIZE', async () => {
|
|
885
|
+
const certs = Array.from({ length: 64 }, (_, i) => xCert(`subject-${i}`, `user-${i}`))
|
|
886
|
+
const result = await IdentityClient.parseIdentities(certs)
|
|
887
|
+
expect(result).toHaveLength(64)
|
|
888
|
+
expect(result[63].name).toBe('user-63')
|
|
889
|
+
})
|
|
890
|
+
|
|
891
|
+
it('parseIdentitiesWithOverrides batches with overrides applied', async () => {
|
|
892
|
+
const certs = Array.from({ length: 50 }, (_, i) => xCert(`subject-${i}`, `user-${i}`))
|
|
893
|
+
const overrideMap = new Map<string, any>([
|
|
894
|
+
['subject-5', contactOf('Override 5', 'subject-5')],
|
|
895
|
+
['subject-40', contactOf('Override 40', 'subject-40')]
|
|
896
|
+
])
|
|
897
|
+
const result = await IdentityClient.parseIdentitiesWithOverrides(certs, overrideMap)
|
|
898
|
+
expect(result[5].name).toBe('Override 5')
|
|
899
|
+
expect(result[40].name).toBe('Override 40')
|
|
900
|
+
expect(result[6].name).toBe('user-6')
|
|
901
|
+
})
|
|
902
|
+
})
|
|
903
|
+
|
|
904
|
+
describe('yieldToEventLoop scheduler.yield path', () => {
|
|
905
|
+
const origScheduler = (globalThis as any).scheduler
|
|
906
|
+
afterEach(() => { (globalThis as any).scheduler = origScheduler })
|
|
907
|
+
|
|
908
|
+
it('uses scheduler.yield when available', async () => {
|
|
909
|
+
const yieldFn = jest.fn().mockResolvedValue(undefined)
|
|
910
|
+
;(globalThis as any).scheduler = { yield: yieldFn }
|
|
911
|
+
const certs = Array.from({ length: 64 }, (_, i) => xCert(`s-${i}`, `u-${i}`))
|
|
912
|
+
await IdentityClient.parseIdentities(certs)
|
|
913
|
+
expect(yieldFn).toHaveBeenCalled()
|
|
914
|
+
})
|
|
915
|
+
})
|
|
767
916
|
})
|
|
@@ -260,11 +260,35 @@ describe('IdentityClient', () => {
|
|
|
260
260
|
mockContactsManager.getContacts = jest.fn().mockResolvedValue([contact])
|
|
261
261
|
walletMock.discoverByIdentityKey = jest.fn().mockResolvedValue({ certificates: [discoveredCertificate] })
|
|
262
262
|
|
|
263
|
-
const identities = await identityClient.resolveByIdentityKey({ identityKey: 'alice-identity-key' })
|
|
263
|
+
const identities = await identityClient.resolveByIdentityKey({ identityKey: 'alice-identity-key' }, { useContacts: true })
|
|
264
264
|
|
|
265
265
|
expect(identities).toHaveLength(1)
|
|
266
266
|
expect(identities[0].name).toBe('Alice Smith (Personal Contact)') // Contact should be returned, not discovered identity
|
|
267
|
-
//
|
|
267
|
+
// With useContacts opt-in, contacts hit short-circuits the overlay query entirely.
|
|
268
|
+
expect(walletMock.discoverByIdentityKey).not.toHaveBeenCalled()
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
it('should still call the overlay when parallel: true is passed', async () => {
|
|
272
|
+
const contact = {
|
|
273
|
+
name: 'Alice Smith (Personal Contact)',
|
|
274
|
+
identityKey: 'alice-identity-key',
|
|
275
|
+
avatarURL: 'alice-avatar.png',
|
|
276
|
+
abbreviatedKey: 'alice-i...',
|
|
277
|
+
badgeIconURL: '',
|
|
278
|
+
badgeLabel: '',
|
|
279
|
+
badgeClickURL: ''
|
|
280
|
+
}
|
|
281
|
+
const mockContactsManager = identityClient['contactsManager']
|
|
282
|
+
mockContactsManager.getContacts = jest.fn().mockResolvedValue([contact])
|
|
283
|
+
walletMock.discoverByIdentityKey = jest.fn().mockResolvedValue({ certificates: [] })
|
|
284
|
+
|
|
285
|
+
const identities = await identityClient.resolveByIdentityKey(
|
|
286
|
+
{ identityKey: 'alice-identity-key' },
|
|
287
|
+
{ useContacts: true, parallel: true }
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
expect(identities).toHaveLength(1)
|
|
291
|
+
expect(identities[0].name).toBe('Alice Smith (Personal Contact)')
|
|
268
292
|
expect(walletMock.discoverByIdentityKey).toHaveBeenCalled()
|
|
269
293
|
})
|
|
270
294
|
})
|
|
@@ -356,7 +380,7 @@ describe('IdentityClient', () => {
|
|
|
356
380
|
mockContactsManager.getContacts = jest.fn().mockResolvedValue([contact])
|
|
357
381
|
walletMock.discoverByAttributes = jest.fn().mockResolvedValue({ certificates: [discoveredCertificate] })
|
|
358
382
|
|
|
359
|
-
const identities = await identityClient.resolveByAttributes({ attributes: { name: 'Alice' } })
|
|
383
|
+
const identities = await identityClient.resolveByAttributes({ attributes: { name: 'Alice' } }, { useContacts: true })
|
|
360
384
|
|
|
361
385
|
expect(identities).toHaveLength(1)
|
|
362
386
|
expect(identities[0].name).toBe('Alice Smith (Personal)') // Contact should be returned, not discovered identity
|