@ton/ton 13.5.1
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/CHANGELOG.md +133 -0
- package/LICENSE +9 -0
- package/README.md +78 -0
- package/dist/client/TonClient.d.ts +231 -0
- package/dist/client/TonClient.js +392 -0
- package/dist/client/TonClient.spec.d.ts +1 -0
- package/dist/client/TonClient.spec.js +37 -0
- package/dist/client/TonClient4.d.ts +289 -0
- package/dist/client/TonClient4.js +514 -0
- package/dist/client/TonClient4.spec.d.ts +1 -0
- package/dist/client/TonClient4.spec.js +36 -0
- package/dist/client/api/HttpApi.d.ts +632 -0
- package/dist/client/api/HttpApi.js +297 -0
- package/dist/client/api/TonCache.d.ts +16 -0
- package/dist/client/api/TonCache.js +33 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +68 -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 +26 -0
- package/dist/multisig/MultisigWallet.js +120 -0
- package/dist/multisig/MultisigWallet.spec.d.ts +1 -0
- package/dist/multisig/MultisigWallet.spec.js +230 -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/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 +62 -0
- package/dist/wallets/WalletContractV3R1.js +111 -0
- package/dist/wallets/WalletContractV3R1.spec.d.ts +8 -0
- package/dist/wallets/WalletContractV3R1.spec.js +44 -0
- package/dist/wallets/WalletContractV3R2.d.ts +62 -0
- package/dist/wallets/WalletContractV3R2.js +111 -0
- package/dist/wallets/WalletContractV3R2.spec.d.ts +8 -0
- package/dist/wallets/WalletContractV3R2.spec.js +44 -0
- package/dist/wallets/WalletContractV4.d.ts +62 -0
- package/dist/wallets/WalletContractV4.js +112 -0
- package/dist/wallets/WalletContractV4.spec.d.ts +8 -0
- package/dist/wallets/WalletContractV4.spec.js +48 -0
- package/dist/wallets/signing/createWalletTransfer.d.ts +39 -0
- package/dist/wallets/signing/createWalletTransfer.js +122 -0
- package/package.json +68 -0
|
@@ -0,0 +1,139 @@
|
|
|
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 MultisigOrderBuilder_1 = require("./MultisigOrderBuilder");
|
|
8
|
+
const MultisigWallet_1 = require("./MultisigWallet");
|
|
9
|
+
const MultisigOrder_1 = require("./MultisigOrder");
|
|
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('MultisigOrder', () => {
|
|
30
|
+
var publicKeys;
|
|
31
|
+
var secretKeys;
|
|
32
|
+
beforeAll(async () => {
|
|
33
|
+
publicKeys = [];
|
|
34
|
+
secretKeys = [];
|
|
35
|
+
for (let i = 0; i < 10; i += 1) {
|
|
36
|
+
let kp = (0, crypto_1.keyPairFromSeed)(await (0, crypto_1.getSecureRandomBytes)(32));
|
|
37
|
+
publicKeys.push(kp.publicKey);
|
|
38
|
+
secretKeys.push(kp.secretKey);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
it('should add messages', () => {
|
|
42
|
+
let order = new MultisigOrderBuilder_1.MultisigOrderBuilder(123);
|
|
43
|
+
order.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 1000000000n, core_1.Cell.EMPTY), 3);
|
|
44
|
+
order.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address2'), 0n, (0, core_1.beginCell)().storeUint(3, 123).endCell()), 3);
|
|
45
|
+
order.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 2000000000n, core_1.Cell.EMPTY), 3);
|
|
46
|
+
expect(order.messages.endCell().refs.length).toEqual(3);
|
|
47
|
+
});
|
|
48
|
+
it('should add signatures', () => {
|
|
49
|
+
let orderBuilder = new MultisigOrderBuilder_1.MultisigOrderBuilder(123);
|
|
50
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 1000000000n, core_1.Cell.EMPTY), 3);
|
|
51
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address2'), 0n, (0, core_1.beginCell)().storeUint(3, 123).endCell()), 3);
|
|
52
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 2000000000n, core_1.Cell.EMPTY), 3);
|
|
53
|
+
let order = orderBuilder.build();
|
|
54
|
+
order.sign(0, secretKeys[0]);
|
|
55
|
+
order.sign(1, secretKeys[1]);
|
|
56
|
+
order.sign(2, secretKeys[2]);
|
|
57
|
+
expect(Object.keys(order.signatures)).toHaveLength(3);
|
|
58
|
+
});
|
|
59
|
+
it('should union signatures', () => {
|
|
60
|
+
let order1Builder = new MultisigOrderBuilder_1.MultisigOrderBuilder(123);
|
|
61
|
+
order1Builder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 1000000000n, core_1.Cell.EMPTY), 3);
|
|
62
|
+
order1Builder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address2'), 0n, (0, core_1.beginCell)().storeUint(3, 123).endCell()), 3);
|
|
63
|
+
order1Builder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 2000000000n, core_1.Cell.EMPTY), 3);
|
|
64
|
+
let order1 = order1Builder.build();
|
|
65
|
+
order1.sign(0, secretKeys[0]);
|
|
66
|
+
order1.sign(1, secretKeys[1]);
|
|
67
|
+
order1.sign(2, secretKeys[2]);
|
|
68
|
+
let order2Builder = new MultisigOrderBuilder_1.MultisigOrderBuilder(123);
|
|
69
|
+
order2Builder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 1000000000n, core_1.Cell.EMPTY), 3);
|
|
70
|
+
order2Builder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address2'), 0n, (0, core_1.beginCell)().storeUint(3, 123).endCell()), 3);
|
|
71
|
+
order2Builder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 2000000000n, core_1.Cell.EMPTY), 3);
|
|
72
|
+
let order2 = order2Builder.build();
|
|
73
|
+
order2.sign(3, secretKeys[3]);
|
|
74
|
+
order2.sign(2, secretKeys[2]);
|
|
75
|
+
order2.sign(5, secretKeys[5]);
|
|
76
|
+
order1.unionSignatures(order2);
|
|
77
|
+
expect(Object.keys(order1.signatures)).toHaveLength(5);
|
|
78
|
+
});
|
|
79
|
+
it('should clear signatures', () => {
|
|
80
|
+
let orderBuilder = new MultisigOrderBuilder_1.MultisigOrderBuilder(123);
|
|
81
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 1000000000n, core_1.Cell.EMPTY), 3);
|
|
82
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address2'), 0n, (0, core_1.beginCell)().storeUint(3, 123).endCell()), 3);
|
|
83
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 2000000000n, core_1.Cell.EMPTY), 3);
|
|
84
|
+
let order = orderBuilder.build();
|
|
85
|
+
order.sign(0, secretKeys[0]);
|
|
86
|
+
order.sign(1, secretKeys[1]);
|
|
87
|
+
order.sign(2, secretKeys[2]);
|
|
88
|
+
order.clearSignatures();
|
|
89
|
+
expect(order.signatures).toBeNull;
|
|
90
|
+
});
|
|
91
|
+
it('should clear messages', () => {
|
|
92
|
+
let orderBuilder = new MultisigOrderBuilder_1.MultisigOrderBuilder(123);
|
|
93
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 1000000000n, core_1.Cell.EMPTY), 3);
|
|
94
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address2'), 0n, (0, core_1.beginCell)().storeUint(3, 123).endCell()), 3);
|
|
95
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 2000000000n, core_1.Cell.EMPTY), 3);
|
|
96
|
+
orderBuilder.clearMessages();
|
|
97
|
+
expect(orderBuilder.messages).toEqual((0, core_1.beginCell)());
|
|
98
|
+
});
|
|
99
|
+
it('should add signatures without secret key', () => {
|
|
100
|
+
let orderBuilder = new MultisigOrderBuilder_1.MultisigOrderBuilder(123);
|
|
101
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 1000000000n, core_1.Cell.EMPTY), 3);
|
|
102
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address2'), 0n, (0, core_1.beginCell)().storeUint(3, 123).endCell()), 3);
|
|
103
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 2000000000n, core_1.Cell.EMPTY), 3);
|
|
104
|
+
let order = orderBuilder.build();
|
|
105
|
+
order.sign(0, secretKeys[0]);
|
|
106
|
+
order.addSignature(1, (0, crypto_1.sign)(order.payload.hash(), secretKeys[1]), new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 2));
|
|
107
|
+
expect(Object.keys(order.signatures)).toHaveLength(2);
|
|
108
|
+
});
|
|
109
|
+
it('should throw on more than 4 messages', () => {
|
|
110
|
+
let orderBuilder = new MultisigOrderBuilder_1.MultisigOrderBuilder(123);
|
|
111
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 1000000000n, core_1.Cell.EMPTY), 3);
|
|
112
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address2'), 0n, (0, core_1.beginCell)().storeUint(3, 123).endCell()), 3);
|
|
113
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 2000000000n, core_1.Cell.EMPTY), 3);
|
|
114
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 2000000000n, core_1.Cell.EMPTY), 3);
|
|
115
|
+
expect(() => orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 2000000000n, core_1.Cell.EMPTY), 3)).toThrow();
|
|
116
|
+
});
|
|
117
|
+
it('should throw on invalid signature', () => {
|
|
118
|
+
let orderBuilder = new MultisigOrderBuilder_1.MultisigOrderBuilder(123);
|
|
119
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 1000000000n, core_1.Cell.EMPTY), 3);
|
|
120
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address2'), 0n, (0, core_1.beginCell)().storeUint(3, 123).endCell()), 3);
|
|
121
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 2000000000n, core_1.Cell.EMPTY), 3);
|
|
122
|
+
let order = orderBuilder.build();
|
|
123
|
+
order.sign(0, secretKeys[0]);
|
|
124
|
+
expect(() => order.addSignature(1, Buffer.alloc(64), new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 2))).toThrow();
|
|
125
|
+
});
|
|
126
|
+
it('should export to cell', () => { });
|
|
127
|
+
it('should load from cell', () => {
|
|
128
|
+
const order1Cell = core_1.Cell.fromBoc(Buffer.from('B5EE9C7241010201004700011B0000000031FD2F910000000001C0010068620014811EF5893924A58891883AA5563EE83305B47E62061D349E4BDECD66D2F2B1A02FAF08000000000000000000000000000021E26136', 'hex'))[0];
|
|
129
|
+
const order2Cell = core_1.Cell.fromBoc(Buffer.from('B5EE9C7241010301008C00021B8000000031FD2F910000000001C001020083E67410438C1007888D2CD45436502FBA877BECE26E7F384709B29B4A607181B8473CC4D45B44F7C47590740936231AE001727CCCA955DCDF959955D3889F4E0F00400068620014811EF5893924A58891883AA5563EE83305B47E62061D349E4BDECD66D2F2B1A02FAF080000000000000000000000000000621311E8', 'hex'))[0];
|
|
130
|
+
const order3Cell = core_1.Cell.fromBoc(Buffer.from('B5EE9C724101040100D100021B8000000031FD2F910000000001C0010201836100CBF8BBD98C5FE999FB232678DF1CC06A3522DB55736B3FF846C65AD1619694B8BDEF50B8DCF390AD54A4076B7444600FE54CC2EBFA68ED07F3063437DF0501C0030068620014811EF5893924A58891883AA5563EE83305B47E62061D349E4BDECD66D2F2B1A02FAF0800000000000000000000000000000083E67410438C1007888D2CD45436502FBA877BECE26E7F384709B29B4A607181B8473CC4D45B44F7C47590740936231AE001727CCCA955DCDF959955D3889F4E0F0040A434CD60', 'hex'))[0];
|
|
131
|
+
const order1 = MultisigOrder_1.MultisigOrder.fromCell(order1Cell);
|
|
132
|
+
const order2 = MultisigOrder_1.MultisigOrder.fromCell(order2Cell);
|
|
133
|
+
const order3 = MultisigOrder_1.MultisigOrder.fromCell(order3Cell);
|
|
134
|
+
expect(order1.payload.refs).toHaveLength(1);
|
|
135
|
+
expect(Object.keys(order1.signatures)).toHaveLength(0);
|
|
136
|
+
expect(Object.keys(order2.signatures)).toHaveLength(1);
|
|
137
|
+
expect(Object.keys(order3.signatures)).toHaveLength(2);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Builder, MessageRelaxed } from '@ton/core';
|
|
2
|
+
import { MultisigOrder } from './MultisigOrder';
|
|
3
|
+
export declare class MultisigOrderBuilder {
|
|
4
|
+
messages: Builder;
|
|
5
|
+
queryId: bigint;
|
|
6
|
+
private walletId;
|
|
7
|
+
private queryOffset;
|
|
8
|
+
constructor(walletId: number, offset?: number);
|
|
9
|
+
addMessage(message: MessageRelaxed, mode: number): void;
|
|
10
|
+
clearMessages(): void;
|
|
11
|
+
build(): MultisigOrder;
|
|
12
|
+
private updateQueryId;
|
|
13
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Made by @Gusarich and @Miandic */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.MultisigOrderBuilder = void 0;
|
|
5
|
+
const core_1 = require("@ton/core");
|
|
6
|
+
const MultisigOrder_1 = require("./MultisigOrder");
|
|
7
|
+
class MultisigOrderBuilder {
|
|
8
|
+
constructor(walletId, offset) {
|
|
9
|
+
this.messages = (0, core_1.beginCell)();
|
|
10
|
+
this.queryId = 0n;
|
|
11
|
+
this.walletId = walletId;
|
|
12
|
+
this.queryOffset = offset || 7200;
|
|
13
|
+
}
|
|
14
|
+
addMessage(message, mode) {
|
|
15
|
+
if (this.messages.refs >= 4) {
|
|
16
|
+
throw Error('only 4 refs are allowed');
|
|
17
|
+
}
|
|
18
|
+
this.updateQueryId();
|
|
19
|
+
this.messages.storeUint(mode, 8);
|
|
20
|
+
this.messages.storeRef((0, core_1.beginCell)().store((0, core_1.storeMessageRelaxed)(message)).endCell());
|
|
21
|
+
}
|
|
22
|
+
clearMessages() {
|
|
23
|
+
this.messages = (0, core_1.beginCell)();
|
|
24
|
+
}
|
|
25
|
+
build() {
|
|
26
|
+
return MultisigOrder_1.MultisigOrder.fromPayload((0, core_1.beginCell)()
|
|
27
|
+
.storeUint(this.walletId, 32)
|
|
28
|
+
.storeUint(this.queryId, 64)
|
|
29
|
+
.storeBuilder(this.messages)
|
|
30
|
+
.endCell());
|
|
31
|
+
}
|
|
32
|
+
updateQueryId() {
|
|
33
|
+
const time = BigInt(Math.floor(Date.now() / 1000 + this.queryOffset));
|
|
34
|
+
this.queryId = time << 32n;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.MultisigOrderBuilder = MultisigOrderBuilder;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { TonClient } from '../index';
|
|
3
|
+
import { Address, ContractProvider, Dictionary, Sender, StateInit } from '@ton/core';
|
|
4
|
+
import { MultisigOrder } from './MultisigOrder';
|
|
5
|
+
export declare class MultisigWallet {
|
|
6
|
+
owners: Dictionary<number, Buffer>;
|
|
7
|
+
workchain: number;
|
|
8
|
+
walletId: number;
|
|
9
|
+
k: number;
|
|
10
|
+
address: Address;
|
|
11
|
+
provider: ContractProvider | null;
|
|
12
|
+
init: StateInit;
|
|
13
|
+
constructor(publicKeys: Buffer[], workchain: number, walletId: number, k: number, opts?: {
|
|
14
|
+
address?: Address;
|
|
15
|
+
provider?: ContractProvider;
|
|
16
|
+
client?: TonClient;
|
|
17
|
+
});
|
|
18
|
+
static fromAddress(address: Address, opts: {
|
|
19
|
+
provider?: ContractProvider;
|
|
20
|
+
client?: TonClient;
|
|
21
|
+
}): Promise<MultisigWallet>;
|
|
22
|
+
deployExternal(provider?: ContractProvider): Promise<void>;
|
|
23
|
+
deployInternal(sender: Sender, value?: bigint): Promise<void>;
|
|
24
|
+
sendOrder(order: MultisigOrder, secretKey: Buffer, provider?: ContractProvider): Promise<void>;
|
|
25
|
+
getOwnerIdByPubkey(publicKey: Buffer): number;
|
|
26
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Made by @Gusarich and @Miandic */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.MultisigWallet = void 0;
|
|
5
|
+
const crypto_1 = require("@ton/crypto");
|
|
6
|
+
const core_1 = require("@ton/core");
|
|
7
|
+
const MULTISIG_CODE = core_1.Cell.fromBase64('te6ccgECKwEABBgAART/APSkE/S88sgLAQIBIAIDAgFIBAUE2vIgxwCOgzDbPOCDCNcYIPkBAdMH2zwiwAAToVNxePQOb6Hyn9s8VBq6+RDyoAb0BCD5AQHTH1EYuvKq0z9wUwHwCgHCCAGDCryx8mhTFYBA9A5voSCYDqQgwgryZw7f+COqH1NAufJhVCOjU04gIyEiAgLMBgcCASAMDQIBIAgJAgFmCgsAA9GEAiPymAvHoHN9CYbZ5S7Z4BPHohwhJQAtAKkItdJEqCTItdKlwLUAdAT8ArobBKAATwhbpEx4CBukTDgAdAg10rDAJrUAvALyFjPFszJ4HHXI8gBzxb0AMmACASAODwIBIBQVARW77ZbVA0cFUg2zyCoCAUgQEQIBIBITAXOxHXQgwjXGCD5AQHTB4IB1MTtQ9hTIHj0Dm+h8p/XC/9eMfkQ8qCuAfQEIW6TW3Ey4PkBWNs8AaQBgJwA9rtqA6ADoAPoCAXoCEfyAgPyA3XlP+AXkegAA54tkwAAXrhlXP8EA1WZ2oexAAgEgFhcCASAYGQFRtyVbZ4YmRmpGEAgegc30McJNhFpAADMaYeYuAFrgJhwLb+4cC3d0bhAjAYm1WZtnhqvgb+2xxsoicAgej430pBHEoFpAADHDhBACGuQkuuBk9kUWE5kAOeLKhACQCB6IYFImHFImHFImXEA2YlzNijAjAgEgGhsAF7UGtc4QQDVZnah7EAIBIBwdAgOZOB4fARGsGm2eL4G2CUAjABWt+UEAzJV2oewYQAENqTbPBVfBYCMAFa3f3CCAarM7UPYgAiDbPALyZfgAUENxQxPbPO1UIyoACtP/0wcwBKDbPC+uUyCw8mISsQKkJbNTHLmwJYEA4aojoCi8sPJpggGGoPgBBZcCERACPj4wjo0REB/bPEDXePRDEL0F4lQWW1Rz51YQU9zbPFRxClR6vCQlKCYAIO1E0NMf0wfTB9M/9AT0BNEAXgGOGjDSAAHyo9MH0wdQA9cBIPkBBfkBFbrypFAD4GwhIddKqgIi10m68qtwVCATAAwByMv/ywcE1ts87VT4D3AlblOJvrGYEG4QLVDHXwePGzBUJANQTds8UFWgRlAQSRA6SwlTuds8UFQWf+L4AAeDJaGOLCaAQPSWb6UglDBTA7neII4WODk5CNIAAZfTBzAW8AcFkTDifwgHBZJsMeKz5jAGKicoKQBgcI4pA9CDCNcY0wf0BDBTFnj0Dm+h8qXXC/9URUT5EPKmrlIgsVIDvRShI27mbCIyAH5SML6OIF8D+ACTItdKmALTB9QC+wAC6DJwyMoAQBSAQPRDAvAHjhdxyMsAFMsHEssHWM8BWM8WQBOAQPRDAeIBII6KEEUQNEMA2zztVJJfBuIqABzIyx/LB8sHyz/0APQAyQ==');
|
|
8
|
+
class MultisigWallet {
|
|
9
|
+
constructor(publicKeys, workchain, walletId, k, opts) {
|
|
10
|
+
this.provider = null;
|
|
11
|
+
this.owners = core_1.Dictionary.empty();
|
|
12
|
+
this.workchain = workchain;
|
|
13
|
+
this.walletId = walletId;
|
|
14
|
+
this.k = k;
|
|
15
|
+
for (let i = 0; i < publicKeys.length; i += 1) {
|
|
16
|
+
this.owners.set(i, Buffer.concat([publicKeys[i], Buffer.alloc(1)]));
|
|
17
|
+
}
|
|
18
|
+
this.init = {
|
|
19
|
+
code: MULTISIG_CODE,
|
|
20
|
+
data: (0, core_1.beginCell)()
|
|
21
|
+
.storeUint(this.walletId, 32)
|
|
22
|
+
.storeUint(this.owners.size, 8)
|
|
23
|
+
.storeUint(this.k, 8)
|
|
24
|
+
.storeUint(0, 64)
|
|
25
|
+
.storeDict(this.owners, core_1.Dictionary.Keys.Uint(8), core_1.Dictionary.Values.Buffer(33))
|
|
26
|
+
.storeBit(0)
|
|
27
|
+
.endCell(),
|
|
28
|
+
};
|
|
29
|
+
this.address = opts?.address || (0, core_1.contractAddress)(workchain, this.init);
|
|
30
|
+
if (opts?.provider) {
|
|
31
|
+
this.provider = opts.provider;
|
|
32
|
+
}
|
|
33
|
+
else if (opts?.client) {
|
|
34
|
+
this.provider = opts.client.provider(this.address, {
|
|
35
|
+
code: this.init.code,
|
|
36
|
+
data: this.init.data,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
static async fromAddress(address, opts) {
|
|
41
|
+
let provider;
|
|
42
|
+
if (opts.provider) {
|
|
43
|
+
provider = opts.provider;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
if (!opts.client) {
|
|
47
|
+
throw Error('Either provider or client must be specified');
|
|
48
|
+
}
|
|
49
|
+
provider = opts.client.provider(address, {
|
|
50
|
+
code: null,
|
|
51
|
+
data: null,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const contractState = (await provider.getState()).state;
|
|
55
|
+
if (contractState.type !== 'active') {
|
|
56
|
+
throw Error('Contract must be active');
|
|
57
|
+
}
|
|
58
|
+
const data = core_1.Cell.fromBoc(contractState.data)[0].beginParse();
|
|
59
|
+
const walletId = data.loadUint(32);
|
|
60
|
+
data.skip(8);
|
|
61
|
+
const k = data.loadUint(8);
|
|
62
|
+
data.skip(64);
|
|
63
|
+
const owners = data.loadDict(core_1.Dictionary.Keys.Uint(8), core_1.Dictionary.Values.Buffer(33));
|
|
64
|
+
let publicKeys = [];
|
|
65
|
+
for (const [key, value] of owners) {
|
|
66
|
+
const publicKey = value.subarray(0, 32);
|
|
67
|
+
publicKeys.push(publicKey);
|
|
68
|
+
}
|
|
69
|
+
return new MultisigWallet(publicKeys, address.workChain, walletId, k, {
|
|
70
|
+
address,
|
|
71
|
+
provider,
|
|
72
|
+
client: opts.client,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
async deployExternal(provider) {
|
|
76
|
+
if (!provider && !this.provider) {
|
|
77
|
+
throw Error('you must specify provider if there is no such property in MultisigWallet instance');
|
|
78
|
+
}
|
|
79
|
+
if (!provider) {
|
|
80
|
+
provider = this.provider;
|
|
81
|
+
}
|
|
82
|
+
await provider.external(core_1.Cell.EMPTY);
|
|
83
|
+
}
|
|
84
|
+
async deployInternal(sender, value = 1000000000n) {
|
|
85
|
+
await sender.send({
|
|
86
|
+
sendMode: 3,
|
|
87
|
+
to: this.address,
|
|
88
|
+
value: value,
|
|
89
|
+
init: this.init,
|
|
90
|
+
body: core_1.Cell.EMPTY,
|
|
91
|
+
bounce: true,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
async sendOrder(order, secretKey, provider) {
|
|
95
|
+
if (!provider && !this.provider) {
|
|
96
|
+
throw Error('you must specify provider if there is no such property in MultisigWallet instance');
|
|
97
|
+
}
|
|
98
|
+
if (!provider) {
|
|
99
|
+
provider = this.provider;
|
|
100
|
+
}
|
|
101
|
+
let publicKey = (0, crypto_1.keyPairFromSecretKey)(secretKey).publicKey;
|
|
102
|
+
let ownerId = this.getOwnerIdByPubkey(publicKey);
|
|
103
|
+
let cell = order.toCell(ownerId);
|
|
104
|
+
let signature = (0, crypto_1.sign)(cell.hash(), secretKey);
|
|
105
|
+
cell = (0, core_1.beginCell)()
|
|
106
|
+
.storeBuffer(signature)
|
|
107
|
+
.storeSlice(cell.asSlice())
|
|
108
|
+
.endCell();
|
|
109
|
+
await provider.external(cell);
|
|
110
|
+
}
|
|
111
|
+
getOwnerIdByPubkey(publicKey) {
|
|
112
|
+
for (const [key, value] of this.owners) {
|
|
113
|
+
if (value.subarray(0, 32).equals(publicKey)) {
|
|
114
|
+
return key;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
throw Error('public key is not an owner');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
exports.MultisigWallet = MultisigWallet;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,230 @@
|
|
|
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 throw in sendOrder if there is no provider', 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 order = new MultisigOrderBuilder_1.MultisigOrderBuilder(123);
|
|
169
|
+
order.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 1000000000n, core_1.Cell.EMPTY), 3);
|
|
170
|
+
order.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address2'), 0n, (0, core_1.beginCell)().storeUint(3, 123).endCell()), 3);
|
|
171
|
+
order.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 2000000000n, core_1.Cell.EMPTY), 3);
|
|
172
|
+
expect(multisig.sendOrder(order.build(), secretKeys[3]))
|
|
173
|
+
.rejects.toThrowError('you must specify provider if there is no such property in MultisigWallet instance');
|
|
174
|
+
});
|
|
175
|
+
it('should accept orders with provider from property', async () => {
|
|
176
|
+
let multisig = new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 2);
|
|
177
|
+
multisig.provider = createProvider(multisig);
|
|
178
|
+
await multisig.deployInternal(treasure, 10000000000n);
|
|
179
|
+
await system.run();
|
|
180
|
+
let orderBuilder = new MultisigOrderBuilder_1.MultisigOrderBuilder(123);
|
|
181
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 1000000000n, core_1.Cell.EMPTY), 3);
|
|
182
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address2'), 0n, (0, core_1.beginCell)().storeUint(3, 123).endCell()), 3);
|
|
183
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 2000000000n, core_1.Cell.EMPTY), 3);
|
|
184
|
+
await multisig.sendOrder(orderBuilder.build(), secretKeys[3]);
|
|
185
|
+
let txs = await system.run();
|
|
186
|
+
expect(txs).toHaveLength(1);
|
|
187
|
+
if (txs[0].description.type == 'generic') {
|
|
188
|
+
expect(txs[0].description.aborted).toBeFalsy();
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
it('should accept multiple orders and send messages', async () => {
|
|
192
|
+
let multisig = new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 5);
|
|
193
|
+
let provider = createProvider(multisig);
|
|
194
|
+
await multisig.deployInternal(treasure, 10000000000n);
|
|
195
|
+
await system.run();
|
|
196
|
+
let orderBuilder = new MultisigOrderBuilder_1.MultisigOrderBuilder(123);
|
|
197
|
+
orderBuilder.addMessage(createInternalMessage(false, (0, emulator_1.testAddress)('address1'), 1000000000n, core_1.Cell.EMPTY), 3);
|
|
198
|
+
orderBuilder.addMessage(createInternalMessage(false, (0, emulator_1.testAddress)('address2'), 0n, (0, core_1.beginCell)().storeUint(3, 123).endCell()), 3);
|
|
199
|
+
orderBuilder.addMessage(createInternalMessage(true, (0, emulator_1.testAddress)('address1'), 2000000000n, core_1.Cell.EMPTY), 3);
|
|
200
|
+
let order = orderBuilder.build();
|
|
201
|
+
for (let i = 0; i < 4; i += 1) {
|
|
202
|
+
await multisig.sendOrder(order, secretKeys[i], provider);
|
|
203
|
+
await system.run();
|
|
204
|
+
}
|
|
205
|
+
await multisig.sendOrder(order, secretKeys[7], provider);
|
|
206
|
+
let txs = await system.run();
|
|
207
|
+
expect(txs).toHaveLength(5);
|
|
208
|
+
});
|
|
209
|
+
it('should accept orders with multiple signatures 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 < 5; i += 1) {
|
|
220
|
+
order.sign(i, secretKeys[i]);
|
|
221
|
+
}
|
|
222
|
+
await multisig.sendOrder(order, secretKeys[0], provider);
|
|
223
|
+
let txs = await system.run();
|
|
224
|
+
expect(txs).toHaveLength(5);
|
|
225
|
+
});
|
|
226
|
+
it('should throw in getOwnerIdByPubkey on invalid public key', () => {
|
|
227
|
+
let multisig = new MultisigWallet_1.MultisigWallet(publicKeys, 0, 123, 2);
|
|
228
|
+
expect(() => multisig.getOwnerIdByPubkey(Buffer.alloc(32))).toThrow('public key is not an owner');
|
|
229
|
+
});
|
|
230
|
+
});
|
|
@@ -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,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;
|