@ritbit/v4-client-js 2.5.2 → 2.6.0
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/build/cjs/node_modules/@ritbit/v4-proto/src/codegen/ritbit/accountplus/models.js +19 -3
- package/build/cjs/node_modules/@ritbit/v4-proto/src/codegen/ritbit/accountplus/params.js +28 -3
- package/build/cjs/node_modules/@ritbit/v4-proto/src/codegen/ritbit/accountplus/tx.js +92 -5
- package/build/cjs/node_modules/@ritbit/v4-proto/src/codegen/ritbit/accountplus/tx.rpc.msg.js +7 -1
- package/build/cjs/node_modules/@ritbit/v4-proto/src/codegen/ritbit/assets/tx.js +19 -3
- package/build/cjs/node_modules/@ritbit/v4-proto/src/codegen/ritbit/bridge/tx.js +1 -1
- package/build/cjs/node_modules/@ritbit/v4-proto/src/codegen/ritbit/denomwrap/params.js +134 -0
- package/build/cjs/node_modules/@ritbit/v4-proto/src/codegen/ritbit/denomwrap/tx.js +204 -0
- package/build/cjs/node_modules/@ritbit/v4-proto/src/codegen/ritbit/denomwrap/tx.rpc.msg.js +57 -0
- package/build/cjs/node_modules/@ritbit/v4-proto/src/codegen/ritbit/lcd.js +4 -1
- package/build/cjs/node_modules/@ritbit/v4-proto/src/codegen/ritbit/rpc.query.js +3 -2
- package/build/cjs/node_modules/@ritbit/v4-proto/src/codegen/ritbit/rpc.tx.js +4 -2
- package/build/cjs/node_modules/@ritbit/v4-proto/src/codegen/ritbit/sending/tx.js +1 -1
- package/build/cjs/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/genesis.js +151 -0
- package/build/cjs/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/params.js +134 -0
- package/build/cjs/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/query.js +248 -0
- package/build/cjs/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/query.lcd.js +34 -0
- package/build/cjs/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/query.rpc.Query.js +71 -0
- package/build/cjs/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/tx.js +282 -0
- package/build/cjs/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/tx.rpc.msg.js +63 -0
- package/build/cjs/src/clients/composite-client.js +7 -3
- package/build/cjs/src/clients/constants.js +15 -3
- package/build/cjs/src/clients/lib/accounts.js +44 -5
- package/build/cjs/src/clients/lib/agent-approval-tx.js +83 -0
- package/build/cjs/src/clients/lib/agent-approval.js +119 -0
- package/build/cjs/src/clients/lib/eip712.js +592 -0
- package/build/cjs/src/clients/lib/eth-pubkey.js +68 -0
- package/build/cjs/src/clients/modules/composer.js +15 -2
- package/build/cjs/src/clients/modules/eip712-signer.js +189 -0
- package/build/cjs/src/clients/modules/eth-agent-wallet.js +101 -0
- package/build/cjs/src/clients/modules/eth-wallet.js +91 -0
- package/build/cjs/src/clients/modules/local-wallet.js +9 -2
- package/build/cjs/src/clients/modules/post.js +14 -4
- package/build/cjs/src/clients/modules/signer.js +7 -2
- package/build/cjs/src/index.js +38 -2
- package/build/cjs/src/lib/evm-address.js +92 -0
- package/build/cjs/src/lib/trading-key-utils.js +41 -3
- package/build/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/accountplus/models.d.ts +15 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/accountplus/models.d.ts.map +1 -1
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/accountplus/models.js +19 -3
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/accountplus/params.d.ts +24 -1
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/accountplus/params.d.ts.map +1 -1
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/accountplus/params.js +28 -3
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/accountplus/tx.d.ts +43 -1
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/accountplus/tx.d.ts.map +1 -1
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/accountplus/tx.js +91 -4
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/accountplus/tx.rpc.msg.d.ts +4 -1
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/accountplus/tx.rpc.msg.d.ts.map +1 -1
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/accountplus/tx.rpc.msg.js +8 -2
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/assets/tx.d.ts +9 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/assets/tx.d.ts.map +1 -1
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/assets/tx.js +19 -3
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/bridge/tx.d.ts +14 -1
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/bridge/tx.d.ts.map +1 -1
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/bridge/tx.js +1 -1
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/denomwrap/params.d.ts +116 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/denomwrap/params.d.ts.map +1 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/denomwrap/params.js +98 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/denomwrap/tx.d.ts +80 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/denomwrap/tx.d.ts.map +1 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/denomwrap/tx.js +168 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/denomwrap/tx.rpc.msg.d.ts +21 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/denomwrap/tx.rpc.msg.d.ts.map +1 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/denomwrap/tx.rpc.msg.js +20 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/lcd.d.ts +1 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/lcd.d.ts.map +1 -1
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/lcd.js +4 -1
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/rpc.query.d.ts +4 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/rpc.query.d.ts.map +1 -1
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/rpc.query.js +3 -2
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/rpc.tx.d.ts +2 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/rpc.tx.d.ts.map +1 -1
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/rpc.tx.js +4 -2
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/sending/tx.d.ts +0 -1
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/sending/tx.d.ts.map +1 -1
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/sending/tx.js +1 -1
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/genesis.d.ts +79 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/genesis.d.ts.map +1 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/genesis.js +115 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/params.d.ts +116 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/params.d.ts.map +1 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/params.js +98 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/query.d.ts +82 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/query.d.ts.map +1 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/query.js +212 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/query.lcd.d.ts +11 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/query.lcd.d.ts.map +1 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/query.lcd.js +30 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/query.rpc.Query.d.ts +29 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/query.rpc.Query.d.ts.map +1 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/query.rpc.Query.js +33 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/tx.d.ts +123 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/tx.d.ts.map +1 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/tx.js +246 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/tx.rpc.msg.d.ts +36 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/tx.rpc.msg.d.ts.map +1 -0
- package/build/esm/node_modules/@ritbit/v4-proto/src/codegen/ritbit/wrap/tx.rpc.msg.js +26 -0
- package/build/esm/src/clients/composite-client.d.ts +6 -1
- package/build/esm/src/clients/composite-client.d.ts.map +1 -1
- package/build/esm/src/clients/composite-client.js +7 -3
- package/build/esm/src/clients/constants.d.ts +13 -1
- package/build/esm/src/clients/constants.d.ts.map +1 -1
- package/build/esm/src/clients/constants.js +13 -1
- package/build/esm/src/clients/lib/accounts.d.ts +4 -3
- package/build/esm/src/clients/lib/accounts.d.ts.map +1 -1
- package/build/esm/src/clients/lib/accounts.js +44 -5
- package/build/esm/src/clients/lib/agent-approval-tx.d.ts +46 -0
- package/build/esm/src/clients/lib/agent-approval-tx.d.ts.map +1 -0
- package/build/esm/src/clients/lib/agent-approval-tx.js +79 -0
- package/build/esm/src/clients/lib/agent-approval.d.ts +64 -0
- package/build/esm/src/clients/lib/agent-approval.d.ts.map +1 -0
- package/build/esm/src/clients/lib/agent-approval.js +112 -0
- package/build/esm/src/clients/lib/eip712.d.ts +95 -0
- package/build/esm/src/clients/lib/eip712.d.ts.map +1 -0
- package/build/esm/src/clients/lib/eip712.js +581 -0
- package/build/esm/src/clients/lib/eth-pubkey.d.ts +44 -0
- package/build/esm/src/clients/lib/eth-pubkey.d.ts.map +1 -0
- package/build/esm/src/clients/lib/eth-pubkey.js +61 -0
- package/build/esm/src/clients/modules/composer.d.ts +12 -1
- package/build/esm/src/clients/modules/composer.d.ts.map +1 -1
- package/build/esm/src/clients/modules/composer.js +15 -2
- package/build/esm/src/clients/modules/eip712-signer.d.ts +99 -0
- package/build/esm/src/clients/modules/eip712-signer.d.ts.map +1 -0
- package/build/esm/src/clients/modules/eip712-signer.js +183 -0
- package/build/esm/src/clients/modules/eth-agent-wallet.d.ts +39 -0
- package/build/esm/src/clients/modules/eth-agent-wallet.d.ts.map +1 -0
- package/build/esm/src/clients/modules/eth-agent-wallet.js +97 -0
- package/build/esm/src/clients/modules/eth-wallet.d.ts +32 -0
- package/build/esm/src/clients/modules/eth-wallet.d.ts.map +1 -0
- package/build/esm/src/clients/modules/eth-wallet.js +83 -0
- package/build/esm/src/clients/modules/local-wallet.d.ts +2 -1
- package/build/esm/src/clients/modules/local-wallet.d.ts.map +1 -1
- package/build/esm/src/clients/modules/local-wallet.js +9 -2
- package/build/esm/src/clients/modules/post.d.ts +1 -1
- package/build/esm/src/clients/modules/post.d.ts.map +1 -1
- package/build/esm/src/clients/modules/post.js +14 -4
- package/build/esm/src/clients/modules/signer.d.ts +2 -1
- package/build/esm/src/clients/modules/signer.d.ts.map +1 -1
- package/build/esm/src/clients/modules/signer.js +7 -2
- package/build/esm/src/index.d.ts +13 -0
- package/build/esm/src/index.d.ts.map +1 -1
- package/build/esm/src/index.js +9 -1
- package/build/esm/src/lib/evm-address.d.ts +31 -0
- package/build/esm/src/lib/evm-address.d.ts.map +1 -0
- package/build/esm/src/lib/evm-address.js +85 -0
- package/build/esm/src/lib/trading-key-utils.d.ts +3 -0
- package/build/esm/src/lib/trading-key-utils.d.ts.map +1 -1
- package/build/esm/src/lib/trading-key-utils.js +42 -4
- package/build/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -5,22 +5,58 @@ const proto_signing_1 = require("@cosmjs/proto-signing");
|
|
|
5
5
|
const stargate_1 = require("@cosmjs/stargate");
|
|
6
6
|
const utils_1 = require("@cosmjs/utils");
|
|
7
7
|
const auth_1 = require("cosmjs-types/cosmos/auth/v1beta1/auth");
|
|
8
|
+
const minimal_1 = require("protobufjs/minimal");
|
|
9
|
+
const eth_pubkey_1 = require("./eth-pubkey");
|
|
8
10
|
function toSafeAccountNumber(value) {
|
|
9
11
|
return value <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(value) : value;
|
|
10
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Like cosmjs's `decodeOptionalPubkey()`, but also understands the
|
|
15
|
+
* eth_secp256k1 pubkey the chain stores for eth accounts on first use
|
|
16
|
+
* (cosmjs throws "Pubkey type_url ... not recognized" for it). The wire
|
|
17
|
+
* format is the same as `cosmos.crypto.secp256k1.PubKey`.
|
|
18
|
+
*/
|
|
19
|
+
function decodeOptionalPubkeyWithEth(pubkeyAny) {
|
|
20
|
+
if (pubkeyAny && pubkeyAny.typeUrl === eth_pubkey_1.ETH_SECP256K1_PUBKEY_TYPE_URL) {
|
|
21
|
+
return (0, eth_pubkey_1.decodeEthSecp256k1Pubkey)(pubkeyAny.value);
|
|
22
|
+
}
|
|
23
|
+
return (0, proto_signing_1.decodeOptionalPubkey)(pubkeyAny);
|
|
24
|
+
}
|
|
11
25
|
function accountFromBaseAccount(input) {
|
|
12
26
|
return {
|
|
13
27
|
address: input.address,
|
|
14
|
-
pubkey: (
|
|
28
|
+
pubkey: decodeOptionalPubkeyWithEth(input.pubKey),
|
|
15
29
|
accountNumber: toSafeAccountNumber(BigInt(input.accountNumber.toString())),
|
|
16
30
|
sequence: Number(input.sequence),
|
|
17
31
|
};
|
|
18
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Extracts the nested `base_account` (field 1) out of a serialized EthAccount
|
|
35
|
+
* (`{ BaseAccount base_account = 1; string code_hash = 2; }`). There is no
|
|
36
|
+
* codegen for EthAccount in the client's proto packages (the chain's
|
|
37
|
+
* cosmos/evm version keeps eth accounts as plain BaseAccount), so the outer
|
|
38
|
+
* message is scanned manually as a defensive fallback for chains that do
|
|
39
|
+
* store EthAccount.
|
|
40
|
+
*/
|
|
41
|
+
function baseAccountFromEthAccount(value) {
|
|
42
|
+
const reader = minimal_1.Reader.create(value);
|
|
43
|
+
while (reader.pos < reader.len) {
|
|
44
|
+
const tag = reader.uint32();
|
|
45
|
+
// eslint-disable-next-line no-bitwise
|
|
46
|
+
if (tag >>> 3 === 1) {
|
|
47
|
+
return auth_1.BaseAccount.decode(reader.bytes());
|
|
48
|
+
}
|
|
49
|
+
// eslint-disable-next-line no-bitwise
|
|
50
|
+
reader.skipType(tag & 7);
|
|
51
|
+
}
|
|
52
|
+
throw new Error('EthAccount does not contain a base account');
|
|
53
|
+
}
|
|
19
54
|
/**
|
|
20
55
|
* Bigint-safe replacement for cosmjs's `accountFromAny()`. Handles the account
|
|
21
|
-
* types the chain actually uses (BaseAccount, ModuleAccount
|
|
22
|
-
*
|
|
23
|
-
*
|
|
56
|
+
* types the chain actually uses (BaseAccount, ModuleAccount — eth accounts are
|
|
57
|
+
* stored as BaseAccount with an eth_secp256k1 pubkey) plus the EthAccount
|
|
58
|
+
* wrappers other cosmos/evm chains use, and falls back to the cosmjs parser
|
|
59
|
+
* for exotic ones (vesting etc.), which keeps the old behavior for them.
|
|
24
60
|
*/
|
|
25
61
|
function accountFromAny(input) {
|
|
26
62
|
switch (input.typeUrl) {
|
|
@@ -31,8 +67,11 @@ function accountFromAny(input) {
|
|
|
31
67
|
(0, utils_1.assert)(baseAccount);
|
|
32
68
|
return accountFromBaseAccount(baseAccount);
|
|
33
69
|
}
|
|
70
|
+
case '/cosmos.evm.types.v1.EthAccount':
|
|
71
|
+
case '/ethermint.types.v1.EthAccount':
|
|
72
|
+
return accountFromBaseAccount(baseAccountFromEthAccount(input.value));
|
|
34
73
|
default:
|
|
35
74
|
return (0, stargate_1.accountFromAny)(input);
|
|
36
75
|
}
|
|
37
76
|
}
|
|
38
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
77
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjb3VudHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvY2xpZW50cy9saWIvYWNjb3VudHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFvRkEsd0NBa0JDO0FBckdELHlEQUE2RDtBQUM3RCwrQ0FBMEU7QUFDMUUseUNBQXVDO0FBQ3ZDLGdFQUFtRjtBQUVuRixnREFBNEM7QUFFNUMsNkNBQXVGO0FBcUJ2RixTQUFTLG1CQUFtQixDQUFDLEtBQWE7SUFDeEMsT0FBTyxLQUFLLElBQUksTUFBTSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztBQUMxRSxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFTLDJCQUEyQixDQUFDLFNBQTBCO0lBQzdELElBQUksU0FBUyxJQUFJLFNBQVMsQ0FBQyxPQUFPLEtBQUssMENBQTZCLEVBQUUsQ0FBQztRQUNyRSxPQUFPLElBQUEscUNBQXdCLEVBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFDRCxPQUFPLElBQUEsb0NBQW9CLEVBQUMsU0FBUyxDQUFDLENBQUM7QUFDekMsQ0FBQztBQUVELFNBQVMsc0JBQXNCLENBQUMsS0FBa0I7SUFDaEQsT0FBTztRQUNMLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTztRQUN0QixNQUFNLEVBQUUsMkJBQTJCLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUNqRCxhQUFhLEVBQUUsbUJBQW1CLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUMxRSxRQUFRLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUM7S0FDakMsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsU0FBUyx5QkFBeUIsQ0FBQyxLQUFpQjtJQUNsRCxNQUFNLE1BQU0sR0FBRyxnQkFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNwQyxPQUFPLE1BQU0sQ0FBQyxHQUFHLEdBQUcsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQy9CLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUM1QixzQ0FBc0M7UUFDdEMsSUFBSSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3BCLE9BQU8sa0JBQVcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDNUMsQ0FBQztRQUNELHNDQUFzQztRQUN0QyxNQUFNLENBQUMsUUFBUSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBQ0QsTUFBTSxJQUFJLEtBQUssQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO0FBQ2hFLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxTQUFnQixjQUFjLENBQUMsS0FBVTtJQUN2QyxRQUFRLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUN0QixLQUFLLGtDQUFrQztZQUNyQyxPQUFPLHNCQUFzQixDQUFDLGtCQUFXLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBRWpFLEtBQUssb0NBQW9DLENBQUMsQ0FBQyxDQUFDO1lBQzFDLE1BQU0sV0FBVyxHQUFHLG9CQUFhLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxXQUFXLENBQUM7WUFDbEUsSUFBQSxjQUFNLEVBQUMsV0FBVyxDQUFDLENBQUM7WUFDcEIsT0FBTyxzQkFBc0IsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUM3QyxDQUFDO1FBRUQsS0FBSyxpQ0FBaUMsQ0FBQztRQUN2QyxLQUFLLGdDQUFnQztZQUNuQyxPQUFPLHNCQUFzQixDQUFDLHlCQUF5QixDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBRXhFO1lBQ0UsT0FBTyxJQUFBLHlCQUFvQixFQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7QUFDSCxDQUFDIn0=
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.agentApprovalDigest = void 0;
|
|
4
|
+
exports.composeAgentApprovalMsg = composeAgentApprovalMsg;
|
|
5
|
+
exports.signAgentApprovalTx = signAgentApprovalTx;
|
|
6
|
+
const math_1 = require("@cosmjs/math");
|
|
7
|
+
const proto_signing_1 = require("@cosmjs/proto-signing");
|
|
8
|
+
const tx_1 = require("cosmjs-types/cosmos/tx/v1beta1/tx");
|
|
9
|
+
const eth_pubkey_1 = require("./eth-pubkey");
|
|
10
|
+
const agent_approval_1 = require("./agent-approval");
|
|
11
|
+
Object.defineProperty(exports, "agentApprovalDigest", { enumerable: true, get: function () { return agent_approval_1.agentApprovalDigest; } });
|
|
12
|
+
const registry_1 = require("./registry");
|
|
13
|
+
const eip712_signer_1 = require("../modules/eip712-signer");
|
|
14
|
+
const constants_1 = require("../constants");
|
|
15
|
+
/** Gas for registering one authenticator; well under the chain's ceiling. */
|
|
16
|
+
const DEFAULT_APPROVAL_GAS = 200000;
|
|
17
|
+
/**
|
|
18
|
+
* Builds MsgAddAuthenticator in its agent form: the chain reads the agent's
|
|
19
|
+
* address from `data` and builds the authenticator tree itself, which is what
|
|
20
|
+
* lets the approval be readable — no part of the granted authority travels in
|
|
21
|
+
* the transaction.
|
|
22
|
+
*/
|
|
23
|
+
function composeAgentApprovalMsg(options) {
|
|
24
|
+
return {
|
|
25
|
+
typeUrl: constants_1.TYPE_URL_MSG_ADD_AUTHENTICATOR,
|
|
26
|
+
value: {
|
|
27
|
+
sender: options.sender,
|
|
28
|
+
authenticatorType: agent_approval_1.AGENT_AUTHENTICATOR_TYPE,
|
|
29
|
+
data: (0, agent_approval_1.agentAddressBytes)(options.approval.agentAddress),
|
|
30
|
+
name: options.approval.agentName,
|
|
31
|
+
expiresAt: options.approval.expiresAt,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Signs an agent approval as a payload and returns the broadcastable TxRaw.
|
|
37
|
+
*
|
|
38
|
+
* The signer's public key is recovered from the very signature the wallet
|
|
39
|
+
* returns, so a wallet the app has never seen before can approve an agent
|
|
40
|
+
* without a separate prompt whose only purpose is to expose its key.
|
|
41
|
+
*/
|
|
42
|
+
async function signAgentApprovalTx(options, signTypedData, registry = (0, registry_1.generateRegistry)()) {
|
|
43
|
+
var _a;
|
|
44
|
+
const typedData = (0, agent_approval_1.agentApprovalTypedData)(options.approval);
|
|
45
|
+
const signatureHex = await signTypedData(typedData);
|
|
46
|
+
const signature = parseApprovalSignature(signatureHex);
|
|
47
|
+
const signerPubkey = (0, eip712_signer_1.recoverPubKeyFromTypedDataSignature)(typedData, signatureHex);
|
|
48
|
+
const msg = composeAgentApprovalMsg(options);
|
|
49
|
+
const bodyBytes = tx_1.TxBody.encode(tx_1.TxBody.fromPartial({
|
|
50
|
+
messages: [registry.encodeAsAny(msg)],
|
|
51
|
+
// Empty on purpose: the payload names none of these, so the ante refuses
|
|
52
|
+
// a transaction that carries them.
|
|
53
|
+
memo: '',
|
|
54
|
+
})).finish();
|
|
55
|
+
const authInfoBytes = (0, proto_signing_1.makeAuthInfoBytes)([
|
|
56
|
+
{
|
|
57
|
+
pubkey: (0, eth_pubkey_1.ethSecp256k1PubkeyToAny)((0, eth_pubkey_1.encodeEthSecp256k1Pubkey)(signerPubkey)),
|
|
58
|
+
// The approval's nonce IS the sequence, so the two cannot disagree.
|
|
59
|
+
sequence: options.approval.nonce,
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
// No fee: registering an agent is a fee-free operation, and a fee is
|
|
63
|
+
// something the signature does not cover.
|
|
64
|
+
[], math_1.Int53.fromString(String((_a = options.gas) !== null && _a !== void 0 ? _a : DEFAULT_APPROVAL_GAS)).toNumber(), undefined, undefined);
|
|
65
|
+
return Uint8Array.from(tx_1.TxRaw.encode(tx_1.TxRaw.fromPartial({
|
|
66
|
+
bodyBytes,
|
|
67
|
+
authInfoBytes,
|
|
68
|
+
signatures: [signature],
|
|
69
|
+
})).finish());
|
|
70
|
+
}
|
|
71
|
+
/** The wallet's 65-byte r ‖ s ‖ v, as the chain's recovery expects it. */
|
|
72
|
+
function parseApprovalSignature(signatureHex) {
|
|
73
|
+
const hex = signatureHex.startsWith('0x') ? signatureHex.slice(2) : signatureHex;
|
|
74
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
75
|
+
for (let i = 0; i < bytes.length; i += 1) {
|
|
76
|
+
bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
77
|
+
}
|
|
78
|
+
if (bytes.length !== 65) {
|
|
79
|
+
throw new Error(`Expected a 65-byte approval signature, got ${bytes.length} bytes`);
|
|
80
|
+
}
|
|
81
|
+
return bytes;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdlbnQtYXBwcm92YWwtdHguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvY2xpZW50cy9saWIvYWdlbnQtYXBwcm92YWwtdHgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBcURBLDBEQVdDO0FBU0Qsa0RBOENDO0FBdkhELHVDQUFxQztBQUNyQyx5REFBa0Y7QUFDbEYsMERBQWtFO0FBRWxFLDZDQUFpRjtBQUNqRixxREFNMEI7QUE0SGpCLG9HQTlIUCxvQ0FBbUIsT0E4SE87QUExSDVCLHlDQUE4QztBQUM5Qyw0REFBK0U7QUFDL0UsNENBQThEO0FBNkI5RCw2RUFBNkU7QUFDN0UsTUFBTSxvQkFBb0IsR0FBRyxNQUFPLENBQUM7QUFFckM7Ozs7O0dBS0c7QUFDSCxTQUFnQix1QkFBdUIsQ0FBQyxPQUErQjtJQUNyRSxPQUFPO1FBQ0wsT0FBTyxFQUFFLDBDQUE4QjtRQUN2QyxLQUFLLEVBQUU7WUFDTCxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07WUFDdEIsaUJBQWlCLEVBQUUseUNBQXdCO1lBQzNDLElBQUksRUFBRSxJQUFBLGtDQUFpQixFQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDO1lBQ3RELElBQUksRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLFNBQVM7WUFDaEMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsU0FBUztTQUN0QztLQUNGLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0ksS0FBSyxVQUFVLG1CQUFtQixDQUN2QyxPQUErQixFQUMvQixhQUF3QyxFQUN4QyxXQUFxQixJQUFBLDJCQUFnQixHQUFFOztJQUV2QyxNQUFNLFNBQVMsR0FBRyxJQUFBLHVDQUFzQixFQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMzRCxNQUFNLFlBQVksR0FBRyxNQUFNLGFBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUVwRCxNQUFNLFNBQVMsR0FBRyxzQkFBc0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN2RCxNQUFNLFlBQVksR0FBRyxJQUFBLG1EQUFtQyxFQUFDLFNBQVMsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUVsRixNQUFNLEdBQUcsR0FBRyx1QkFBdUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM3QyxNQUFNLFNBQVMsR0FBRyxXQUFNLENBQUMsTUFBTSxDQUM3QixXQUFNLENBQUMsV0FBVyxDQUFDO1FBQ2pCLFFBQVEsRUFBRSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDckMseUVBQXlFO1FBQ3pFLG1DQUFtQztRQUNuQyxJQUFJLEVBQUUsRUFBRTtLQUNULENBQUMsQ0FDSCxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBRVgsTUFBTSxhQUFhLEdBQUcsSUFBQSxpQ0FBaUIsRUFDckM7UUFDRTtZQUNFLE1BQU0sRUFBRSxJQUFBLG9DQUF1QixFQUFDLElBQUEscUNBQXdCLEVBQUMsWUFBWSxDQUFDLENBQUM7WUFDdkUsb0VBQW9FO1lBQ3BFLFFBQVEsRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUs7U0FDakM7S0FDRjtJQUNELHFFQUFxRTtJQUNyRSwwQ0FBMEM7SUFDMUMsRUFBRSxFQUNGLFlBQUssQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLE1BQUEsT0FBTyxDQUFDLEdBQUcsbUNBQUksb0JBQW9CLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUN4RSxTQUFTLEVBQ1QsU0FBUyxDQUNWLENBQUM7SUFFRixPQUFPLFVBQVUsQ0FBQyxJQUFJLENBQ3BCLFVBQUssQ0FBQyxNQUFNLENBQ1YsVUFBSyxDQUFDLFdBQVcsQ0FBQztRQUNoQixTQUFTO1FBQ1QsYUFBYTtRQUNiLFVBQVUsRUFBRSxDQUFDLFNBQVMsQ0FBQztLQUN4QixDQUFDLENBQ0gsQ0FBQyxNQUFNLEVBQUUsQ0FDWCxDQUFDO0FBQ0osQ0FBQztBQUVELDBFQUEwRTtBQUMxRSxTQUFTLHNCQUFzQixDQUFDLFlBQW9CO0lBQ2xELE1BQU0sR0FBRyxHQUFHLFlBQVksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQztJQUNqRixNQUFNLEtBQUssR0FBRyxJQUFJLFVBQVUsQ0FBQyxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQzdDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUN6QyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ3ZELENBQUM7SUFDRCxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssRUFBRSxFQUFFLENBQUM7UUFDeEIsTUFBTSxJQUFJLEtBQUssQ0FBQyw4Q0FBOEMsS0FBSyxDQUFDLE1BQU0sUUFBUSxDQUFDLENBQUM7SUFDdEYsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQyJ9
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AGENT_AUTHENTICATOR_TYPE = exports.AGENT_REVOCATION_ADDRESS = exports.AGENT_APPROVAL_PRIMARY_TYPE = exports.AGENT_APPROVAL_DOMAIN_VERSION = exports.AGENT_APPROVAL_DOMAIN_NAME = void 0;
|
|
4
|
+
exports.agentAddressToHex = agentAddressToHex;
|
|
5
|
+
exports.agentApprovalTypedData = agentApprovalTypedData;
|
|
6
|
+
exports.agentApprovalDigest = agentApprovalDigest;
|
|
7
|
+
exports.agentAddressBytes = agentAddressBytes;
|
|
8
|
+
const encoding_1 = require("@cosmjs/encoding");
|
|
9
|
+
const ethers_1 = require("ethers");
|
|
10
|
+
/**
|
|
11
|
+
* The approval a wallet is asked to sign when a trading key is authorized.
|
|
12
|
+
*
|
|
13
|
+
* Unlike a cosmos transaction — which EIP-712 renders as a machine-built "Tx"
|
|
14
|
+
* wrapping account_number, sequence, fee, gas and a nested msg0 — this payload
|
|
15
|
+
* is the approval itself: the agent, its name, when it expires, and a nonce.
|
|
16
|
+
* The chain rebuilds exactly this from MsgApproveAgent and checks the signature
|
|
17
|
+
* against it, so what the user read is what was authorized.
|
|
18
|
+
*
|
|
19
|
+
* Every name here is part of the digest and must match the chain byte for byte
|
|
20
|
+
* (protocol/x/accountplus/types/agent_eip712.go). The fixtures in
|
|
21
|
+
* __tests__/fixtures/agent_approval_goldens.json are generated by the chain and
|
|
22
|
+
* are what keeps the two in step.
|
|
23
|
+
*/
|
|
24
|
+
exports.AGENT_APPROVAL_DOMAIN_NAME = 'RubinSignTransaction';
|
|
25
|
+
exports.AGENT_APPROVAL_DOMAIN_VERSION = '1';
|
|
26
|
+
exports.AGENT_APPROVAL_PRIMARY_TYPE = 'RubinTransaction:ApproveAgent';
|
|
27
|
+
/** verifyingContract is unused; the payload is not addressed to a contract. */
|
|
28
|
+
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
|
29
|
+
/**
|
|
30
|
+
* Renders a bech32 address as the 0x form the payload declares. Both are the
|
|
31
|
+
* same 20 bytes; a wallet can only display the hex one.
|
|
32
|
+
*/
|
|
33
|
+
function agentAddressToHex(address) {
|
|
34
|
+
if (address.startsWith('0x')) {
|
|
35
|
+
return address.toLowerCase();
|
|
36
|
+
}
|
|
37
|
+
return `0x${(0, encoding_1.toHex)((0, encoding_1.fromBech32)(address).data)}`;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The agent address that means "approve nobody": a revocation.
|
|
41
|
+
*
|
|
42
|
+
* Withdrawing a key rides the same payload as granting one — same domain, same
|
|
43
|
+
* fields, same signing path — because the moment a user most needs to read the
|
|
44
|
+
* dialog is the moment they are taking a key away. The chain removes the key
|
|
45
|
+
* whose name the payload carries (see IsAgentRevocation in agent.go).
|
|
46
|
+
*/
|
|
47
|
+
exports.AGENT_REVOCATION_ADDRESS = ZERO_ADDRESS;
|
|
48
|
+
/** Builds the typed data the wallet signs. */
|
|
49
|
+
function agentApprovalTypedData(approval) {
|
|
50
|
+
// The expiry is shown only when it says something. Zero means "give me the
|
|
51
|
+
// chain's default lifetime", and a wallet rendering `expiresAt: 0` reads as
|
|
52
|
+
// "never expires" — the opposite of the truth. So the zero case drops the
|
|
53
|
+
// field, which is a second SHAPE, not a hidden value: EIP-712 hashes the
|
|
54
|
+
// declared field list, so the two produce different digests and neither
|
|
55
|
+
// signature can be replayed as the other. The chain decides which shape
|
|
56
|
+
// applies from the message it executes (agent_eip712.go), never the signer.
|
|
57
|
+
const withExpiry = approval.expiresAt !== 0;
|
|
58
|
+
const fields = [
|
|
59
|
+
{ name: 'rubinChain', type: 'string' },
|
|
60
|
+
{ name: 'agentAddress', type: 'address' },
|
|
61
|
+
{ name: 'agentName', type: 'string' },
|
|
62
|
+
...(withExpiry ? [{ name: 'expiresAt', type: 'uint64' }] : []),
|
|
63
|
+
{ name: 'nonce', type: 'uint64' },
|
|
64
|
+
];
|
|
65
|
+
const message = {
|
|
66
|
+
rubinChain: approval.rubinChain,
|
|
67
|
+
agentAddress: agentAddressToHex(approval.agentAddress),
|
|
68
|
+
agentName: approval.agentName,
|
|
69
|
+
...(withExpiry ? { expiresAt: approval.expiresAt } : {}),
|
|
70
|
+
nonce: approval.nonce,
|
|
71
|
+
};
|
|
72
|
+
return {
|
|
73
|
+
types: {
|
|
74
|
+
// No chainId: EIP-712 lets the domain carry any subset of its fields, and
|
|
75
|
+
// a wallet only compares chainId when it is present. Leaving it out means
|
|
76
|
+
// the approval does not depend on which network the wallet happens to be
|
|
77
|
+
// on, and the chain does not have to learn that from the transaction. The
|
|
78
|
+
// binding that matters is rubinChain below.
|
|
79
|
+
EIP712Domain: [
|
|
80
|
+
{ name: 'name', type: 'string' },
|
|
81
|
+
{ name: 'version', type: 'string' },
|
|
82
|
+
{ name: 'verifyingContract', type: 'address' },
|
|
83
|
+
],
|
|
84
|
+
[exports.AGENT_APPROVAL_PRIMARY_TYPE]: fields,
|
|
85
|
+
},
|
|
86
|
+
primaryType: exports.AGENT_APPROVAL_PRIMARY_TYPE,
|
|
87
|
+
domain: {
|
|
88
|
+
name: exports.AGENT_APPROVAL_DOMAIN_NAME,
|
|
89
|
+
version: exports.AGENT_APPROVAL_DOMAIN_VERSION,
|
|
90
|
+
verifyingContract: ZERO_ADDRESS,
|
|
91
|
+
},
|
|
92
|
+
message,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* The 32-byte digest the wallet signs: keccak(0x19 0x01 ‖ domainSeparator ‖
|
|
97
|
+
* hashStruct(message)).
|
|
98
|
+
*/
|
|
99
|
+
function agentApprovalDigest(approval) {
|
|
100
|
+
const typedData = agentApprovalTypedData(approval);
|
|
101
|
+
// ethers derives the primary type from the types map, so the EIP712Domain
|
|
102
|
+
// entry must not be part of what it is handed.
|
|
103
|
+
const { EIP712Domain: _domainType, ...messageTypes } = typedData.types;
|
|
104
|
+
return (0, ethers_1.getBytes)(ethers_1.TypedDataEncoder.hash(typedData.domain, messageTypes, typedData.message));
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* The authenticator type that marks the readable agent form of
|
|
108
|
+
* MsgAddAuthenticator: `data` is then the agent's 20-byte address and the chain
|
|
109
|
+
* builds the tree itself.
|
|
110
|
+
*/
|
|
111
|
+
exports.AGENT_AUTHENTICATOR_TYPE = 'Agent';
|
|
112
|
+
/** The 20 address bytes the agent form carries as `data`. */
|
|
113
|
+
function agentAddressBytes(address) {
|
|
114
|
+
if (address.startsWith('0x')) {
|
|
115
|
+
return (0, encoding_1.fromHex)(address.slice(2));
|
|
116
|
+
}
|
|
117
|
+
return (0, encoding_1.fromBech32)(address).data;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdlbnQtYXBwcm92YWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvY2xpZW50cy9saWIvYWdlbnQtYXBwcm92YWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBK0NBLDhDQUtDO0FBYUQsd0RBOENDO0FBTUQsa0RBWUM7QUFVRCw4Q0FLQztBQWhKRCwrQ0FBOEQ7QUFDOUQsbUNBQW9EO0FBSXBEOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDVSxRQUFBLDBCQUEwQixHQUFHLHNCQUFzQixDQUFDO0FBQ3BELFFBQUEsNkJBQTZCLEdBQUcsR0FBRyxDQUFDO0FBQ3BDLFFBQUEsMkJBQTJCLEdBQUcsK0JBQStCLENBQUM7QUFFM0UsK0VBQStFO0FBQy9FLE1BQU0sWUFBWSxHQUFHLDRDQUE0QyxDQUFDO0FBbUJsRTs7O0dBR0c7QUFDSCxTQUFnQixpQkFBaUIsQ0FBQyxPQUFlO0lBQy9DLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQzdCLE9BQU8sT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQy9CLENBQUM7SUFDRCxPQUFPLEtBQUssSUFBQSxnQkFBSyxFQUFDLElBQUEscUJBQVUsRUFBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO0FBQ2hELENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ1UsUUFBQSx3QkFBd0IsR0FBRyxZQUFZLENBQUM7QUFFckQsOENBQThDO0FBQzlDLFNBQWdCLHNCQUFzQixDQUFDLFFBQXVCO0lBQzVELDJFQUEyRTtJQUMzRSw0RUFBNEU7SUFDNUUsMEVBQTBFO0lBQzFFLHlFQUF5RTtJQUN6RSx3RUFBd0U7SUFDeEUsd0VBQXdFO0lBQ3hFLDRFQUE0RTtJQUM1RSxNQUFNLFVBQVUsR0FBRyxRQUFRLENBQUMsU0FBUyxLQUFLLENBQUMsQ0FBQztJQUM1QyxNQUFNLE1BQU0sR0FBRztRQUNiLEVBQUUsSUFBSSxFQUFFLFlBQVks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
|