wowok 2.1.40 → 2.1.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/bcs/bcs.js +1 -253
- package/dist/cjs/bcs/effects.js +1 -199
- package/dist/cjs/bcs/index.js +1 -51
- package/dist/cjs/bcs/pure.js +1 -36
- package/dist/cjs/bcs/type-tag-serializer.js +1 -104
- package/dist/cjs/bcs/types.js +1 -3
- package/dist/cjs/client/index.js +1 -4
- package/dist/cjs/client/network.js +1 -15
- package/dist/cjs/cryptography/index.js +1 -6
- package/dist/cjs/cryptography/intent.js +1 -14
- package/dist/cjs/cryptography/keypair.js +1 -74
- package/dist/cjs/cryptography/mnemonics.js +1 -20
- package/dist/cjs/cryptography/publickey.js +1 -80
- package/dist/cjs/cryptography/signature-scheme.js +1 -22
- package/dist/cjs/cryptography/signature.js +1 -41
- package/dist/cjs/experimental/cache.js +1 -58
- package/dist/cjs/experimental/client.js +1 -19
- package/dist/cjs/experimental/core.js +1 -80
- package/dist/cjs/experimental/errors.js +1 -24
- package/dist/cjs/experimental/index.js +1 -5
- package/dist/cjs/experimental/persistent-storage.js +1 -220
- package/dist/cjs/experimental/persistent-storage.test.js +1 -144
- package/dist/cjs/experimental/transports/utils.js +1 -96
- package/dist/cjs/experimental/types.js +1 -1
- package/dist/cjs/faucet/faucet.js +1 -99
- package/dist/cjs/faucet/index.js +1 -1
- package/dist/cjs/grpc/client.js +1 -42
- package/dist/cjs/grpc/core.js +1 -587
- package/dist/cjs/grpc/index.js +1 -2
- package/dist/cjs/grpc/proto/google/protobuf/any.js +1 -106
- package/dist/cjs/grpc/proto/google/protobuf/duration.js +1 -58
- package/dist/cjs/grpc/proto/google/protobuf/empty.js +1 -7
- package/dist/cjs/grpc/proto/google/protobuf/field_mask.js +1 -47
- package/dist/cjs/grpc/proto/google/protobuf/struct.js +1 -191
- package/dist/cjs/grpc/proto/google/protobuf/timestamp.js +1 -91
- package/dist/cjs/grpc/proto/google/rpc/error_details.js +1 -265
- package/dist/cjs/grpc/proto/google/rpc/status.js +1 -23
- package/dist/cjs/grpc/proto/sui/rpc/v2/argument.js +1 -46
- package/dist/cjs/grpc/proto/sui/rpc/v2/balance_change.js +1 -29
- package/dist/cjs/grpc/proto/sui/rpc/v2/bcs.js +1 -22
- package/dist/cjs/grpc/proto/sui/rpc/v2/checkpoint.js +1 -54
- package/dist/cjs/grpc/proto/sui/rpc/v2/checkpoint_contents.js +1 -60
- package/dist/cjs/grpc/proto/sui/rpc/v2/checkpoint_summary.js +1 -144
- package/dist/cjs/grpc/proto/sui/rpc/v2/effects.js +1 -271
- package/dist/cjs/grpc/proto/sui/rpc/v2/epoch.js +1 -64
- package/dist/cjs/grpc/proto/sui/rpc/v2/error_reason.js +1 -6
- package/dist/cjs/grpc/proto/sui/rpc/v2/event.js +1 -62
- package/dist/cjs/grpc/proto/sui/rpc/v2/executed_transaction.js +1 -64
- package/dist/cjs/grpc/proto/sui/rpc/v2/execution_status.js +1 -481
- package/dist/cjs/grpc/proto/sui/rpc/v2/gas_cost_summary.js +1 -40
- package/dist/cjs/grpc/proto/sui/rpc/v2/input.js +1 -61
- package/dist/cjs/grpc/proto/sui/rpc/v2/jwk.js +1 -57
- package/dist/cjs/grpc/proto/sui/rpc/v2/ledger_service.client.js +1 -39
- package/dist/cjs/grpc/proto/sui/rpc/v2/ledger_service.js +1 -329
- package/dist/cjs/grpc/proto/sui/rpc/v2/move_package.js +1 -447
- package/dist/cjs/grpc/proto/sui/rpc/v2/move_package_service.client.js +1 -27
- package/dist/cjs/grpc/proto/sui/rpc/v2/move_package_service.js +1 -206
- package/dist/cjs/grpc/proto/sui/rpc/v2/name_service.client.js +1 -19
- package/dist/cjs/grpc/proto/sui/rpc/v2/name_service.js +1 -109
- package/dist/cjs/grpc/proto/sui/rpc/v2/object.js +1 -90
- package/dist/cjs/grpc/proto/sui/rpc/v2/object_reference.js +1 -30
- package/dist/cjs/grpc/proto/sui/rpc/v2/owner.js +1 -39
- package/dist/cjs/grpc/proto/sui/rpc/v2/protocol_config.js +1 -30
- package/dist/cjs/grpc/proto/sui/rpc/v2/signature.js +1 -501
- package/dist/cjs/grpc/proto/sui/rpc/v2/signature_scheme.js +1 -10
- package/dist/cjs/grpc/proto/sui/rpc/v2/signature_verification_service.client.js +1 -15
- package/dist/cjs/grpc/proto/sui/rpc/v2/signature_verification_service.js +1 -62
- package/dist/cjs/grpc/proto/sui/rpc/v2/state_service.client.js +1 -31
- package/dist/cjs/grpc/proto/sui/rpc/v2/state_service.js +1 -504
- package/dist/cjs/grpc/proto/sui/rpc/v2/subscription_service.client.js +1 -15
- package/dist/cjs/grpc/proto/sui/rpc/v2/subscription_service.js +1 -37
- package/dist/cjs/grpc/proto/sui/rpc/v2/system_state.js +1 -709
- package/dist/cjs/grpc/proto/sui/rpc/v2/transaction.js +1 -950
- package/dist/cjs/grpc/proto/sui/rpc/v2/transaction_execution_service.client.js +1 -19
- package/dist/cjs/grpc/proto/sui/rpc/v2/transaction_execution_service.js +1 -144
- package/dist/cjs/index.js +1 -22
- package/dist/cjs/jsonRpc/client.js +1 -516
- package/dist/cjs/jsonRpc/core.js +1 -587
- package/dist/cjs/jsonRpc/errors.js +1 -38
- package/dist/cjs/jsonRpc/http-transport.js +1 -70
- package/dist/cjs/jsonRpc/index.js +1 -3
- package/dist/cjs/jsonRpc/json-rpc-resolver.js +1 -296
- package/dist/cjs/jsonRpc/rpc-websocket-client.js +1 -155
- package/dist/cjs/jsonRpc/types/chain.js +1 -1
- package/dist/cjs/jsonRpc/types/changes.js +1 -1
- package/dist/cjs/jsonRpc/types/coins.js +1 -1
- package/dist/cjs/jsonRpc/types/common.js +1 -1
- package/dist/cjs/jsonRpc/types/generated.js +1 -1
- package/dist/cjs/jsonRpc/types/index.js +1 -1
- package/dist/cjs/jsonRpc/types/params.js +1 -1
- package/dist/cjs/keypairs/ed25519/ed25519-hd-key.js +1 -58
- package/dist/cjs/keypairs/ed25519/index.js +1 -2
- package/dist/cjs/keypairs/ed25519/keypair.js +1 -90
- package/dist/cjs/keypairs/ed25519/publickey.js +1 -50
- package/dist/cjs/keypairs/index.js +1 -4
- package/dist/cjs/keypairs/passkey/index.js +1 -2
- package/dist/cjs/keypairs/passkey/keypair.js +1 -155
- package/dist/cjs/keypairs/passkey/publickey.js +1 -117
- package/dist/cjs/keypairs/passkey/types.js +1 -1
- package/dist/cjs/keypairs/secp256k1/index.js +1 -2
- package/dist/cjs/keypairs/secp256k1/keypair.js +1 -82
- package/dist/cjs/keypairs/secp256k1/publickey.js +1 -51
- package/dist/cjs/keypairs/secp256r1/index.js +1 -2
- package/dist/cjs/keypairs/secp256r1/keypair.js +1 -78
- package/dist/cjs/keypairs/secp256r1/publickey.js +1 -52
- package/dist/cjs/multisig/index.js +1 -2
- package/dist/cjs/multisig/publickey.js +1 -201
- package/dist/cjs/multisig/signer.js +1 -58
- package/dist/cjs/transactions/Arguments.js +1 -9
- package/dist/cjs/transactions/Commands.js +1 -102
- package/dist/cjs/transactions/Inputs.js +1 -52
- package/dist/cjs/transactions/ObjectCache.js +1 -205
- package/dist/cjs/transactions/Transaction.js +1 -574
- package/dist/cjs/transactions/TransactionData.js +1 -409
- package/dist/cjs/transactions/__tests__/Transaction.test.js +1 -160
- package/dist/cjs/transactions/__tests__/bcs.test.js +1 -182
- package/dist/cjs/transactions/data/internal.js +1 -169
- package/dist/cjs/transactions/data/v1.js +1 -469
- package/dist/cjs/transactions/data/v2.js +1 -97
- package/dist/cjs/transactions/executor/caching.js +1 -65
- package/dist/cjs/transactions/executor/parallel.js +1 -347
- package/dist/cjs/transactions/executor/queue.js +1 -59
- package/dist/cjs/transactions/executor/serial.js +1 -99
- package/dist/cjs/transactions/hash.js +1 -8
- package/dist/cjs/transactions/index.js +1 -12
- package/dist/cjs/transactions/intents/CoinWithBalance.js +1 -145
- package/dist/cjs/transactions/object.js +1 -87
- package/dist/cjs/transactions/plugins/NamedPackagesPlugin.js +1 -11
- package/dist/cjs/transactions/pure.js +1 -36
- package/dist/cjs/transactions/resolve.js +1 -69
- package/dist/cjs/transactions/serializer.js +1 -167
- package/dist/cjs/transactions/utils.js +1 -121
- package/dist/cjs/utils/constants.js +1 -18
- package/dist/cjs/utils/derived-objects.js +1 -8
- package/dist/cjs/utils/dynamic-fields.js +1 -17
- package/dist/cjs/utils/format.js +1 -11
- package/dist/cjs/utils/index.js +1 -8
- package/dist/cjs/utils/move-registry.js +1 -24
- package/dist/cjs/utils/sui-types.js +1 -66
- package/dist/cjs/utils/suins.js +1 -33
- package/dist/cjs/verify/index.js +1 -1
- package/dist/cjs/verify/verify.js +1 -87
- package/dist/cjs/version.js +1 -2
- package/dist/cjs/w/call/allocation.js +1 -345
- package/dist/cjs/w/call/arb.js +1 -103
- package/dist/cjs/w/call/arbitration.js +1 -1192
- package/dist/cjs/w/call/base.js +1 -293
- package/dist/cjs/w/call/contact.js +1 -345
- package/dist/cjs/w/call/demand.js +1 -681
- package/dist/cjs/w/call/entity.js +1 -173
- package/dist/cjs/w/call/guard-ins.js +1 -4449
- package/dist/cjs/w/call/guard.d.ts +111 -0
- package/dist/cjs/w/call/guard.js +1 -1048
- package/dist/cjs/w/call/index.js +1 -22
- package/dist/cjs/w/call/machine.js +1 -1127
- package/dist/cjs/w/call/order.js +1 -337
- package/dist/cjs/w/call/passport.js +1 -220
- package/dist/cjs/w/call/payment.js +1 -178
- package/dist/cjs/w/call/permission.js +1 -1162
- package/dist/cjs/w/call/personal.js +1 -139
- package/dist/cjs/w/call/progress.js +1 -678
- package/dist/cjs/w/call/proof.js +1 -66
- package/dist/cjs/w/call/repository.js +1 -1024
- package/dist/cjs/w/call/resource.js +1 -108
- package/dist/cjs/w/call/reward.js +1 -675
- package/dist/cjs/w/call/service.js +1 -1960
- package/dist/cjs/w/call/treasury.js +1 -873
- package/dist/cjs/w/call/util.d.ts +1 -0
- package/dist/cjs/w/call/util.js +1 -566
- package/dist/cjs/w/common.js +1 -571
- package/dist/cjs/w/exception.js +1 -618
- package/dist/cjs/w/index.js +1 -8
- package/dist/cjs/w/local/account.js +1 -656
- package/dist/cjs/w/local/cache.js +1 -161
- package/dist/cjs/w/local/config.js +1 -43
- package/dist/cjs/w/local/index.js +1 -228
- package/dist/cjs/w/local/local.js +1 -574
- package/dist/cjs/w/local/storage.js +1 -185
- package/dist/cjs/w/local/token.js +1 -131
- package/dist/cjs/w/local/util.js +1 -26
- package/dist/cjs/w/local/wip.js +1 -864
- package/dist/cjs/w/messenger/crypto.js +1 -380
- package/dist/cjs/w/messenger/index.js +1 -4
- package/dist/cjs/w/messenger/messenger-api.js +1 -1154
- package/dist/cjs/w/messenger/messenger-manager.js +1 -1003
- package/dist/cjs/w/messenger/messenger.js +1 -1093
- package/dist/cjs/w/messenger/server.js +1 -343
- package/dist/cjs/w/messenger/session.js +1 -628
- package/dist/cjs/w/messenger/storage.js +1 -1023
- package/dist/cjs/w/messenger/templates/wts-html-template.js +1 -371
- package/dist/cjs/w/messenger/types.js +1 -76
- package/dist/cjs/w/messenger/utils.js +1 -12
- package/dist/cjs/w/query/bult-in.js +1 -95
- package/dist/cjs/w/query/event.js +1 -137
- package/dist/cjs/w/query/index.js +1 -5
- package/dist/cjs/w/query/object.js +1 -1550
- package/dist/cjs/w/query/received.js +1 -62
- package/dist/cjs/w/query/util.js +1 -49
- package/dist/cjs/w/util.js +1 -587
- package/dist/esm/bcs/bcs.js +1 -253
- package/dist/esm/bcs/effects.js +1 -199
- package/dist/esm/bcs/index.js +1 -51
- package/dist/esm/bcs/pure.js +1 -36
- package/dist/esm/bcs/type-tag-serializer.js +1 -104
- package/dist/esm/bcs/types.js +1 -3
- package/dist/esm/client/index.js +1 -4
- package/dist/esm/client/network.js +1 -15
- package/dist/esm/cryptography/index.js +1 -6
- package/dist/esm/cryptography/intent.js +1 -14
- package/dist/esm/cryptography/keypair.js +1 -74
- package/dist/esm/cryptography/mnemonics.js +1 -20
- package/dist/esm/cryptography/publickey.js +1 -80
- package/dist/esm/cryptography/signature-scheme.js +1 -22
- package/dist/esm/cryptography/signature.js +1 -41
- package/dist/esm/experimental/cache.js +1 -58
- package/dist/esm/experimental/client.js +1 -19
- package/dist/esm/experimental/core.js +1 -80
- package/dist/esm/experimental/errors.js +1 -24
- package/dist/esm/experimental/index.js +1 -5
- package/dist/esm/experimental/persistent-storage.js +1 -220
- package/dist/esm/experimental/persistent-storage.test.js +1 -144
- package/dist/esm/experimental/transports/utils.js +1 -96
- package/dist/esm/experimental/types.js +1 -1
- package/dist/esm/faucet/faucet.js +1 -99
- package/dist/esm/faucet/index.js +1 -1
- package/dist/esm/grpc/client.js +1 -42
- package/dist/esm/grpc/core.js +1 -587
- package/dist/esm/grpc/index.js +1 -2
- package/dist/esm/grpc/proto/google/protobuf/any.js +1 -106
- package/dist/esm/grpc/proto/google/protobuf/duration.js +1 -58
- package/dist/esm/grpc/proto/google/protobuf/empty.js +1 -7
- package/dist/esm/grpc/proto/google/protobuf/field_mask.js +1 -47
- package/dist/esm/grpc/proto/google/protobuf/struct.js +1 -191
- package/dist/esm/grpc/proto/google/protobuf/timestamp.js +1 -91
- package/dist/esm/grpc/proto/google/rpc/error_details.js +1 -265
- package/dist/esm/grpc/proto/google/rpc/status.js +1 -23
- package/dist/esm/grpc/proto/sui/rpc/v2/argument.js +1 -46
- package/dist/esm/grpc/proto/sui/rpc/v2/balance_change.js +1 -29
- package/dist/esm/grpc/proto/sui/rpc/v2/bcs.js +1 -22
- package/dist/esm/grpc/proto/sui/rpc/v2/checkpoint.js +1 -54
- package/dist/esm/grpc/proto/sui/rpc/v2/checkpoint_contents.js +1 -60
- package/dist/esm/grpc/proto/sui/rpc/v2/checkpoint_summary.js +1 -144
- package/dist/esm/grpc/proto/sui/rpc/v2/effects.js +1 -271
- package/dist/esm/grpc/proto/sui/rpc/v2/epoch.js +1 -64
- package/dist/esm/grpc/proto/sui/rpc/v2/error_reason.js +1 -6
- package/dist/esm/grpc/proto/sui/rpc/v2/event.js +1 -62
- package/dist/esm/grpc/proto/sui/rpc/v2/executed_transaction.js +1 -64
- package/dist/esm/grpc/proto/sui/rpc/v2/execution_status.js +1 -481
- package/dist/esm/grpc/proto/sui/rpc/v2/gas_cost_summary.js +1 -40
- package/dist/esm/grpc/proto/sui/rpc/v2/input.js +1 -61
- package/dist/esm/grpc/proto/sui/rpc/v2/jwk.js +1 -57
- package/dist/esm/grpc/proto/sui/rpc/v2/ledger_service.client.js +1 -39
- package/dist/esm/grpc/proto/sui/rpc/v2/ledger_service.js +1 -329
- package/dist/esm/grpc/proto/sui/rpc/v2/move_package.js +1 -447
- package/dist/esm/grpc/proto/sui/rpc/v2/move_package_service.client.js +1 -27
- package/dist/esm/grpc/proto/sui/rpc/v2/move_package_service.js +1 -206
- package/dist/esm/grpc/proto/sui/rpc/v2/name_service.client.js +1 -19
- package/dist/esm/grpc/proto/sui/rpc/v2/name_service.js +1 -109
- package/dist/esm/grpc/proto/sui/rpc/v2/object.js +1 -90
- package/dist/esm/grpc/proto/sui/rpc/v2/object_reference.js +1 -30
- package/dist/esm/grpc/proto/sui/rpc/v2/owner.js +1 -39
- package/dist/esm/grpc/proto/sui/rpc/v2/protocol_config.js +1 -30
- package/dist/esm/grpc/proto/sui/rpc/v2/signature.js +1 -501
- package/dist/esm/grpc/proto/sui/rpc/v2/signature_scheme.js +1 -10
- package/dist/esm/grpc/proto/sui/rpc/v2/signature_verification_service.client.js +1 -15
- package/dist/esm/grpc/proto/sui/rpc/v2/signature_verification_service.js +1 -62
- package/dist/esm/grpc/proto/sui/rpc/v2/state_service.client.js +1 -31
- package/dist/esm/grpc/proto/sui/rpc/v2/state_service.js +1 -504
- package/dist/esm/grpc/proto/sui/rpc/v2/subscription_service.client.js +1 -15
- package/dist/esm/grpc/proto/sui/rpc/v2/subscription_service.js +1 -37
- package/dist/esm/grpc/proto/sui/rpc/v2/system_state.js +1 -709
- package/dist/esm/grpc/proto/sui/rpc/v2/transaction.js +1 -950
- package/dist/esm/grpc/proto/sui/rpc/v2/transaction_execution_service.client.js +1 -19
- package/dist/esm/grpc/proto/sui/rpc/v2/transaction_execution_service.js +1 -144
- package/dist/esm/index.js +1 -22
- package/dist/esm/jsonRpc/client.js +1 -516
- package/dist/esm/jsonRpc/core.js +1 -587
- package/dist/esm/jsonRpc/errors.js +1 -38
- package/dist/esm/jsonRpc/http-transport.js +1 -70
- package/dist/esm/jsonRpc/index.js +1 -3
- package/dist/esm/jsonRpc/json-rpc-resolver.js +1 -296
- package/dist/esm/jsonRpc/rpc-websocket-client.js +1 -155
- package/dist/esm/jsonRpc/types/chain.js +1 -1
- package/dist/esm/jsonRpc/types/changes.js +1 -1
- package/dist/esm/jsonRpc/types/coins.js +1 -1
- package/dist/esm/jsonRpc/types/common.js +1 -1
- package/dist/esm/jsonRpc/types/generated.js +1 -1
- package/dist/esm/jsonRpc/types/index.js +1 -1
- package/dist/esm/jsonRpc/types/params.js +1 -1
- package/dist/esm/keypairs/ed25519/ed25519-hd-key.js +1 -58
- package/dist/esm/keypairs/ed25519/index.js +1 -2
- package/dist/esm/keypairs/ed25519/keypair.js +1 -90
- package/dist/esm/keypairs/ed25519/publickey.js +1 -50
- package/dist/esm/keypairs/index.js +1 -4
- package/dist/esm/keypairs/passkey/index.js +1 -2
- package/dist/esm/keypairs/passkey/keypair.js +1 -155
- package/dist/esm/keypairs/passkey/publickey.js +1 -117
- package/dist/esm/keypairs/passkey/types.js +1 -1
- package/dist/esm/keypairs/secp256k1/index.js +1 -2
- package/dist/esm/keypairs/secp256k1/keypair.js +1 -82
- package/dist/esm/keypairs/secp256k1/publickey.js +1 -51
- package/dist/esm/keypairs/secp256r1/index.js +1 -2
- package/dist/esm/keypairs/secp256r1/keypair.js +1 -78
- package/dist/esm/keypairs/secp256r1/publickey.js +1 -52
- package/dist/esm/multisig/index.js +1 -2
- package/dist/esm/multisig/publickey.js +1 -201
- package/dist/esm/multisig/signer.js +1 -58
- package/dist/esm/transactions/Arguments.js +1 -9
- package/dist/esm/transactions/Commands.js +1 -102
- package/dist/esm/transactions/Inputs.js +1 -52
- package/dist/esm/transactions/ObjectCache.js +1 -205
- package/dist/esm/transactions/Transaction.js +1 -574
- package/dist/esm/transactions/TransactionData.js +1 -409
- package/dist/esm/transactions/__tests__/Transaction.test.js +1 -160
- package/dist/esm/transactions/__tests__/bcs.test.js +1 -182
- package/dist/esm/transactions/data/internal.js +1 -169
- package/dist/esm/transactions/data/v1.js +1 -469
- package/dist/esm/transactions/data/v2.js +1 -97
- package/dist/esm/transactions/executor/caching.js +1 -65
- package/dist/esm/transactions/executor/parallel.js +1 -347
- package/dist/esm/transactions/executor/queue.js +1 -59
- package/dist/esm/transactions/executor/serial.js +1 -99
- package/dist/esm/transactions/hash.js +1 -8
- package/dist/esm/transactions/index.js +1 -12
- package/dist/esm/transactions/intents/CoinWithBalance.js +1 -145
- package/dist/esm/transactions/object.js +1 -87
- package/dist/esm/transactions/plugins/NamedPackagesPlugin.js +1 -11
- package/dist/esm/transactions/pure.js +1 -36
- package/dist/esm/transactions/resolve.js +1 -69
- package/dist/esm/transactions/serializer.js +1 -167
- package/dist/esm/transactions/utils.js +1 -121
- package/dist/esm/utils/constants.js +1 -18
- package/dist/esm/utils/derived-objects.js +1 -8
- package/dist/esm/utils/dynamic-fields.js +1 -17
- package/dist/esm/utils/format.js +1 -11
- package/dist/esm/utils/index.js +1 -8
- package/dist/esm/utils/move-registry.js +1 -24
- package/dist/esm/utils/sui-types.js +1 -66
- package/dist/esm/utils/suins.js +1 -33
- package/dist/esm/verify/index.js +1 -1
- package/dist/esm/verify/verify.js +1 -87
- package/dist/esm/version.js +1 -2
- package/dist/esm/w/call/allocation.js +1 -345
- package/dist/esm/w/call/arb.js +1 -103
- package/dist/esm/w/call/arbitration.js +1 -1192
- package/dist/esm/w/call/base.js +1 -293
- package/dist/esm/w/call/contact.js +1 -345
- package/dist/esm/w/call/demand.js +1 -681
- package/dist/esm/w/call/entity.js +1 -173
- package/dist/esm/w/call/guard-ins.js +1 -4449
- package/dist/esm/w/call/guard.d.ts +111 -0
- package/dist/esm/w/call/guard.js +1 -1048
- package/dist/esm/w/call/index.js +1 -22
- package/dist/esm/w/call/machine.js +1 -1127
- package/dist/esm/w/call/order.js +1 -337
- package/dist/esm/w/call/passport.js +1 -220
- package/dist/esm/w/call/payment.js +1 -178
- package/dist/esm/w/call/permission.js +1 -1162
- package/dist/esm/w/call/personal.js +1 -139
- package/dist/esm/w/call/progress.js +1 -678
- package/dist/esm/w/call/proof.js +1 -66
- package/dist/esm/w/call/repository.js +1 -1024
- package/dist/esm/w/call/resource.js +1 -108
- package/dist/esm/w/call/reward.js +1 -675
- package/dist/esm/w/call/service.js +1 -1960
- package/dist/esm/w/call/treasury.js +1 -873
- package/dist/esm/w/call/util.d.ts +1 -0
- package/dist/esm/w/call/util.js +1 -566
- package/dist/esm/w/common.js +1 -571
- package/dist/esm/w/exception.js +1 -618
- package/dist/esm/w/index.js +1 -8
- package/dist/esm/w/local/account.js +1 -656
- package/dist/esm/w/local/cache.js +1 -161
- package/dist/esm/w/local/config.js +1 -43
- package/dist/esm/w/local/index.js +1 -228
- package/dist/esm/w/local/local.js +1 -574
- package/dist/esm/w/local/storage.js +1 -185
- package/dist/esm/w/local/token.js +1 -131
- package/dist/esm/w/local/util.js +1 -26
- package/dist/esm/w/local/wip.js +1 -864
- package/dist/esm/w/messenger/crypto.js +1 -380
- package/dist/esm/w/messenger/index.js +1 -4
- package/dist/esm/w/messenger/messenger-api.js +1 -1154
- package/dist/esm/w/messenger/messenger-manager.js +1 -1003
- package/dist/esm/w/messenger/messenger.js +1 -1093
- package/dist/esm/w/messenger/server.js +1 -343
- package/dist/esm/w/messenger/session.js +1 -628
- package/dist/esm/w/messenger/storage.js +1 -1023
- package/dist/esm/w/messenger/templates/wts-html-template.js +1 -371
- package/dist/esm/w/messenger/types.js +1 -76
- package/dist/esm/w/messenger/utils.js +1 -12
- package/dist/esm/w/query/bult-in.js +1 -95
- package/dist/esm/w/query/event.js +1 -137
- package/dist/esm/w/query/index.js +1 -5
- package/dist/esm/w/query/object.js +1 -1550
- package/dist/esm/w/query/received.js +1 -62
- package/dist/esm/w/query/util.js +1 -49
- package/dist/esm/w/util.js +1 -587
- package/package.json +5 -2
|
@@ -1,628 +1 @@
|
|
|
1
|
-
import { KeyHelper, SessionBuilder, SessionCipher, SignalProtocolAddress, } from "libsignal-protocol-typescript";
|
|
2
|
-
import { SignalProtocolStorage } from "./storage.js";
|
|
3
|
-
import { MessengerServerClient } from "./server.js";
|
|
4
|
-
import { recoverXed25519FromX25519PrivateKey, arrayBufferToUint8Array, bytesToBase64, base64ToBytes, } from "./crypto.js";
|
|
5
|
-
import { MessageType, DEFAULT_MESSENGER_CONFIG, MessengerError, MessengerErrorCode, DEFAULT_DEVICE_ID, } from "./types.js";
|
|
6
|
-
async function getAccount() {
|
|
7
|
-
const { Account } = await import("../local/account.js");
|
|
8
|
-
return Account.Instance();
|
|
9
|
-
}
|
|
10
|
-
export class MessengerSession {
|
|
11
|
-
store;
|
|
12
|
-
serverClient;
|
|
13
|
-
config;
|
|
14
|
-
identity = null;
|
|
15
|
-
constructor(userAddress, config) {
|
|
16
|
-
this.store = new SignalProtocolStorage(userAddress);
|
|
17
|
-
this.config = { ...DEFAULT_MESSENGER_CONFIG, ...config };
|
|
18
|
-
this.serverClient = new MessengerServerClient(this.config);
|
|
19
|
-
}
|
|
20
|
-
async ensureIdentity(userAddress) {
|
|
21
|
-
if (this.identity) {
|
|
22
|
-
return this.identity;
|
|
23
|
-
}
|
|
24
|
-
const existingSignalIdentity = await this.store.getIdentityKeyPair();
|
|
25
|
-
const existingRegId = await this.store.getLocalRegistrationId();
|
|
26
|
-
if (existingSignalIdentity && existingRegId) {
|
|
27
|
-
const x25519PrivateKey = new Uint8Array(existingSignalIdentity.privKey);
|
|
28
|
-
const xed25519 = recoverXed25519FromX25519PrivateKey(x25519PrivateKey);
|
|
29
|
-
this.identity = {
|
|
30
|
-
xed25519,
|
|
31
|
-
signalIdentity: existingSignalIdentity,
|
|
32
|
-
registrationId: existingRegId,
|
|
33
|
-
};
|
|
34
|
-
return this.identity;
|
|
35
|
-
}
|
|
36
|
-
if (!userAddress) {
|
|
37
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "userAddress is required to derive identity");
|
|
38
|
-
}
|
|
39
|
-
const { privateKey, publicKey } = await (await getAccount()).deriveX25519KeyPair(userAddress);
|
|
40
|
-
const registrationId = this.deriveRegistrationId(publicKey);
|
|
41
|
-
const prefixedPublicKey = new Uint8Array(33);
|
|
42
|
-
prefixedPublicKey[0] = 0x05;
|
|
43
|
-
prefixedPublicKey.set(publicKey, 1);
|
|
44
|
-
const signalIdentity = {
|
|
45
|
-
privKey: privateKey.slice().buffer,
|
|
46
|
-
pubKey: prefixedPublicKey.slice().buffer,
|
|
47
|
-
};
|
|
48
|
-
await this.store.setIdentity(signalIdentity, registrationId);
|
|
49
|
-
const xed25519 = recoverXed25519FromX25519PrivateKey(privateKey);
|
|
50
|
-
this.identity = {
|
|
51
|
-
xed25519,
|
|
52
|
-
signalIdentity,
|
|
53
|
-
registrationId,
|
|
54
|
-
};
|
|
55
|
-
return this.identity;
|
|
56
|
-
}
|
|
57
|
-
deriveRegistrationId(publicKey) {
|
|
58
|
-
const id = (publicKey[0] << 8) | publicKey[1];
|
|
59
|
-
return id === 0 ? 1 : id;
|
|
60
|
-
}
|
|
61
|
-
async registerDevice(userAddress) {
|
|
62
|
-
const identity = await this.ensureIdentity(userAddress);
|
|
63
|
-
const signedPreKeyId = 1;
|
|
64
|
-
let signedPreKey;
|
|
65
|
-
let signedPreKeyPublicKey;
|
|
66
|
-
let signedPreKeySignature;
|
|
67
|
-
let isNewKey = false;
|
|
68
|
-
const existingSignedPreKey = await this.store.loadSignedPreKeyWithSignature(signedPreKeyId);
|
|
69
|
-
if (existingSignedPreKey) {
|
|
70
|
-
signedPreKeyPublicKey = arrayBufferToUint8Array(existingSignedPreKey.pubKey);
|
|
71
|
-
signedPreKeySignature = arrayBufferToUint8Array(existingSignedPreKey.signature);
|
|
72
|
-
signedPreKey = {
|
|
73
|
-
keyId: signedPreKeyId,
|
|
74
|
-
keyPair: {
|
|
75
|
-
pubKey: existingSignedPreKey.pubKey,
|
|
76
|
-
privKey: existingSignedPreKey.privKey,
|
|
77
|
-
},
|
|
78
|
-
signature: existingSignedPreKey.signature,
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
signedPreKey = await KeyHelper.generateSignedPreKey(identity.signalIdentity, signedPreKeyId);
|
|
83
|
-
signedPreKeyPublicKey = arrayBufferToUint8Array(signedPreKey.keyPair.pubKey);
|
|
84
|
-
signedPreKeySignature = arrayBufferToUint8Array(signedPreKey.signature);
|
|
85
|
-
isNewKey = true;
|
|
86
|
-
}
|
|
87
|
-
const oneTimePrekeys = await this.generatePreKeyBatch(this.config.prekey_count, userAddress);
|
|
88
|
-
const prefixedIdentityKey = arrayBufferToUint8Array(identity.signalIdentity.pubKey);
|
|
89
|
-
const account = await (await getAccount()).get(userAddress, false);
|
|
90
|
-
if (!account?.pubkey) {
|
|
91
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, `Account not found for ${userAddress}`);
|
|
92
|
-
}
|
|
93
|
-
const timestamp = Date.now();
|
|
94
|
-
const nonce = this.generateNonce();
|
|
95
|
-
const message = `register:${account.pubkey}:${timestamp}:${nonce}`;
|
|
96
|
-
const signResult = await (await getAccount()).signData(userAddress, message);
|
|
97
|
-
const signature = Buffer.from(signResult.signature.slice(2), "hex");
|
|
98
|
-
const registerRequest = {
|
|
99
|
-
userAddress,
|
|
100
|
-
deviceId: DEFAULT_DEVICE_ID,
|
|
101
|
-
registrationId: identity.registrationId,
|
|
102
|
-
identityKey: bytesToBase64(prefixedIdentityKey),
|
|
103
|
-
signedPrekey: {
|
|
104
|
-
keyId: signedPreKeyId,
|
|
105
|
-
publicKey: bytesToBase64(signedPreKeyPublicKey),
|
|
106
|
-
signature: bytesToBase64(signedPreKeySignature),
|
|
107
|
-
},
|
|
108
|
-
prekeys: oneTimePrekeys,
|
|
109
|
-
publicKey: account.pubkey,
|
|
110
|
-
signatureScheme: "ED25519",
|
|
111
|
-
signature: bytesToBase64(signature),
|
|
112
|
-
timestamp,
|
|
113
|
-
nonce,
|
|
114
|
-
};
|
|
115
|
-
console.log(`[Session Debug] Sending register request to server...`);
|
|
116
|
-
await this.serverClient.registerDevice(registerRequest);
|
|
117
|
-
console.log(`[Session Debug] Server register request successful!`);
|
|
118
|
-
console.log(`[Session Debug] Verifying registration complete...`);
|
|
119
|
-
await this.verifyRegistrationComplete(userAddress);
|
|
120
|
-
console.log(`[Session Debug] Registration verification complete!`);
|
|
121
|
-
if (isNewKey) {
|
|
122
|
-
await this.store.storeSignedPreKeyWithSignature(signedPreKeyId, signedPreKey.keyPair, signedPreKeySignature.buffer.slice(0));
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
async verifyRegistrationComplete(userAddress, maxRetries = 10, retryDelay = 500) {
|
|
126
|
-
for (let i = 0; i < maxRetries; i++) {
|
|
127
|
-
try {
|
|
128
|
-
const status = await this.serverClient.getPrekeyStatus(userAddress);
|
|
129
|
-
console.log(`Registration verified for ${userAddress}, prekeys: ${status.currentCount}/${status.maxAllowed}`);
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
catch (error) {
|
|
133
|
-
if (error?.message?.includes("404") || error?.status === 404) {
|
|
134
|
-
if (i < maxRetries - 1) {
|
|
135
|
-
console.log(`Waiting for registration to complete... (${i + 1}/${maxRetries})`);
|
|
136
|
-
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
137
|
-
continue;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
throw error;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
throw new MessengerError(MessengerErrorCode.REGISTRATION_FAILED, `Registration verification failed after ${maxRetries} attempts`);
|
|
144
|
-
}
|
|
145
|
-
async isDeviceRegistered(userAddress) {
|
|
146
|
-
try {
|
|
147
|
-
const signedPreKey = await this.store.loadSignedPreKeyWithSignature(1);
|
|
148
|
-
if (!signedPreKey) {
|
|
149
|
-
return false;
|
|
150
|
-
}
|
|
151
|
-
const _status = await this.serverClient.getPrekeyStatus(userAddress);
|
|
152
|
-
return true;
|
|
153
|
-
}
|
|
154
|
-
catch (error) {
|
|
155
|
-
if (error?.message?.includes("404") || error?.status === 404) {
|
|
156
|
-
return false;
|
|
157
|
-
}
|
|
158
|
-
return false;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
async generatePreKeyBatch(count, userAddress) {
|
|
162
|
-
if (count <= 0)
|
|
163
|
-
return [];
|
|
164
|
-
const meta = await this.store.getMeta();
|
|
165
|
-
let nextPreKeyId = meta.nextPreKeyId || 1;
|
|
166
|
-
const prekeys = [];
|
|
167
|
-
for (let i = 0; i < count; i++) {
|
|
168
|
-
const keyId = nextPreKeyId + i;
|
|
169
|
-
const existingPreKey = await this.store.loadPreKey(keyId);
|
|
170
|
-
if (existingPreKey) {
|
|
171
|
-
const pubKeyBytes = new Uint8Array(existingPreKey.pubKey);
|
|
172
|
-
const publicKeyBase64 = bytesToBase64(pubKeyBytes);
|
|
173
|
-
const signResult = await (await getAccount()).signData(userAddress, pubKeyBytes);
|
|
174
|
-
const signature = Buffer.from(signResult.signature.slice(2), "hex");
|
|
175
|
-
prekeys.push({
|
|
176
|
-
keyId,
|
|
177
|
-
publicKey: publicKeyBase64,
|
|
178
|
-
signature: bytesToBase64(signature),
|
|
179
|
-
});
|
|
180
|
-
continue;
|
|
181
|
-
}
|
|
182
|
-
const preKey = await KeyHelper.generatePreKey(keyId);
|
|
183
|
-
const pubKeyBytes = new Uint8Array(preKey.keyPair.pubKey);
|
|
184
|
-
const signResult = await (await getAccount()).signData(userAddress, pubKeyBytes);
|
|
185
|
-
const signature = Buffer.from(signResult.signature.slice(2), "hex");
|
|
186
|
-
await this.store.storePreKey(keyId, preKey.keyPair);
|
|
187
|
-
prekeys.push({
|
|
188
|
-
keyId,
|
|
189
|
-
publicKey: bytesToBase64(pubKeyBytes),
|
|
190
|
-
signature: bytesToBase64(signature),
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
nextPreKeyId += count;
|
|
194
|
-
await this.store.setMeta({ nextPreKeyId });
|
|
195
|
-
return prekeys;
|
|
196
|
-
}
|
|
197
|
-
async ensurePreKeys(userAddress, force = false) {
|
|
198
|
-
const status = await this.serverClient.getPrekeyStatus(userAddress);
|
|
199
|
-
if (!force && status.currentCount >= status.maxAllowed) {
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
const needCount = status.maxAllowed - status.currentCount;
|
|
203
|
-
if (needCount <= 0) {
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
await this.ensureIdentity(userAddress);
|
|
207
|
-
const prekeys = await this.generatePreKeyBatch(needCount, userAddress);
|
|
208
|
-
if (prekeys.length === 0) {
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
const account = await (await getAccount()).get(userAddress, false);
|
|
212
|
-
if (!account?.pubkey) {
|
|
213
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, `Account not found for ${userAddress}`);
|
|
214
|
-
}
|
|
215
|
-
const timestamp = Date.now();
|
|
216
|
-
const nonce = this.generateNonce();
|
|
217
|
-
const message = `upload_prekeys:${account.pubkey}:${timestamp}:${nonce}`;
|
|
218
|
-
const signResult = await (await getAccount()).signData(userAddress, message);
|
|
219
|
-
const signature = Buffer.from(signResult.signature.slice(2), "hex");
|
|
220
|
-
await this.serverClient.uploadPreKeys({
|
|
221
|
-
userAddress,
|
|
222
|
-
prekeys,
|
|
223
|
-
publicKey: account.pubkey,
|
|
224
|
-
signatureScheme: "ED25519",
|
|
225
|
-
signature: bytesToBase64(signature),
|
|
226
|
-
timestamp,
|
|
227
|
-
nonce,
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
generateNonce() {
|
|
231
|
-
const array = new Uint8Array(16);
|
|
232
|
-
crypto.getRandomValues(array);
|
|
233
|
-
return Array.from(array, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
234
|
-
}
|
|
235
|
-
async establishSession(myAddress, peerAddress, peerDeviceId = DEFAULT_DEVICE_ID, remoteBundle) {
|
|
236
|
-
const protocolAddress = new SignalProtocolAddress(peerAddress, peerDeviceId);
|
|
237
|
-
const existingSession = await this.store.loadSession(protocolAddress.toString());
|
|
238
|
-
if (existingSession) {
|
|
239
|
-
return;
|
|
240
|
-
}
|
|
241
|
-
if (!remoteBundle) {
|
|
242
|
-
const account = await (await getAccount()).get(myAddress, false);
|
|
243
|
-
if (!account?.pubkey) {
|
|
244
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, `Account not found for ${myAddress}`);
|
|
245
|
-
}
|
|
246
|
-
const timestamp = Date.now();
|
|
247
|
-
const nonce = this.generateNonce();
|
|
248
|
-
const publicKeyWithFlag = account.pubkey;
|
|
249
|
-
const message = `get_bundle:${myAddress}:${timestamp}:${nonce}`;
|
|
250
|
-
const signResult = await (await getAccount()).signData(myAddress, message);
|
|
251
|
-
const signature = Buffer.from(signResult.signature.slice(2), "hex");
|
|
252
|
-
remoteBundle = await this.serverClient.fetchRemoteBundle(peerAddress, myAddress, publicKeyWithFlag, {
|
|
253
|
-
signatureScheme: "ED25519",
|
|
254
|
-
signature: bytesToBase64(new Uint8Array(signature)),
|
|
255
|
-
timestamp,
|
|
256
|
-
nonce,
|
|
257
|
-
}, peerDeviceId);
|
|
258
|
-
}
|
|
259
|
-
const oneTimePreKey = remoteBundle.oneTimePrekey;
|
|
260
|
-
const signedPreKey = remoteBundle.signedPrekey;
|
|
261
|
-
if (!signedPreKey) {
|
|
262
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, `No signed prekey available for ${peerAddress}`);
|
|
263
|
-
}
|
|
264
|
-
const identityKeyBytes = base64ToBytes(remoteBundle.identityKey);
|
|
265
|
-
const originalIdentityKeyWithPrefix = new Uint8Array(identityKeyBytes);
|
|
266
|
-
const signedPreKeyPublicBytes = base64ToBytes(signedPreKey.publicKey);
|
|
267
|
-
const signedPreKeySignatureBytes = base64ToBytes(signedPreKey.signature);
|
|
268
|
-
const originalSignedPreKeyWithPrefix = new Uint8Array(signedPreKeyPublicBytes);
|
|
269
|
-
let oneTimePreKeyData = undefined;
|
|
270
|
-
if (oneTimePreKey) {
|
|
271
|
-
const oneTimePreKeyPublicBytes = base64ToBytes(oneTimePreKey.publicKey);
|
|
272
|
-
const originalOneTimePreKeyWithPrefix = new Uint8Array(oneTimePreKeyPublicBytes);
|
|
273
|
-
oneTimePreKeyData = {
|
|
274
|
-
keyId: oneTimePreKey.keyId,
|
|
275
|
-
publicKey: originalOneTimePreKeyWithPrefix.buffer.slice(originalOneTimePreKeyWithPrefix.byteOffset, originalOneTimePreKeyWithPrefix.byteOffset +
|
|
276
|
-
originalOneTimePreKeyWithPrefix.byteLength),
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
const device = {
|
|
280
|
-
registrationId: remoteBundle.registrationId,
|
|
281
|
-
identityKey: originalIdentityKeyWithPrefix.buffer.slice(originalIdentityKeyWithPrefix.byteOffset, originalIdentityKeyWithPrefix.byteOffset +
|
|
282
|
-
originalIdentityKeyWithPrefix.byteLength),
|
|
283
|
-
signedPreKey: {
|
|
284
|
-
keyId: signedPreKey.keyId,
|
|
285
|
-
publicKey: originalSignedPreKeyWithPrefix.buffer.slice(originalSignedPreKeyWithPrefix.byteOffset, originalSignedPreKeyWithPrefix.byteOffset +
|
|
286
|
-
originalSignedPreKeyWithPrefix.byteLength),
|
|
287
|
-
signature: new Uint8Array(signedPreKeySignatureBytes).buffer.slice(signedPreKeySignatureBytes.byteOffset, signedPreKeySignatureBytes.byteOffset +
|
|
288
|
-
signedPreKeySignatureBytes.byteLength),
|
|
289
|
-
},
|
|
290
|
-
preKey: oneTimePreKeyData,
|
|
291
|
-
};
|
|
292
|
-
const builder = new SessionBuilder(this.store, protocolAddress);
|
|
293
|
-
await builder.processPreKey(device);
|
|
294
|
-
await this.store.saveIdentity(protocolAddress.toString(), device.identityKey);
|
|
295
|
-
const defaultSessionKey = protocolAddress.toString();
|
|
296
|
-
const sendSessionKey = `send:${peerAddress}.${peerDeviceId}`;
|
|
297
|
-
const sessionData = await this.store.loadSession(defaultSessionKey);
|
|
298
|
-
if (sessionData) {
|
|
299
|
-
await this.store.storeSession(sendSessionKey, sessionData);
|
|
300
|
-
console.log(`[Session] 会话已保存到发送key: ${sendSessionKey}`);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
async encryptMessage(myAddress, peerAddress, plaintext, peerDeviceId = DEFAULT_DEVICE_ID) {
|
|
304
|
-
const protocolAddress = new SignalProtocolAddress(peerAddress, peerDeviceId);
|
|
305
|
-
const defaultSessionKey = protocolAddress.toString();
|
|
306
|
-
const sendSessionKey = `send:${peerAddress}.${peerDeviceId}`;
|
|
307
|
-
const recvSessionKey = `recv:${peerAddress}.${peerDeviceId}`;
|
|
308
|
-
let existingDefaultSession = await this.store.loadSession(defaultSessionKey);
|
|
309
|
-
let existingSendSession = await this.store.loadSession(sendSessionKey);
|
|
310
|
-
const existingRecvSession = await this.store.loadSession(recvSessionKey);
|
|
311
|
-
if (!existingDefaultSession && existingRecvSession) {
|
|
312
|
-
console.log(`[Session] 复制接收会话到默认key: ${peerAddress}`);
|
|
313
|
-
await this.store.storeSession(defaultSessionKey, existingRecvSession);
|
|
314
|
-
existingDefaultSession = existingRecvSession;
|
|
315
|
-
}
|
|
316
|
-
if (!existingSendSession && existingRecvSession) {
|
|
317
|
-
console.log(`[Session] 复制接收会话到发送会话: ${peerAddress}`);
|
|
318
|
-
await this.store.storeSession(sendSessionKey, existingRecvSession);
|
|
319
|
-
existingSendSession = existingRecvSession;
|
|
320
|
-
}
|
|
321
|
-
let existingSession = existingDefaultSession || existingSendSession;
|
|
322
|
-
let isNewSession = !existingSession;
|
|
323
|
-
let retryCount = 0;
|
|
324
|
-
const maxRetries = 5;
|
|
325
|
-
while (retryCount <= maxRetries) {
|
|
326
|
-
try {
|
|
327
|
-
if (isNewSession) {
|
|
328
|
-
console.log(`[Session] 建立新会话 (尝试 ${retryCount + 1}/${maxRetries + 1})`);
|
|
329
|
-
const account = await (await getAccount()).get(myAddress, false);
|
|
330
|
-
if (!account?.pubkey) {
|
|
331
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, `Account not found for ${myAddress}`);
|
|
332
|
-
}
|
|
333
|
-
const timestamp = Date.now();
|
|
334
|
-
const nonce = this.generateNonce();
|
|
335
|
-
const publicKeyWithFlag = account.pubkey;
|
|
336
|
-
const message = `get_bundle:${myAddress}:${timestamp}:${nonce}`;
|
|
337
|
-
const signResult = await (await getAccount()).signData(myAddress, message);
|
|
338
|
-
const signature = Buffer.from(signResult.signature.slice(2), "hex");
|
|
339
|
-
const remoteBundle = await this.serverClient.fetchRemoteBundle(peerAddress, myAddress, publicKeyWithFlag, {
|
|
340
|
-
signatureScheme: "ED25519",
|
|
341
|
-
signature: bytesToBase64(new Uint8Array(signature)),
|
|
342
|
-
timestamp,
|
|
343
|
-
nonce,
|
|
344
|
-
}, peerDeviceId);
|
|
345
|
-
await this.establishSession(myAddress, peerAddress, peerDeviceId, remoteBundle);
|
|
346
|
-
}
|
|
347
|
-
const cipher = new SessionCipher(this.store, protocolAddress);
|
|
348
|
-
const encoder = new TextEncoder();
|
|
349
|
-
const cipherMessage = await cipher.encrypt(encoder.encode(plaintext).buffer);
|
|
350
|
-
let bodyBuffer;
|
|
351
|
-
if (typeof cipherMessage.body === "string") {
|
|
352
|
-
const bodyBytes = Buffer.from(cipherMessage.body, "binary");
|
|
353
|
-
bodyBuffer = new Uint8Array(bodyBytes).buffer;
|
|
354
|
-
}
|
|
355
|
-
else if (cipherMessage.body) {
|
|
356
|
-
bodyBuffer = cipherMessage.body;
|
|
357
|
-
}
|
|
358
|
-
else {
|
|
359
|
-
throw new MessengerError(MessengerErrorCode.ENCRYPTION_FAILED, "Cipher message body is empty");
|
|
360
|
-
}
|
|
361
|
-
return {
|
|
362
|
-
type: cipherMessage.type,
|
|
363
|
-
body: bodyBuffer,
|
|
364
|
-
registrationId: cipherMessage.registrationId,
|
|
365
|
-
};
|
|
366
|
-
}
|
|
367
|
-
catch (error) {
|
|
368
|
-
console.error(`[Session] 加密失败 (尝试 ${retryCount + 1}/${maxRetries + 1}):`, error);
|
|
369
|
-
if (retryCount >= maxRetries) {
|
|
370
|
-
throw error;
|
|
371
|
-
}
|
|
372
|
-
console.log(`[Session] 尝试删除旧会话并重新建立...`);
|
|
373
|
-
try {
|
|
374
|
-
if (existingSession) {
|
|
375
|
-
await this.store.removeSession(defaultSessionKey);
|
|
376
|
-
await this.store.removeSession(sendSessionKey);
|
|
377
|
-
await this.store.removeSession(recvSessionKey);
|
|
378
|
-
existingSession = undefined;
|
|
379
|
-
}
|
|
380
|
-
isNewSession = true;
|
|
381
|
-
retryCount++;
|
|
382
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
383
|
-
}
|
|
384
|
-
catch (rebuildError) {
|
|
385
|
-
console.error(`[Session] 重新建立会话失败:`, rebuildError);
|
|
386
|
-
throw error;
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
throw new MessengerError(MessengerErrorCode.ENCRYPTION_FAILED, "Encryption failed after multiple attempts");
|
|
391
|
-
}
|
|
392
|
-
async decryptMessage(myAddress, peerAddress, ciphertext, msgType, peerDeviceId = DEFAULT_DEVICE_ID) {
|
|
393
|
-
const protocolAddress = new SignalProtocolAddress(peerAddress, peerDeviceId);
|
|
394
|
-
const sessionKey = protocolAddress.toString();
|
|
395
|
-
let existingSession = await this.store.loadSession(sessionKey);
|
|
396
|
-
const decoder = new TextDecoder();
|
|
397
|
-
let ciphertextBinary = "";
|
|
398
|
-
const ciphertextArray = new Uint8Array(ciphertext);
|
|
399
|
-
for (let i = 0; i < ciphertextArray.length; i++) {
|
|
400
|
-
ciphertextBinary += String.fromCharCode(ciphertextArray[i]);
|
|
401
|
-
}
|
|
402
|
-
let retryCount = 0;
|
|
403
|
-
const maxRetries = 5;
|
|
404
|
-
if (msgType !== MessageType.PREKEY_MESSAGE && !existingSession) {
|
|
405
|
-
console.log(`[Session] 收到 WHISPER_MESSAGE 但无现有会话,需要等待 PREKEY_MESSAGE`);
|
|
406
|
-
throw new Error("收到 WHISPER_MESSAGE 但无现有会话,需要等待 PREKEY_MESSAGE");
|
|
407
|
-
}
|
|
408
|
-
while (retryCount <= maxRetries) {
|
|
409
|
-
try {
|
|
410
|
-
const cipher = new SessionCipher(this.store, protocolAddress);
|
|
411
|
-
let plaintextBuffer;
|
|
412
|
-
if (msgType === MessageType.PREKEY_MESSAGE) {
|
|
413
|
-
console.log(`[Session] 收到 PREKEY_MESSAGE,尝试解密 (尝试 ${retryCount + 1}/${maxRetries + 1})`);
|
|
414
|
-
try {
|
|
415
|
-
plaintextBuffer =
|
|
416
|
-
await cipher.decryptPreKeyWhisperMessage(ciphertextBinary, "binary");
|
|
417
|
-
console.log(`[Session] PREKEY_MESSAGE 解密成功!`);
|
|
418
|
-
return decoder.decode(plaintextBuffer);
|
|
419
|
-
}
|
|
420
|
-
catch (decryptError) {
|
|
421
|
-
console.log(`[Session] 直接解密 PREKEY_MESSAGE 失败: ${decryptError instanceof Error ? decryptError.message : String(decryptError)}`);
|
|
422
|
-
if (existingSession && retryCount === 0) {
|
|
423
|
-
const myAddr = myAddress.toLowerCase();
|
|
424
|
-
const peerAddr = peerAddress.toLowerCase();
|
|
425
|
-
if (myAddr < peerAddr) {
|
|
426
|
-
console.log(`[Session] 我的地址较小 (${myAddr} < ${peerAddr}),保留我的会话,稍后重试`);
|
|
427
|
-
throw new Error("PREKEY 竞争:我的地址较小,保留我的会话");
|
|
428
|
-
}
|
|
429
|
-
else {
|
|
430
|
-
console.log(`[Session] 我的地址较大 (${myAddr} > ${peerAddr}),删除我的会话,用对方的 PREKEY_MESSAGE 建立新会话`);
|
|
431
|
-
await this.store.removeSession(sessionKey);
|
|
432
|
-
existingSession = undefined;
|
|
433
|
-
console.log(`[Session] 已删除旧会话,重新尝试解密...`);
|
|
434
|
-
plaintextBuffer =
|
|
435
|
-
await cipher.decryptPreKeyWhisperMessage(ciphertextBinary, "binary");
|
|
436
|
-
console.log(`[Session] PREKEY_MESSAGE 解密成功,新会话已建立`);
|
|
437
|
-
return decoder.decode(plaintextBuffer);
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
else {
|
|
441
|
-
throw decryptError;
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
else {
|
|
446
|
-
plaintextBuffer = await cipher.decryptWhisperMessage(ciphertextBinary, "binary");
|
|
447
|
-
}
|
|
448
|
-
return decoder.decode(plaintextBuffer);
|
|
449
|
-
}
|
|
450
|
-
catch (error) {
|
|
451
|
-
console.error(`[Session Debug] 解密失败 (尝试 ${retryCount + 1}/${maxRetries + 1}):`);
|
|
452
|
-
console.error(` 错误类型: ${error instanceof Error ? error.constructor.name : typeof error}`);
|
|
453
|
-
console.error(` 错误消息: ${error instanceof Error ? error.message : String(error)}`);
|
|
454
|
-
if (error instanceof Error && error.stack) {
|
|
455
|
-
console.error(` 堆栈: ${error.stack.split("\n")[0]}`);
|
|
456
|
-
}
|
|
457
|
-
console.error(` 上下文:`);
|
|
458
|
-
console.error(` - myAddress: ${myAddress}`);
|
|
459
|
-
console.error(` - peerAddress: ${peerAddress}`);
|
|
460
|
-
console.error(` - msgType: ${msgType} (${msgType === MessageType.PREKEY_MESSAGE ? "PREKEY" : "WHISPER"})`);
|
|
461
|
-
console.error(` - sessionKey: ${sessionKey}`);
|
|
462
|
-
console.error(` - existingSession: ${existingSession ? "存在" : "不存在"}`);
|
|
463
|
-
console.error(` - ciphertext.length: ${ciphertext.byteLength}`);
|
|
464
|
-
const identityKey = await this.store.getIdentityKeyPair();
|
|
465
|
-
const regId = await this.store.getLocalRegistrationId();
|
|
466
|
-
console.error(` - identityKey: ${identityKey ? "存在" : "缺失"}`);
|
|
467
|
-
console.error(` - registrationId: ${regId}`);
|
|
468
|
-
if (retryCount >= maxRetries) {
|
|
469
|
-
throw error;
|
|
470
|
-
}
|
|
471
|
-
console.log(`[Session] 尝试重新建立会话...`);
|
|
472
|
-
try {
|
|
473
|
-
if (existingSession) {
|
|
474
|
-
console.log(`[Session] 删除旧会话`);
|
|
475
|
-
await this.store.removeSession(sessionKey);
|
|
476
|
-
existingSession = undefined;
|
|
477
|
-
}
|
|
478
|
-
if (msgType === MessageType.PREKEY_MESSAGE) {
|
|
479
|
-
console.log(`[Session] 收到的是 PREKEY_MESSAGE,等待发送方的 PreKey 即可重建会话`);
|
|
480
|
-
}
|
|
481
|
-
else {
|
|
482
|
-
console.log(`[Session] 收到的是 WHISPER_MESSAGE,需要让对方重新发送 PREKEY_MESSAGE`);
|
|
483
|
-
}
|
|
484
|
-
retryCount++;
|
|
485
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
486
|
-
}
|
|
487
|
-
catch (rebuildError) {
|
|
488
|
-
console.error(`[Session] 重新建立会话失败:`, rebuildError);
|
|
489
|
-
throw error;
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
throw new MessengerError(MessengerErrorCode.DECRYPTION_FAILED, "Decryption failed after multiple attempts");
|
|
494
|
-
}
|
|
495
|
-
async getIdentityKey() {
|
|
496
|
-
const identity = await this.ensureIdentity();
|
|
497
|
-
return bytesToBase64(arrayBufferToUint8Array(identity.signalIdentity.pubKey));
|
|
498
|
-
}
|
|
499
|
-
async getRegistrationId() {
|
|
500
|
-
const identity = await this.ensureIdentity();
|
|
501
|
-
return identity.registrationId;
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
export class SessionStateManager {
|
|
505
|
-
store;
|
|
506
|
-
constructor(store) {
|
|
507
|
-
this.store = store;
|
|
508
|
-
}
|
|
509
|
-
async snapshotSession(sessionKey) {
|
|
510
|
-
const sessionData = await this.store.loadSession(sessionKey);
|
|
511
|
-
return {
|
|
512
|
-
sessionData: sessionData || null,
|
|
513
|
-
timestamp: Date.now(),
|
|
514
|
-
};
|
|
515
|
-
}
|
|
516
|
-
async rollbackSession(sessionKey, snapshot) {
|
|
517
|
-
if (snapshot.sessionData) {
|
|
518
|
-
await this.store.storeSession(sessionKey, snapshot.sessionData);
|
|
519
|
-
console.log(`[SessionState] 回滚会话: ${sessionKey}`);
|
|
520
|
-
}
|
|
521
|
-
else {
|
|
522
|
-
await this.store.removeSession(sessionKey);
|
|
523
|
-
console.log(`[SessionState] 清除会话: ${sessionKey}`);
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
async commitSession(_sessionKey) {
|
|
527
|
-
console.log(`[SessionState] 提交新会话`);
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
export class DecryptionEngine {
|
|
531
|
-
sessionManager;
|
|
532
|
-
store;
|
|
533
|
-
constructor(store) {
|
|
534
|
-
this.store = store;
|
|
535
|
-
this.sessionManager = new SessionStateManager(store);
|
|
536
|
-
}
|
|
537
|
-
getRecvSessionKey(peerAddress, deviceId) {
|
|
538
|
-
return `recv:${peerAddress}.${deviceId}`;
|
|
539
|
-
}
|
|
540
|
-
getSendSessionKey(peerAddress, deviceId) {
|
|
541
|
-
return `send:${peerAddress}.${deviceId}`;
|
|
542
|
-
}
|
|
543
|
-
async decryptMessage(myAddress, peerAddress, ciphertext, msgType, peerDeviceId = DEFAULT_DEVICE_ID) {
|
|
544
|
-
const recvSessionKey = this.getRecvSessionKey(peerAddress, peerDeviceId);
|
|
545
|
-
const protocolAddress = new SignalProtocolAddress(peerAddress, peerDeviceId);
|
|
546
|
-
const snapshot = await this.sessionManager.snapshotSession(recvSessionKey);
|
|
547
|
-
try {
|
|
548
|
-
if (msgType === MessageType.PREKEY_MESSAGE) {
|
|
549
|
-
return await this.handlePreKeyMessage(myAddress, peerAddress, ciphertext, protocolAddress, recvSessionKey, snapshot);
|
|
550
|
-
}
|
|
551
|
-
else {
|
|
552
|
-
return await this.handleWhisperMessage(myAddress, peerAddress, ciphertext, protocolAddress, recvSessionKey, snapshot);
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
catch (error) {
|
|
556
|
-
await this.sessionManager.rollbackSession(recvSessionKey, snapshot);
|
|
557
|
-
return {
|
|
558
|
-
success: false,
|
|
559
|
-
sessionUpdated: false,
|
|
560
|
-
sessionRolledBack: true,
|
|
561
|
-
messageType: msgType === MessageType.PREKEY_MESSAGE
|
|
562
|
-
? "PREKEY"
|
|
563
|
-
: "WHISPER",
|
|
564
|
-
error: error instanceof Error ? error.message : String(error),
|
|
565
|
-
};
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
async handlePreKeyMessage(myAddress, peerAddress, ciphertext, protocolAddress, recvSessionKey, snapshot) {
|
|
569
|
-
console.log(`[Decrypt] 处理 PREKEY_MESSAGE from ${peerAddress}`);
|
|
570
|
-
const cipher = new SessionCipher(this.store, protocolAddress);
|
|
571
|
-
const decoder = new TextDecoder();
|
|
572
|
-
const ciphertextBinary = this.arrayBufferToBinary(ciphertext);
|
|
573
|
-
const plaintextBuffer = await cipher.decryptPreKeyWhisperMessage(ciphertextBinary, "binary");
|
|
574
|
-
const plaintext = decoder.decode(plaintextBuffer);
|
|
575
|
-
console.log(`[Decrypt] PREKEY_MESSAGE 解密成功`);
|
|
576
|
-
await this.sessionManager.commitSession(recvSessionKey);
|
|
577
|
-
const myAddr = myAddress.toLowerCase();
|
|
578
|
-
const peerAddr = peerAddress.toLowerCase();
|
|
579
|
-
if (myAddr < peerAddr) {
|
|
580
|
-
console.log(`[Decrypt] 小地址(${myAddr})保存接收会话用于解密,发送会话保持不变`);
|
|
581
|
-
}
|
|
582
|
-
else {
|
|
583
|
-
console.log(`[Decrypt] 大地址(${myAddr})接受新会话`);
|
|
584
|
-
}
|
|
585
|
-
return {
|
|
586
|
-
success: true,
|
|
587
|
-
plaintext,
|
|
588
|
-
sessionUpdated: true,
|
|
589
|
-
sessionRolledBack: false,
|
|
590
|
-
messageType: "PREKEY",
|
|
591
|
-
};
|
|
592
|
-
}
|
|
593
|
-
async handleWhisperMessage(_myAddress, peerAddress, ciphertext, protocolAddress, recvSessionKey, snapshot) {
|
|
594
|
-
console.log(`[Decrypt] 处理 WHISPER_MESSAGE from ${peerAddress}`);
|
|
595
|
-
const existingSession = await this.store.loadSession(recvSessionKey);
|
|
596
|
-
if (!existingSession) {
|
|
597
|
-
console.log(`[Decrypt] 无接收会话,WHISPER_MESSAGE 需要等待 PREKEY`);
|
|
598
|
-
await this.sessionManager.rollbackSession(recvSessionKey, snapshot);
|
|
599
|
-
return {
|
|
600
|
-
success: false,
|
|
601
|
-
sessionUpdated: false,
|
|
602
|
-
sessionRolledBack: false,
|
|
603
|
-
messageType: "WHISPER",
|
|
604
|
-
error: "NO_SESSION",
|
|
605
|
-
};
|
|
606
|
-
}
|
|
607
|
-
const cipher = new SessionCipher(this.store, protocolAddress);
|
|
608
|
-
const decoder = new TextDecoder();
|
|
609
|
-
const ciphertextBinary = this.arrayBufferToBinary(ciphertext);
|
|
610
|
-
const plaintextBuffer = await cipher.decryptWhisperMessage(ciphertextBinary, "binary");
|
|
611
|
-
console.log(`[Decrypt] WHISPER_MESSAGE 解密成功`);
|
|
612
|
-
return {
|
|
613
|
-
success: true,
|
|
614
|
-
plaintext: decoder.decode(plaintextBuffer),
|
|
615
|
-
sessionUpdated: true,
|
|
616
|
-
sessionRolledBack: false,
|
|
617
|
-
messageType: "WHISPER",
|
|
618
|
-
};
|
|
619
|
-
}
|
|
620
|
-
arrayBufferToBinary(buffer) {
|
|
621
|
-
const array = new Uint8Array(buffer);
|
|
622
|
-
let binary = "";
|
|
623
|
-
for (let i = 0; i < array.length; i++) {
|
|
624
|
-
binary += String.fromCharCode(array[i]);
|
|
625
|
-
}
|
|
626
|
-
return binary;
|
|
627
|
-
}
|
|
628
|
-
}
|
|
1
|
+
import{KeyHelper,SessionBuilder,SessionCipher,SignalProtocolAddress}from'libsignal-protocol-typescript';import{SignalProtocolStorage}from'./storage.js';import{MessengerServerClient}from'./server.js';import{recoverXed25519FromX25519PrivateKey,arrayBufferToUint8Array,bytesToBase64,base64ToBytes}from'./crypto.js';import{MessageType,DEFAULT_MESSENGER_CONFIG,MessengerError,MessengerErrorCode,DEFAULT_DEVICE_ID}from'./types.js';async function getAccount(){const {Account:a}=await import('../local/account.js');return a['Instance']();}export class MessengerSession{['store'];['serverClient'];['config'];['identity']=null;constructor(a,b){this['store']=new SignalProtocolStorage(a),this['config']={...DEFAULT_MESSENGER_CONFIG,...b},this['serverClient']=new MessengerServerClient(this['config']);}async['ensureIdentity'](a){if(this['identity'])return this['identity'];const b=await this['store']['getIdentityKeyPair'](),c=await this['store']['getLocalRegistrationId']();if(b&&c){const j=new Uint8Array(b['privKey']),k=recoverXed25519FromX25519PrivateKey(j);return this['identity']={'xed25519':k,'signalIdentity':b,'registrationId':c},this['identity'];}if(!a)throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'userAddress\x20is\x20required\x20to\x20derive\x20identity');const {privateKey:d,publicKey:e}=await(await getAccount())['deriveX25519KeyPair'](a),f=this['deriveRegistrationId'](e),g=new Uint8Array(0x21);g[0x0]=0x5,g['set'](e,0x1);const h={'privKey':d['slice']()['buffer'],'pubKey':g['slice']()['buffer']};await this['store']['setIdentity'](h,f);const i=recoverXed25519FromX25519PrivateKey(d);return this['identity']={'xed25519':i,'signalIdentity':h,'registrationId':f},this['identity'];}['deriveRegistrationId'](a){const b=a[0x0]<<0x8|a[0x1];return b===0x0?0x1:b;}async['registerDevice'](a){const b=await this['ensureIdentity'](a),c=0x1;let d,e,f,g=![];const h=await this['store']['loadSignedPreKeyWithSignature'](c);h?(e=arrayBufferToUint8Array(h['pubKey']),f=arrayBufferToUint8Array(h['signature']),d={'keyId':c,'keyPair':{'pubKey':h['pubKey'],'privKey':h['privKey']},'signature':h['signature']}):(d=await KeyHelper['generateSignedPreKey'](b['signalIdentity'],c),e=arrayBufferToUint8Array(d['keyPair']['pubKey']),f=arrayBufferToUint8Array(d['signature']),g=!![]);const i=await this['generatePreKeyBatch'](this['config']['prekey_count'],a),j=arrayBufferToUint8Array(b['signalIdentity']['pubKey']),k=await(await getAccount())['get'](a,![]);if(!k?.['pubkey'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'Account\x20not\x20found\x20for\x20'+a);const l=Date['now'](),m=this['generateNonce'](),n='register:'+k['pubkey']+':'+l+':'+m,o=await(await getAccount())['signData'](a,n),p=Buffer['from'](o['signature']['slice'](0x2),'hex'),q={'userAddress':a,'deviceId':DEFAULT_DEVICE_ID,'registrationId':b['registrationId'],'identityKey':bytesToBase64(j),'signedPrekey':{'keyId':c,'publicKey':bytesToBase64(e),'signature':bytesToBase64(f)},'prekeys':i,'publicKey':k['pubkey'],'signatureScheme':'ED25519','signature':bytesToBase64(p),'timestamp':l,'nonce':m};console['log']('[Session\x20Debug]\x20Sending\x20register\x20request\x20to\x20server...'),await this['serverClient']['registerDevice'](q),console['log']('[Session\x20Debug]\x20Server\x20register\x20request\x20successful!'),console['log']('[Session\x20Debug]\x20Verifying\x20registration\x20complete...'),await this['verifyRegistrationComplete'](a),console['log']('[Session\x20Debug]\x20Registration\x20verification\x20complete!'),g&&await this['store']['storeSignedPreKeyWithSignature'](c,d['keyPair'],f['buffer']['slice'](0x0));}async['verifyRegistrationComplete'](a,b=0xa,c=0x1f4){for(let d=0x0;d<b;d++){try{const e=await this['serverClient']['getPrekeyStatus'](a);console['log']('Registration\x20verified\x20for\x20'+a+',\x20prekeys:\x20'+e['currentCount']+'/'+e['maxAllowed']);return;}catch(f){if(f?.['message']?.['includes']('404')||f?.['status']===0x194){if(d<b-0x1){console['log']('Waiting\x20for\x20registration\x20to\x20complete...\x20('+(d+0x1)+'/'+b+')'),await new Promise(g=>setTimeout(g,c));continue;}}throw f;}}throw new MessengerError(MessengerErrorCode['REGISTRATION_FAILED'],'Registration\x20verification\x20failed\x20after\x20'+b+'\x20attempts');}async['isDeviceRegistered'](a){try{const b=await this['store']['loadSignedPreKeyWithSignature'](0x1);if(!b)return![];const c=await this['serverClient']['getPrekeyStatus'](a);return!![];}catch(d){if(d?.['message']?.['includes']('404')||d?.['status']===0x194)return![];return![];}}async['generatePreKeyBatch'](a,b){if(a<=0x0)return[];const c=await this['store']['getMeta']();let d=c['nextPreKeyId']||0x1;const e=[];for(let f=0x0;f<a;f++){const g=d+f,h=await this['store']['loadPreKey'](g);if(h){const n=new Uint8Array(h['pubKey']),o=bytesToBase64(n),p=await(await getAccount())['signData'](b,n),q=Buffer['from'](p['signature']['slice'](0x2),'hex');e['push']({'keyId':g,'publicKey':o,'signature':bytesToBase64(q)});continue;}const j=await KeyHelper['generatePreKey'](g),k=new Uint8Array(j['keyPair']['pubKey']),l=await(await getAccount())['signData'](b,k),m=Buffer['from'](l['signature']['slice'](0x2),'hex');await this['store']['storePreKey'](g,j['keyPair']),e['push']({'keyId':g,'publicKey':bytesToBase64(k),'signature':bytesToBase64(m)});}return d+=a,await this['store']['setMeta']({'nextPreKeyId':d}),e;}async['ensurePreKeys'](a,b=![]){const c=await this['serverClient']['getPrekeyStatus'](a);if(!b&&c['currentCount']>=c['maxAllowed'])return;const d=c['maxAllowed']-c['currentCount'];if(d<=0x0)return;await this['ensureIdentity'](a);const e=await this['generatePreKeyBatch'](d,a);if(e['length']===0x0)return;const f=await(await getAccount())['get'](a,![]);if(!f?.['pubkey'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'Account\x20not\x20found\x20for\x20'+a);const g=Date['now'](),h=this['generateNonce'](),i='upload_prekeys:'+f['pubkey']+':'+g+':'+h,j=await(await getAccount())['signData'](a,i),k=Buffer['from'](j['signature']['slice'](0x2),'hex');await this['serverClient']['uploadPreKeys']({'userAddress':a,'prekeys':e,'publicKey':f['pubkey'],'signatureScheme':'ED25519','signature':bytesToBase64(k),'timestamp':g,'nonce':h});}['generateNonce'](){const a=new Uint8Array(0x10);return crypto['getRandomValues'](a),Array['from'](a,c=>c['toString'](0x10)['padStart'](0x2,'0'))['join']('');}async['establishSession'](a,b,c=DEFAULT_DEVICE_ID,d){const e=new SignalProtocolAddress(b,c),f=await this['store']['loadSession'](e['toString']());if(f)return;if(!d){const t=await(await getAccount())['get'](a,![]);if(!t?.['pubkey'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'Account\x20not\x20found\x20for\x20'+a);const u=Date['now'](),v=this['generateNonce'](),w=t['pubkey'],x='get_bundle:'+a+':'+u+':'+v,y=await(await getAccount())['signData'](a,x),z=Buffer['from'](y['signature']['slice'](0x2),'hex');d=await this['serverClient']['fetchRemoteBundle'](b,a,w,{'signatureScheme':'ED25519','signature':bytesToBase64(new Uint8Array(z)),'timestamp':u,'nonce':v},c);}const g=d['oneTimePrekey'],h=d['signedPrekey'];if(!h)throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'No\x20signed\x20prekey\x20available\x20for\x20'+b);const i=base64ToBytes(d['identityKey']),j=new Uint8Array(i),k=base64ToBytes(h['publicKey']),l=base64ToBytes(h['signature']),m=new Uint8Array(k);let n=undefined;if(g){const A=base64ToBytes(g['publicKey']),B=new Uint8Array(A);n={'keyId':g['keyId'],'publicKey':B['buffer']['slice'](B['byteOffset'],B['byteOffset']+B['byteLength'])};}const o={'registrationId':d['registrationId'],'identityKey':j['buffer']['slice'](j['byteOffset'],j['byteOffset']+j['byteLength']),'signedPreKey':{'keyId':h['keyId'],'publicKey':m['buffer']['slice'](m['byteOffset'],m['byteOffset']+m['byteLength']),'signature':new Uint8Array(l)['buffer']['slice'](l['byteOffset'],l['byteOffset']+l['byteLength'])},'preKey':n},p=new SessionBuilder(this['store'],e);await p['processPreKey'](o),await this['store']['saveIdentity'](e['toString'](),o['identityKey']);const q=e['toString'](),r='send:'+b+'.'+c,s=await this['store']['loadSession'](q);s&&(await this['store']['storeSession'](r,s),console['log']('[Session]\x20会话已保存到发送key:\x20'+r));}async['encryptMessage'](a,b,c,d=DEFAULT_DEVICE_ID){const e=new SignalProtocolAddress(b,d),f=e['toString'](),g='send:'+b+'.'+d,h='recv:'+b+'.'+d;let i=await this['store']['loadSession'](f),j=await this['store']['loadSession'](g);const k=await this['store']['loadSession'](h);!i&&k&&(console['log']('[Session]\x20复制接收会话到默认key:\x20'+b),await this['store']['storeSession'](f,k),i=k);!j&&k&&(console['log']('[Session]\x20复制接收会话到发送会话:\x20'+b),await this['store']['storeSession'](g,k),j=k);let l=i||j,m=!l,n=0x0;const o=0x5;while(n<=o){try{if(m){console['log']('[Session]\x20建立新会话\x20(尝试\x20'+(n+0x1)+'/'+(o+0x1)+')');const t=await(await getAccount())['get'](a,![]);if(!t?.['pubkey'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'Account\x20not\x20found\x20for\x20'+a);const u=Date['now'](),v=this['generateNonce'](),w=t['pubkey'],x='get_bundle:'+a+':'+u+':'+v,y=await(await getAccount())['signData'](a,x),z=Buffer['from'](y['signature']['slice'](0x2),'hex'),A=await this['serverClient']['fetchRemoteBundle'](b,a,w,{'signatureScheme':'ED25519','signature':bytesToBase64(new Uint8Array(z)),'timestamp':u,'nonce':v},d);await this['establishSession'](a,b,d,A);}const p=new SessionCipher(this['store'],e),q=new TextEncoder(),r=await p['encrypt'](q['encode'](c)['buffer']);let s;if(typeof r['body']==='string'){const B=Buffer['from'](r['body'],'binary');s=new Uint8Array(B)['buffer'];}else{if(r['body'])s=r['body'];else throw new MessengerError(MessengerErrorCode['ENCRYPTION_FAILED'],'Cipher\x20message\x20body\x20is\x20empty');}return{'type':r['type'],'body':s,'registrationId':r['registrationId']};}catch(C){console['error']('[Session]\x20加密失败\x20(尝试\x20'+(n+0x1)+'/'+(o+0x1)+'):',C);if(n>=o)throw C;console['log']('[Session]\x20尝试删除旧会话并重新建立...');try{l&&(await this['store']['removeSession'](f),await this['store']['removeSession'](g),await this['store']['removeSession'](h),l=undefined),m=!![],n++,await new Promise(D=>setTimeout(D,0x64));}catch(D){console['error']('[Session]\x20重新建立会话失败:',D);throw C;}}}throw new MessengerError(MessengerErrorCode['ENCRYPTION_FAILED'],'Encryption\x20failed\x20after\x20multiple\x20attempts');}async['decryptMessage'](a,b,c,d,e=DEFAULT_DEVICE_ID){const f=new SignalProtocolAddress(b,e),g=f['toString']();let h=await this['store']['loadSession'](g);const j=new TextDecoder();let k='';const l=new Uint8Array(c);for(let o=0x0;o<l['length'];o++){k+=String['fromCharCode'](l[o]);}let m=0x0;const n=0x5;if(d!==MessageType['PREKEY_MESSAGE']&&!h){console['log']('[Session]\x20收到\x20WHISPER_MESSAGE\x20但无现有会话,需要等待\x20PREKEY_MESSAGE');throw new Error('收到\x20WHISPER_MESSAGE\x20但无现有会话,需要等待\x20PREKEY_MESSAGE');}while(m<=n){try{const p=new SessionCipher(this['store'],f);let q;if(d===MessageType['PREKEY_MESSAGE']){console['log']('[Session]\x20收到\x20PREKEY_MESSAGE,尝试解密\x20(尝试\x20'+(m+0x1)+'/'+(n+0x1)+')');try{return q=await p['decryptPreKeyWhisperMessage'](k,'binary'),console['log']('[Session]\x20PREKEY_MESSAGE\x20解密成功!'),j['decode'](q);}catch(r){console['log']('[Session]\x20直接解密\x20PREKEY_MESSAGE\x20失败:\x20'+(r instanceof Error?r['message']:String(r)));if(h&&m===0x0){const s=a['toLowerCase'](),t=b['toLowerCase']();if(s<t){console['log']('[Session]\x20我的地址较小\x20('+s+'\x20<\x20'+t+'),保留我的会话,稍后重试');throw new Error('PREKEY\x20竞争:我的地址较小,保留我的会话');}else return console['log']('[Session]\x20我的地址较大\x20('+s+'\x20>\x20'+t+'),删除我的会话,用对方的\x20PREKEY_MESSAGE\x20建立新会话'),await this['store']['removeSession'](g),h=undefined,console['log']('[Session]\x20已删除旧会话,重新尝试解密...'),q=await p['decryptPreKeyWhisperMessage'](k,'binary'),console['log']('[Session]\x20PREKEY_MESSAGE\x20解密成功,新会话已建立'),j['decode'](q);}else throw r;}}else q=await p['decryptWhisperMessage'](k,'binary');return j['decode'](q);}catch(u){console['error']('[Session\x20Debug]\x20解密失败\x20(尝试\x20'+(m+0x1)+'/'+(n+0x1)+'):'),console['error']('\x20\x20错误类型:\x20'+(u instanceof Error?u['constructor']['name']:typeof u)),console['error']('\x20\x20错误消息:\x20'+(u instanceof Error?u['message']:String(u)));u instanceof Error&&u['stack']&&console['error']('\x20\x20堆栈:\x20'+u['stack']['split']('\x0a')[0x0]);console['error']('\x20\x20上下文:'),console['error']('\x20\x20\x20\x20-\x20myAddress:\x20'+a),console['error']('\x20\x20\x20\x20-\x20peerAddress:\x20'+b),console['error']('\x20\x20\x20\x20-\x20msgType:\x20'+d+'\x20('+(d===MessageType['PREKEY_MESSAGE']?'PREKEY':'WHISPER')+')'),console['error']('\x20\x20\x20\x20-\x20sessionKey:\x20'+g),console['error']('\x20\x20\x20\x20-\x20existingSession:\x20'+(h?'存在':'不存在')),console['error']('\x20\x20\x20\x20-\x20ciphertext.length:\x20'+c['byteLength']);const v=await this['store']['getIdentityKeyPair'](),w=await this['store']['getLocalRegistrationId']();console['error']('\x20\x20\x20\x20-\x20identityKey:\x20'+(v?'存在':'缺失')),console['error']('\x20\x20\x20\x20-\x20registrationId:\x20'+w);if(m>=n)throw u;console['log']('[Session]\x20尝试重新建立会话...');try{h&&(console['log']('[Session]\x20删除旧会话'),await this['store']['removeSession'](g),h=undefined),d===MessageType['PREKEY_MESSAGE']?console['log']('[Session]\x20收到的是\x20PREKEY_MESSAGE,等待发送方的\x20PreKey\x20即可重建会话'):console['log']('[Session]\x20收到的是\x20WHISPER_MESSAGE,需要让对方重新发送\x20PREKEY_MESSAGE'),m++,await new Promise(x=>setTimeout(x,0x64));}catch(x){console['error']('[Session]\x20重新建立会话失败:',x);throw u;}}}throw new MessengerError(MessengerErrorCode['DECRYPTION_FAILED'],'Decryption\x20failed\x20after\x20multiple\x20attempts');}async['getIdentityKey'](){const a=await this['ensureIdentity']();return bytesToBase64(arrayBufferToUint8Array(a['signalIdentity']['pubKey']));}async['getRegistrationId'](){const a=await this['ensureIdentity']();return a['registrationId'];}}export class SessionStateManager{['store'];constructor(a){this['store']=a;}async['snapshotSession'](a){const b=await this['store']['loadSession'](a);return{'sessionData':b||null,'timestamp':Date['now']()};}async['rollbackSession'](a,b){b['sessionData']?(await this['store']['storeSession'](a,b['sessionData']),console['log']('[SessionState]\x20回滚会话:\x20'+a)):(await this['store']['removeSession'](a),console['log']('[SessionState]\x20清除会话:\x20'+a));}async['commitSession'](a){console['log']('[SessionState]\x20提交新会话');}}export class DecryptionEngine{['sessionManager'];['store'];constructor(a){this['store']=a,this['sessionManager']=new SessionStateManager(a);}['getRecvSessionKey'](a,b){return'recv:'+a+'.'+b;}['getSendSessionKey'](a,b){return'send:'+a+'.'+b;}async['decryptMessage'](a,b,c,d,e=DEFAULT_DEVICE_ID){const f=this['getRecvSessionKey'](b,e),g=new SignalProtocolAddress(b,e),h=await this['sessionManager']['snapshotSession'](f);try{return d===MessageType['PREKEY_MESSAGE']?await this['handlePreKeyMessage'](a,b,c,g,f,h):await this['handleWhisperMessage'](a,b,c,g,f,h);}catch(i){return await this['sessionManager']['rollbackSession'](f,h),{'success':![],'sessionUpdated':![],'sessionRolledBack':!![],'messageType':d===MessageType['PREKEY_MESSAGE']?'PREKEY':'WHISPER','error':i instanceof Error?i['message']:String(i)};}}async['handlePreKeyMessage'](a,b,c,d,e,f){console['log']('[Decrypt]\x20处理\x20PREKEY_MESSAGE\x20from\x20'+b);const g=new SessionCipher(this['store'],d),h=new TextDecoder(),i=this['arrayBufferToBinary'](c),j=await g['decryptPreKeyWhisperMessage'](i,'binary'),k=h['decode'](j);console['log']('[Decrypt]\x20PREKEY_MESSAGE\x20解密成功'),await this['sessionManager']['commitSession'](e);const l=a['toLowerCase'](),m=b['toLowerCase']();return l<m?console['log']('[Decrypt]\x20小地址('+l+')保存接收会话用于解密,发送会话保持不变'):console['log']('[Decrypt]\x20大地址('+l+')接受新会话'),{'success':!![],'plaintext':k,'sessionUpdated':!![],'sessionRolledBack':![],'messageType':'PREKEY'};}async['handleWhisperMessage'](a,b,c,d,e,f){console['log']('[Decrypt]\x20处理\x20WHISPER_MESSAGE\x20from\x20'+b);const g=await this['store']['loadSession'](e);if(!g)return console['log']('[Decrypt]\x20无接收会话,WHISPER_MESSAGE\x20需要等待\x20PREKEY'),await this['sessionManager']['rollbackSession'](e,f),{'success':![],'sessionUpdated':![],'sessionRolledBack':![],'messageType':'WHISPER','error':'NO_SESSION'};const h=new SessionCipher(this['store'],d),i=new TextDecoder(),j=this['arrayBufferToBinary'](c),k=await h['decryptWhisperMessage'](j,'binary');return console['log']('[Decrypt]\x20WHISPER_MESSAGE\x20解密成功'),{'success':!![],'plaintext':i['decode'](k),'sessionUpdated':!![],'sessionRolledBack':![],'messageType':'WHISPER'};}['arrayBufferToBinary'](a){const b=new Uint8Array(a);let c='';for(let d=0x0;d<b['length'];d++){c+=String['fromCharCode'](b[d]);}return c;}}
|