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,1093 +1 @@
|
|
|
1
|
-
import { createHash } from "crypto";
|
|
2
|
-
import * as fs from "fs";
|
|
3
|
-
import * as path from "path";
|
|
4
|
-
import { MessengerSession, DecryptionEngine } from "./session.js";
|
|
5
|
-
import { MessengerServerClient } from "./server.js";
|
|
6
|
-
import { MessageStorage, SessionStateStorage } from "./storage.js";
|
|
7
|
-
import { hashPlaintext, verifyMessage, bytesToBase64 } from "./crypto.js";
|
|
8
|
-
import { canonicalizeJson } from "./utils.js";
|
|
9
|
-
import { DEFAULT_MESSENGER_CONFIG, MessengerError, MessengerErrorCode, MessageDirection, MessageStatus, WTS_FILE_BYTES_LIMIT, NORMAL_MESSAGE_BYTES_LIMIT, CHAIN_PROOF_TYPE, } from "./types.js";
|
|
10
|
-
import { isValidWowAddress } from "../../utils/sui-types.js";
|
|
11
|
-
async function getAccount() {
|
|
12
|
-
const { Account } = await import("../local/account.js");
|
|
13
|
-
return Account.Instance();
|
|
14
|
-
}
|
|
15
|
-
export class Messenger {
|
|
16
|
-
session;
|
|
17
|
-
serverClient;
|
|
18
|
-
config;
|
|
19
|
-
userAddress = null;
|
|
20
|
-
onMessageCallback = null;
|
|
21
|
-
pollingTimer = null;
|
|
22
|
-
messageConsecutiveEmptyPulls = 0;
|
|
23
|
-
prekeyConsecutiveOkCount = 0;
|
|
24
|
-
currentMessageInterval;
|
|
25
|
-
isPollingRunning = false;
|
|
26
|
-
messageStorage;
|
|
27
|
-
sessionStateStorage;
|
|
28
|
-
decryptionEngine;
|
|
29
|
-
waitingMessages = new Map();
|
|
30
|
-
failedMessages = new Map();
|
|
31
|
-
waitingMessageRetries = new Map();
|
|
32
|
-
constructor(userAddress, config) {
|
|
33
|
-
this.userAddress = userAddress;
|
|
34
|
-
this.config = { ...DEFAULT_MESSENGER_CONFIG, ...config };
|
|
35
|
-
this.session = new MessengerSession(userAddress, this.config);
|
|
36
|
-
this.serverClient = new MessengerServerClient(this.config);
|
|
37
|
-
this.messageStorage = new MessageStorage(userAddress);
|
|
38
|
-
this.sessionStateStorage = new SessionStateStorage(userAddress);
|
|
39
|
-
this.decryptionEngine = new DecryptionEngine(this.session["store"]);
|
|
40
|
-
this.currentMessageInterval =
|
|
41
|
-
this.config.message_poll_default_interval_ms ?? 6 * 60 * 1000;
|
|
42
|
-
}
|
|
43
|
-
getUserAddress() {
|
|
44
|
-
if (!this.userAddress) {
|
|
45
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
46
|
-
}
|
|
47
|
-
return this.userAddress;
|
|
48
|
-
}
|
|
49
|
-
async getPublicKey() {
|
|
50
|
-
if (!this.userAddress) {
|
|
51
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
52
|
-
}
|
|
53
|
-
const account = await (await getAccount()).get(this.userAddress, false);
|
|
54
|
-
return account?.pubkey || "";
|
|
55
|
-
}
|
|
56
|
-
isValidGuardMessage(guardAddress, passportAddress) {
|
|
57
|
-
return Boolean(guardAddress &&
|
|
58
|
-
passportAddress &&
|
|
59
|
-
isValidWowAddress(guardAddress) &&
|
|
60
|
-
isValidWowAddress(passportAddress));
|
|
61
|
-
}
|
|
62
|
-
async generateSignatureParams(operation) {
|
|
63
|
-
if (!this.userAddress) {
|
|
64
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
65
|
-
}
|
|
66
|
-
const account = await (await getAccount()).get(this.userAddress, false);
|
|
67
|
-
if (!account?.secret) {
|
|
68
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, `Account not found or no secret key for ${this.userAddress}`);
|
|
69
|
-
}
|
|
70
|
-
const { Ed25519Keypair } = await import("../../keypairs/ed25519/index.js");
|
|
71
|
-
const keypair = Ed25519Keypair.fromSecretKey(account.secret);
|
|
72
|
-
const publicKey = keypair.getPublicKey();
|
|
73
|
-
const publicKeyWithFlag = publicKey.toWPublicKey();
|
|
74
|
-
const timestamp = Date.now();
|
|
75
|
-
const nonce = this.generateNonce();
|
|
76
|
-
const message = `${operation}:${publicKeyWithFlag}:${timestamp}:${nonce}`;
|
|
77
|
-
const signature = await keypair.sign(new TextEncoder().encode(message));
|
|
78
|
-
return {
|
|
79
|
-
signatureScheme: "ED25519",
|
|
80
|
-
signature: Buffer.from(signature).toString("base64"),
|
|
81
|
-
timestamp,
|
|
82
|
-
nonce,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
generateNonce() {
|
|
86
|
-
const array = new Uint8Array(16);
|
|
87
|
-
crypto.getRandomValues(array);
|
|
88
|
-
return Array.from(array, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
89
|
-
}
|
|
90
|
-
async initialize() {
|
|
91
|
-
if (!this.userAddress) {
|
|
92
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
93
|
-
}
|
|
94
|
-
await this.session.ensureIdentity(this.userAddress);
|
|
95
|
-
await this.session.registerDevice(this.userAddress);
|
|
96
|
-
await this.session.ensurePreKeys(this.userAddress);
|
|
97
|
-
await this.checkAndRefillPrekeys();
|
|
98
|
-
this.startPollingTimer();
|
|
99
|
-
}
|
|
100
|
-
async checkAndRefillPrekeys() {
|
|
101
|
-
if (!this.userAddress)
|
|
102
|
-
return;
|
|
103
|
-
await this.session.ensurePreKeys(this.userAddress, false);
|
|
104
|
-
}
|
|
105
|
-
startPollingTimer() {
|
|
106
|
-
if (this.pollingTimer) {
|
|
107
|
-
clearTimeout(this.pollingTimer);
|
|
108
|
-
}
|
|
109
|
-
this.isPollingRunning = true;
|
|
110
|
-
this.scheduleNextPoll();
|
|
111
|
-
}
|
|
112
|
-
stopPollingTimer() {
|
|
113
|
-
this.isPollingRunning = false;
|
|
114
|
-
if (this.pollingTimer) {
|
|
115
|
-
clearTimeout(this.pollingTimer);
|
|
116
|
-
this.pollingTimer = null;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
scheduleNextPoll() {
|
|
120
|
-
if (!this.isPollingRunning)
|
|
121
|
-
return;
|
|
122
|
-
const interval = this.getNextPollInterval();
|
|
123
|
-
this.pollingTimer = setTimeout(() => {
|
|
124
|
-
this.poll()
|
|
125
|
-
.catch((error) => {
|
|
126
|
-
console.error("[Polling] Error during poll:", error);
|
|
127
|
-
})
|
|
128
|
-
.finally(() => {
|
|
129
|
-
this.scheduleNextPoll();
|
|
130
|
-
});
|
|
131
|
-
}, interval);
|
|
132
|
-
}
|
|
133
|
-
getNextPollInterval() {
|
|
134
|
-
if (this.waitingMessages.size > 0) {
|
|
135
|
-
return this.config.message_poll_waiting_interval_ms ?? 3 * 1000;
|
|
136
|
-
}
|
|
137
|
-
return this.currentMessageInterval;
|
|
138
|
-
}
|
|
139
|
-
async poll() {
|
|
140
|
-
if (!this.userAddress)
|
|
141
|
-
return;
|
|
142
|
-
try {
|
|
143
|
-
const response = await this.pullMessages();
|
|
144
|
-
if (response.messages.length > 0) {
|
|
145
|
-
this.messageConsecutiveEmptyPulls = 0;
|
|
146
|
-
this.currentMessageInterval =
|
|
147
|
-
this.config.message_poll_fast_interval_ms ?? 6 * 1000;
|
|
148
|
-
if (this.onMessageCallback) {
|
|
149
|
-
this.onMessageCallback(response.messages);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
this.messageConsecutiveEmptyPulls++;
|
|
154
|
-
if (this.messageConsecutiveEmptyPulls >=
|
|
155
|
-
(this.config.message_poll_consecutive_empty_limit ?? 3)) {
|
|
156
|
-
this.currentMessageInterval =
|
|
157
|
-
this.config.message_poll_default_interval_ms ??
|
|
158
|
-
6 * 60 * 1000;
|
|
159
|
-
this.messageConsecutiveEmptyPulls = 0;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
if (response.prekey_status) {
|
|
163
|
-
const prekeyStatus = response.prekey_status;
|
|
164
|
-
if (prekeyStatus.shouldRefill) {
|
|
165
|
-
this.prekeyConsecutiveOkCount = 0;
|
|
166
|
-
await this.checkAndRefillPrekeys();
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
this.prekeyConsecutiveOkCount++;
|
|
170
|
-
if (this.prekeyConsecutiveOkCount >=
|
|
171
|
-
(this.config.prekey_poll_consecutive_ok_limit ?? 3)) {
|
|
172
|
-
this.prekeyConsecutiveOkCount = 0;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
catch (error) {
|
|
178
|
-
console.error("[Polling] Poll error:", error);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
triggerFastPoll() {
|
|
182
|
-
this.currentMessageInterval =
|
|
183
|
-
this.config.message_poll_fast_interval_ms ?? 6 * 1000;
|
|
184
|
-
this.messageConsecutiveEmptyPulls = 0;
|
|
185
|
-
if (this.isPollingRunning) {
|
|
186
|
-
if (this.pollingTimer) {
|
|
187
|
-
clearTimeout(this.pollingTimer);
|
|
188
|
-
}
|
|
189
|
-
this.scheduleNextPoll();
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
async sendMessage(recipientAddress, plaintext, options) {
|
|
193
|
-
if (!this.userAddress) {
|
|
194
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
195
|
-
}
|
|
196
|
-
const createdAt = Date.now();
|
|
197
|
-
const timestamp = Date.now();
|
|
198
|
-
const nonce = this.generateNonce();
|
|
199
|
-
const plaintextBytes = new TextEncoder().encode(plaintext).length;
|
|
200
|
-
if (plaintextBytes > NORMAL_MESSAGE_BYTES_LIMIT) {
|
|
201
|
-
throw new MessengerError(MessengerErrorCode.INVALID_INPUT, `Message size (${plaintextBytes} bytes) exceeds maximum allowed size (${NORMAL_MESSAGE_BYTES_LIMIT} bytes). Consider using sendZipFile for large content.`);
|
|
202
|
-
}
|
|
203
|
-
await this.pullMessages();
|
|
204
|
-
const lastReceivedLeafIndex = this.messageStorage.getLastReceivedLeafIndex(this.userAddress, recipientAddress);
|
|
205
|
-
const encrypted = await this.session.encryptMessage(this.userAddress, recipientAddress, plaintext);
|
|
206
|
-
const ciphertext = Buffer.from(new Uint8Array(encrypted.body)).toString("base64");
|
|
207
|
-
const plaintextHash = hashPlaintext(plaintext, createdAt, options?.guardAddress, options?.passportAddress, lastReceivedLeafIndex);
|
|
208
|
-
const account = await (await getAccount()).get(this.userAddress, false);
|
|
209
|
-
if (!account) {
|
|
210
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User account not found");
|
|
211
|
-
}
|
|
212
|
-
const publicKey = account.pubkey;
|
|
213
|
-
const guardAddr = options?.guardAddress || "";
|
|
214
|
-
const passportAddr = options?.passportAddress || "";
|
|
215
|
-
const lastReceivedStr = lastReceivedLeafIndex >= 0 ? lastReceivedLeafIndex.toString() : "";
|
|
216
|
-
const forceStr = options?.force ? "true" : "false";
|
|
217
|
-
const signMessage = `send_message:${this.userAddress}:${recipientAddress}:${guardAddr}:${passportAddr}:${plaintextHash}:${lastReceivedStr}:${publicKey}:${timestamp}:${nonce}:${forceStr}`;
|
|
218
|
-
const signResult = await (await getAccount()).signData(this.userAddress, signMessage);
|
|
219
|
-
const signatureBuffer = Buffer.from(signResult.signature.slice(2), "hex");
|
|
220
|
-
const signatureBase64 = bytesToBase64(new Uint8Array(signatureBuffer));
|
|
221
|
-
const response = await this.serverClient.sendMessage({
|
|
222
|
-
sender: signResult.publicKey,
|
|
223
|
-
recipient: recipientAddress,
|
|
224
|
-
ciphertext,
|
|
225
|
-
plaintextHash,
|
|
226
|
-
clientTimestamp: createdAt,
|
|
227
|
-
msgType: encrypted.type,
|
|
228
|
-
signatureScheme: "ED25519",
|
|
229
|
-
signature: signatureBase64,
|
|
230
|
-
timestamp,
|
|
231
|
-
nonce,
|
|
232
|
-
guardAddress: options?.guardAddress,
|
|
233
|
-
passportAddress: options?.passportAddress,
|
|
234
|
-
force: options?.force,
|
|
235
|
-
lastReceivedLeafIndex: lastReceivedLeafIndex >= 0
|
|
236
|
-
? lastReceivedLeafIndex
|
|
237
|
-
: undefined,
|
|
238
|
-
});
|
|
239
|
-
const message = {
|
|
240
|
-
messageId: response.messageId,
|
|
241
|
-
fromAddress: this.userAddress,
|
|
242
|
-
toAddress: recipientAddress,
|
|
243
|
-
plaintextHash,
|
|
244
|
-
plaintext,
|
|
245
|
-
guardAddress: options?.guardAddress,
|
|
246
|
-
passportAddress: options?.passportAddress,
|
|
247
|
-
lastReceivedLeafIndex,
|
|
248
|
-
direction: MessageDirection.SENT,
|
|
249
|
-
status: response.status === "confirmed"
|
|
250
|
-
? MessageStatus.CONFIRMED
|
|
251
|
-
: MessageStatus.PENDING,
|
|
252
|
-
msgType: encrypted.type,
|
|
253
|
-
createdAt,
|
|
254
|
-
};
|
|
255
|
-
if (response.merkleData) {
|
|
256
|
-
message.leafIndex = response.merkleData.leafIndex;
|
|
257
|
-
message.prevRoot = response.merkleData.prevRoot;
|
|
258
|
-
message.newRoot = response.merkleData.newRoot;
|
|
259
|
-
message.serverSignature = response.merkleData.serverSignature;
|
|
260
|
-
message.serverTimestamp = response.merkleData.serverTimestamp;
|
|
261
|
-
message.serverPublicKey = response.merkleData.serverPublicKey;
|
|
262
|
-
this.sessionStateStorage.updateSessionState(this.userAddress, recipientAddress, {
|
|
263
|
-
currentRoot: response.merkleData.newRoot,
|
|
264
|
-
prevRoot: response.merkleData.prevRoot,
|
|
265
|
-
lastLeafIndex: response.merkleData.leafIndex,
|
|
266
|
-
lastSyncAt: Date.now(),
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
this.messageStorage.saveMessage(message);
|
|
270
|
-
if (response.pendingMerkleData) {
|
|
271
|
-
for (const [msgId, merkleData] of Object.entries(response.pendingMerkleData)) {
|
|
272
|
-
const existingMsg = this.messageStorage.getMessage(msgId);
|
|
273
|
-
if (existingMsg &&
|
|
274
|
-
existingMsg.status === MessageStatus.PENDING) {
|
|
275
|
-
this.messageStorage.updateMessageStatus(msgId, MessageStatus.CONFIRMED, {
|
|
276
|
-
leafIndex: merkleData.leafIndex,
|
|
277
|
-
newRoot: merkleData.newRoot,
|
|
278
|
-
serverSignature: merkleData.serverSignature,
|
|
279
|
-
serverTimestamp: merkleData.serverTimestamp,
|
|
280
|
-
serverPublicKey: merkleData.serverPublicKey,
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
this.triggerFastPoll();
|
|
286
|
-
return {
|
|
287
|
-
messageId: response.messageId,
|
|
288
|
-
status: message.status,
|
|
289
|
-
merkleData: response.merkleData,
|
|
290
|
-
guardList: response.guard_list,
|
|
291
|
-
lastReceivedLeafIndex: lastReceivedLeafIndex >= 0 ? lastReceivedLeafIndex : undefined,
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
async pullMessages(limit) {
|
|
295
|
-
if (!this.userAddress) {
|
|
296
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
297
|
-
}
|
|
298
|
-
const timestamp = Date.now();
|
|
299
|
-
const nonce = this.generateNonce();
|
|
300
|
-
const message = `fetch_messages:${this.userAddress}:${limit || 100}:${timestamp}:${nonce}`;
|
|
301
|
-
const account = await (await getAccount()).get(this.userAddress, false);
|
|
302
|
-
const publicKey = account?.pubkey || "";
|
|
303
|
-
const signResult = await (await getAccount()).signData(this.userAddress, message);
|
|
304
|
-
const signature = Buffer.from(signResult.signature.slice(2), "hex");
|
|
305
|
-
const signatureParams = {
|
|
306
|
-
signatureScheme: "ED25519",
|
|
307
|
-
signature: bytesToBase64(signature),
|
|
308
|
-
timestamp,
|
|
309
|
-
nonce,
|
|
310
|
-
};
|
|
311
|
-
const response = await this.serverClient.pullMessages(this.userAddress, publicKey, signatureParams, limit);
|
|
312
|
-
if (response.messages.length === 0) {
|
|
313
|
-
return {
|
|
314
|
-
messages: [],
|
|
315
|
-
prekey_status: response.prekey_status,
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
|
-
const decryptedMessages = [];
|
|
319
|
-
const acknowledgedIds = [];
|
|
320
|
-
const sortedMessages = [...response.messages].sort(function (a, b) {
|
|
321
|
-
return (a.clientTimestamp || 0) - (b.clientTimestamp || 0);
|
|
322
|
-
});
|
|
323
|
-
await this.processWaitingMessages(decryptedMessages, acknowledgedIds);
|
|
324
|
-
for (const serverMsg of sortedMessages) {
|
|
325
|
-
if (this.waitingMessages.has(serverMsg.id)) {
|
|
326
|
-
acknowledgedIds.push(serverMsg.id);
|
|
327
|
-
continue;
|
|
328
|
-
}
|
|
329
|
-
if (this.failedMessages.has(serverMsg.id)) {
|
|
330
|
-
acknowledgedIds.push(serverMsg.id);
|
|
331
|
-
continue;
|
|
332
|
-
}
|
|
333
|
-
const existingMessage = this.messageStorage.getMessage(serverMsg.id);
|
|
334
|
-
if (existingMessage) {
|
|
335
|
-
acknowledgedIds.push(serverMsg.id);
|
|
336
|
-
continue;
|
|
337
|
-
}
|
|
338
|
-
const decryptResult = await this.tryDecryptMessage(serverMsg);
|
|
339
|
-
if (decryptResult.success &&
|
|
340
|
-
decryptResult.message &&
|
|
341
|
-
decryptResult.decryptedData) {
|
|
342
|
-
this.messageStorage.saveMessage(decryptResult.message);
|
|
343
|
-
decryptedMessages.push(decryptResult.decryptedData);
|
|
344
|
-
acknowledgedIds.push(serverMsg.id);
|
|
345
|
-
this.waitingMessages.delete(serverMsg.id);
|
|
346
|
-
}
|
|
347
|
-
else if (decryptResult.shouldRetry) {
|
|
348
|
-
console.warn(`[Messenger] 消息 ${serverMsg.id} 解密失败,加入等待池: ${decryptResult.error}`);
|
|
349
|
-
this.waitingMessages.set(serverMsg.id, serverMsg);
|
|
350
|
-
}
|
|
351
|
-
else {
|
|
352
|
-
console.error(`[Messenger] 消息 ${serverMsg.id} 解密永久失败: ${decryptResult.error}`);
|
|
353
|
-
this.failedMessages.set(serverMsg.id, {
|
|
354
|
-
message: serverMsg,
|
|
355
|
-
error: decryptResult.error || "Unknown error",
|
|
356
|
-
});
|
|
357
|
-
await this.saveFailedMessage(serverMsg, decryptResult.error || "Unknown error");
|
|
358
|
-
acknowledgedIds.push(serverMsg.id);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
if (this.waitingMessages.size > 0 && this.isPollingRunning) {
|
|
362
|
-
this.reschedulePolling();
|
|
363
|
-
}
|
|
364
|
-
if (acknowledgedIds.length > 0 && this.userAddress) {
|
|
365
|
-
const ackTimestamp = Date.now();
|
|
366
|
-
const ackNonce = this.generateNonce();
|
|
367
|
-
const account = await (await getAccount()).get(this.userAddress, false);
|
|
368
|
-
if (account?.pubkey) {
|
|
369
|
-
const ackMessage = `ack_messages:${this.userAddress}:${acknowledgedIds.join(",")}:${account.pubkey}:${ackTimestamp}:${ackNonce}`;
|
|
370
|
-
const signResult = await (await getAccount()).signData(this.userAddress, ackMessage);
|
|
371
|
-
const signatureBuffer = Buffer.from(signResult.signature.slice(2), "hex");
|
|
372
|
-
const signatureBase64 = bytesToBase64(new Uint8Array(signatureBuffer));
|
|
373
|
-
await this.serverClient.acknowledgeMessages(acknowledgedIds, signResult.publicKey, {
|
|
374
|
-
publicKey: signResult.publicKey,
|
|
375
|
-
signatureScheme: "ED25519",
|
|
376
|
-
signature: signatureBase64,
|
|
377
|
-
timestamp: ackTimestamp,
|
|
378
|
-
nonce: ackNonce,
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
return {
|
|
383
|
-
messages: decryptedMessages,
|
|
384
|
-
prekey_status: response.prekey_status,
|
|
385
|
-
};
|
|
386
|
-
}
|
|
387
|
-
getLastSentLeafIndex(peerAddress) {
|
|
388
|
-
if (!this.userAddress)
|
|
389
|
-
return -1;
|
|
390
|
-
const messages = this.messageStorage.getMessagesBySession(this.userAddress, peerAddress);
|
|
391
|
-
const sentMessages = messages.filter((m) => m.direction === MessageDirection.SENT &&
|
|
392
|
-
m.leafIndex !== undefined);
|
|
393
|
-
if (sentMessages.length === 0)
|
|
394
|
-
return -1;
|
|
395
|
-
return Math.max(...sentMessages.map((m) => m.leafIndex));
|
|
396
|
-
}
|
|
397
|
-
getSessionMessages(peerAddress) {
|
|
398
|
-
if (!this.userAddress) {
|
|
399
|
-
return [];
|
|
400
|
-
}
|
|
401
|
-
return this.messageStorage.getMessagesBySession(this.userAddress, peerAddress);
|
|
402
|
-
}
|
|
403
|
-
getSessionState(peerAddress) {
|
|
404
|
-
if (!this.userAddress) {
|
|
405
|
-
return undefined;
|
|
406
|
-
}
|
|
407
|
-
return this.sessionStateStorage.getSessionState(this.userAddress, peerAddress);
|
|
408
|
-
}
|
|
409
|
-
async submitChainProof(env, peerAddress, description) {
|
|
410
|
-
if (!this.userAddress) {
|
|
411
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
412
|
-
}
|
|
413
|
-
const sessionState = this.sessionStateStorage.getSessionState(this.userAddress, peerAddress);
|
|
414
|
-
if (!sessionState || !sessionState.currentRoot) {
|
|
415
|
-
throw new MessengerError(MessengerErrorCode.SESSION_NOT_ESTABLISHED, "No session state found");
|
|
416
|
-
}
|
|
417
|
-
const messages = this.messageStorage.getMessagesBySession(this.userAddress, peerAddress);
|
|
418
|
-
const lastMessage = messages[messages.length - 1];
|
|
419
|
-
if (!lastMessage ||
|
|
420
|
-
!lastMessage.serverPublicKey ||
|
|
421
|
-
!lastMessage.serverSignature) {
|
|
422
|
-
throw new MessengerError(MessengerErrorCode.INVALID_PROOF, "No temporal proof (missing server public key or signature), cannot submit Proof to WoWok blockchain");
|
|
423
|
-
}
|
|
424
|
-
const serverPubKey = lastMessage.serverPublicKey;
|
|
425
|
-
const serverSignature = lastMessage.serverSignature;
|
|
426
|
-
const proofData = {
|
|
427
|
-
sessionId: sessionState.sessionId,
|
|
428
|
-
merkleRoot: sessionState.currentRoot,
|
|
429
|
-
messageCount: sessionState.messageCount,
|
|
430
|
-
timestamp: Date.now(),
|
|
431
|
-
};
|
|
432
|
-
const { CallProof } = await import("../call/proof.js");
|
|
433
|
-
const callProof = new CallProof({
|
|
434
|
-
proof: JSON.stringify(proofData),
|
|
435
|
-
server_pubkey: serverPubKey,
|
|
436
|
-
server_signature: serverSignature,
|
|
437
|
-
proof_type: CHAIN_PROOF_TYPE,
|
|
438
|
-
description: description ||
|
|
439
|
-
`Messenger session proof for ${this.userAddress} <-> ${peerAddress}`,
|
|
440
|
-
item_count: sessionState.messageCount,
|
|
441
|
-
about_address: sessionState.sessionId,
|
|
442
|
-
});
|
|
443
|
-
const result = await callProof.call(env);
|
|
444
|
-
const responseData = result?.objectChanges;
|
|
445
|
-
const proofAddress = responseData?.find((change) => change.objectType?.includes("Proof"))?.objectId;
|
|
446
|
-
return {
|
|
447
|
-
proofAddress: proofAddress || "",
|
|
448
|
-
txHash: result?.digest || "",
|
|
449
|
-
};
|
|
450
|
-
}
|
|
451
|
-
destroy() {
|
|
452
|
-
this.stopPollingTimer();
|
|
453
|
-
}
|
|
454
|
-
disconnect() {
|
|
455
|
-
this.destroy();
|
|
456
|
-
}
|
|
457
|
-
setOnMessageCallback(onMessage) {
|
|
458
|
-
this.onMessageCallback = onMessage;
|
|
459
|
-
}
|
|
460
|
-
async sendZipFile(recipientAddress, source, options) {
|
|
461
|
-
if (!this.userAddress) {
|
|
462
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
463
|
-
}
|
|
464
|
-
const fileData = await this.loadFileData(source);
|
|
465
|
-
const { ZipWriter, BlobWriter, Uint8ArrayReader } = await import("@zip.js/zip.js");
|
|
466
|
-
const fileName = options?.fileName || path.basename(source) || "file.zip";
|
|
467
|
-
const contentType = options?.contentType || this.detectContentType(fileName);
|
|
468
|
-
const zipFileWriter = new BlobWriter("application/zip");
|
|
469
|
-
const zipWriter = new ZipWriter(zipFileWriter);
|
|
470
|
-
await zipWriter.add(fileName, new Uint8ArrayReader(fileData));
|
|
471
|
-
await zipWriter.close();
|
|
472
|
-
const zipFileBlob = await zipFileWriter.getData();
|
|
473
|
-
const zipBlob = new Uint8Array(await zipFileBlob.arrayBuffer());
|
|
474
|
-
if (zipBlob.length > WTS_FILE_BYTES_LIMIT) {
|
|
475
|
-
throw new MessengerError(MessengerErrorCode.INVALID_INPUT, `ZIP file size (${zipBlob.length} bytes) exceeds local maximum allowed size (${WTS_FILE_BYTES_LIMIT} bytes)`);
|
|
476
|
-
}
|
|
477
|
-
const zipFileHash = "0x" + createHash("sha256").update(zipBlob).digest("hex");
|
|
478
|
-
const zipBase64 = Buffer.from(zipBlob).toString("base64");
|
|
479
|
-
const zipMetadata = {
|
|
480
|
-
fileName: `${fileName}.zip`,
|
|
481
|
-
fileSize: zipBlob.length,
|
|
482
|
-
fileHash: zipFileHash,
|
|
483
|
-
contentType: contentType,
|
|
484
|
-
};
|
|
485
|
-
await this.pullMessages();
|
|
486
|
-
const lastReceivedLeafIndex = this.messageStorage.getLastReceivedLeafIndex(this.userAddress, recipientAddress);
|
|
487
|
-
const createdAt = Date.now();
|
|
488
|
-
const encrypted = await this.session.encryptMessage(this.userAddress, recipientAddress, zipBase64);
|
|
489
|
-
const ciphertext = Buffer.from(new Uint8Array(encrypted.body)).toString("base64");
|
|
490
|
-
const guardAddr = options?.guardAddress || "";
|
|
491
|
-
const passportAddr = options?.passportAddress || "";
|
|
492
|
-
const plaintextHash = hashPlaintext(zipBase64, createdAt, guardAddr, passportAddr, lastReceivedLeafIndex);
|
|
493
|
-
const timestamp = Date.now();
|
|
494
|
-
const nonce = this.generateNonce();
|
|
495
|
-
const account = await (await getAccount()).get(this.userAddress, false);
|
|
496
|
-
if (!account) {
|
|
497
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User account not found");
|
|
498
|
-
}
|
|
499
|
-
const publicKey = account.pubkey;
|
|
500
|
-
const lastReceivedStr = lastReceivedLeafIndex >= 0 ? lastReceivedLeafIndex.toString() : "";
|
|
501
|
-
const forceStr = options?.force ? "true" : "false";
|
|
502
|
-
const signMessage = `send_message:${this.userAddress}:${recipientAddress}:${guardAddr}:${passportAddr}:${plaintextHash}:${lastReceivedStr}:${publicKey}:${timestamp}:${nonce}:${forceStr}`;
|
|
503
|
-
const signResult = await (await getAccount()).signData(this.userAddress, signMessage);
|
|
504
|
-
const signatureBuffer = Buffer.from(signResult.signature.slice(2), "hex");
|
|
505
|
-
const signatureBase64 = bytesToBase64(new Uint8Array(signatureBuffer));
|
|
506
|
-
const response = await this.serverClient.sendMessage({
|
|
507
|
-
sender: signResult.publicKey,
|
|
508
|
-
recipient: recipientAddress,
|
|
509
|
-
ciphertext,
|
|
510
|
-
plaintextHash,
|
|
511
|
-
clientTimestamp: createdAt,
|
|
512
|
-
msgType: encrypted.type,
|
|
513
|
-
zipMetadata,
|
|
514
|
-
guardAddress: options?.guardAddress,
|
|
515
|
-
passportAddress: options?.passportAddress,
|
|
516
|
-
force: options?.force,
|
|
517
|
-
lastReceivedLeafIndex: lastReceivedLeafIndex >= 0
|
|
518
|
-
? lastReceivedLeafIndex
|
|
519
|
-
: undefined,
|
|
520
|
-
signatureScheme: "ED25519",
|
|
521
|
-
signature: signatureBase64,
|
|
522
|
-
timestamp,
|
|
523
|
-
nonce,
|
|
524
|
-
});
|
|
525
|
-
const message = {
|
|
526
|
-
messageId: response.messageId,
|
|
527
|
-
fromAddress: this.userAddress,
|
|
528
|
-
toAddress: recipientAddress,
|
|
529
|
-
plaintextHash,
|
|
530
|
-
plaintext: zipBase64,
|
|
531
|
-
guardAddress: options?.guardAddress,
|
|
532
|
-
passportAddress: options?.passportAddress,
|
|
533
|
-
lastReceivedLeafIndex,
|
|
534
|
-
direction: MessageDirection.SENT,
|
|
535
|
-
status: response.status === "confirmed"
|
|
536
|
-
? MessageStatus.CONFIRMED
|
|
537
|
-
: MessageStatus.PENDING,
|
|
538
|
-
msgType: encrypted.type,
|
|
539
|
-
zipMetadata,
|
|
540
|
-
createdAt,
|
|
541
|
-
};
|
|
542
|
-
if (response.merkleData) {
|
|
543
|
-
message.leafIndex = response.merkleData.leafIndex;
|
|
544
|
-
message.prevRoot = response.merkleData.prevRoot;
|
|
545
|
-
message.newRoot = response.merkleData.newRoot;
|
|
546
|
-
message.serverSignature = response.merkleData.serverSignature;
|
|
547
|
-
message.serverTimestamp = response.merkleData.serverTimestamp;
|
|
548
|
-
message.serverPublicKey = response.merkleData.serverPublicKey;
|
|
549
|
-
this.sessionStateStorage.updateSessionState(this.userAddress, recipientAddress, {
|
|
550
|
-
currentRoot: response.merkleData.newRoot,
|
|
551
|
-
prevRoot: response.merkleData.prevRoot,
|
|
552
|
-
lastLeafIndex: response.merkleData.leafIndex,
|
|
553
|
-
lastSyncAt: Date.now(),
|
|
554
|
-
});
|
|
555
|
-
}
|
|
556
|
-
this.messageStorage.saveMessage(message);
|
|
557
|
-
if (response.pendingMerkleData) {
|
|
558
|
-
for (const [msgId, merkleData] of Object.entries(response.pendingMerkleData)) {
|
|
559
|
-
const existingMsg = this.messageStorage.getMessage(msgId);
|
|
560
|
-
if (existingMsg &&
|
|
561
|
-
existingMsg.status === MessageStatus.PENDING) {
|
|
562
|
-
this.messageStorage.updateMessageStatus(msgId, MessageStatus.CONFIRMED, {
|
|
563
|
-
leafIndex: merkleData.leafIndex,
|
|
564
|
-
newRoot: merkleData.newRoot,
|
|
565
|
-
serverSignature: merkleData.serverSignature,
|
|
566
|
-
serverTimestamp: merkleData.serverTimestamp,
|
|
567
|
-
serverPublicKey: merkleData.serverPublicKey,
|
|
568
|
-
});
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
this.triggerFastPoll();
|
|
573
|
-
return {
|
|
574
|
-
messageId: response.messageId,
|
|
575
|
-
status: message.status,
|
|
576
|
-
merkleData: response.merkleData,
|
|
577
|
-
guardList: response.guard_list,
|
|
578
|
-
lastReceivedLeafIndex: lastReceivedLeafIndex >= 0 ? lastReceivedLeafIndex : undefined,
|
|
579
|
-
};
|
|
580
|
-
}
|
|
581
|
-
async loadFileData(source) {
|
|
582
|
-
if (source.startsWith("http://") || source.startsWith("https://")) {
|
|
583
|
-
const response = await fetch(source);
|
|
584
|
-
if (!response.ok) {
|
|
585
|
-
throw new MessengerError(MessengerErrorCode.NETWORK_ERROR, `Failed to fetch file from ${source}: ${response.statusText}`);
|
|
586
|
-
}
|
|
587
|
-
const arrayBuffer = await response.arrayBuffer();
|
|
588
|
-
return new Uint8Array(arrayBuffer);
|
|
589
|
-
}
|
|
590
|
-
const resolvedPath = path.resolve(source);
|
|
591
|
-
if (!fs.existsSync(resolvedPath)) {
|
|
592
|
-
throw new MessengerError(MessengerErrorCode.FILE_NOT_FOUND, `File not found: ${resolvedPath}`);
|
|
593
|
-
}
|
|
594
|
-
const buffer = fs.readFileSync(resolvedPath);
|
|
595
|
-
return new Uint8Array(buffer);
|
|
596
|
-
}
|
|
597
|
-
detectContentType(fileName) {
|
|
598
|
-
const ext = path.extname(fileName).toLowerCase();
|
|
599
|
-
switch (ext) {
|
|
600
|
-
case ".wts":
|
|
601
|
-
return "wts";
|
|
602
|
-
case ".wip":
|
|
603
|
-
return "wip";
|
|
604
|
-
default:
|
|
605
|
-
return "zip";
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
async _createSignedRequest(data) {
|
|
609
|
-
if (!this.userAddress) {
|
|
610
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
611
|
-
}
|
|
612
|
-
const timestamp = Date.now();
|
|
613
|
-
const nonce = this.generateNonce();
|
|
614
|
-
const dataJson = canonicalizeJson(data);
|
|
615
|
-
const signMessage = `${timestamp}:${nonce}:${dataJson}`;
|
|
616
|
-
const signResult = await (await getAccount()).signData(this.userAddress, signMessage);
|
|
617
|
-
const signatureBuffer = Buffer.from(signResult.signature.slice(2), "hex");
|
|
618
|
-
const signatureBase64 = bytesToBase64(new Uint8Array(signatureBuffer));
|
|
619
|
-
const account = await (await getAccount()).get(this.userAddress, false);
|
|
620
|
-
if (!account || !account.pubkey) {
|
|
621
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "Account public key not found");
|
|
622
|
-
}
|
|
623
|
-
return {
|
|
624
|
-
userAddress: this.userAddress,
|
|
625
|
-
publicKey: account.pubkey,
|
|
626
|
-
signatureScheme: "ED25519",
|
|
627
|
-
signature: signatureBase64,
|
|
628
|
-
timestamp,
|
|
629
|
-
nonce,
|
|
630
|
-
data,
|
|
631
|
-
};
|
|
632
|
-
}
|
|
633
|
-
_validateAddresses(addresses) {
|
|
634
|
-
const valid = [];
|
|
635
|
-
const invalid = [];
|
|
636
|
-
for (const addr of addresses) {
|
|
637
|
-
if (isValidWowAddress(addr)) {
|
|
638
|
-
valid.push(addr);
|
|
639
|
-
}
|
|
640
|
-
else {
|
|
641
|
-
invalid.push(addr);
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
return { valid, invalid };
|
|
645
|
-
}
|
|
646
|
-
async addToBlacklist(addresses) {
|
|
647
|
-
if (!this.userAddress) {
|
|
648
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
649
|
-
}
|
|
650
|
-
const { valid, invalid } = this._validateAddresses(addresses);
|
|
651
|
-
if (invalid.length > 0) {
|
|
652
|
-
return {
|
|
653
|
-
success: false,
|
|
654
|
-
operation: "add",
|
|
655
|
-
modifiedCount: 0,
|
|
656
|
-
currentCount: 0,
|
|
657
|
-
maxCount: 0,
|
|
658
|
-
invalidAddresses: invalid,
|
|
659
|
-
message: `Invalid addresses: ${invalid.join(", ")}`,
|
|
660
|
-
};
|
|
661
|
-
}
|
|
662
|
-
const data = { addresses: valid };
|
|
663
|
-
const signedRequest = await this._createSignedRequest(data);
|
|
664
|
-
return this.serverClient.addToBlacklist(this.userAddress, signedRequest);
|
|
665
|
-
}
|
|
666
|
-
async removeFromBlacklist(addresses) {
|
|
667
|
-
if (!this.userAddress) {
|
|
668
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
669
|
-
}
|
|
670
|
-
const { valid, invalid } = this._validateAddresses(addresses);
|
|
671
|
-
if (invalid.length > 0) {
|
|
672
|
-
return {
|
|
673
|
-
success: false,
|
|
674
|
-
operation: "remove",
|
|
675
|
-
modifiedCount: 0,
|
|
676
|
-
currentCount: 0,
|
|
677
|
-
maxCount: 0,
|
|
678
|
-
invalidAddresses: invalid,
|
|
679
|
-
message: `Invalid addresses: ${invalid.join(", ")}`,
|
|
680
|
-
};
|
|
681
|
-
}
|
|
682
|
-
const data = { addresses: valid };
|
|
683
|
-
const signedRequest = await this._createSignedRequest(data);
|
|
684
|
-
return this.serverClient.removeFromBlacklist(this.userAddress, signedRequest);
|
|
685
|
-
}
|
|
686
|
-
async clearBlacklist() {
|
|
687
|
-
if (!this.userAddress) {
|
|
688
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
689
|
-
}
|
|
690
|
-
const data = {};
|
|
691
|
-
const signedRequest = await this._createSignedRequest(data);
|
|
692
|
-
return this.serverClient.clearBlacklist(this.userAddress, signedRequest);
|
|
693
|
-
}
|
|
694
|
-
async getBlacklist() {
|
|
695
|
-
if (!this.userAddress) {
|
|
696
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
697
|
-
}
|
|
698
|
-
const signedRequest = await this._createSignedRequest({});
|
|
699
|
-
return this.serverClient.getBlacklist(this.userAddress, signedRequest);
|
|
700
|
-
}
|
|
701
|
-
async existInBlacklist(addresses) {
|
|
702
|
-
if (!this.userAddress) {
|
|
703
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
704
|
-
}
|
|
705
|
-
const { valid, invalid } = this._validateAddresses(addresses);
|
|
706
|
-
if (invalid.length > 0) {
|
|
707
|
-
return {
|
|
708
|
-
success: false,
|
|
709
|
-
operation: "exist",
|
|
710
|
-
modifiedCount: 0,
|
|
711
|
-
currentCount: 0,
|
|
712
|
-
maxCount: 0,
|
|
713
|
-
invalidAddresses: invalid,
|
|
714
|
-
message: `Invalid addresses: ${invalid.join(", ")}`,
|
|
715
|
-
};
|
|
716
|
-
}
|
|
717
|
-
const data = { addresses: valid };
|
|
718
|
-
const signedRequest = await this._createSignedRequest(data);
|
|
719
|
-
return this.serverClient.existInBlacklist(this.userAddress, signedRequest);
|
|
720
|
-
}
|
|
721
|
-
async addToFriendsList(addresses) {
|
|
722
|
-
if (!this.userAddress) {
|
|
723
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
724
|
-
}
|
|
725
|
-
const { valid, invalid } = this._validateAddresses(addresses);
|
|
726
|
-
if (invalid.length > 0) {
|
|
727
|
-
return {
|
|
728
|
-
success: false,
|
|
729
|
-
operation: "add",
|
|
730
|
-
modifiedCount: 0,
|
|
731
|
-
currentCount: 0,
|
|
732
|
-
maxCount: 0,
|
|
733
|
-
invalidAddresses: invalid,
|
|
734
|
-
message: `Invalid addresses: ${invalid.join(", ")}`,
|
|
735
|
-
};
|
|
736
|
-
}
|
|
737
|
-
const data = { addresses: valid };
|
|
738
|
-
const signedRequest = await this._createSignedRequest(data);
|
|
739
|
-
return this.serverClient.addToFriendsList(this.userAddress, signedRequest);
|
|
740
|
-
}
|
|
741
|
-
async removeFromFriendsList(addresses) {
|
|
742
|
-
if (!this.userAddress) {
|
|
743
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
744
|
-
}
|
|
745
|
-
const { valid, invalid } = this._validateAddresses(addresses);
|
|
746
|
-
if (invalid.length > 0) {
|
|
747
|
-
return {
|
|
748
|
-
success: false,
|
|
749
|
-
operation: "remove",
|
|
750
|
-
modifiedCount: 0,
|
|
751
|
-
currentCount: 0,
|
|
752
|
-
maxCount: 0,
|
|
753
|
-
invalidAddresses: invalid,
|
|
754
|
-
message: `Invalid addresses: ${invalid.join(", ")}`,
|
|
755
|
-
};
|
|
756
|
-
}
|
|
757
|
-
const data = { addresses: valid };
|
|
758
|
-
const signedRequest = await this._createSignedRequest(data);
|
|
759
|
-
return this.serverClient.removeFromFriendsList(this.userAddress, signedRequest);
|
|
760
|
-
}
|
|
761
|
-
async clearFriendsList() {
|
|
762
|
-
if (!this.userAddress) {
|
|
763
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
764
|
-
}
|
|
765
|
-
const data = {};
|
|
766
|
-
const signedRequest = await this._createSignedRequest(data);
|
|
767
|
-
return this.serverClient.clearFriendsList(this.userAddress, signedRequest);
|
|
768
|
-
}
|
|
769
|
-
async getFriendsList() {
|
|
770
|
-
if (!this.userAddress) {
|
|
771
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
772
|
-
}
|
|
773
|
-
const signedRequest = await this._createSignedRequest({});
|
|
774
|
-
return this.serverClient.getFriendsList(this.userAddress, signedRequest);
|
|
775
|
-
}
|
|
776
|
-
async existInFriendsList(addresses) {
|
|
777
|
-
if (!this.userAddress) {
|
|
778
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
779
|
-
}
|
|
780
|
-
const { valid, invalid } = this._validateAddresses(addresses);
|
|
781
|
-
if (invalid.length > 0) {
|
|
782
|
-
return {
|
|
783
|
-
success: false,
|
|
784
|
-
operation: "exist",
|
|
785
|
-
modifiedCount: 0,
|
|
786
|
-
currentCount: 0,
|
|
787
|
-
maxCount: 0,
|
|
788
|
-
invalidAddresses: invalid,
|
|
789
|
-
message: `Invalid addresses: ${invalid.join(", ")}`,
|
|
790
|
-
};
|
|
791
|
-
}
|
|
792
|
-
const data = { addresses: valid };
|
|
793
|
-
const signedRequest = await this._createSignedRequest(data);
|
|
794
|
-
return this.serverClient.existInFriendsList(this.userAddress, signedRequest);
|
|
795
|
-
}
|
|
796
|
-
async addToGuardList(guards) {
|
|
797
|
-
if (!this.userAddress) {
|
|
798
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
799
|
-
}
|
|
800
|
-
const data = { guards };
|
|
801
|
-
const signedRequest = await this._createSignedRequest(data);
|
|
802
|
-
return this.serverClient.addToGuardList(this.userAddress, signedRequest);
|
|
803
|
-
}
|
|
804
|
-
async removeFromGuardList(addresses) {
|
|
805
|
-
if (!this.userAddress) {
|
|
806
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
807
|
-
}
|
|
808
|
-
const { valid, invalid } = this._validateAddresses(addresses);
|
|
809
|
-
if (invalid.length > 0) {
|
|
810
|
-
return {
|
|
811
|
-
success: false,
|
|
812
|
-
operation: "remove",
|
|
813
|
-
modifiedCount: 0,
|
|
814
|
-
currentCount: 0,
|
|
815
|
-
maxCount: 0,
|
|
816
|
-
invalidAddresses: invalid,
|
|
817
|
-
message: `Invalid addresses: ${invalid.join(", ")}`,
|
|
818
|
-
};
|
|
819
|
-
}
|
|
820
|
-
const data = { addresses: valid };
|
|
821
|
-
const signedRequest = await this._createSignedRequest(data);
|
|
822
|
-
return this.serverClient.removeFromGuardList(this.userAddress, signedRequest);
|
|
823
|
-
}
|
|
824
|
-
async getGuardList() {
|
|
825
|
-
if (!this.userAddress) {
|
|
826
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
827
|
-
}
|
|
828
|
-
const signedRequest = await this._createSignedRequest({});
|
|
829
|
-
return this.serverClient.getGuardList(this.userAddress, signedRequest);
|
|
830
|
-
}
|
|
831
|
-
async getSettings() {
|
|
832
|
-
if (!this.userAddress) {
|
|
833
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
834
|
-
}
|
|
835
|
-
const signedRequest = await this._createSignedRequest({});
|
|
836
|
-
return this.serverClient.getSettings(this.userAddress, signedRequest);
|
|
837
|
-
}
|
|
838
|
-
async setSettings(settings) {
|
|
839
|
-
if (!this.userAddress) {
|
|
840
|
-
throw new MessengerError(MessengerErrorCode.IDENTITY_NOT_FOUND, "User address not set");
|
|
841
|
-
}
|
|
842
|
-
const fullSettings = {
|
|
843
|
-
allowStrangerMessages: settings.allowStrangerMessages,
|
|
844
|
-
maxInboxSize: settings.maxInboxSize,
|
|
845
|
-
};
|
|
846
|
-
const signedRequest = await this._createSignedRequest(fullSettings);
|
|
847
|
-
return this.serverClient.updateSettings(this.userAddress, signedRequest);
|
|
848
|
-
}
|
|
849
|
-
async tryDecryptMessage(serverMsg) {
|
|
850
|
-
try {
|
|
851
|
-
const ciphertext = Uint8Array.from(Buffer.from(serverMsg.bodyB64, "base64"));
|
|
852
|
-
const decryptResult = await this.decryptionEngine.decryptMessage(this.userAddress, serverMsg.from, ciphertext.buffer, serverMsg.msgType);
|
|
853
|
-
if (!decryptResult.success) {
|
|
854
|
-
const shouldRetry = this.isRetryableError(decryptResult.error || "");
|
|
855
|
-
return {
|
|
856
|
-
success: false,
|
|
857
|
-
shouldRetry,
|
|
858
|
-
error: decryptResult.error,
|
|
859
|
-
sessionUpdated: decryptResult.sessionUpdated,
|
|
860
|
-
};
|
|
861
|
-
}
|
|
862
|
-
const plaintext = decryptResult.plaintext;
|
|
863
|
-
if (!serverMsg.clientTimestamp) {
|
|
864
|
-
throw new Error(`Missing clientTimestamp for message ${serverMsg.id}`);
|
|
865
|
-
}
|
|
866
|
-
if (!serverMsg.plaintextHash) {
|
|
867
|
-
throw new Error(`Missing plaintextHash for message ${serverMsg.id}`);
|
|
868
|
-
}
|
|
869
|
-
const verificationResult = verifyMessage({
|
|
870
|
-
messageId: serverMsg.id,
|
|
871
|
-
plaintext,
|
|
872
|
-
plaintextHash: serverMsg.plaintextHash,
|
|
873
|
-
createdAt: serverMsg.clientTimestamp,
|
|
874
|
-
guardAddress: serverMsg.guardAddress,
|
|
875
|
-
passportAddress: serverMsg.passportAddress,
|
|
876
|
-
lastReceivedLeafIndex: serverMsg.lastReceivedLeafIndex,
|
|
877
|
-
serverSignature: serverMsg.merkleMetadata?.serverSignature,
|
|
878
|
-
serverPublicKey: serverMsg.merkleMetadata?.serverPublicKey,
|
|
879
|
-
merkleMetadata: serverMsg.merkleMetadata
|
|
880
|
-
? {
|
|
881
|
-
prevRoot: serverMsg.merkleMetadata.prevRoot,
|
|
882
|
-
newRoot: serverMsg.merkleMetadata.newRoot,
|
|
883
|
-
serverTimestamp: serverMsg.merkleMetadata.serverTimestamp,
|
|
884
|
-
leafIndex: serverMsg.merkleMetadata.leafIndex,
|
|
885
|
-
proofSiblings: serverMsg.merkleMetadata.proofSiblings,
|
|
886
|
-
proofIndices: serverMsg.merkleMetadata.proofIndices,
|
|
887
|
-
}
|
|
888
|
-
: undefined,
|
|
889
|
-
});
|
|
890
|
-
if (!verificationResult.valid) {
|
|
891
|
-
throw new Error(verificationResult.error);
|
|
892
|
-
}
|
|
893
|
-
const message = {
|
|
894
|
-
messageId: serverMsg.id,
|
|
895
|
-
fromAddress: serverMsg.from,
|
|
896
|
-
toAddress: this.userAddress,
|
|
897
|
-
plaintextHash: serverMsg.plaintextHash,
|
|
898
|
-
plaintext,
|
|
899
|
-
guardAddress: serverMsg.guardAddress,
|
|
900
|
-
passportAddress: serverMsg.passportAddress,
|
|
901
|
-
lastReceivedLeafIndex: serverMsg.lastReceivedLeafIndex,
|
|
902
|
-
direction: MessageDirection.RECEIVED,
|
|
903
|
-
status: MessageStatus.DECRYPTED,
|
|
904
|
-
msgType: serverMsg.msgType,
|
|
905
|
-
leafIndex: serverMsg.merkleMetadata?.leafIndex,
|
|
906
|
-
prevRoot: serverMsg.merkleMetadata?.prevRoot,
|
|
907
|
-
newRoot: serverMsg.merkleMetadata?.newRoot,
|
|
908
|
-
serverSignature: serverMsg.merkleMetadata?.serverSignature,
|
|
909
|
-
serverTimestamp: serverMsg.merkleMetadata?.serverTimestamp,
|
|
910
|
-
serverPublicKey: serverMsg.merkleMetadata?.serverPublicKey,
|
|
911
|
-
createdAt: serverMsg.clientTimestamp,
|
|
912
|
-
receivedAt: Date.now(),
|
|
913
|
-
zipMetadata: serverMsg.zipMetadata,
|
|
914
|
-
};
|
|
915
|
-
if (serverMsg.merkleMetadata) {
|
|
916
|
-
this.sessionStateStorage.updateSessionState(this.userAddress, serverMsg.from, {
|
|
917
|
-
currentRoot: serverMsg.merkleMetadata.newRoot,
|
|
918
|
-
prevRoot: serverMsg.merkleMetadata.prevRoot,
|
|
919
|
-
lastLeafIndex: serverMsg.merkleMetadata.leafIndex,
|
|
920
|
-
lastSyncAt: Date.now(),
|
|
921
|
-
});
|
|
922
|
-
}
|
|
923
|
-
const timestamp = serverMsg.merkleMetadata?.serverTimestamp ||
|
|
924
|
-
serverMsg.clientTimestamp ||
|
|
925
|
-
Date.now();
|
|
926
|
-
if (serverMsg.lastReceivedLeafIndex !== undefined &&
|
|
927
|
-
serverMsg.lastReceivedLeafIndex >= 0) {
|
|
928
|
-
const mySentMessages = this.messageStorage
|
|
929
|
-
.getMessagesBySession(this.userAddress, serverMsg.from)
|
|
930
|
-
.filter((m) => m.direction === MessageDirection.SENT &&
|
|
931
|
-
m.status === MessageStatus.CONFIRMED &&
|
|
932
|
-
m.leafIndex !== undefined &&
|
|
933
|
-
m.leafIndex <= serverMsg.lastReceivedLeafIndex);
|
|
934
|
-
for (const sentMsg of mySentMessages) {
|
|
935
|
-
this.messageStorage.updateMessageStatus(sentMsg.messageId, MessageStatus.READ);
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
return {
|
|
939
|
-
success: true,
|
|
940
|
-
shouldRetry: false,
|
|
941
|
-
message,
|
|
942
|
-
decryptedData: {
|
|
943
|
-
id: serverMsg.id,
|
|
944
|
-
from: serverMsg.from,
|
|
945
|
-
plaintext,
|
|
946
|
-
timestamp,
|
|
947
|
-
merkleVerified: !!serverMsg.merkleMetadata,
|
|
948
|
-
merkleData: serverMsg.merkleMetadata
|
|
949
|
-
? {
|
|
950
|
-
leafIndex: serverMsg.merkleMetadata.leafIndex,
|
|
951
|
-
rootHash: serverMsg.merkleMetadata.newRoot,
|
|
952
|
-
}
|
|
953
|
-
: undefined,
|
|
954
|
-
},
|
|
955
|
-
sessionUpdated: decryptResult.sessionUpdated,
|
|
956
|
-
};
|
|
957
|
-
}
|
|
958
|
-
catch (error) {
|
|
959
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
960
|
-
const shouldRetry = this.isRetryableError(errorMessage);
|
|
961
|
-
return {
|
|
962
|
-
success: false,
|
|
963
|
-
shouldRetry,
|
|
964
|
-
error: errorMessage,
|
|
965
|
-
};
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
isRetryableError(errorMessage) {
|
|
969
|
-
const retryablePatterns = [
|
|
970
|
-
/message number/i,
|
|
971
|
-
/chain key/i,
|
|
972
|
-
/session not found/i,
|
|
973
|
-
/prekey not found/i,
|
|
974
|
-
/PREKEY 竞争:我的地址较小,保留我的会话/i,
|
|
975
|
-
/The operation failed for an operation-specific reason/i,
|
|
976
|
-
/DOMException/i,
|
|
977
|
-
/收到 WHISPER_MESSAGE 但无现有会话,需要等待 PREKEY_MESSAGE/i,
|
|
978
|
-
];
|
|
979
|
-
return retryablePatterns.some((pattern) => pattern.test(errorMessage));
|
|
980
|
-
}
|
|
981
|
-
async processWaitingMessages(decryptedMessages, acknowledgedIds) {
|
|
982
|
-
if (this.waitingMessages.size === 0)
|
|
983
|
-
return;
|
|
984
|
-
console.log(`[Messenger] 尝试处理 ${this.waitingMessages.size} 条等待消息`);
|
|
985
|
-
const processedIds = [];
|
|
986
|
-
const sortedWaitingMsgs = Array.from(this.waitingMessages.values()).sort(function (a, b) {
|
|
987
|
-
return (a.clientTimestamp || 0) - (b.clientTimestamp || 0);
|
|
988
|
-
});
|
|
989
|
-
for (const serverMsg of sortedWaitingMsgs) {
|
|
990
|
-
const id = serverMsg.id;
|
|
991
|
-
const decryptResult = await this.tryDecryptMessage(serverMsg);
|
|
992
|
-
if (decryptResult.success &&
|
|
993
|
-
decryptResult.message &&
|
|
994
|
-
decryptResult.decryptedData) {
|
|
995
|
-
this.messageStorage.saveMessage(decryptResult.message);
|
|
996
|
-
decryptedMessages.push(decryptResult.decryptedData);
|
|
997
|
-
acknowledgedIds.push(id);
|
|
998
|
-
processedIds.push(id);
|
|
999
|
-
this.waitingMessageRetries.delete(id);
|
|
1000
|
-
}
|
|
1001
|
-
else if (!decryptResult.shouldRetry) {
|
|
1002
|
-
console.error(`[Messenger] 等待消息 ${id} 解密永久失败: ${decryptResult.error}`);
|
|
1003
|
-
this.failedMessages.set(id, {
|
|
1004
|
-
message: serverMsg,
|
|
1005
|
-
error: decryptResult.error || "Unknown error",
|
|
1006
|
-
});
|
|
1007
|
-
await this.saveFailedMessage(serverMsg, decryptResult.error || "Unknown error");
|
|
1008
|
-
acknowledgedIds.push(id);
|
|
1009
|
-
processedIds.push(id);
|
|
1010
|
-
this.waitingMessageRetries.delete(id);
|
|
1011
|
-
}
|
|
1012
|
-
else {
|
|
1013
|
-
const currentRetries = this.waitingMessageRetries.get(id) || 0;
|
|
1014
|
-
const newRetries = currentRetries + 1;
|
|
1015
|
-
if (newRetries >= 3) {
|
|
1016
|
-
console.error(`[Messenger] 等待消息 ${id} 重试3次后仍失败,标记为永久失败`);
|
|
1017
|
-
this.failedMessages.set(id, {
|
|
1018
|
-
message: serverMsg,
|
|
1019
|
-
error: decryptResult.error || "Retry limit exceeded",
|
|
1020
|
-
});
|
|
1021
|
-
await this.saveFailedMessage(serverMsg, decryptResult.error || "Retry limit exceeded");
|
|
1022
|
-
acknowledgedIds.push(id);
|
|
1023
|
-
processedIds.push(id);
|
|
1024
|
-
this.waitingMessageRetries.delete(id);
|
|
1025
|
-
}
|
|
1026
|
-
else {
|
|
1027
|
-
this.waitingMessageRetries.set(id, newRetries);
|
|
1028
|
-
console.log(`[Messenger] 消息 ${id} 第 ${newRetries}/3 次重试失败,继续等待`);
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1032
|
-
for (const id of processedIds) {
|
|
1033
|
-
this.waitingMessages.delete(id);
|
|
1034
|
-
}
|
|
1035
|
-
if (processedIds.length > 0) {
|
|
1036
|
-
console.log(`[Messenger] 成功处理 ${processedIds.length} 条等待消息`);
|
|
1037
|
-
}
|
|
1038
|
-
}
|
|
1039
|
-
async saveFailedMessage(serverMsg, error) {
|
|
1040
|
-
const failedMessage = {
|
|
1041
|
-
messageId: serverMsg.id,
|
|
1042
|
-
fromAddress: serverMsg.from,
|
|
1043
|
-
toAddress: this.userAddress,
|
|
1044
|
-
plaintextHash: serverMsg.plaintextHash || "",
|
|
1045
|
-
guardAddress: serverMsg.guardAddress,
|
|
1046
|
-
passportAddress: serverMsg.passportAddress,
|
|
1047
|
-
lastReceivedLeafIndex: serverMsg.lastReceivedLeafIndex,
|
|
1048
|
-
direction: MessageDirection.RECEIVED,
|
|
1049
|
-
status: MessageStatus.DECRYPT_FAILED,
|
|
1050
|
-
msgType: serverMsg.msgType,
|
|
1051
|
-
leafIndex: serverMsg.merkleMetadata?.leafIndex,
|
|
1052
|
-
prevRoot: serverMsg.merkleMetadata?.prevRoot,
|
|
1053
|
-
newRoot: serverMsg.merkleMetadata?.newRoot,
|
|
1054
|
-
serverSignature: serverMsg.merkleMetadata?.serverSignature,
|
|
1055
|
-
serverTimestamp: serverMsg.merkleMetadata?.serverTimestamp,
|
|
1056
|
-
serverPublicKey: serverMsg.merkleMetadata?.serverPublicKey,
|
|
1057
|
-
createdAt: serverMsg.clientTimestamp || Date.now(),
|
|
1058
|
-
receivedAt: Date.now(),
|
|
1059
|
-
zipMetadata: serverMsg.zipMetadata,
|
|
1060
|
-
decryptError: error,
|
|
1061
|
-
decryptAttempts: 1,
|
|
1062
|
-
lastDecryptAttemptAt: Date.now(),
|
|
1063
|
-
};
|
|
1064
|
-
this.messageStorage.saveMessage(failedMessage);
|
|
1065
|
-
}
|
|
1066
|
-
reschedulePolling() {
|
|
1067
|
-
if (!this.isPollingRunning || !this.pollingTimer)
|
|
1068
|
-
return;
|
|
1069
|
-
console.log(`[Messenger] 重新调度轮询,切换到快速模式(等待消息: ${this.waitingMessages.size})`);
|
|
1070
|
-
clearTimeout(this.pollingTimer);
|
|
1071
|
-
this.pollingTimer = null;
|
|
1072
|
-
this.scheduleNextPoll();
|
|
1073
|
-
}
|
|
1074
|
-
getFailedMessages() {
|
|
1075
|
-
return Array.from(this.failedMessages.entries()).map(([id, data]) => ({
|
|
1076
|
-
messageId: id,
|
|
1077
|
-
from: data.message.from,
|
|
1078
|
-
error: data.error,
|
|
1079
|
-
leafIndex: data.message.merkleMetadata?.leafIndex,
|
|
1080
|
-
}));
|
|
1081
|
-
}
|
|
1082
|
-
clearFailedMessages(messageId) {
|
|
1083
|
-
if (messageId) {
|
|
1084
|
-
this.failedMessages.delete(messageId);
|
|
1085
|
-
}
|
|
1086
|
-
else {
|
|
1087
|
-
this.failedMessages.clear();
|
|
1088
|
-
}
|
|
1089
|
-
}
|
|
1090
|
-
getWaitingMessageCount() {
|
|
1091
|
-
return this.waitingMessages.size;
|
|
1092
|
-
}
|
|
1093
|
-
}
|
|
1
|
+
import{createHash}from'crypto';import*as a183a from'fs';import*as a183b from'path';import{MessengerSession,DecryptionEngine}from'./session.js';import{MessengerServerClient}from'./server.js';import{MessageStorage,SessionStateStorage}from'./storage.js';import{hashPlaintext,verifyMessage,bytesToBase64}from'./crypto.js';import{canonicalizeJson}from'./utils.js';import{DEFAULT_MESSENGER_CONFIG,MessengerError,MessengerErrorCode,MessageDirection,MessageStatus,WTS_FILE_BYTES_LIMIT,NORMAL_MESSAGE_BYTES_LIMIT,CHAIN_PROOF_TYPE}from'./types.js';import{isValidWowAddress}from'../../utils/sui-types.js';async function getAccount(){const {Account:a}=await import('../local/account.js');return a['Instance']();}export class Messenger{['session'];['serverClient'];['config'];['userAddress']=null;['onMessageCallback']=null;['pollingTimer']=null;['messageConsecutiveEmptyPulls']=0x0;['prekeyConsecutiveOkCount']=0x0;['currentMessageInterval'];['isPollingRunning']=![];['messageStorage'];['sessionStateStorage'];['decryptionEngine'];['waitingMessages']=new Map();['failedMessages']=new Map();['waitingMessageRetries']=new Map();constructor(a,b){this['userAddress']=a,this['config']={...DEFAULT_MESSENGER_CONFIG,...b},this['session']=new MessengerSession(a,this['config']),this['serverClient']=new MessengerServerClient(this['config']),this['messageStorage']=new MessageStorage(a),this['sessionStateStorage']=new SessionStateStorage(a),this['decryptionEngine']=new DecryptionEngine(this['session']['store']),this['currentMessageInterval']=this['config']['message_poll_default_interval_ms']??0x6*0x3c*0x3e8;}['getUserAddress'](){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');return this['userAddress'];}async['getPublicKey'](){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const a=await(await getAccount())['get'](this['userAddress'],![]);return a?.['pubkey']||'';}['isValidGuardMessage'](a,b){return Boolean(a&&b&&isValidWowAddress(a)&&isValidWowAddress(b));}async['generateSignatureParams'](a){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const b=await(await getAccount())['get'](this['userAddress'],![]);if(!b?.['secret'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'Account\x20not\x20found\x20or\x20no\x20secret\x20key\x20for\x20'+this['userAddress']);const {Ed25519Keypair:c}=await import('../../keypairs/ed25519/index.js'),d=c['fromSecretKey'](b['secret']),e=d['getPublicKey'](),f=e['toWPublicKey'](),g=Date['now'](),h=this['generateNonce'](),i=a+':'+f+':'+g+':'+h,j=await d['sign'](new TextEncoder()['encode'](i));return{'signatureScheme':'ED25519','signature':Buffer['from'](j)['toString']('base64'),'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['initialize'](){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');await this['session']['ensureIdentity'](this['userAddress']),await this['session']['registerDevice'](this['userAddress']),await this['session']['ensurePreKeys'](this['userAddress']),await this['checkAndRefillPrekeys'](),this['startPollingTimer']();}async['checkAndRefillPrekeys'](){if(!this['userAddress'])return;await this['session']['ensurePreKeys'](this['userAddress'],![]);}['startPollingTimer'](){this['pollingTimer']&&clearTimeout(this['pollingTimer']),this['isPollingRunning']=!![],this['scheduleNextPoll']();}['stopPollingTimer'](){this['isPollingRunning']=![],this['pollingTimer']&&(clearTimeout(this['pollingTimer']),this['pollingTimer']=null);}['scheduleNextPoll'](){if(!this['isPollingRunning'])return;const a=this['getNextPollInterval']();this['pollingTimer']=setTimeout(()=>{this['poll']()['catch'](b=>{console['error']('[Polling]\x20Error\x20during\x20poll:',b);})['finally'](()=>{this['scheduleNextPoll']();});},a);}['getNextPollInterval'](){if(this['waitingMessages']['size']>0x0)return this['config']['message_poll_waiting_interval_ms']??0x3*0x3e8;return this['currentMessageInterval'];}async['poll'](){if(!this['userAddress'])return;try{const a=await this['pullMessages']();a['messages']['length']>0x0?(this['messageConsecutiveEmptyPulls']=0x0,this['currentMessageInterval']=this['config']['message_poll_fast_interval_ms']??0x6*0x3e8,this['onMessageCallback']&&this['onMessageCallback'](a['messages'])):(this['messageConsecutiveEmptyPulls']++,this['messageConsecutiveEmptyPulls']>=(this['config']['message_poll_consecutive_empty_limit']??0x3)&&(this['currentMessageInterval']=this['config']['message_poll_default_interval_ms']??0x6*0x3c*0x3e8,this['messageConsecutiveEmptyPulls']=0x0));if(a['prekey_status']){const b=a['prekey_status'];b['shouldRefill']?(this['prekeyConsecutiveOkCount']=0x0,await this['checkAndRefillPrekeys']()):(this['prekeyConsecutiveOkCount']++,this['prekeyConsecutiveOkCount']>=(this['config']['prekey_poll_consecutive_ok_limit']??0x3)&&(this['prekeyConsecutiveOkCount']=0x0));}}catch(c){console['error']('[Polling]\x20Poll\x20error:',c);}}['triggerFastPoll'](){this['currentMessageInterval']=this['config']['message_poll_fast_interval_ms']??0x6*0x3e8,this['messageConsecutiveEmptyPulls']=0x0,this['isPollingRunning']&&(this['pollingTimer']&&clearTimeout(this['pollingTimer']),this['scheduleNextPoll']());}async['sendMessage'](a,b,c){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const d=Date['now'](),e=Date['now'](),f=this['generateNonce'](),g=new TextEncoder()['encode'](b)['length'];if(g>NORMAL_MESSAGE_BYTES_LIMIT)throw new MessengerError(MessengerErrorCode['INVALID_INPUT'],'Message\x20size\x20('+g+'\x20bytes)\x20exceeds\x20maximum\x20allowed\x20size\x20('+NORMAL_MESSAGE_BYTES_LIMIT+'\x20bytes).\x20Consider\x20using\x20sendZipFile\x20for\x20large\x20content.');await this['pullMessages']();const h=this['messageStorage']['getLastReceivedLeafIndex'](this['userAddress'],a),i=await this['session']['encryptMessage'](this['userAddress'],a,b),j=Buffer['from'](new Uint8Array(i['body']))['toString']('base64'),k=hashPlaintext(b,d,c?.['guardAddress'],c?.['passportAddress'],h),l=await(await getAccount())['get'](this['userAddress'],![]);if(!l)throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20account\x20not\x20found');const m=l['pubkey'],n=c?.['guardAddress']||'',o=c?.['passportAddress']||'',p=h>=0x0?h['toString']():'',q=c?.['force']?'true':'false',r='send_message:'+this['userAddress']+':'+a+':'+n+':'+o+':'+k+':'+p+':'+m+':'+e+':'+f+':'+q,s=await(await getAccount())['signData'](this['userAddress'],r),t=Buffer['from'](s['signature']['slice'](0x2),'hex'),u=bytesToBase64(new Uint8Array(t)),v=await this['serverClient']['sendMessage']({'sender':s['publicKey'],'recipient':a,'ciphertext':j,'plaintextHash':k,'clientTimestamp':d,'msgType':i['type'],'signatureScheme':'ED25519','signature':u,'timestamp':e,'nonce':f,'guardAddress':c?.['guardAddress'],'passportAddress':c?.['passportAddress'],'force':c?.['force'],'lastReceivedLeafIndex':h>=0x0?h:undefined}),w={'messageId':v['messageId'],'fromAddress':this['userAddress'],'toAddress':a,'plaintextHash':k,'plaintext':b,'guardAddress':c?.['guardAddress'],'passportAddress':c?.['passportAddress'],'lastReceivedLeafIndex':h,'direction':MessageDirection['SENT'],'status':v['status']==='confirmed'?MessageStatus['CONFIRMED']:MessageStatus['PENDING'],'msgType':i['type'],'createdAt':d};v['merkleData']&&(w['leafIndex']=v['merkleData']['leafIndex'],w['prevRoot']=v['merkleData']['prevRoot'],w['newRoot']=v['merkleData']['newRoot'],w['serverSignature']=v['merkleData']['serverSignature'],w['serverTimestamp']=v['merkleData']['serverTimestamp'],w['serverPublicKey']=v['merkleData']['serverPublicKey'],this['sessionStateStorage']['updateSessionState'](this['userAddress'],a,{'currentRoot':v['merkleData']['newRoot'],'prevRoot':v['merkleData']['prevRoot'],'lastLeafIndex':v['merkleData']['leafIndex'],'lastSyncAt':Date['now']()}));this['messageStorage']['saveMessage'](w);if(v['pendingMerkleData'])for(const [x,y]of Object['entries'](v['pendingMerkleData'])){const z=this['messageStorage']['getMessage'](x);z&&z['status']===MessageStatus['PENDING']&&this['messageStorage']['updateMessageStatus'](x,MessageStatus['CONFIRMED'],{'leafIndex':y['leafIndex'],'newRoot':y['newRoot'],'serverSignature':y['serverSignature'],'serverTimestamp':y['serverTimestamp'],'serverPublicKey':y['serverPublicKey']});}return this['triggerFastPoll'](),{'messageId':v['messageId'],'status':w['status'],'merkleData':v['merkleData'],'guardList':v['guard_list'],'lastReceivedLeafIndex':h>=0x0?h:undefined};}async['pullMessages'](a){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const b=Date['now'](),c=this['generateNonce'](),d='fetch_messages:'+this['userAddress']+':'+(a||0x64)+':'+b+':'+c,e=await(await getAccount())['get'](this['userAddress'],![]),f=e?.['pubkey']||'',g=await(await getAccount())['signData'](this['userAddress'],d),h=Buffer['from'](g['signature']['slice'](0x2),'hex'),i={'signatureScheme':'ED25519','signature':bytesToBase64(h),'timestamp':b,'nonce':c},j=await this['serverClient']['pullMessages'](this['userAddress'],f,i,a);if(j['messages']['length']===0x0)return{'messages':[],'prekey_status':j['prekey_status']};const k=[],l=[],m=[...j['messages']]['sort'](function(n,o){return(n['clientTimestamp']||0x0)-(o['clientTimestamp']||0x0);});await this['processWaitingMessages'](k,l);for(const n of m){if(this['waitingMessages']['has'](n['id'])){l['push'](n['id']);continue;}if(this['failedMessages']['has'](n['id'])){l['push'](n['id']);continue;}const o=this['messageStorage']['getMessage'](n['id']);if(o){l['push'](n['id']);continue;}const p=await this['tryDecryptMessage'](n);if(p['success']&&p['message']&&p['decryptedData'])this['messageStorage']['saveMessage'](p['message']),k['push'](p['decryptedData']),l['push'](n['id']),this['waitingMessages']['delete'](n['id']);else p['shouldRetry']?(console['warn']('[Messenger]\x20消息\x20'+n['id']+'\x20解密失败,加入等待池:\x20'+p['error']),this['waitingMessages']['set'](n['id'],n)):(console['error']('[Messenger]\x20消息\x20'+n['id']+'\x20解密永久失败:\x20'+p['error']),this['failedMessages']['set'](n['id'],{'message':n,'error':p['error']||'Unknown\x20error'}),await this['saveFailedMessage'](n,p['error']||'Unknown\x20error'),l['push'](n['id']));}this['waitingMessages']['size']>0x0&&this['isPollingRunning']&&this['reschedulePolling']();if(l['length']>0x0&&this['userAddress']){const q=Date['now'](),r=this['generateNonce'](),s=await(await getAccount())['get'](this['userAddress'],![]);if(s?.['pubkey']){const t='ack_messages:'+this['userAddress']+':'+l['join'](',')+':'+s['pubkey']+':'+q+':'+r,u=await(await getAccount())['signData'](this['userAddress'],t),v=Buffer['from'](u['signature']['slice'](0x2),'hex'),w=bytesToBase64(new Uint8Array(v));await this['serverClient']['acknowledgeMessages'](l,u['publicKey'],{'publicKey':u['publicKey'],'signatureScheme':'ED25519','signature':w,'timestamp':q,'nonce':r});}}return{'messages':k,'prekey_status':j['prekey_status']};}['getLastSentLeafIndex'](a){if(!this['userAddress'])return-0x1;const b=this['messageStorage']['getMessagesBySession'](this['userAddress'],a),c=b['filter'](d=>d['direction']===MessageDirection['SENT']&&d['leafIndex']!==undefined);if(c['length']===0x0)return-0x1;return Math['max'](...c['map'](d=>d['leafIndex']));}['getSessionMessages'](a){if(!this['userAddress'])return[];return this['messageStorage']['getMessagesBySession'](this['userAddress'],a);}['getSessionState'](a){if(!this['userAddress'])return undefined;return this['sessionStateStorage']['getSessionState'](this['userAddress'],a);}async['submitChainProof'](a,b,c){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const d=this['sessionStateStorage']['getSessionState'](this['userAddress'],b);if(!d||!d['currentRoot'])throw new MessengerError(MessengerErrorCode['SESSION_NOT_ESTABLISHED'],'No\x20session\x20state\x20found');const e=this['messageStorage']['getMessagesBySession'](this['userAddress'],b),f=e[e['length']-0x1];if(!f||!f['serverPublicKey']||!f['serverSignature'])throw new MessengerError(MessengerErrorCode['INVALID_PROOF'],'No\x20temporal\x20proof\x20(missing\x20server\x20public\x20key\x20or\x20signature),\x20cannot\x20submit\x20Proof\x20to\x20WoWok\x20blockchain');const g=f['serverPublicKey'],h=f['serverSignature'],i={'sessionId':d['sessionId'],'merkleRoot':d['currentRoot'],'messageCount':d['messageCount'],'timestamp':Date['now']()},{CallProof:j}=await import('../call/proof.js'),k=new j({'proof':JSON['stringify'](i),'server_pubkey':g,'server_signature':h,'proof_type':CHAIN_PROOF_TYPE,'description':c||'Messenger\x20session\x20proof\x20for\x20'+this['userAddress']+'\x20<->\x20'+b,'item_count':d['messageCount'],'about_address':d['sessionId']}),l=await k['call'](a),m=l?.['objectChanges'],n=m?.['find'](o=>o['objectType']?.['includes']('Proof'))?.['objectId'];return{'proofAddress':n||'','txHash':l?.['digest']||''};}['destroy'](){this['stopPollingTimer']();}['disconnect'](){this['destroy']();}['setOnMessageCallback'](a){this['onMessageCallback']=a;}async['sendZipFile'](a,b,c){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const d=await this['loadFileData'](b),{ZipWriter:e,BlobWriter:f,Uint8ArrayReader:g}=await import('@zip.js/zip.js'),h=c?.['fileName']||a183b['basename'](b)||'file.zip',i=c?.['contentType']||this['detectContentType'](h),j=new f('application/zip'),k=new e(j);await k['add'](h,new g(d)),await k['close']();const l=await j['getData'](),m=new Uint8Array(await l['arrayBuffer']());if(m['length']>WTS_FILE_BYTES_LIMIT)throw new MessengerError(MessengerErrorCode['INVALID_INPUT'],'ZIP\x20file\x20size\x20('+m['length']+'\x20bytes)\x20exceeds\x20local\x20maximum\x20allowed\x20size\x20('+WTS_FILE_BYTES_LIMIT+'\x20bytes)');const n='0x'+createHash('sha256')['update'](m)['digest']('hex'),o=Buffer['from'](m)['toString']('base64'),p={'fileName':h+'.zip','fileSize':m['length'],'fileHash':n,'contentType':i};await this['pullMessages']();const q=this['messageStorage']['getLastReceivedLeafIndex'](this['userAddress'],a),r=Date['now'](),s=await this['session']['encryptMessage'](this['userAddress'],a,o),t=Buffer['from'](new Uint8Array(s['body']))['toString']('base64'),u=c?.['guardAddress']||'',v=c?.['passportAddress']||'',w=hashPlaintext(o,r,u,v,q),x=Date['now'](),y=this['generateNonce'](),z=await(await getAccount())['get'](this['userAddress'],![]);if(!z)throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20account\x20not\x20found');const A=z['pubkey'],B=q>=0x0?q['toString']():'',C=c?.['force']?'true':'false',D='send_message:'+this['userAddress']+':'+a+':'+u+':'+v+':'+w+':'+B+':'+A+':'+x+':'+y+':'+C,E=await(await getAccount())['signData'](this['userAddress'],D),F=Buffer['from'](E['signature']['slice'](0x2),'hex'),G=bytesToBase64(new Uint8Array(F)),H=await this['serverClient']['sendMessage']({'sender':E['publicKey'],'recipient':a,'ciphertext':t,'plaintextHash':w,'clientTimestamp':r,'msgType':s['type'],'zipMetadata':p,'guardAddress':c?.['guardAddress'],'passportAddress':c?.['passportAddress'],'force':c?.['force'],'lastReceivedLeafIndex':q>=0x0?q:undefined,'signatureScheme':'ED25519','signature':G,'timestamp':x,'nonce':y}),I={'messageId':H['messageId'],'fromAddress':this['userAddress'],'toAddress':a,'plaintextHash':w,'plaintext':o,'guardAddress':c?.['guardAddress'],'passportAddress':c?.['passportAddress'],'lastReceivedLeafIndex':q,'direction':MessageDirection['SENT'],'status':H['status']==='confirmed'?MessageStatus['CONFIRMED']:MessageStatus['PENDING'],'msgType':s['type'],'zipMetadata':p,'createdAt':r};H['merkleData']&&(I['leafIndex']=H['merkleData']['leafIndex'],I['prevRoot']=H['merkleData']['prevRoot'],I['newRoot']=H['merkleData']['newRoot'],I['serverSignature']=H['merkleData']['serverSignature'],I['serverTimestamp']=H['merkleData']['serverTimestamp'],I['serverPublicKey']=H['merkleData']['serverPublicKey'],this['sessionStateStorage']['updateSessionState'](this['userAddress'],a,{'currentRoot':H['merkleData']['newRoot'],'prevRoot':H['merkleData']['prevRoot'],'lastLeafIndex':H['merkleData']['leafIndex'],'lastSyncAt':Date['now']()}));this['messageStorage']['saveMessage'](I);if(H['pendingMerkleData'])for(const [J,K]of Object['entries'](H['pendingMerkleData'])){const L=this['messageStorage']['getMessage'](J);L&&L['status']===MessageStatus['PENDING']&&this['messageStorage']['updateMessageStatus'](J,MessageStatus['CONFIRMED'],{'leafIndex':K['leafIndex'],'newRoot':K['newRoot'],'serverSignature':K['serverSignature'],'serverTimestamp':K['serverTimestamp'],'serverPublicKey':K['serverPublicKey']});}return this['triggerFastPoll'](),{'messageId':H['messageId'],'status':I['status'],'merkleData':H['merkleData'],'guardList':H['guard_list'],'lastReceivedLeafIndex':q>=0x0?q:undefined};}async['loadFileData'](a){if(a['startsWith']('http://')||a['startsWith']('https://')){const d=await fetch(a);if(!d['ok'])throw new MessengerError(MessengerErrorCode['NETWORK_ERROR'],'Failed\x20to\x20fetch\x20file\x20from\x20'+a+':\x20'+d['statusText']);const e=await d['arrayBuffer']();return new Uint8Array(e);}const b=a183b['resolve'](a);if(!a183a['existsSync'](b))throw new MessengerError(MessengerErrorCode['FILE_NOT_FOUND'],'File\x20not\x20found:\x20'+b);const c=a183a['readFileSync'](b);return new Uint8Array(c);}['detectContentType'](a){const b=a183b['extname'](a)['toLowerCase']();switch(b){case'.wts':return'wts';case'.wip':return'wip';default:return'zip';}}async['_createSignedRequest'](a){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const b=Date['now'](),c=this['generateNonce'](),d=canonicalizeJson(a),e=b+':'+c+':'+d,f=await(await getAccount())['signData'](this['userAddress'],e),g=Buffer['from'](f['signature']['slice'](0x2),'hex'),h=bytesToBase64(new Uint8Array(g)),i=await(await getAccount())['get'](this['userAddress'],![]);if(!i||!i['pubkey'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'Account\x20public\x20key\x20not\x20found');return{'userAddress':this['userAddress'],'publicKey':i['pubkey'],'signatureScheme':'ED25519','signature':h,'timestamp':b,'nonce':c,'data':a};}['_validateAddresses'](a){const b=[],c=[];for(const d of a){isValidWowAddress(d)?b['push'](d):c['push'](d);}return{'valid':b,'invalid':c};}async['addToBlacklist'](a){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const {valid:b,invalid:c}=this['_validateAddresses'](a);if(c['length']>0x0)return{'success':![],'operation':'add','modifiedCount':0x0,'currentCount':0x0,'maxCount':0x0,'invalidAddresses':c,'message':'Invalid\x20addresses:\x20'+c['join'](',\x20')};const d={'addresses':b},e=await this['_createSignedRequest'](d);return this['serverClient']['addToBlacklist'](this['userAddress'],e);}async['removeFromBlacklist'](a){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const {valid:b,invalid:c}=this['_validateAddresses'](a);if(c['length']>0x0)return{'success':![],'operation':'remove','modifiedCount':0x0,'currentCount':0x0,'maxCount':0x0,'invalidAddresses':c,'message':'Invalid\x20addresses:\x20'+c['join'](',\x20')};const d={'addresses':b},e=await this['_createSignedRequest'](d);return this['serverClient']['removeFromBlacklist'](this['userAddress'],e);}async['clearBlacklist'](){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const a={},b=await this['_createSignedRequest'](a);return this['serverClient']['clearBlacklist'](this['userAddress'],b);}async['getBlacklist'](){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const a=await this['_createSignedRequest']({});return this['serverClient']['getBlacklist'](this['userAddress'],a);}async['existInBlacklist'](a){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const {valid:b,invalid:c}=this['_validateAddresses'](a);if(c['length']>0x0)return{'success':![],'operation':'exist','modifiedCount':0x0,'currentCount':0x0,'maxCount':0x0,'invalidAddresses':c,'message':'Invalid\x20addresses:\x20'+c['join'](',\x20')};const d={'addresses':b},e=await this['_createSignedRequest'](d);return this['serverClient']['existInBlacklist'](this['userAddress'],e);}async['addToFriendsList'](a){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const {valid:b,invalid:c}=this['_validateAddresses'](a);if(c['length']>0x0)return{'success':![],'operation':'add','modifiedCount':0x0,'currentCount':0x0,'maxCount':0x0,'invalidAddresses':c,'message':'Invalid\x20addresses:\x20'+c['join'](',\x20')};const d={'addresses':b},e=await this['_createSignedRequest'](d);return this['serverClient']['addToFriendsList'](this['userAddress'],e);}async['removeFromFriendsList'](a){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const {valid:b,invalid:c}=this['_validateAddresses'](a);if(c['length']>0x0)return{'success':![],'operation':'remove','modifiedCount':0x0,'currentCount':0x0,'maxCount':0x0,'invalidAddresses':c,'message':'Invalid\x20addresses:\x20'+c['join'](',\x20')};const d={'addresses':b},e=await this['_createSignedRequest'](d);return this['serverClient']['removeFromFriendsList'](this['userAddress'],e);}async['clearFriendsList'](){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const a={},b=await this['_createSignedRequest'](a);return this['serverClient']['clearFriendsList'](this['userAddress'],b);}async['getFriendsList'](){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const a=await this['_createSignedRequest']({});return this['serverClient']['getFriendsList'](this['userAddress'],a);}async['existInFriendsList'](a){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const {valid:b,invalid:c}=this['_validateAddresses'](a);if(c['length']>0x0)return{'success':![],'operation':'exist','modifiedCount':0x0,'currentCount':0x0,'maxCount':0x0,'invalidAddresses':c,'message':'Invalid\x20addresses:\x20'+c['join'](',\x20')};const d={'addresses':b},e=await this['_createSignedRequest'](d);return this['serverClient']['existInFriendsList'](this['userAddress'],e);}async['addToGuardList'](a){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const b={'guards':a},c=await this['_createSignedRequest'](b);return this['serverClient']['addToGuardList'](this['userAddress'],c);}async['removeFromGuardList'](a){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const {valid:b,invalid:c}=this['_validateAddresses'](a);if(c['length']>0x0)return{'success':![],'operation':'remove','modifiedCount':0x0,'currentCount':0x0,'maxCount':0x0,'invalidAddresses':c,'message':'Invalid\x20addresses:\x20'+c['join'](',\x20')};const d={'addresses':b},e=await this['_createSignedRequest'](d);return this['serverClient']['removeFromGuardList'](this['userAddress'],e);}async['getGuardList'](){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const a=await this['_createSignedRequest']({});return this['serverClient']['getGuardList'](this['userAddress'],a);}async['getSettings'](){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const a=await this['_createSignedRequest']({});return this['serverClient']['getSettings'](this['userAddress'],a);}async['setSettings'](a){if(!this['userAddress'])throw new MessengerError(MessengerErrorCode['IDENTITY_NOT_FOUND'],'User\x20address\x20not\x20set');const b={'allowStrangerMessages':a['allowStrangerMessages'],'maxInboxSize':a['maxInboxSize']},c=await this['_createSignedRequest'](b);return this['serverClient']['updateSettings'](this['userAddress'],c);}async['tryDecryptMessage'](a){try{const b=Uint8Array['from'](Buffer['from'](a['bodyB64'],'base64')),c=await this['decryptionEngine']['decryptMessage'](this['userAddress'],a['from'],b['buffer'],a['msgType']);if(!c['success']){const h=this['isRetryableError'](c['error']||'');return{'success':![],'shouldRetry':h,'error':c['error'],'sessionUpdated':c['sessionUpdated']};}const d=c['plaintext'];if(!a['clientTimestamp'])throw new Error('Missing\x20clientTimestamp\x20for\x20message\x20'+a['id']);if(!a['plaintextHash'])throw new Error('Missing\x20plaintextHash\x20for\x20message\x20'+a['id']);const e=verifyMessage({'messageId':a['id'],'plaintext':d,'plaintextHash':a['plaintextHash'],'createdAt':a['clientTimestamp'],'guardAddress':a['guardAddress'],'passportAddress':a['passportAddress'],'lastReceivedLeafIndex':a['lastReceivedLeafIndex'],'serverSignature':a['merkleMetadata']?.['serverSignature'],'serverPublicKey':a['merkleMetadata']?.['serverPublicKey'],'merkleMetadata':a['merkleMetadata']?{'prevRoot':a['merkleMetadata']['prevRoot'],'newRoot':a['merkleMetadata']['newRoot'],'serverTimestamp':a['merkleMetadata']['serverTimestamp'],'leafIndex':a['merkleMetadata']['leafIndex'],'proofSiblings':a['merkleMetadata']['proofSiblings'],'proofIndices':a['merkleMetadata']['proofIndices']}:undefined});if(!e['valid'])throw new Error(e['error']);const f={'messageId':a['id'],'fromAddress':a['from'],'toAddress':this['userAddress'],'plaintextHash':a['plaintextHash'],'plaintext':d,'guardAddress':a['guardAddress'],'passportAddress':a['passportAddress'],'lastReceivedLeafIndex':a['lastReceivedLeafIndex'],'direction':MessageDirection['RECEIVED'],'status':MessageStatus['DECRYPTED'],'msgType':a['msgType'],'leafIndex':a['merkleMetadata']?.['leafIndex'],'prevRoot':a['merkleMetadata']?.['prevRoot'],'newRoot':a['merkleMetadata']?.['newRoot'],'serverSignature':a['merkleMetadata']?.['serverSignature'],'serverTimestamp':a['merkleMetadata']?.['serverTimestamp'],'serverPublicKey':a['merkleMetadata']?.['serverPublicKey'],'createdAt':a['clientTimestamp'],'receivedAt':Date['now'](),'zipMetadata':a['zipMetadata']};a['merkleMetadata']&&this['sessionStateStorage']['updateSessionState'](this['userAddress'],a['from'],{'currentRoot':a['merkleMetadata']['newRoot'],'prevRoot':a['merkleMetadata']['prevRoot'],'lastLeafIndex':a['merkleMetadata']['leafIndex'],'lastSyncAt':Date['now']()});const g=a['merkleMetadata']?.['serverTimestamp']||a['clientTimestamp']||Date['now']();if(a['lastReceivedLeafIndex']!==undefined&&a['lastReceivedLeafIndex']>=0x0){const i=this['messageStorage']['getMessagesBySession'](this['userAddress'],a['from'])['filter'](j=>j['direction']===MessageDirection['SENT']&&j['status']===MessageStatus['CONFIRMED']&&j['leafIndex']!==undefined&&j['leafIndex']<=a['lastReceivedLeafIndex']);for(const j of i){this['messageStorage']['updateMessageStatus'](j['messageId'],MessageStatus['READ']);}}return{'success':!![],'shouldRetry':![],'message':f,'decryptedData':{'id':a['id'],'from':a['from'],'plaintext':d,'timestamp':g,'merkleVerified':!!a['merkleMetadata'],'merkleData':a['merkleMetadata']?{'leafIndex':a['merkleMetadata']['leafIndex'],'rootHash':a['merkleMetadata']['newRoot']}:undefined},'sessionUpdated':c['sessionUpdated']};}catch(k){const l=k instanceof Error?k['message']:String(k),m=this['isRetryableError'](l);return{'success':![],'shouldRetry':m,'error':l};}}['isRetryableError'](a){const b=[/message number/i,/chain key/i,/session not found/i,/prekey not found/i,/PREKEY 竞争:我的地址较小,保留我的会话/i,/The operation failed for an operation-specific reason/i,/DOMException/i,/收到 WHISPER_MESSAGE 但无现有会话,需要等待 PREKEY_MESSAGE/i];return b['some'](c=>c['test'](a));}async['processWaitingMessages'](a,b){if(this['waitingMessages']['size']===0x0)return;console['log']('[Messenger]\x20尝试处理\x20'+this['waitingMessages']['size']+'\x20条等待消息');const c=[],d=Array['from'](this['waitingMessages']['values']())['sort'](function(e,f){return(e['clientTimestamp']||0x0)-(f['clientTimestamp']||0x0);});for(const e of d){const f=e['id'],g=await this['tryDecryptMessage'](e);if(g['success']&&g['message']&&g['decryptedData'])this['messageStorage']['saveMessage'](g['message']),a['push'](g['decryptedData']),b['push'](f),c['push'](f),this['waitingMessageRetries']['delete'](f);else{if(!g['shouldRetry'])console['error']('[Messenger]\x20等待消息\x20'+f+'\x20解密永久失败:\x20'+g['error']),this['failedMessages']['set'](f,{'message':e,'error':g['error']||'Unknown\x20error'}),await this['saveFailedMessage'](e,g['error']||'Unknown\x20error'),b['push'](f),c['push'](f),this['waitingMessageRetries']['delete'](f);else{const h=this['waitingMessageRetries']['get'](f)||0x0,i=h+0x1;i>=0x3?(console['error']('[Messenger]\x20等待消息\x20'+f+'\x20重试3次后仍失败,标记为永久失败'),this['failedMessages']['set'](f,{'message':e,'error':g['error']||'Retry\x20limit\x20exceeded'}),await this['saveFailedMessage'](e,g['error']||'Retry\x20limit\x20exceeded'),b['push'](f),c['push'](f),this['waitingMessageRetries']['delete'](f)):(this['waitingMessageRetries']['set'](f,i),console['log']('[Messenger]\x20消息\x20'+f+'\x20第\x20'+i+'/3\x20次重试失败,继续等待'));}}}for(const j of c){this['waitingMessages']['delete'](j);}c['length']>0x0&&console['log']('[Messenger]\x20成功处理\x20'+c['length']+'\x20条等待消息');}async['saveFailedMessage'](a,b){const c={'messageId':a['id'],'fromAddress':a['from'],'toAddress':this['userAddress'],'plaintextHash':a['plaintextHash']||'','guardAddress':a['guardAddress'],'passportAddress':a['passportAddress'],'lastReceivedLeafIndex':a['lastReceivedLeafIndex'],'direction':MessageDirection['RECEIVED'],'status':MessageStatus['DECRYPT_FAILED'],'msgType':a['msgType'],'leafIndex':a['merkleMetadata']?.['leafIndex'],'prevRoot':a['merkleMetadata']?.['prevRoot'],'newRoot':a['merkleMetadata']?.['newRoot'],'serverSignature':a['merkleMetadata']?.['serverSignature'],'serverTimestamp':a['merkleMetadata']?.['serverTimestamp'],'serverPublicKey':a['merkleMetadata']?.['serverPublicKey'],'createdAt':a['clientTimestamp']||Date['now'](),'receivedAt':Date['now'](),'zipMetadata':a['zipMetadata'],'decryptError':b,'decryptAttempts':0x1,'lastDecryptAttemptAt':Date['now']()};this['messageStorage']['saveMessage'](c);}['reschedulePolling'](){if(!this['isPollingRunning']||!this['pollingTimer'])return;console['log']('[Messenger]\x20重新调度轮询,切换到快速模式(等待消息:\x20'+this['waitingMessages']['size']+')'),clearTimeout(this['pollingTimer']),this['pollingTimer']=null,this['scheduleNextPoll']();}['getFailedMessages'](){return Array['from'](this['failedMessages']['entries']())['map'](([a,b])=>({'messageId':a,'from':b['message']['from'],'error':b['error'],'leafIndex':b['message']['merkleMetadata']?.['leafIndex']}));}['clearFailedMessages'](a){a?this['failedMessages']['delete'](a):this['failedMessages']['clear']();}['getWaitingMessageCount'](){return this['waitingMessages']['size'];}}
|