@ton-wallet/create 14.0.6 → 14.0.7
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/client/TonClient.d.ts +228 -0
- package/dist/client/TonClient.js +441 -0
- package/dist/client/TonClient.spec.d.ts +1 -0
- package/dist/client/TonClient.spec.js +45 -0
- package/dist/client/TonClient4.d.ts +1130 -0
- package/dist/client/TonClient4.js +687 -0
- package/dist/client/TonClient4.spec.d.ts +1 -0
- package/dist/client/TonClient4.spec.js +42 -0
- package/dist/client/api/HttpApi.d.ts +764 -0
- package/dist/client/api/HttpApi.js +306 -0
- package/dist/client/api/TonCache.d.ts +16 -0
- package/dist/client/api/TonCache.js +33 -0
- package/dist/config/ConfigParser.d.ts +622 -0
- package/dist/config/ConfigParser.js +711 -0
- package/dist/config/ConfigParser.spec.d.ts +8 -0
- package/dist/config/ConfigParser.spec.js +97 -0
- package/dist/elector/ElectorContract.d.ts +51 -0
- package/dist/elector/ElectorContract.js +192 -0
- package/dist/elector/ElectorContract.spec.d.ts +8 -0
- package/dist/elector/ElectorContract.spec.js +104 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +129 -0
- package/dist/jetton/JettonMaster.d.ts +21 -0
- package/dist/jetton/JettonMaster.js +39 -0
- package/dist/jetton/JettonMaster.spec.d.ts +8 -0
- package/dist/jetton/JettonMaster.spec.js +27 -0
- package/dist/jetton/JettonWallet.d.ts +14 -0
- package/dist/jetton/JettonWallet.js +27 -0
- package/dist/multisig/MultisigOrder.d.ts +17 -0
- package/dist/multisig/MultisigOrder.js +73 -0
- package/dist/multisig/MultisigOrder.spec.d.ts +1 -0
- package/dist/multisig/MultisigOrder.spec.js +139 -0
- package/dist/multisig/MultisigOrderBuilder.d.ts +13 -0
- package/dist/multisig/MultisigOrderBuilder.js +37 -0
- package/dist/multisig/MultisigWallet.d.ts +27 -0
- package/dist/multisig/MultisigWallet.js +134 -0
- package/dist/multisig/MultisigWallet.spec.d.ts +1 -0
- package/dist/multisig/MultisigWallet.spec.js +248 -0
- package/dist/utils/createTestClient.d.ts +9 -0
- package/dist/utils/createTestClient.js +18 -0
- package/dist/utils/createTestClient4.d.ts +9 -0
- package/dist/utils/createTestClient4.js +15 -0
- package/dist/utils/fees.d.ts +25 -0
- package/dist/utils/fees.js +105 -0
- package/dist/utils/fees.spec.d.ts +1 -0
- package/dist/utils/fees.spec.js +83 -0
- package/dist/utils/maybe.d.ts +8 -0
- package/dist/utils/maybe.js +9 -0
- package/dist/utils/randomTestKey.d.ts +8 -0
- package/dist/utils/randomTestKey.js +24 -0
- package/dist/utils/time.d.ts +15 -0
- package/dist/utils/time.js +63 -0
- package/dist/utils/toUrlSafe.d.ts +8 -0
- package/dist/utils/toUrlSafe.js +23 -0
- package/dist/wallets/WalletContractV1R1.d.ts +58 -0
- package/dist/wallets/WalletContractV1R1.js +100 -0
- package/dist/wallets/WalletContractV1R1.spec.d.ts +8 -0
- package/dist/wallets/WalletContractV1R1.spec.js +44 -0
- package/dist/wallets/WalletContractV1R2.d.ts +58 -0
- package/dist/wallets/WalletContractV1R2.js +101 -0
- package/dist/wallets/WalletContractV1R2.spec.d.ts +8 -0
- package/dist/wallets/WalletContractV1R2.spec.js +44 -0
- package/dist/wallets/WalletContractV1R3.d.ts +58 -0
- package/dist/wallets/WalletContractV1R3.js +101 -0
- package/dist/wallets/WalletContractV1R3.spec.d.ts +8 -0
- package/dist/wallets/WalletContractV1R3.spec.js +44 -0
- package/dist/wallets/WalletContractV2R1.d.ts +60 -0
- package/dist/wallets/WalletContractV2R1.js +102 -0
- package/dist/wallets/WalletContractV2R1.spec.d.ts +8 -0
- package/dist/wallets/WalletContractV2R1.spec.js +44 -0
- package/dist/wallets/WalletContractV2R2.d.ts +60 -0
- package/dist/wallets/WalletContractV2R2.js +102 -0
- package/dist/wallets/WalletContractV2R2.spec.d.ts +8 -0
- package/dist/wallets/WalletContractV2R2.spec.js +44 -0
- package/dist/wallets/WalletContractV3R1.d.ts +57 -0
- package/dist/wallets/WalletContractV3R1.js +104 -0
- package/dist/wallets/WalletContractV3R1.spec.d.ts +8 -0
- package/dist/wallets/WalletContractV3R1.spec.js +44 -0
- package/dist/wallets/WalletContractV3R2.d.ts +57 -0
- package/dist/wallets/WalletContractV3R2.js +104 -0
- package/dist/wallets/WalletContractV3R2.spec.d.ts +8 -0
- package/dist/wallets/WalletContractV3R2.spec.js +44 -0
- package/dist/wallets/WalletContractV3Types.d.ts +12 -0
- package/dist/wallets/WalletContractV3Types.js +2 -0
- package/dist/wallets/WalletContractV4.d.ts +65 -0
- package/dist/wallets/WalletContractV4.js +105 -0
- package/dist/wallets/WalletContractV4.spec.d.ts +8 -0
- package/dist/wallets/WalletContractV4.spec.js +48 -0
- package/dist/wallets/WalletContractV5Beta.d.ts +3 -0
- package/dist/wallets/WalletContractV5Beta.js +19 -0
- package/dist/wallets/WalletContractV5R1.d.ts +3 -0
- package/dist/wallets/WalletContractV5R1.js +19 -0
- package/dist/wallets/signing/createWalletTransfer.d.ts +48 -0
- package/dist/wallets/signing/createWalletTransfer.js +190 -0
- package/dist/wallets/signing/singer.d.ts +9 -0
- package/dist/wallets/signing/singer.js +21 -0
- package/dist/wallets/v5beta/WalletContractV5Beta.d.ts +130 -0
- package/dist/wallets/v5beta/WalletContractV5Beta.js +211 -0
- package/dist/wallets/v5beta/WalletContractV5Beta.spec.d.ts +8 -0
- package/dist/wallets/v5beta/WalletContractV5Beta.spec.js +298 -0
- package/dist/wallets/v5beta/WalletV5BetaActions.d.ts +6 -0
- package/dist/wallets/v5beta/WalletV5BetaActions.js +92 -0
- package/dist/wallets/v5beta/WalletV5BetaActions.spec.d.ts +1 -0
- package/dist/wallets/v5beta/WalletV5BetaActions.spec.js +166 -0
- package/dist/wallets/v5beta/WalletV5BetaWalletId.d.ts +13 -0
- package/dist/wallets/v5beta/WalletV5BetaWalletId.js +31 -0
- package/dist/wallets/v5beta/WalletV5BetaWalletId.spec.d.ts +1 -0
- package/dist/wallets/v5beta/WalletV5BetaWalletId.spec.js +68 -0
- package/dist/wallets/v5beta/WalletV5OutActions.d.ts +17 -0
- package/dist/wallets/v5beta/WalletV5OutActions.js +11 -0
- package/dist/wallets/v5r1/WalletContractV5R1.d.ts +125 -0
- package/dist/wallets/v5r1/WalletContractV5R1.js +207 -0
- package/dist/wallets/v5r1/WalletContractV5R1.spec.d.ts +8 -0
- package/dist/wallets/v5r1/WalletContractV5R1.spec.js +321 -0
- package/dist/wallets/v5r1/WalletV5R1Actions.d.ts +12 -0
- package/dist/wallets/v5r1/WalletV5R1Actions.js +128 -0
- package/dist/wallets/v5r1/WalletV5R1Actions.spec.d.ts +1 -0
- package/dist/wallets/v5r1/WalletV5R1Actions.spec.js +262 -0
- package/dist/wallets/v5r1/WalletV5R1WalletId.d.ts +47 -0
- package/dist/wallets/v5r1/WalletV5R1WalletId.js +69 -0
- package/dist/wallets/v5r1/WalletV5R1WalletId.spec.d.ts +1 -0
- package/dist/wallets/v5r1/WalletV5R1WalletId.spec.js +72 -0
- package/package.json +1 -1
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Made by @Gusarich and @Miandic */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const core_1 = require("@ton/core");
|
|
5
|
+
const crypto_1 = require("@ton/crypto");
|
|
6
|
+
const emulator_1 = require("@ton/emulator");
|
|
7
|
+
const MultisigWallet_1 = require("./MultisigWallet");
|
|
8
|
+
const MultisigOrderBuilder_1 = require("./MultisigOrderBuilder");
|
|
9
|
+
const createTestClient_1 = require("../utils/createTestClient");
|
|
10
|
+
function createInternalMessage(bounce, dest, value, body, mode = 3) {
|
|
11
|
+
return {
|
|
12
|
+
info: {
|
|
13
|
+
bounce,
|
|
14
|
+
bounced: false,
|
|
15
|
+
createdAt: 0,
|
|
16
|
+
createdLt: 0n,
|
|
17
|
+
dest,
|
|
18
|
+
forwardFee: 0n,
|
|
19
|
+
ihrDisabled: true,
|
|
20
|
+
ihrFee: 0n,
|
|
21
|
+
type: 'internal',
|
|
22
|
+
value: {
|
|
23
|
+
coins: value,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
body,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
describe('MultisigWallet', () => {
|
|
30
|
+
var publicKeys;
|
|
31
|
+
var secretKeys;
|
|
32
|
+
var system;
|
|
33
|
+
var treasure;
|
|
34
|
+
var client;
|
|
35
|
+
function createProvider(multisig) {
|
|
36
|
+
const stateInit = multisig.init;
|
|
37
|
+
return system.provider({
|
|
38
|
+
address: multisig.address,
|
|
39
|
+
init: {
|
|
40
|
+
code: stateInit.code,
|
|
41
|
+
data: stateInit.data,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function signOrder(order) {
|
|
46
|
+
for (let i = 0; i < 3; i++) {
|
|
47
|
+
order.sign(i, secretKeys[i]);
|
|
48
|
+
}
|
|
49
|
+
return order;
|
|
50
|
+
}
|
|
51
|
+
beforeAll(async () => {
|
|
52
|
+
publicKeys = [];
|
|
53
|
+
secretKeys = [];
|
|
54
|
+
for (let i = 0; i < 10; i += 1) {
|
|
55
|
+
let kp = (0, crypto_1.keyPairFromSeed)(await (0, crypto_1.getSecureRandomBytes)(32));
|
|
56
|
+
publicKeys.push(kp.publicKey);
|
|
57
|
+
secretKeys.push(kp.secretKey);
|
|
58
|
+
}
|
|
59
|
+
client = (0, createTestClient_1.createTestClient)('mainnet');
|
|
60
|
+
});
|
|
61
|
+
beforeEach(async () => {
|
|
62
|
+
system = await emulator_1.ContractSystem.create();
|
|
63
|
+
treasure = system.treasure('my-treasure');
|
|
64
|
+
});
|
|
65
|
+
it('should create MultisigWallet object', () => {
|
|
66
|
+
let multisig = new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 2);
|
|
67
|
+
});
|
|
68
|
+
it('should create MultisigWallet object from client', async () => {
|
|
69
|
+
let multisig = new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 2, { client });
|
|
70
|
+
});
|
|
71
|
+
it('should throw in fromAddress if no provider and no client', async () => {
|
|
72
|
+
expect(MultisigWallet_1.MultisigWallet.fromAddress(core_1.Address.parse('EQADBXugwmn4YvWsQizHdWGgfCTN_s3qFP0Ae0pzkU-jwzoE'), {})).rejects.toThrowError('Either provider or client must be specified');
|
|
73
|
+
});
|
|
74
|
+
it('should throw in fromAddress if the contract is inactive', async () => {
|
|
75
|
+
expect(MultisigWallet_1.MultisigWallet.fromAddress(core_1.Address.parse('EQCzD8HVMlGCbXf3oOBxXBt5AfjhmmWKAC9fsJvJLFEO0SQt'), { client })).rejects.toThrowError('Contract must be active');
|
|
76
|
+
});
|
|
77
|
+
it('should deploy via internal message', async () => {
|
|
78
|
+
let multisig = new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 2);
|
|
79
|
+
let provider = createProvider(multisig);
|
|
80
|
+
await multisig.deployInternal(treasure);
|
|
81
|
+
let txs = await system.run();
|
|
82
|
+
expect(txs).toHaveLength(2);
|
|
83
|
+
expect(txs[1].endStatus).toEqual('active');
|
|
84
|
+
});
|
|
85
|
+
it('should deploy via external message', async () => {
|
|
86
|
+
let multisig = new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 2);
|
|
87
|
+
let provider = createProvider(multisig);
|
|
88
|
+
await treasure.send({
|
|
89
|
+
sendMode: 0,
|
|
90
|
+
to: multisig.address,
|
|
91
|
+
value: 1000000000n,
|
|
92
|
+
body: core_1.Cell.EMPTY,
|
|
93
|
+
bounce: false,
|
|
94
|
+
});
|
|
95
|
+
await system.run();
|
|
96
|
+
await multisig.deployExternal(provider);
|
|
97
|
+
let txs = await system.run();
|
|
98
|
+
expect(txs).toHaveLength(1);
|
|
99
|
+
expect(txs[0].endStatus).toEqual('active');
|
|
100
|
+
});
|
|
101
|
+
it('should throw in deployExternal if there is no provider', async () => {
|
|
102
|
+
let multisig = new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 2);
|
|
103
|
+
expect(multisig.deployExternal()).rejects.toThrowError('you must specify provider if there is no such property in MultisigWallet instance');
|
|
104
|
+
});
|
|
105
|
+
it('should deploy via external message with provider from property', async () => {
|
|
106
|
+
let multisigTmp = new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 2);
|
|
107
|
+
let provider = createProvider(multisigTmp);
|
|
108
|
+
let multisig = new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 2, { provider });
|
|
109
|
+
await treasure.send({
|
|
110
|
+
sendMode: 0,
|
|
111
|
+
to: multisig.address,
|
|
112
|
+
value: 1000000000n,
|
|
113
|
+
body: core_1.Cell.EMPTY,
|
|
114
|
+
bounce: false,
|
|
115
|
+
});
|
|
116
|
+
await system.run();
|
|
117
|
+
await multisig.deployExternal();
|
|
118
|
+
let txs = await system.run();
|
|
119
|
+
expect(txs).toHaveLength(1);
|
|
120
|
+
expect(txs[0].endStatus).toEqual('active');
|
|
121
|
+
});
|
|
122
|
+
it('should load contract from address', async () => {
|
|
123
|
+
let multisig = new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 2);
|
|
124
|
+
let provider = createProvider(multisig);
|
|
125
|
+
await multisig.deployInternal(treasure);
|
|
126
|
+
await system.run();
|
|
127
|
+
let multisigFromProvider = await MultisigWallet_1.MultisigWallet.fromAddress(multisig.address, { provider });
|
|
128
|
+
expect(multisig.address.toRawString()).toEqual(multisigFromProvider.address.toRawString());
|
|
129
|
+
expect(multisig.owners.keys().toString()).toEqual(multisigFromProvider.owners.keys().toString());
|
|
130
|
+
expect(multisig.owners.values().toString()).toEqual(multisigFromProvider.owners.values().toString());
|
|
131
|
+
const testMultisigAddress = core_1.Address.parse('EQADBXugwmn4YvWsQizHdWGgfCTN_s3qFP0Ae0pzkU-jwzoE');
|
|
132
|
+
let multisigFromClient = await MultisigWallet_1.MultisigWallet.fromAddress(testMultisigAddress, { client });
|
|
133
|
+
expect(testMultisigAddress.toRawString()).toEqual(multisigFromClient.address.toRawString());
|
|
134
|
+
expect(multisigFromClient.owners.keys().toString()).toEqual('0,1,2');
|
|
135
|
+
expect(multisigFromClient.owners.values().toString()).toEqual([
|
|
136
|
+
Buffer.from('51ce50ebcced0fdcc7520a2cacf653c81fb49f34f9c570a9e1bb23c7f7186d8d00', 'hex'),
|
|
137
|
+
Buffer.from('f7a92e5a7b97b81fdc366c4c77298cfd1e9b97ba04feecf0c1d85d63d16d9f2000', 'hex'),
|
|
138
|
+
Buffer.from('6ec29f8fd53761b94291d5801cda5d0d00c48d78dc6c147ec4c6e088c3d93d8400', 'hex'),
|
|
139
|
+
].toString());
|
|
140
|
+
});
|
|
141
|
+
it('should find order by public key', () => {
|
|
142
|
+
let multisig = new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 2);
|
|
143
|
+
for (let i = 0; i < publicKeys.length; i += 1) {
|
|
144
|
+
expect(multisig.getOwnerIdByPubkey(publicKeys[i])).toEqual(i);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
it('should accept orders', async () => {
|
|
148
|
+
let multisig = new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 2);
|
|
149
|
+
let provider = createProvider(multisig);
|
|
150
|
+
await multisig.deployInternal(treasure, 10000000000n);
|
|
151
|
+
await system.run();
|
|
152
|
+
let orderBuilder = new MultisigOrderBuilder_1.MultisigOrderBuilder(123);
|
|
153
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 1000000000n, core_1.Cell.EMPTY), 3);
|
|
154
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address2'), 0n, (0, core_1.beginCell)().storeUint(3, 123).endCell()), 3);
|
|
155
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 2000000000n, core_1.Cell.EMPTY), 3);
|
|
156
|
+
await multisig.sendOrder(orderBuilder.build(), secretKeys[3], provider);
|
|
157
|
+
let txs = await system.run();
|
|
158
|
+
expect(txs).toHaveLength(1);
|
|
159
|
+
if (txs[0].description.type == 'generic') {
|
|
160
|
+
expect(txs[0].description.aborted).toBeFalsy;
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
it('should accept orders sent by `sendWithoutSecretKey` method', async () => {
|
|
164
|
+
let multisig = new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 2);
|
|
165
|
+
let provider = createProvider(multisig);
|
|
166
|
+
await multisig.deployInternal(treasure, 10000000000n);
|
|
167
|
+
await system.run();
|
|
168
|
+
let orderBuilder = new MultisigOrderBuilder_1.MultisigOrderBuilder(123);
|
|
169
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 1000000000n, core_1.Cell.EMPTY), 3);
|
|
170
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address2'), 0n, (0, core_1.beginCell)().storeUint(3, 123).endCell()), 3);
|
|
171
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 2000000000n, core_1.Cell.EMPTY), 3);
|
|
172
|
+
const order = orderBuilder.build();
|
|
173
|
+
const signature = (0, crypto_1.sign)(order.toCell(3).hash(), secretKeys[3]);
|
|
174
|
+
await multisig.sendOrderWithoutSecretKey(orderBuilder.build(), signature, 3, provider);
|
|
175
|
+
let txs = await system.run();
|
|
176
|
+
expect(txs).toHaveLength(1);
|
|
177
|
+
if (txs[0].description.type == 'generic') {
|
|
178
|
+
expect(txs[0].description.aborted).toBeFalsy;
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
it('should throw in sendOrder if there is no provider', async () => {
|
|
182
|
+
let multisig = new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 2);
|
|
183
|
+
let provider = createProvider(multisig);
|
|
184
|
+
await multisig.deployInternal(treasure, 10000000000n);
|
|
185
|
+
await system.run();
|
|
186
|
+
let order = new MultisigOrderBuilder_1.MultisigOrderBuilder(123);
|
|
187
|
+
order.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 1000000000n, core_1.Cell.EMPTY), 3);
|
|
188
|
+
order.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address2'), 0n, (0, core_1.beginCell)().storeUint(3, 123).endCell()), 3);
|
|
189
|
+
order.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 2000000000n, core_1.Cell.EMPTY), 3);
|
|
190
|
+
expect(multisig.sendOrder(order.build(), secretKeys[3]))
|
|
191
|
+
.rejects.toThrowError('you must specify provider if there is no such property in MultisigWallet instance');
|
|
192
|
+
});
|
|
193
|
+
it('should accept orders with provider from property', async () => {
|
|
194
|
+
let multisig = new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 2);
|
|
195
|
+
multisig.provider = createProvider(multisig);
|
|
196
|
+
await multisig.deployInternal(treasure, 10000000000n);
|
|
197
|
+
await system.run();
|
|
198
|
+
let orderBuilder = new MultisigOrderBuilder_1.MultisigOrderBuilder(123);
|
|
199
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 1000000000n, core_1.Cell.EMPTY), 3);
|
|
200
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address2'), 0n, (0, core_1.beginCell)().storeUint(3, 123).endCell()), 3);
|
|
201
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 2000000000n, core_1.Cell.EMPTY), 3);
|
|
202
|
+
await multisig.sendOrder(orderBuilder.build(), secretKeys[3]);
|
|
203
|
+
let txs = await system.run();
|
|
204
|
+
expect(txs).toHaveLength(1);
|
|
205
|
+
if (txs[0].description.type == 'generic') {
|
|
206
|
+
expect(txs[0].description.aborted).toBeFalsy();
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
it('should accept multiple orders and send messages', async () => {
|
|
210
|
+
let multisig = new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 5);
|
|
211
|
+
let provider = createProvider(multisig);
|
|
212
|
+
await multisig.deployInternal(treasure, 10000000000n);
|
|
213
|
+
await system.run();
|
|
214
|
+
let orderBuilder = new MultisigOrderBuilder_1.MultisigOrderBuilder(123);
|
|
215
|
+
orderBuilder.addMessage(createInternalMessage(false, (0, emulator_1.testAddress)('address1'), 1000000000n, core_1.Cell.EMPTY), 3);
|
|
216
|
+
orderBuilder.addMessage(createInternalMessage(false, (0, emulator_1.testAddress)('address2'), 0n, (0, core_1.beginCell)().storeUint(3, 123).endCell()), 3);
|
|
217
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 2000000000n, core_1.Cell.EMPTY), 3);
|
|
218
|
+
let order = orderBuilder.build();
|
|
219
|
+
for (let i = 0; i < 4; i += 1) {
|
|
220
|
+
await multisig.sendOrder(order, secretKeys[i], provider);
|
|
221
|
+
await system.run();
|
|
222
|
+
}
|
|
223
|
+
await multisig.sendOrder(order, secretKeys[7], provider);
|
|
224
|
+
let txs = await system.run();
|
|
225
|
+
expect(txs).toHaveLength(5);
|
|
226
|
+
});
|
|
227
|
+
it('should accept orders with multiple signatures and send messages', async () => {
|
|
228
|
+
let multisig = new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 5);
|
|
229
|
+
let provider = createProvider(multisig);
|
|
230
|
+
await multisig.deployInternal(treasure, 10000000000n);
|
|
231
|
+
await system.run();
|
|
232
|
+
let orderBuilder = new MultisigOrderBuilder_1.MultisigOrderBuilder(123);
|
|
233
|
+
orderBuilder.addMessage(createInternalMessage(false, (0, emulator_1.testAddress)('address1'), 1000000000n, core_1.Cell.EMPTY), 3);
|
|
234
|
+
orderBuilder.addMessage(createInternalMessage(false, (0, emulator_1.testAddress)('address2'), 0n, (0, core_1.beginCell)().storeUint(3, 123).endCell()), 3);
|
|
235
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 2000000000n, core_1.Cell.EMPTY), 3);
|
|
236
|
+
let order = orderBuilder.build();
|
|
237
|
+
for (let i = 0; i < 5; i += 1) {
|
|
238
|
+
order.sign(i, secretKeys[i]);
|
|
239
|
+
}
|
|
240
|
+
await multisig.sendOrder(order, secretKeys[0], provider);
|
|
241
|
+
let txs = await system.run();
|
|
242
|
+
expect(txs).toHaveLength(5);
|
|
243
|
+
});
|
|
244
|
+
it('should throw in getOwnerIdByPubkey on invalid public key', () => {
|
|
245
|
+
let multisig = new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 2);
|
|
246
|
+
expect(() => multisig.getOwnerIdByPubkey(Buffer.alloc(32))).toThrow('public key is not an owner');
|
|
247
|
+
});
|
|
248
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Whales Corp.
|
|
3
|
+
* All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
import { TonClient } from "../client/TonClient";
|
|
9
|
+
export declare function createTestClient(net?: 'testnet' | 'mainnet'): TonClient;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Whales Corp.
|
|
4
|
+
* All Rights Reserved.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.createTestClient = void 0;
|
|
11
|
+
const TonClient_1 = require("../client/TonClient");
|
|
12
|
+
function createTestClient(net) {
|
|
13
|
+
return new TonClient_1.TonClient({
|
|
14
|
+
endpoint: net === 'mainnet' ? 'https://mainnet.tonhubapi.com/jsonRPC' : 'https://testnet.toncenter.com/api/v2/jsonRPC',
|
|
15
|
+
apiKey: net !== 'mainnet' ? '32df40f4ffc11053334bcdf09c7d3a9e6487ee0cb715edf8cf667c543edb10ca' : undefined
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
exports.createTestClient = createTestClient;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Whales Corp.
|
|
3
|
+
* All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
import { TonClient4 } from "../client/TonClient4";
|
|
9
|
+
export declare function createTestClient4(net?: 'testnet' | 'mainnet'): TonClient4;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Whales Corp.
|
|
4
|
+
* All Rights Reserved.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.createTestClient4 = void 0;
|
|
11
|
+
const TonClient4_1 = require("../client/TonClient4");
|
|
12
|
+
function createTestClient4(net) {
|
|
13
|
+
return new TonClient4_1.TonClient4({ endpoint: net === 'mainnet' ? 'https://mainnet-v4.tonhubapi.com' : 'https://testnet-v4.tonhubapi.com' });
|
|
14
|
+
}
|
|
15
|
+
exports.createTestClient4 = createTestClient4;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Cell } from '@ton/core';
|
|
2
|
+
import { MsgPrices, StoragePrices } from '../config/ConfigParser';
|
|
3
|
+
export declare function computeStorageFees(data: {
|
|
4
|
+
now: number;
|
|
5
|
+
lastPaid: number;
|
|
6
|
+
storagePrices: StoragePrices[];
|
|
7
|
+
storageStat: {
|
|
8
|
+
cells: number;
|
|
9
|
+
bits: number;
|
|
10
|
+
publicCells: number;
|
|
11
|
+
};
|
|
12
|
+
special: boolean;
|
|
13
|
+
masterchain: boolean;
|
|
14
|
+
}): bigint;
|
|
15
|
+
export declare function computeFwdFees(msgPrices: MsgPrices, cells: bigint, bits: bigint): bigint;
|
|
16
|
+
export declare function computeGasPrices(gasUsed: bigint, prices: {
|
|
17
|
+
flatLimit: bigint;
|
|
18
|
+
flatPrice: bigint;
|
|
19
|
+
price: bigint;
|
|
20
|
+
}): bigint;
|
|
21
|
+
export declare function computeExternalMessageFees(msgPrices: MsgPrices, cell: Cell): bigint;
|
|
22
|
+
export declare function computeMessageForwardFees(msgPrices: MsgPrices, cell: Cell): {
|
|
23
|
+
fees: bigint;
|
|
24
|
+
remaining: bigint;
|
|
25
|
+
};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.computeMessageForwardFees = exports.computeExternalMessageFees = exports.computeGasPrices = exports.computeFwdFees = exports.computeStorageFees = void 0;
|
|
4
|
+
const core_1 = require("@ton/core");
|
|
5
|
+
//
|
|
6
|
+
// Source: https://github.com/ton-foundation/ton/blob/ae5c0720143e231c32c3d2034cfe4e533a16d969/crypto/block/transaction.cpp#L425
|
|
7
|
+
//
|
|
8
|
+
function computeStorageFees(data) {
|
|
9
|
+
const { lastPaid, now, storagePrices, storageStat, special, masterchain } = data;
|
|
10
|
+
if (now <= lastPaid || storagePrices.length === 0 || now < storagePrices[0].utime_since || special) {
|
|
11
|
+
return BigInt(0);
|
|
12
|
+
}
|
|
13
|
+
let upto = Math.max(lastPaid, storagePrices[0].utime_since);
|
|
14
|
+
let total = BigInt(0);
|
|
15
|
+
for (let i = 0; i < storagePrices.length && upto < now; i++) {
|
|
16
|
+
let valid_until = (i < storagePrices.length - 1 ? Math.min(now, storagePrices[i + 1].utime_since) : now);
|
|
17
|
+
let payment = BigInt(0);
|
|
18
|
+
if (upto < valid_until) {
|
|
19
|
+
let delta = valid_until - upto;
|
|
20
|
+
payment += (BigInt(storageStat.cells) * (masterchain ? storagePrices[i].mc_cell_price_ps : storagePrices[i].cell_price_ps));
|
|
21
|
+
payment += (BigInt(storageStat.bits) * (masterchain ? storagePrices[i].mc_bit_price_ps : storagePrices[i].bit_price_ps));
|
|
22
|
+
payment = payment * BigInt(delta);
|
|
23
|
+
}
|
|
24
|
+
upto = valid_until;
|
|
25
|
+
total += payment;
|
|
26
|
+
}
|
|
27
|
+
return shr16ceil(total);
|
|
28
|
+
}
|
|
29
|
+
exports.computeStorageFees = computeStorageFees;
|
|
30
|
+
//
|
|
31
|
+
// Source: https://github.com/ton-foundation/ton/blob/ae5c0720143e231c32c3d2034cfe4e533a16d969/crypto/block/transaction.cpp#L1218
|
|
32
|
+
//
|
|
33
|
+
function computeFwdFees(msgPrices, cells, bits) {
|
|
34
|
+
return msgPrices.lumpPrice + (shr16ceil(msgPrices.bitPrice * bits + (msgPrices.cellPrice * cells)));
|
|
35
|
+
}
|
|
36
|
+
exports.computeFwdFees = computeFwdFees;
|
|
37
|
+
//
|
|
38
|
+
// Source: https://github.com/ton-foundation/ton/blob/ae5c0720143e231c32c3d2034cfe4e533a16d969/crypto/block/transaction.cpp#L761
|
|
39
|
+
//
|
|
40
|
+
function computeGasPrices(gasUsed, prices) {
|
|
41
|
+
if (gasUsed <= prices.flatLimit) {
|
|
42
|
+
return prices.flatPrice;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// td::rshift(gas_price256 * (gas_used - cfg.flat_gas_limit), 16, 1) + cfg.flat_gas_price
|
|
46
|
+
return prices.flatPrice + ((prices.price * (gasUsed - prices.flatLimit)) >> 16n);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.computeGasPrices = computeGasPrices;
|
|
50
|
+
//
|
|
51
|
+
// Source: https://github.com/ton-foundation/ton/blob/ae5c0720143e231c32c3d2034cfe4e533a16d969/crypto/block/transaction.cpp#L530
|
|
52
|
+
//
|
|
53
|
+
function computeExternalMessageFees(msgPrices, cell) {
|
|
54
|
+
// Collect stats
|
|
55
|
+
let storageStats = collectCellStats(cell);
|
|
56
|
+
storageStats.bits -= cell.bits.length;
|
|
57
|
+
storageStats.cells -= 1;
|
|
58
|
+
return computeFwdFees(msgPrices, BigInt(storageStats.cells), BigInt(storageStats.bits));
|
|
59
|
+
}
|
|
60
|
+
exports.computeExternalMessageFees = computeExternalMessageFees;
|
|
61
|
+
function computeMessageForwardFees(msgPrices, cell) {
|
|
62
|
+
let msg = (0, core_1.loadMessageRelaxed)(cell.beginParse());
|
|
63
|
+
let storageStats = { bits: 0, cells: 0 };
|
|
64
|
+
// Init
|
|
65
|
+
if (msg.init) {
|
|
66
|
+
const rawBuilder = new core_1.Cell().asBuilder();
|
|
67
|
+
(0, core_1.storeStateInit)(msg.init)(rawBuilder);
|
|
68
|
+
const raw = rawBuilder.endCell();
|
|
69
|
+
let c = collectCellStats(raw);
|
|
70
|
+
c.bits -= raw.bits.length;
|
|
71
|
+
c.cells -= 1;
|
|
72
|
+
storageStats.bits += c.bits;
|
|
73
|
+
storageStats.cells += c.cells;
|
|
74
|
+
}
|
|
75
|
+
// Body
|
|
76
|
+
let bc = collectCellStats(msg.body);
|
|
77
|
+
bc.bits -= msg.body.bits.length;
|
|
78
|
+
bc.cells -= 1;
|
|
79
|
+
storageStats.bits += bc.bits;
|
|
80
|
+
storageStats.cells += bc.cells;
|
|
81
|
+
// NOTE: Extra currencies are ignored for now
|
|
82
|
+
let fees = computeFwdFees(msgPrices, BigInt(storageStats.cells), BigInt(storageStats.bits));
|
|
83
|
+
let res = (fees * BigInt(msgPrices.firstFrac)) >> 16n;
|
|
84
|
+
let remaining = fees - res;
|
|
85
|
+
return { fees: res, remaining };
|
|
86
|
+
}
|
|
87
|
+
exports.computeMessageForwardFees = computeMessageForwardFees;
|
|
88
|
+
function collectCellStats(cell) {
|
|
89
|
+
let bits = cell.bits.length;
|
|
90
|
+
let cells = 1;
|
|
91
|
+
for (let ref of cell.refs) {
|
|
92
|
+
let r = collectCellStats(ref);
|
|
93
|
+
cells += r.cells;
|
|
94
|
+
bits += r.bits;
|
|
95
|
+
}
|
|
96
|
+
return { bits, cells };
|
|
97
|
+
}
|
|
98
|
+
function shr16ceil(src) {
|
|
99
|
+
let rem = src % 65536n;
|
|
100
|
+
let res = src >> 16n;
|
|
101
|
+
if (rem !== 0n) {
|
|
102
|
+
res += 1n;
|
|
103
|
+
}
|
|
104
|
+
return res;
|
|
105
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const fees_1 = require("./fees");
|
|
4
|
+
const core_1 = require("@ton/core");
|
|
5
|
+
const WalletContractV4_1 = require("../wallets/WalletContractV4");
|
|
6
|
+
describe('estimateFees', () => {
|
|
7
|
+
it('should estimate fees correctly', () => {
|
|
8
|
+
const config = {
|
|
9
|
+
storage: [{ utime_since: 0, bit_price_ps: BigInt(1), cell_price_ps: BigInt(500), mc_bit_price_ps: BigInt(1000), mc_cell_price_ps: BigInt(500000) }],
|
|
10
|
+
workchain: {
|
|
11
|
+
gas: { flatLimit: BigInt(100), flatGasPrice: BigInt(100000), price: BigInt(65536000) },
|
|
12
|
+
message: { lumpPrice: BigInt(1000000), bitPrice: BigInt(65536000), cellPrice: BigInt(6553600000), firstFrac: 21845 }
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
const storageStats = [{
|
|
16
|
+
lastPaid: 1696792239, duePayment: null,
|
|
17
|
+
used: { bits: 6888, cells: 14, publicCells: 0 }
|
|
18
|
+
}];
|
|
19
|
+
const gasUsageByOutMsgs = { 1: 3308, 2: 3950, 3: 4592, 4: 5234 };
|
|
20
|
+
const contract = WalletContractV4_1.WalletContractV4.create({ workchain: 0, publicKey: Buffer.from('MUP3GpbKCQu64L4PIU0QprZxmSUygHcaYKuo2tZYA1c=', 'base64') });
|
|
21
|
+
const body = (0, core_1.comment)('Test message fees estimation');
|
|
22
|
+
const testAddress = core_1.Address.parse('EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N');
|
|
23
|
+
// Create transfer
|
|
24
|
+
let intMessage = (0, core_1.internal)({
|
|
25
|
+
to: testAddress,
|
|
26
|
+
value: 1400000000n,
|
|
27
|
+
bounce: true,
|
|
28
|
+
body,
|
|
29
|
+
});
|
|
30
|
+
let transfer = contract.createTransfer({
|
|
31
|
+
seqno: 14,
|
|
32
|
+
secretKey: Buffer.alloc(64),
|
|
33
|
+
sendMode: core_1.SendMode.IGNORE_ERRORS | core_1.SendMode.PAY_GAS_SEPARATELY,
|
|
34
|
+
messages: [intMessage]
|
|
35
|
+
});
|
|
36
|
+
const externalMessage = (0, core_1.external)({
|
|
37
|
+
to: contract.address,
|
|
38
|
+
body: transfer,
|
|
39
|
+
init: null
|
|
40
|
+
});
|
|
41
|
+
let inMsg = new core_1.Cell().asBuilder();
|
|
42
|
+
(0, core_1.storeMessage)(externalMessage)(inMsg);
|
|
43
|
+
let outMsg = new core_1.Cell().asBuilder();
|
|
44
|
+
(0, core_1.storeMessageRelaxed)(intMessage)(outMsg);
|
|
45
|
+
// Storage fees
|
|
46
|
+
let storageFees = BigInt(0);
|
|
47
|
+
for (let storageStat of storageStats) {
|
|
48
|
+
if (storageStat) {
|
|
49
|
+
const computed = (0, fees_1.computeStorageFees)({
|
|
50
|
+
lastPaid: storageStat.lastPaid,
|
|
51
|
+
masterchain: false,
|
|
52
|
+
now: 1697445678,
|
|
53
|
+
special: false,
|
|
54
|
+
storagePrices: config.storage,
|
|
55
|
+
storageStat: {
|
|
56
|
+
bits: storageStat.used.bits,
|
|
57
|
+
cells: storageStat.used.cells,
|
|
58
|
+
publicCells: storageStat.used.publicCells
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
storageFees = storageFees + computed;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
expect((0, core_1.fromNano)(storageFees)).toBe('0.000138473');
|
|
65
|
+
// Calculate import fees
|
|
66
|
+
let importFees = (0, fees_1.computeExternalMessageFees)(config.workchain.message, inMsg.endCell());
|
|
67
|
+
expect((0, core_1.fromNano)(importFees)).toBe('0.001772');
|
|
68
|
+
// Any transaction use this amount of gas
|
|
69
|
+
const gasUsed = gasUsageByOutMsgs[1];
|
|
70
|
+
let gasFees = (0, fees_1.computeGasPrices)(BigInt(gasUsed), { flatLimit: config.workchain.gas.flatLimit, flatPrice: config.workchain.gas.flatGasPrice, price: config.workchain.gas.price });
|
|
71
|
+
expect((0, core_1.fromNano)(gasFees)).toBe('0.003308');
|
|
72
|
+
// Total
|
|
73
|
+
let total = BigInt(0);
|
|
74
|
+
total += storageFees;
|
|
75
|
+
total += importFees;
|
|
76
|
+
total += gasFees;
|
|
77
|
+
// Forward fees
|
|
78
|
+
let fwdFees = (0, fees_1.computeMessageForwardFees)(config.workchain.message, outMsg.endCell());
|
|
79
|
+
expect((0, core_1.fromNano)(fwdFees.fees)).toBe('0.000333328');
|
|
80
|
+
total += fwdFees.fees;
|
|
81
|
+
expect((0, core_1.fromNano)(total)).toBe('0.005551801');
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Whales Corp.
|
|
4
|
+
* All Rights Reserved.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Whales Corp.
|
|
3
|
+
* All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
export declare function randomTestKey(seed: string): import("@ton/crypto").KeyPair;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Whales Corp.
|
|
4
|
+
* All Rights Reserved.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.randomTestKey = void 0;
|
|
14
|
+
const prando_1 = __importDefault(require("prando"));
|
|
15
|
+
const crypto_1 = require("@ton/crypto");
|
|
16
|
+
function randomTestKey(seed) {
|
|
17
|
+
let random = new prando_1.default(seed);
|
|
18
|
+
let res = Buffer.alloc(32);
|
|
19
|
+
for (let i = 0; i < res.length; i++) {
|
|
20
|
+
res[i] = random.nextInt(0, 256);
|
|
21
|
+
}
|
|
22
|
+
return (0, crypto_1.keyPairFromSeed)(res);
|
|
23
|
+
}
|
|
24
|
+
exports.randomTestKey = randomTestKey;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Whales Corp.
|
|
3
|
+
* All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
export declare function exponentialBackoffDelay(currentFailureCount: number, minDelay: number, maxDelay: number, maxFailureCount: number): number;
|
|
9
|
+
export declare function delay(ms: number): Promise<unknown>;
|
|
10
|
+
export declare function delayBreakable(ms: number): {
|
|
11
|
+
promise: Promise<unknown>;
|
|
12
|
+
resolver: () => void;
|
|
13
|
+
};
|
|
14
|
+
export declare function forever(): Promise<unknown>;
|
|
15
|
+
export declare function backoff<T>(callback: () => Promise<T>, log: boolean): Promise<T>;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Whales Corp.
|
|
4
|
+
* All Rights Reserved.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.backoff = exports.forever = exports.delayBreakable = exports.delay = exports.exponentialBackoffDelay = void 0;
|
|
11
|
+
function exponentialBackoffDelay(currentFailureCount, minDelay, maxDelay, maxFailureCount) {
|
|
12
|
+
let maxDelayRet = minDelay + ((maxDelay - minDelay) / maxFailureCount) * Math.max(currentFailureCount, maxFailureCount);
|
|
13
|
+
return Math.round(Math.random() * maxDelayRet);
|
|
14
|
+
}
|
|
15
|
+
exports.exponentialBackoffDelay = exponentialBackoffDelay;
|
|
16
|
+
async function delay(ms) {
|
|
17
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
18
|
+
}
|
|
19
|
+
exports.delay = delay;
|
|
20
|
+
function delayBreakable(ms) {
|
|
21
|
+
// We can cancel delay from outer code
|
|
22
|
+
let promiseResolver = null;
|
|
23
|
+
let resolver = () => {
|
|
24
|
+
if (promiseResolver) {
|
|
25
|
+
promiseResolver();
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
let promise = new Promise(resolve => {
|
|
29
|
+
promiseResolver = resolve;
|
|
30
|
+
setTimeout(resolve, ms);
|
|
31
|
+
});
|
|
32
|
+
return { promise, resolver };
|
|
33
|
+
}
|
|
34
|
+
exports.delayBreakable = delayBreakable;
|
|
35
|
+
const promise = new Promise(() => { });
|
|
36
|
+
function forever() {
|
|
37
|
+
return promise;
|
|
38
|
+
}
|
|
39
|
+
exports.forever = forever;
|
|
40
|
+
async function backoff(callback, log) {
|
|
41
|
+
let currentFailureCount = 0;
|
|
42
|
+
const minDelay = 500;
|
|
43
|
+
const maxDelay = 15000;
|
|
44
|
+
const maxFailureCount = 50;
|
|
45
|
+
while (true) {
|
|
46
|
+
try {
|
|
47
|
+
return await callback();
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
if (currentFailureCount > 3) {
|
|
51
|
+
if (log) {
|
|
52
|
+
console.warn(e);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (currentFailureCount < maxFailureCount) {
|
|
56
|
+
currentFailureCount++;
|
|
57
|
+
}
|
|
58
|
+
let waitForRequest = exponentialBackoffDelay(currentFailureCount, minDelay, maxDelay, maxFailureCount);
|
|
59
|
+
await delay(waitForRequest);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.backoff = backoff;
|