@ton/ton 15.3.1 → 16.0.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/dist/wallets/WalletContractV4.d.ts +2 -64
- package/dist/wallets/WalletContractV4.js +16 -104
- package/dist/wallets/signing/createWalletTransfer.d.ts +5 -4
- package/dist/wallets/signing/createWalletTransfer.js +2 -9
- package/dist/wallets/v4/WalletContractV4.d.ts +114 -0
- package/dist/wallets/v4/WalletContractV4.js +226 -0
- package/dist/wallets/v4/WalletContractV4.spec.js +157 -0
- package/dist/wallets/v4/WalletContractV4Actions.d.ts +37 -0
- package/dist/wallets/v4/WalletContractV4Actions.js +109 -0
- package/dist/wallets/v4/WalletContractV4Actions.spec.d.ts +1 -0
- package/dist/wallets/v4/WalletContractV4Actions.spec.js +74 -0
- package/dist/wallets/v5r1/WalletV5R1Actions.js +1 -1
- package/dist/wallets/v5r1/WalletV5R1Actions.spec.js +1 -1
- package/dist/wallets/v5r1/WalletV5R1WalletId.js +1 -1
- package/dist/wallets/v5r1/WalletV5R1WalletId.spec.js +31 -0
- package/package.json +3 -3
- package/dist/wallets/WalletContractV4.spec.js +0 -73
- /package/dist/wallets/{WalletContractV4.spec.d.ts → v4/WalletContractV4.spec.d.ts} +0 -0
|
@@ -1,64 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
*
|
|
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 { Address, Cell, Contract, ContractProvider, MessageRelaxed, Sender, SendMode } from "@ton/core";
|
|
9
|
-
import { Maybe } from "../utils/maybe";
|
|
10
|
-
import { SendArgsSignable, SendArgsSigned } from "./signing/singer";
|
|
11
|
-
export type WalletV4BasicSendArgs = {
|
|
12
|
-
seqno: number;
|
|
13
|
-
messages: MessageRelaxed[];
|
|
14
|
-
sendMode?: Maybe<SendMode>;
|
|
15
|
-
timeout?: Maybe<number>;
|
|
16
|
-
};
|
|
17
|
-
export type Wallet4SendArgsSigned = WalletV4BasicSendArgs & SendArgsSigned;
|
|
18
|
-
export type Wallet4SendArgsSignable = WalletV4BasicSendArgs & SendArgsSignable;
|
|
19
|
-
export declare class WalletContractV4 implements Contract {
|
|
20
|
-
static create(args: {
|
|
21
|
-
workchain: number;
|
|
22
|
-
publicKey: Buffer;
|
|
23
|
-
walletId?: Maybe<number>;
|
|
24
|
-
}): WalletContractV4;
|
|
25
|
-
readonly workchain: number;
|
|
26
|
-
readonly publicKey: Buffer;
|
|
27
|
-
readonly address: Address;
|
|
28
|
-
readonly walletId: number;
|
|
29
|
-
readonly init: {
|
|
30
|
-
data: Cell;
|
|
31
|
-
code: Cell;
|
|
32
|
-
};
|
|
33
|
-
private constructor();
|
|
34
|
-
/**
|
|
35
|
-
* Get Wallet Balance
|
|
36
|
-
*/
|
|
37
|
-
getBalance(provider: ContractProvider): Promise<bigint>;
|
|
38
|
-
/**
|
|
39
|
-
* Get Wallet Seqno
|
|
40
|
-
*/
|
|
41
|
-
getSeqno(provider: ContractProvider): Promise<number>;
|
|
42
|
-
/**
|
|
43
|
-
* Send signed transfer
|
|
44
|
-
*/
|
|
45
|
-
send(provider: ContractProvider, message: Cell): Promise<void>;
|
|
46
|
-
/**
|
|
47
|
-
* Sign and send transfer
|
|
48
|
-
*/
|
|
49
|
-
sendTransfer(provider: ContractProvider, args: {
|
|
50
|
-
seqno: number;
|
|
51
|
-
secretKey: Buffer;
|
|
52
|
-
messages: MessageRelaxed[];
|
|
53
|
-
sendMode?: Maybe<SendMode>;
|
|
54
|
-
timeout?: Maybe<number>;
|
|
55
|
-
}): Promise<void>;
|
|
56
|
-
/**
|
|
57
|
-
* Create signed transfer
|
|
58
|
-
*/
|
|
59
|
-
createTransfer<T extends Wallet4SendArgsSigned | Wallet4SendArgsSignable>(args: T): T extends Wallet4SendArgsSignable ? Promise<Cell> : Cell;
|
|
60
|
-
/**
|
|
61
|
-
* Create sender
|
|
62
|
-
*/
|
|
63
|
-
sender(provider: ContractProvider, secretKey: Buffer): Sender;
|
|
64
|
-
}
|
|
1
|
+
export * from './v4/WalletContractV4';
|
|
2
|
+
export * from './v4/WalletContractV4Actions';
|
|
@@ -1,106 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
9
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const createWalletTransfer_1 = require("./signing/createWalletTransfer");
|
|
13
|
-
class WalletContractV4 {
|
|
14
|
-
static create(args) {
|
|
15
|
-
return new WalletContractV4(args.workchain, args.publicKey, args.walletId);
|
|
16
|
-
}
|
|
17
|
-
constructor(workchain, publicKey, walletId) {
|
|
18
|
-
// Resolve parameters
|
|
19
|
-
this.workchain = workchain;
|
|
20
|
-
this.publicKey = publicKey;
|
|
21
|
-
if (walletId !== null && walletId !== undefined) {
|
|
22
|
-
this.walletId = walletId;
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
this.walletId = 698983191 + workchain;
|
|
26
|
-
}
|
|
27
|
-
// Build initial code and data
|
|
28
|
-
let code = core_1.Cell.fromBoc(Buffer.from('te6ccgECFAEAAtQAART/APSkE/S88sgLAQIBIAIDAgFIBAUE+PKDCNcYINMf0x/THwL4I7vyZO1E0NMf0x/T//QE0VFDuvKhUVG68qIF+QFUEGT5EPKj+AAkpMjLH1JAyx9SMMv/UhD0AMntVPgPAdMHIcAAn2xRkyDXSpbTB9QC+wDoMOAhwAHjACHAAuMAAcADkTDjDQOkyMsfEssfy/8QERITAubQAdDTAyFxsJJfBOAi10nBIJJfBOAC0x8hghBwbHVnvSKCEGRzdHK9sJJfBeAD+kAwIPpEAcjKB8v/ydDtRNCBAUDXIfQEMFyBAQj0Cm+hMbOSXwfgBdM/yCWCEHBsdWe6kjgw4w0DghBkc3RyupJfBuMNBgcCASAICQB4AfoA9AQw+CdvIjBQCqEhvvLgUIIQcGx1Z4MesXCAGFAEywUmzxZY+gIZ9ADLaRfLH1Jgyz8gyYBA+wAGAIpQBIEBCPRZMO1E0IEBQNcgyAHPFvQAye1UAXKwjiOCEGRzdHKDHrFwgBhQBcsFUAPPFiP6AhPLassfyz/JgED7AJJfA+ICASAKCwBZvSQrb2omhAgKBrkPoCGEcNQICEekk30pkQzmkD6f+YN4EoAbeBAUiYcVnzGEAgFYDA0AEbjJftRNDXCx+AA9sp37UTQgQFA1yH0BDACyMoHy//J0AGBAQj0Cm+hMYAIBIA4PABmtznaiaEAga5Drhf/AABmvHfaiaEAQa5DrhY/AAG7SB/oA1NQi+QAFyMoHFcv/ydB3dIAYyMsFywIizxZQBfoCFMtrEszMyXP7AMhAFIEBCPRR8qcCAHCBAQjXGPoA0z/IVCBHgQEI9FHyp4IQbm90ZXB0gBjIywXLAlAGzxZQBPoCFMtqEssfyz/Jc/sAAgBsgQEI1xj6ANM/MFIkgQEI9Fnyp4IQZHN0cnB0gBjIywXLAlAFzxZQA/oCE8tqyx8Syz/Jc/sAAAr0AMntVA==', 'base64'))[0];
|
|
29
|
-
let data = (0, core_1.beginCell)()
|
|
30
|
-
.storeUint(0, 32) // Seqno
|
|
31
|
-
.storeUint(this.walletId, 32)
|
|
32
|
-
.storeBuffer(this.publicKey)
|
|
33
|
-
.storeBit(0) // Empty plugins dict
|
|
34
|
-
.endCell();
|
|
35
|
-
this.init = { code, data };
|
|
36
|
-
this.address = (0, core_1.contractAddress)(workchain, { code, data });
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Get Wallet Balance
|
|
40
|
-
*/
|
|
41
|
-
async getBalance(provider) {
|
|
42
|
-
let state = await provider.getState();
|
|
43
|
-
return state.balance;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Get Wallet Seqno
|
|
47
|
-
*/
|
|
48
|
-
async getSeqno(provider) {
|
|
49
|
-
let state = await provider.getState();
|
|
50
|
-
if (state.state.type === 'active') {
|
|
51
|
-
let res = await provider.get('seqno', []);
|
|
52
|
-
return res.stack.readNumber();
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
return 0;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Send signed transfer
|
|
60
|
-
*/
|
|
61
|
-
async send(provider, message) {
|
|
62
|
-
await provider.external(message);
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Sign and send transfer
|
|
66
|
-
*/
|
|
67
|
-
async sendTransfer(provider, args) {
|
|
68
|
-
let transfer = this.createTransfer(args);
|
|
69
|
-
await this.send(provider, transfer);
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Create signed transfer
|
|
73
|
-
*/
|
|
74
|
-
createTransfer(args) {
|
|
75
|
-
return (0, createWalletTransfer_1.createWalletTransferV4)({
|
|
76
|
-
...args,
|
|
77
|
-
sendMode: args.sendMode ?? core_1.SendMode.PAY_GAS_SEPARATELY,
|
|
78
|
-
walletId: this.walletId
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Create sender
|
|
83
|
-
*/
|
|
84
|
-
sender(provider, secretKey) {
|
|
85
|
-
return {
|
|
86
|
-
send: async (args) => {
|
|
87
|
-
let seqno = await this.getSeqno(provider);
|
|
88
|
-
let transfer = this.createTransfer({
|
|
89
|
-
seqno,
|
|
90
|
-
secretKey,
|
|
91
|
-
sendMode: args.sendMode,
|
|
92
|
-
messages: [(0, core_1.internal)({
|
|
93
|
-
to: args.to,
|
|
94
|
-
value: args.value,
|
|
95
|
-
extracurrency: args.extracurrency,
|
|
96
|
-
init: args.init,
|
|
97
|
-
body: args.body,
|
|
98
|
-
bounce: args.bounce
|
|
99
|
-
})]
|
|
100
|
-
});
|
|
101
|
-
await this.send(provider, transfer);
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
exports.WalletContractV4 = WalletContractV4;
|
|
17
|
+
__exportStar(require("./v4/WalletContractV4"), exports);
|
|
18
|
+
__exportStar(require("./v4/WalletContractV4Actions"), exports);
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
import { Builder, Cell, MessageRelaxed, OutActionSendMsg } from "@ton/core";
|
|
9
9
|
import { Maybe } from "../../utils/maybe";
|
|
10
10
|
import { WalletV5BetaPackedCell, WalletV5BetaSendArgs, WalletV5BetaSendArgsExtensionAuth } from "../v5beta/WalletContractV5Beta";
|
|
11
|
-
import { Wallet4SendArgsSignable, Wallet4SendArgsSigned } from "../WalletContractV4";
|
|
12
11
|
import { WalletV3SendArgsSignable, WalletV3SendArgsSigned } from "../WalletContractV3Types";
|
|
13
12
|
import { OutActionExtended } from "../v5beta/WalletV5OutActions";
|
|
14
13
|
import { Wallet5VR1SendArgsExtensionAuth, WalletV5R1PackedCell, WalletV5R1SendArgs } from "../v5r1/WalletContractV5R1";
|
|
14
|
+
import { OutActionWalletV4, WalletV4SendArgs, WalletV4SendArgsSignable } from "../v4/WalletContractV4Actions";
|
|
15
15
|
export declare function createWalletTransferV1(args: {
|
|
16
16
|
seqno: number;
|
|
17
17
|
sendMode: number;
|
|
@@ -29,10 +29,11 @@ export declare function createWalletTransferV3<T extends WalletV3SendArgsSignabl
|
|
|
29
29
|
sendMode: number;
|
|
30
30
|
walletId: number;
|
|
31
31
|
}): T extends WalletV3SendArgsSignable ? Promise<Cell> : Cell;
|
|
32
|
-
export declare function createWalletTransferV4<T extends
|
|
33
|
-
|
|
32
|
+
export declare function createWalletTransferV4<T extends WalletV4SendArgs & {
|
|
33
|
+
action: OutActionWalletV4;
|
|
34
|
+
}>(args: T & {
|
|
34
35
|
walletId: number;
|
|
35
|
-
}): T extends
|
|
36
|
+
}): T extends WalletV4SendArgsSignable ? Promise<Cell> : Cell;
|
|
36
37
|
export declare function createWalletTransferV5Beta<T extends WalletV5BetaSendArgs>(args: T extends WalletV5BetaSendArgsExtensionAuth ? T & {
|
|
37
38
|
actions: (OutActionSendMsg | OutActionExtended)[];
|
|
38
39
|
} : T & {
|
|
@@ -20,6 +20,7 @@ const WalletV5BetaActions_1 = require("../v5beta/WalletV5BetaActions");
|
|
|
20
20
|
const singer_1 = require("./singer");
|
|
21
21
|
const WalletContractV5R1_1 = require("../v5r1/WalletContractV5R1");
|
|
22
22
|
const WalletV5R1Actions_1 = require("../v5r1/WalletV5R1Actions");
|
|
23
|
+
const WalletContractV4Actions_1 = require("../v4/WalletContractV4Actions");
|
|
23
24
|
function packSignatureToFront(signature, signingMessage) {
|
|
24
25
|
const body = (0, core_1.beginCell)()
|
|
25
26
|
.storeBuffer(signature)
|
|
@@ -104,10 +105,6 @@ function createWalletTransferV3(args) {
|
|
|
104
105
|
return (0, singer_1.signPayload)(args, signingMessage, packSignatureToFront);
|
|
105
106
|
}
|
|
106
107
|
function createWalletTransferV4(args) {
|
|
107
|
-
// Check number of messages
|
|
108
|
-
if (args.messages.length > 4) {
|
|
109
|
-
throw Error("Maximum number of messages in a single transfer is 4");
|
|
110
|
-
}
|
|
111
108
|
let signingMessage = (0, core_1.beginCell)()
|
|
112
109
|
.storeUint(args.walletId, 32);
|
|
113
110
|
if (args.seqno === 0) {
|
|
@@ -119,11 +116,7 @@ function createWalletTransferV4(args) {
|
|
|
119
116
|
signingMessage.storeUint(args.timeout || Math.floor(Date.now() / 1e3) + 60, 32); // Default timeout: 60 seconds
|
|
120
117
|
}
|
|
121
118
|
signingMessage.storeUint(args.seqno, 32);
|
|
122
|
-
signingMessage.
|
|
123
|
-
for (let m of args.messages) {
|
|
124
|
-
signingMessage.storeUint(args.sendMode, 8);
|
|
125
|
-
signingMessage.storeRef((0, core_1.beginCell)().store((0, core_1.storeMessageRelaxed)(m)));
|
|
126
|
-
}
|
|
119
|
+
signingMessage.store((0, WalletContractV4Actions_1.storeExtendedAction)(args.action));
|
|
127
120
|
return (0, singer_1.signPayload)(args, signingMessage, packSignatureToFront);
|
|
128
121
|
}
|
|
129
122
|
function createWalletTransferV5Beta(args) {
|
|
@@ -0,0 +1,114 @@
|
|
|
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 { Address, Cell, Contract, ContractProvider, MessageRelaxed, Sender, SendMode, StateInit } from "@ton/core";
|
|
9
|
+
import { Maybe } from "../../utils/maybe";
|
|
10
|
+
import { SendArgsSignable, SendArgsSigned } from "../signing/singer";
|
|
11
|
+
import { OutActionWalletV4, WalletV4SendArgs, WalletV4SendArgsSignable } from "./WalletContractV4Actions";
|
|
12
|
+
export type WalletV4BasicSendArgs = {
|
|
13
|
+
seqno: number;
|
|
14
|
+
messages: MessageRelaxed[];
|
|
15
|
+
sendMode?: Maybe<SendMode>;
|
|
16
|
+
timeout?: Maybe<number>;
|
|
17
|
+
};
|
|
18
|
+
export type Wallet4SendArgsSigned = WalletV4BasicSendArgs & SendArgsSigned;
|
|
19
|
+
export type Wallet4SendArgsSignable = WalletV4BasicSendArgs & SendArgsSignable;
|
|
20
|
+
export declare class WalletContractV4 implements Contract {
|
|
21
|
+
static create(args: {
|
|
22
|
+
workchain: number;
|
|
23
|
+
publicKey: Buffer;
|
|
24
|
+
walletId?: Maybe<number>;
|
|
25
|
+
}): WalletContractV4;
|
|
26
|
+
readonly workchain: number;
|
|
27
|
+
readonly publicKey: Buffer;
|
|
28
|
+
readonly address: Address;
|
|
29
|
+
readonly walletId: number;
|
|
30
|
+
readonly init: {
|
|
31
|
+
data: Cell;
|
|
32
|
+
code: Cell;
|
|
33
|
+
};
|
|
34
|
+
private constructor();
|
|
35
|
+
/**
|
|
36
|
+
* Get Wallet Balance
|
|
37
|
+
*/
|
|
38
|
+
getBalance(provider: ContractProvider): Promise<bigint>;
|
|
39
|
+
/**
|
|
40
|
+
* Get Wallet Seqno
|
|
41
|
+
*/
|
|
42
|
+
getSeqno(provider: ContractProvider): Promise<number>;
|
|
43
|
+
getIsPluginInstalled(provider: ContractProvider, pluginAddress: Address): Promise<boolean>;
|
|
44
|
+
getPluginsArray(provider: ContractProvider): Promise<Address[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Send signed transfer
|
|
47
|
+
*/
|
|
48
|
+
send(provider: ContractProvider, message: Cell): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Sign and send transfer
|
|
51
|
+
*/
|
|
52
|
+
sendTransfer(provider: ContractProvider, args: {
|
|
53
|
+
seqno: number;
|
|
54
|
+
secretKey: Buffer;
|
|
55
|
+
messages: MessageRelaxed[];
|
|
56
|
+
sendMode?: Maybe<SendMode>;
|
|
57
|
+
timeout?: Maybe<number>;
|
|
58
|
+
}): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Create signed transfer
|
|
61
|
+
*/
|
|
62
|
+
createTransfer<T extends Wallet4SendArgsSigned | Wallet4SendArgsSignable>(args: T): T extends SendArgsSignable ? Promise<Cell> : Cell;
|
|
63
|
+
sendRequest<T extends WalletV4SendArgs & {
|
|
64
|
+
action: OutActionWalletV4;
|
|
65
|
+
}>(provider: ContractProvider, args: T): Promise<void>;
|
|
66
|
+
createRequest<T extends WalletV4SendArgs & {
|
|
67
|
+
action: OutActionWalletV4;
|
|
68
|
+
}>(args: T): T extends WalletV4SendArgsSignable ? Promise<Cell> : Cell;
|
|
69
|
+
/**
|
|
70
|
+
* Create sender
|
|
71
|
+
*/
|
|
72
|
+
sender(provider: ContractProvider, secretKey: Buffer): Sender;
|
|
73
|
+
sendAddPlugin<T extends WalletV4SendArgs & {
|
|
74
|
+
address: Address;
|
|
75
|
+
forwardAmount: bigint;
|
|
76
|
+
queryId?: bigint;
|
|
77
|
+
}>(provider: ContractProvider, args: T): Promise<void>;
|
|
78
|
+
sendRemovePlugin<T extends WalletV4SendArgs & {
|
|
79
|
+
address: Address;
|
|
80
|
+
forwardAmount: bigint;
|
|
81
|
+
queryId?: bigint;
|
|
82
|
+
}>(provider: ContractProvider, args: T): Promise<void>;
|
|
83
|
+
sendAddAndDeployPlugin<T extends WalletV4SendArgs & {
|
|
84
|
+
workchain: number;
|
|
85
|
+
stateInit: StateInit;
|
|
86
|
+
body: Cell;
|
|
87
|
+
forwardAmount: bigint;
|
|
88
|
+
}>(provider: ContractProvider, args: T): Promise<void>;
|
|
89
|
+
createAddPlugin<T extends WalletV4SendArgs & {
|
|
90
|
+
address: Address;
|
|
91
|
+
forwardAmount: bigint;
|
|
92
|
+
queryId?: bigint;
|
|
93
|
+
}>(args: T): Cell | Promise<Cell>;
|
|
94
|
+
createRemovePlugin<T extends WalletV4SendArgs & {
|
|
95
|
+
address: Address;
|
|
96
|
+
forwardAmount: bigint;
|
|
97
|
+
queryId?: bigint;
|
|
98
|
+
}>(args: T): Cell | Promise<Cell>;
|
|
99
|
+
createAddAndDeployPlugin<T extends WalletV4SendArgs & {
|
|
100
|
+
workchain: number;
|
|
101
|
+
stateInit: StateInit;
|
|
102
|
+
body: Cell;
|
|
103
|
+
forwardAmount: bigint;
|
|
104
|
+
}>(args: T): Cell | Promise<Cell>;
|
|
105
|
+
sendPluginRequestFunds(provider: ContractProvider, sender: Sender, args: {
|
|
106
|
+
forwardAmount: bigint;
|
|
107
|
+
toncoinsToWithdraw: bigint;
|
|
108
|
+
queryId?: bigint;
|
|
109
|
+
sendMode?: SendMode;
|
|
110
|
+
}): Promise<void>;
|
|
111
|
+
private createPluginRequestFundsMessage;
|
|
112
|
+
sendPluginRemovePlugin(provider: ContractProvider, sender: Sender, amount: bigint, queryId?: bigint): Promise<void>;
|
|
113
|
+
private createPluginRemovePluginMessage;
|
|
114
|
+
}
|
|
@@ -0,0 +1,226 @@
|
|
|
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.WalletContractV4 = void 0;
|
|
11
|
+
const core_1 = require("@ton/core");
|
|
12
|
+
const createWalletTransfer_1 = require("../signing/createWalletTransfer");
|
|
13
|
+
class WalletContractV4 {
|
|
14
|
+
static create(args) {
|
|
15
|
+
return new WalletContractV4(args.workchain, args.publicKey, args.walletId);
|
|
16
|
+
}
|
|
17
|
+
constructor(workchain, publicKey, walletId) {
|
|
18
|
+
// Resolve parameters
|
|
19
|
+
this.workchain = workchain;
|
|
20
|
+
this.publicKey = publicKey;
|
|
21
|
+
if (walletId !== null && walletId !== undefined) {
|
|
22
|
+
this.walletId = walletId;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
this.walletId = 698983191 + workchain;
|
|
26
|
+
}
|
|
27
|
+
// Build initial code and data
|
|
28
|
+
let code = core_1.Cell.fromBoc(Buffer.from('te6ccgECFAEAAtQAART/APSkE/S88sgLAQIBIAIDAgFIBAUE+PKDCNcYINMf0x/THwL4I7vyZO1E0NMf0x/T//QE0VFDuvKhUVG68qIF+QFUEGT5EPKj+AAkpMjLH1JAyx9SMMv/UhD0AMntVPgPAdMHIcAAn2xRkyDXSpbTB9QC+wDoMOAhwAHjACHAAuMAAcADkTDjDQOkyMsfEssfy/8QERITAubQAdDTAyFxsJJfBOAi10nBIJJfBOAC0x8hghBwbHVnvSKCEGRzdHK9sJJfBeAD+kAwIPpEAcjKB8v/ydDtRNCBAUDXIfQEMFyBAQj0Cm+hMbOSXwfgBdM/yCWCEHBsdWe6kjgw4w0DghBkc3RyupJfBuMNBgcCASAICQB4AfoA9AQw+CdvIjBQCqEhvvLgUIIQcGx1Z4MesXCAGFAEywUmzxZY+gIZ9ADLaRfLH1Jgyz8gyYBA+wAGAIpQBIEBCPRZMO1E0IEBQNcgyAHPFvQAye1UAXKwjiOCEGRzdHKDHrFwgBhQBcsFUAPPFiP6AhPLassfyz/JgED7AJJfA+ICASAKCwBZvSQrb2omhAgKBrkPoCGEcNQICEekk30pkQzmkD6f+YN4EoAbeBAUiYcVnzGEAgFYDA0AEbjJftRNDXCx+AA9sp37UTQgQFA1yH0BDACyMoHy//J0AGBAQj0Cm+hMYAIBIA4PABmtznaiaEAga5Drhf/AABmvHfaiaEAQa5DrhY/AAG7SB/oA1NQi+QAFyMoHFcv/ydB3dIAYyMsFywIizxZQBfoCFMtrEszMyXP7AMhAFIEBCPRR8qcCAHCBAQjXGPoA0z/IVCBHgQEI9FHyp4IQbm90ZXB0gBjIywXLAlAGzxZQBPoCFMtqEssfyz/Jc/sAAgBsgQEI1xj6ANM/MFIkgQEI9Fnyp4IQZHN0cnB0gBjIywXLAlAFzxZQA/oCE8tqyx8Syz/Jc/sAAAr0AMntVA==', 'base64'))[0];
|
|
29
|
+
let data = (0, core_1.beginCell)()
|
|
30
|
+
.storeUint(0, 32) // Seqno
|
|
31
|
+
.storeUint(this.walletId, 32)
|
|
32
|
+
.storeBuffer(this.publicKey)
|
|
33
|
+
.storeBit(0) // Empty plugins dict
|
|
34
|
+
.endCell();
|
|
35
|
+
this.init = { code, data };
|
|
36
|
+
this.address = (0, core_1.contractAddress)(workchain, { code, data });
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get Wallet Balance
|
|
40
|
+
*/
|
|
41
|
+
async getBalance(provider) {
|
|
42
|
+
let state = await provider.getState();
|
|
43
|
+
return state.balance;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get Wallet Seqno
|
|
47
|
+
*/
|
|
48
|
+
async getSeqno(provider) {
|
|
49
|
+
let state = await provider.getState();
|
|
50
|
+
if (state.state.type === 'active') {
|
|
51
|
+
let res = await provider.get('seqno', []);
|
|
52
|
+
return res.stack.readNumber();
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
return 0;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async getIsPluginInstalled(provider, pluginAddress) {
|
|
59
|
+
const state = await provider.getState();
|
|
60
|
+
if (state.state.type !== 'active') {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
const wc = BigInt(pluginAddress.workChain);
|
|
64
|
+
const addrHash = BigInt('0x' + pluginAddress.hash.toString('hex'));
|
|
65
|
+
const res = await provider.get('is_plugin_installed', [
|
|
66
|
+
{ type: 'int', value: wc },
|
|
67
|
+
{ type: 'int', value: addrHash }
|
|
68
|
+
]);
|
|
69
|
+
return res.stack.readBoolean();
|
|
70
|
+
}
|
|
71
|
+
async getPluginsArray(provider) {
|
|
72
|
+
const state = await provider.getState();
|
|
73
|
+
if (state.state.type !== 'active') {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
const res = await provider.get('get_plugin_list', []);
|
|
77
|
+
return res.stack.readLispList().map(item => {
|
|
78
|
+
if (item.type !== 'tuple') {
|
|
79
|
+
throw Error('Not a tuple');
|
|
80
|
+
}
|
|
81
|
+
const entry = new core_1.TupleReader(item.items);
|
|
82
|
+
const workchain = entry.readNumber();
|
|
83
|
+
const addrHash = entry.readBigNumber();
|
|
84
|
+
const addressHex = addrHash.toString(16).padStart(64, '0');
|
|
85
|
+
return core_1.Address.parseRaw(`${workchain}:${addressHex}`);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Send signed transfer
|
|
90
|
+
*/
|
|
91
|
+
async send(provider, message) {
|
|
92
|
+
await provider.external(message);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Sign and send transfer
|
|
96
|
+
*/
|
|
97
|
+
async sendTransfer(provider, args) {
|
|
98
|
+
let transfer = this.createTransfer(args);
|
|
99
|
+
await this.send(provider, transfer);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Create signed transfer
|
|
103
|
+
*/
|
|
104
|
+
createTransfer(args) {
|
|
105
|
+
return this.createRequest({
|
|
106
|
+
seqno: args.seqno,
|
|
107
|
+
timeout: args.timeout,
|
|
108
|
+
action: {
|
|
109
|
+
type: 'sendMsg',
|
|
110
|
+
messages: args.messages,
|
|
111
|
+
sendMode: args.sendMode,
|
|
112
|
+
},
|
|
113
|
+
...('secretKey' in args
|
|
114
|
+
? { secretKey: args.secretKey }
|
|
115
|
+
: { signer: args.signer })
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
async sendRequest(provider, args) {
|
|
119
|
+
const action = await this.createRequest(args);
|
|
120
|
+
await this.send(provider, action);
|
|
121
|
+
}
|
|
122
|
+
createRequest(args) {
|
|
123
|
+
return (0, createWalletTransfer_1.createWalletTransferV4)({
|
|
124
|
+
...args,
|
|
125
|
+
walletId: this.walletId
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Create sender
|
|
130
|
+
*/
|
|
131
|
+
sender(provider, secretKey) {
|
|
132
|
+
return {
|
|
133
|
+
send: async (args) => {
|
|
134
|
+
let seqno = await this.getSeqno(provider);
|
|
135
|
+
let transfer = this.createTransfer({
|
|
136
|
+
seqno,
|
|
137
|
+
secretKey,
|
|
138
|
+
sendMode: args.sendMode,
|
|
139
|
+
messages: [(0, core_1.internal)({
|
|
140
|
+
to: args.to,
|
|
141
|
+
value: args.value,
|
|
142
|
+
extracurrency: args.extracurrency,
|
|
143
|
+
init: args.init,
|
|
144
|
+
body: args.body,
|
|
145
|
+
bounce: args.bounce
|
|
146
|
+
})]
|
|
147
|
+
});
|
|
148
|
+
await this.send(provider, transfer);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
async sendAddPlugin(provider, args) {
|
|
153
|
+
const request = await this.createAddPlugin(args);
|
|
154
|
+
return await this.send(provider, request);
|
|
155
|
+
}
|
|
156
|
+
async sendRemovePlugin(provider, args) {
|
|
157
|
+
const request = await this.createRemovePlugin(args);
|
|
158
|
+
return await this.send(provider, request);
|
|
159
|
+
}
|
|
160
|
+
async sendAddAndDeployPlugin(provider, args) {
|
|
161
|
+
const request = await this.createAddAndDeployPlugin(args);
|
|
162
|
+
return await this.send(provider, request);
|
|
163
|
+
}
|
|
164
|
+
createAddPlugin(args) {
|
|
165
|
+
return this.createRequest({
|
|
166
|
+
action: {
|
|
167
|
+
type: 'addPlugin',
|
|
168
|
+
address: args.address,
|
|
169
|
+
forwardAmount: args.forwardAmount,
|
|
170
|
+
queryId: args.queryId,
|
|
171
|
+
},
|
|
172
|
+
...args
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
createRemovePlugin(args) {
|
|
176
|
+
return this.createRequest({
|
|
177
|
+
action: {
|
|
178
|
+
type: 'removePlugin',
|
|
179
|
+
address: args.address,
|
|
180
|
+
forwardAmount: args.forwardAmount,
|
|
181
|
+
queryId: args.queryId,
|
|
182
|
+
},
|
|
183
|
+
...args
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
createAddAndDeployPlugin(args) {
|
|
187
|
+
return this.createRequest({
|
|
188
|
+
action: {
|
|
189
|
+
type: 'addAndDeployPlugin',
|
|
190
|
+
workchain: args.workchain,
|
|
191
|
+
stateInit: args.stateInit,
|
|
192
|
+
body: args.body,
|
|
193
|
+
forwardAmount: args.forwardAmount
|
|
194
|
+
},
|
|
195
|
+
...args
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
async sendPluginRequestFunds(provider, sender, args) {
|
|
199
|
+
await provider.internal(sender, {
|
|
200
|
+
value: args.forwardAmount,
|
|
201
|
+
body: this.createPluginRequestFundsMessage(args),
|
|
202
|
+
sendMode: args.sendMode
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
createPluginRequestFundsMessage(args) {
|
|
206
|
+
return (0, core_1.beginCell)()
|
|
207
|
+
.storeUint(0x706c7567, 32)
|
|
208
|
+
.storeUint(args.queryId ?? 0, 64)
|
|
209
|
+
.storeCoins(args.toncoinsToWithdraw)
|
|
210
|
+
.storeDict(null)
|
|
211
|
+
.endCell();
|
|
212
|
+
}
|
|
213
|
+
async sendPluginRemovePlugin(provider, sender, amount, queryId) {
|
|
214
|
+
await provider.internal(sender, {
|
|
215
|
+
value: amount,
|
|
216
|
+
body: this.createPluginRemovePluginMessage(queryId),
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
createPluginRemovePluginMessage(queryId) {
|
|
220
|
+
return (0, core_1.beginCell)()
|
|
221
|
+
.storeUint(0x64737472, 32)
|
|
222
|
+
.storeUint(queryId ?? 0, 64)
|
|
223
|
+
.endCell();
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
exports.WalletContractV4 = WalletContractV4;
|
|
@@ -0,0 +1,157 @@
|
|
|
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
|
+
const randomTestKey_1 = require("../../utils/randomTestKey");
|
|
11
|
+
const testWallets_1 = require("../../utils/testWallets");
|
|
12
|
+
const WalletContractV4_1 = require("./WalletContractV4");
|
|
13
|
+
const createTestClient4_1 = require("../../utils/createTestClient4");
|
|
14
|
+
const core_1 = require("@ton/core");
|
|
15
|
+
describe('WalletContractV4', () => {
|
|
16
|
+
it('should has balance and correct address', async () => {
|
|
17
|
+
// Create contract
|
|
18
|
+
let client = (0, createTestClient4_1.createTestClient4)();
|
|
19
|
+
let key = (0, randomTestKey_1.randomTestKey)('v4-treasure');
|
|
20
|
+
let contract = client.open(WalletContractV4_1.WalletContractV4.create({ workchain: 0, publicKey: key.publicKey }));
|
|
21
|
+
let balance = await contract.getBalance();
|
|
22
|
+
// Check parameters
|
|
23
|
+
expect(contract.address.equals(core_1.Address.parse('EQDnBF4JTFKHTYjulEJyNd4dstLGH1m51UrLdu01_tw4z2Au'))).toBe(true);
|
|
24
|
+
expect(balance > 0n).toBe(true);
|
|
25
|
+
});
|
|
26
|
+
it('should perform transfer', async () => {
|
|
27
|
+
// Create contract
|
|
28
|
+
let client = (0, createTestClient4_1.createTestClient4)();
|
|
29
|
+
let key = (0, randomTestKey_1.randomTestKey)('v4-treasure');
|
|
30
|
+
let contract = client.open(WalletContractV4_1.WalletContractV4.create({ workchain: 0, publicKey: key.publicKey }));
|
|
31
|
+
// Prepare transfer
|
|
32
|
+
let seqno = await contract.getSeqno();
|
|
33
|
+
let transfer = contract.createTransfer({
|
|
34
|
+
seqno,
|
|
35
|
+
secretKey: key.secretKey,
|
|
36
|
+
messages: [(0, core_1.internal)({
|
|
37
|
+
to: 'kQD6oPnzaaAMRW24R8F0_nlSsJQni0cGHntR027eT9_sgtwt',
|
|
38
|
+
value: '0.1',
|
|
39
|
+
body: 'Hello world: 1'
|
|
40
|
+
}), (0, core_1.internal)({
|
|
41
|
+
to: 'kQD6oPnzaaAMRW24R8F0_nlSsJQni0cGHntR027eT9_sgtwt',
|
|
42
|
+
value: '0.1',
|
|
43
|
+
body: 'Hello world: 2'
|
|
44
|
+
})]
|
|
45
|
+
});
|
|
46
|
+
// Perform transfer
|
|
47
|
+
await contract.send(transfer);
|
|
48
|
+
// Awaiting update
|
|
49
|
+
await (0, testWallets_1.tillNextSeqno)(contract, seqno);
|
|
50
|
+
});
|
|
51
|
+
it('should perform extra currency transfer', async () => {
|
|
52
|
+
// Create contract
|
|
53
|
+
let client = (0, createTestClient4_1.createTestClient4)();
|
|
54
|
+
let key = (0, randomTestKey_1.randomTestKey)('v4-treasure');
|
|
55
|
+
let contract = client.open(WalletContractV4_1.WalletContractV4.create({ workchain: 0, publicKey: key.publicKey }));
|
|
56
|
+
// Prepare transfer
|
|
57
|
+
let seqno = await contract.getSeqno();
|
|
58
|
+
let transfer = contract.createTransfer({
|
|
59
|
+
seqno,
|
|
60
|
+
secretKey: key.secretKey,
|
|
61
|
+
messages: [(0, core_1.internal)({
|
|
62
|
+
to: 'kQD6oPnzaaAMRW24R8F0_nlSsJQni0cGHntR027eT9_sgtwt',
|
|
63
|
+
value: '0.01',
|
|
64
|
+
extracurrency: { 100: BigInt(10 ** 6) },
|
|
65
|
+
body: 'Hello extra currency v4'
|
|
66
|
+
})]
|
|
67
|
+
});
|
|
68
|
+
// Perform transfer
|
|
69
|
+
await contract.send(transfer);
|
|
70
|
+
// Awaiting update
|
|
71
|
+
await (0, testWallets_1.tillNextSeqno)(contract, seqno);
|
|
72
|
+
});
|
|
73
|
+
describe('plugins', () => {
|
|
74
|
+
let client;
|
|
75
|
+
let walletKey;
|
|
76
|
+
let contract;
|
|
77
|
+
let randomAddress;
|
|
78
|
+
let pluginKey;
|
|
79
|
+
let pluginContract;
|
|
80
|
+
beforeEach(() => {
|
|
81
|
+
client = (0, createTestClient4_1.createTestClient4)();
|
|
82
|
+
walletKey = (0, randomTestKey_1.randomTestKey)('v4-treasure');
|
|
83
|
+
contract = client.open(WalletContractV4_1.WalletContractV4.create({ workchain: 0, publicKey: walletKey.publicKey }));
|
|
84
|
+
pluginContract = client.open(WalletContractV4_1.WalletContractV4.create({ workchain: 0, publicKey: walletKey.publicKey }));
|
|
85
|
+
randomAddress = WalletContractV4_1.WalletContractV4.create({
|
|
86
|
+
workchain: 0,
|
|
87
|
+
publicKey: (0, randomTestKey_1.randomTestKey)('v4-test-plugin').publicKey
|
|
88
|
+
}).address;
|
|
89
|
+
});
|
|
90
|
+
it('should install plugin', async () => {
|
|
91
|
+
let seqno = await contract.getSeqno();
|
|
92
|
+
await contract.sendRequest({
|
|
93
|
+
seqno: await contract.getSeqno(),
|
|
94
|
+
secretKey: walletKey.secretKey,
|
|
95
|
+
action: {
|
|
96
|
+
type: 'addPlugin',
|
|
97
|
+
address: randomAddress,
|
|
98
|
+
forwardAmount: (0, core_1.toNano)('0.01'),
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
await (0, testWallets_1.tillNextSeqno)(contract, seqno);
|
|
102
|
+
});
|
|
103
|
+
it('should return plugin in get methods', async () => {
|
|
104
|
+
expect(await contract.getIsPluginInstalled(randomAddress)).toBeTruthy();
|
|
105
|
+
const plugins = await contract.getPluginsArray();
|
|
106
|
+
expect(plugins.find(plugin => plugin.equals(randomAddress))).toBeTruthy();
|
|
107
|
+
});
|
|
108
|
+
it('should uninstall plugin', async () => {
|
|
109
|
+
let seqno = await contract.getSeqno();
|
|
110
|
+
await contract.sendRequest({
|
|
111
|
+
seqno: await contract.getSeqno(),
|
|
112
|
+
secretKey: walletKey.secretKey,
|
|
113
|
+
action: {
|
|
114
|
+
type: 'removePlugin',
|
|
115
|
+
address: randomAddress,
|
|
116
|
+
forwardAmount: (0, core_1.toNano)('0.01'),
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
await (0, testWallets_1.tillNextSeqno)(contract, seqno);
|
|
120
|
+
});
|
|
121
|
+
it('should return plugin in get methods', async () => {
|
|
122
|
+
expect(await contract.getIsPluginInstalled(randomAddress)).toBeFalsy();
|
|
123
|
+
const plugins = await contract.getPluginsArray();
|
|
124
|
+
plugins.forEach(plugin => {
|
|
125
|
+
expect(plugin.equals(randomAddress)).toBeFalsy();
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
it('should install and deploy plugin', async () => {
|
|
129
|
+
let seqno = await contract.getSeqno();
|
|
130
|
+
await contract.sendRequest({
|
|
131
|
+
seqno: await contract.getSeqno(),
|
|
132
|
+
secretKey: walletKey.secretKey,
|
|
133
|
+
action: {
|
|
134
|
+
type: 'addAndDeployPlugin',
|
|
135
|
+
workchain: 0,
|
|
136
|
+
stateInit: pluginContract.init,
|
|
137
|
+
body: (0, core_1.beginCell)().endCell(),
|
|
138
|
+
forwardAmount: (0, core_1.toNano)('0.1'),
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
await (0, testWallets_1.tillNextSeqno)(contract, seqno);
|
|
142
|
+
});
|
|
143
|
+
it('should withdraw funds by plugin request', async () => {
|
|
144
|
+
let seqno = await contract.getSeqno();
|
|
145
|
+
await pluginContract.sendPluginRequestFunds(pluginContract.sender(walletKey.secretKey), {
|
|
146
|
+
forwardAmount: (0, core_1.toNano)('0.01'),
|
|
147
|
+
toncoinsToWithdraw: (0, core_1.toNano)('0.05')
|
|
148
|
+
});
|
|
149
|
+
await (0, testWallets_1.tillNextSeqno)(contract, seqno);
|
|
150
|
+
});
|
|
151
|
+
it('should delete plugin by plugin request', async () => {
|
|
152
|
+
let seqno = await pluginContract.getSeqno();
|
|
153
|
+
await pluginContract.sendPluginRemovePlugin(pluginContract.sender(walletKey.secretKey), (0, core_1.toNano)('0.01'));
|
|
154
|
+
await (0, testWallets_1.tillNextSeqno)(contract, seqno);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Maybe } from "../../utils/maybe";
|
|
2
|
+
import { Address, Builder, Cell, MessageRelaxed, SendMode, StateInit, Slice } from "@ton/core";
|
|
3
|
+
import { SendArgsSignable, SendArgsSigned } from "../signing/singer";
|
|
4
|
+
export type WalletV4ExtendedSendArgs = {
|
|
5
|
+
seqno: number;
|
|
6
|
+
timeout?: Maybe<number>;
|
|
7
|
+
};
|
|
8
|
+
export interface OutActionSendMsg {
|
|
9
|
+
type: 'sendMsg';
|
|
10
|
+
messages: MessageRelaxed[];
|
|
11
|
+
sendMode?: Maybe<SendMode>;
|
|
12
|
+
}
|
|
13
|
+
export interface OutActionAddAndDeployPlugin {
|
|
14
|
+
type: 'addAndDeployPlugin';
|
|
15
|
+
workchain: number;
|
|
16
|
+
stateInit: StateInit;
|
|
17
|
+
body: Cell;
|
|
18
|
+
forwardAmount: bigint;
|
|
19
|
+
}
|
|
20
|
+
export interface OutActionAddPlugin {
|
|
21
|
+
type: 'addPlugin';
|
|
22
|
+
address: Address;
|
|
23
|
+
forwardAmount: bigint;
|
|
24
|
+
queryId?: bigint;
|
|
25
|
+
}
|
|
26
|
+
export interface OutActionRemovePlugin {
|
|
27
|
+
type: 'removePlugin';
|
|
28
|
+
address: Address;
|
|
29
|
+
forwardAmount: bigint;
|
|
30
|
+
queryId?: bigint;
|
|
31
|
+
}
|
|
32
|
+
export type OutActionWalletV4 = OutActionSendMsg | OutActionAddAndDeployPlugin | OutActionAddPlugin | OutActionRemovePlugin;
|
|
33
|
+
export type WalletV4SendArgsSigned = WalletV4ExtendedSendArgs & SendArgsSigned;
|
|
34
|
+
export type WalletV4SendArgsSignable = WalletV4ExtendedSendArgs & SendArgsSignable;
|
|
35
|
+
export type WalletV4SendArgs = WalletV4SendArgsSigned | WalletV4SendArgsSignable;
|
|
36
|
+
export declare function storeExtendedAction(action: OutActionWalletV4): (builder: Builder) => void;
|
|
37
|
+
export declare function loadExtendedAction(slice: Slice): OutActionWalletV4;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.storeExtendedAction = storeExtendedAction;
|
|
4
|
+
exports.loadExtendedAction = loadExtendedAction;
|
|
5
|
+
const core_1 = require("@ton/core");
|
|
6
|
+
function storeExtendedAction(action) {
|
|
7
|
+
return (builder) => {
|
|
8
|
+
switch (action.type) {
|
|
9
|
+
case 'sendMsg':
|
|
10
|
+
builder.storeUint(0, 8);
|
|
11
|
+
for (let m of action.messages) {
|
|
12
|
+
builder.storeUint(action.sendMode ?? core_1.SendMode.NONE, 8);
|
|
13
|
+
builder.storeRef((0, core_1.beginCell)().store((0, core_1.storeMessageRelaxed)(m)));
|
|
14
|
+
}
|
|
15
|
+
break;
|
|
16
|
+
case 'addAndDeployPlugin':
|
|
17
|
+
builder.storeUint(1, 8);
|
|
18
|
+
builder.storeInt(action.workchain, 8);
|
|
19
|
+
builder.storeCoins(action.forwardAmount);
|
|
20
|
+
builder.storeRef((0, core_1.beginCell)().store((0, core_1.storeStateInit)(action.stateInit)));
|
|
21
|
+
builder.storeRef(action.body);
|
|
22
|
+
break;
|
|
23
|
+
case 'addPlugin':
|
|
24
|
+
builder.storeUint(2, 8);
|
|
25
|
+
builder.storeInt(action.address.workChain, 8);
|
|
26
|
+
builder.storeBuffer(action.address.hash);
|
|
27
|
+
builder.storeCoins(action.forwardAmount);
|
|
28
|
+
builder.storeUint(action.queryId ?? 0n, 64);
|
|
29
|
+
break;
|
|
30
|
+
case 'removePlugin':
|
|
31
|
+
builder.storeUint(3, 8);
|
|
32
|
+
builder.storeInt(action.address.workChain, 8);
|
|
33
|
+
builder.storeBuffer(action.address.hash);
|
|
34
|
+
builder.storeCoins(action.forwardAmount);
|
|
35
|
+
builder.storeUint(action.queryId ?? 0n, 64);
|
|
36
|
+
break;
|
|
37
|
+
default:
|
|
38
|
+
throw new Error(`Unsupported plugin action`);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function loadExtendedAction(slice) {
|
|
43
|
+
const actionType = slice.loadUint(8);
|
|
44
|
+
switch (actionType) {
|
|
45
|
+
case 0: {
|
|
46
|
+
const messages = [];
|
|
47
|
+
let sendModeValue = undefined;
|
|
48
|
+
while (slice.remainingRefs > 0) {
|
|
49
|
+
if (slice.remainingBits < 8) {
|
|
50
|
+
throw new Error('Invalid sendMsg action: insufficient bits for send mode');
|
|
51
|
+
}
|
|
52
|
+
const mode = slice.loadUint(8);
|
|
53
|
+
const messageCell = slice.loadRef();
|
|
54
|
+
const message = (0, core_1.loadMessageRelaxed)(messageCell.beginParse());
|
|
55
|
+
if (sendModeValue === undefined) {
|
|
56
|
+
sendModeValue = mode;
|
|
57
|
+
}
|
|
58
|
+
else if (sendModeValue !== mode) {
|
|
59
|
+
throw new Error('Invalid sendMsg action: mixed send modes are not supported');
|
|
60
|
+
}
|
|
61
|
+
messages.push(message);
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
type: 'sendMsg',
|
|
65
|
+
messages,
|
|
66
|
+
sendMode: sendModeValue,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
case 1: {
|
|
70
|
+
const workchain = slice.loadInt(8);
|
|
71
|
+
const forwardAmount = slice.loadCoins();
|
|
72
|
+
const stateInit = (0, core_1.loadStateInit)(slice.loadRef().beginParse());
|
|
73
|
+
const body = slice.loadRef();
|
|
74
|
+
return {
|
|
75
|
+
type: 'addAndDeployPlugin',
|
|
76
|
+
workchain,
|
|
77
|
+
stateInit,
|
|
78
|
+
body,
|
|
79
|
+
forwardAmount,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
case 2: {
|
|
83
|
+
const workchain = slice.loadInt(8);
|
|
84
|
+
const hash = slice.loadBuffer(32);
|
|
85
|
+
const forwardAmount = slice.loadCoins();
|
|
86
|
+
const queryId = slice.loadUintBig(64);
|
|
87
|
+
return {
|
|
88
|
+
type: 'addPlugin',
|
|
89
|
+
address: new core_1.Address(workchain, hash),
|
|
90
|
+
forwardAmount,
|
|
91
|
+
queryId: queryId === 0n ? undefined : queryId,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
case 3: {
|
|
95
|
+
const workchain = slice.loadInt(8);
|
|
96
|
+
const hash = slice.loadBuffer(32);
|
|
97
|
+
const forwardAmount = slice.loadCoins();
|
|
98
|
+
const queryId = slice.loadUintBig(64);
|
|
99
|
+
return {
|
|
100
|
+
type: 'removePlugin',
|
|
101
|
+
address: new core_1.Address(workchain, hash),
|
|
102
|
+
forwardAmount,
|
|
103
|
+
queryId: queryId === 0n ? undefined : queryId,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
default:
|
|
107
|
+
throw new Error(`Unsupported action with opcode ${actionType}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@ton/core");
|
|
4
|
+
const WalletContractV4Actions_1 = require("./WalletContractV4Actions");
|
|
5
|
+
describe('Wallet V5R1 actions', () => {
|
|
6
|
+
it('should serialize and deserialize OutActionSendMsg', async () => {
|
|
7
|
+
const msg = {
|
|
8
|
+
type: 'sendMsg',
|
|
9
|
+
messages: [(0, core_1.internal)({
|
|
10
|
+
to: new core_1.Address(0, Buffer.alloc(32, 0xaa)),
|
|
11
|
+
value: '0.001',
|
|
12
|
+
})],
|
|
13
|
+
sendMode: core_1.SendMode.PAY_GAS_SEPARATELY,
|
|
14
|
+
};
|
|
15
|
+
const serialized = (0, core_1.beginCell)().store((0, WalletContractV4Actions_1.storeExtendedAction)(msg)).endCell();
|
|
16
|
+
const deserialized = (0, WalletContractV4Actions_1.loadExtendedAction)(serialized.beginParse());
|
|
17
|
+
if (deserialized.type !== 'sendMsg')
|
|
18
|
+
throw new Error();
|
|
19
|
+
expect(deserialized.messages.length).toEqual(msg.messages.length);
|
|
20
|
+
expect(deserialized.messages[0].info.dest.toString()).toEqual(msg.messages[0].info.dest.toString());
|
|
21
|
+
expect(deserialized.sendMode).toEqual(msg.sendMode);
|
|
22
|
+
});
|
|
23
|
+
it('should serialize and deserialize OutActionAddAndDeployPlugin', () => {
|
|
24
|
+
const stateInit = {
|
|
25
|
+
code: (0, core_1.beginCell)().storeUint(0xa, 4).endCell(),
|
|
26
|
+
data: (0, core_1.beginCell)().storeUint(0xb, 4).endCell(),
|
|
27
|
+
};
|
|
28
|
+
const action = {
|
|
29
|
+
type: 'addAndDeployPlugin',
|
|
30
|
+
workchain: -1,
|
|
31
|
+
stateInit,
|
|
32
|
+
body: (0, core_1.beginCell)().storeUint(0xcc, 8).endCell(),
|
|
33
|
+
forwardAmount: 1000n,
|
|
34
|
+
};
|
|
35
|
+
const serialized = (0, core_1.beginCell)().store((0, WalletContractV4Actions_1.storeExtendedAction)(action)).endCell();
|
|
36
|
+
const deserialized = (0, WalletContractV4Actions_1.loadExtendedAction)(serialized.beginParse());
|
|
37
|
+
if (deserialized.type !== 'addAndDeployPlugin')
|
|
38
|
+
throw new Error();
|
|
39
|
+
expect(deserialized.workchain).toEqual(action.workchain);
|
|
40
|
+
expect(deserialized.forwardAmount).toEqual(action.forwardAmount);
|
|
41
|
+
expect(deserialized.body.equals(action.body)).toBe(true);
|
|
42
|
+
expect(deserialized.stateInit.code?.equals(action.stateInit.code)).toBe(true);
|
|
43
|
+
expect(deserialized.stateInit.data?.equals(action.stateInit.data)).toBe(true);
|
|
44
|
+
});
|
|
45
|
+
it('should serialize and deserialize OutActionAddPlugin', () => {
|
|
46
|
+
const action = {
|
|
47
|
+
type: 'addPlugin',
|
|
48
|
+
address: new core_1.Address(0, Buffer.alloc(32, 0xaa)),
|
|
49
|
+
forwardAmount: 123n,
|
|
50
|
+
queryId: 77n,
|
|
51
|
+
};
|
|
52
|
+
const serialized = (0, core_1.beginCell)().store((0, WalletContractV4Actions_1.storeExtendedAction)(action)).endCell();
|
|
53
|
+
const deserialized = (0, WalletContractV4Actions_1.loadExtendedAction)(serialized.beginParse());
|
|
54
|
+
if (deserialized.type !== 'addPlugin')
|
|
55
|
+
throw new Error();
|
|
56
|
+
expect(deserialized.address.equals(action.address)).toBe(true);
|
|
57
|
+
expect(deserialized.forwardAmount).toEqual(action.forwardAmount);
|
|
58
|
+
expect(deserialized.queryId).toEqual(action.queryId);
|
|
59
|
+
});
|
|
60
|
+
it('should serialize and deserialize OutActionRemovePlugin', () => {
|
|
61
|
+
const action = {
|
|
62
|
+
type: 'removePlugin',
|
|
63
|
+
address: new core_1.Address(0, Buffer.alloc(32, 0xbb)),
|
|
64
|
+
forwardAmount: 987654321n,
|
|
65
|
+
};
|
|
66
|
+
const serialized = (0, core_1.beginCell)().store((0, WalletContractV4Actions_1.storeExtendedAction)(action)).endCell();
|
|
67
|
+
const deserialized = (0, WalletContractV4Actions_1.loadExtendedAction)(serialized.beginParse());
|
|
68
|
+
if (deserialized.type !== 'removePlugin')
|
|
69
|
+
throw new Error();
|
|
70
|
+
expect(deserialized.address.equals(action.address)).toBe(true);
|
|
71
|
+
expect(deserialized.forwardAmount).toEqual(action.forwardAmount);
|
|
72
|
+
expect(deserialized.queryId).toBeUndefined();
|
|
73
|
+
});
|
|
74
|
+
});
|
|
@@ -64,7 +64,7 @@ function storeOutListExtendedV5R1(actions) {
|
|
|
64
64
|
const extendedActions = actions.filter(WalletV5OutActions_1.isOutActionExtended);
|
|
65
65
|
const basicActions = actions.filter(WalletV5OutActions_1.isOutActionBasic);
|
|
66
66
|
return (builder) => {
|
|
67
|
-
const outListPacked = basicActions.length ? (0, core_1.beginCell)().store((0, core_1.storeOutList)(basicActions
|
|
67
|
+
const outListPacked = basicActions.length ? (0, core_1.beginCell)().store((0, core_1.storeOutList)(basicActions)) : null;
|
|
68
68
|
builder.storeMaybeRef(outListPacked);
|
|
69
69
|
if (extendedActions.length === 0) {
|
|
70
70
|
builder.storeUint(0, 1);
|
|
@@ -173,7 +173,7 @@ describe('Wallet V5R1 actions', () => {
|
|
|
173
173
|
}
|
|
174
174
|
];
|
|
175
175
|
const actual = (0, core_1.beginCell)().store((0, WalletV5R1Actions_1.storeOutListExtendedV5R1)(actions)).endCell();
|
|
176
|
-
const expected = core_1.Cell.fromBoc(Buffer.from('
|
|
176
|
+
const expected = core_1.Cell.fromBoc(Buffer.from('b5ee9c724101080100ab000245c0a000888888888888888888888888888888888888888888888888888888888888888c0301010304400200450380022222222222222222222222222222222222222222222222222222222222222230020a0ec3c86d0005040068420011111111111111111111111111111111111111111111111111111111111111110808404404000000000000c0e40007890000020a0ec3c86d030706001cc0000000000000000000000000000000a78e5373', 'hex'))[0];
|
|
177
177
|
expect(actual.equals(expected)).toBeTruthy();
|
|
178
178
|
});
|
|
179
179
|
it('Should deserialize extended out list', () => {
|
|
@@ -16,7 +16,7 @@ const walletV5R1VersionsSerialisation = {
|
|
|
16
16
|
*/
|
|
17
17
|
function loadWalletIdV5R1(value, networkGlobalId) {
|
|
18
18
|
const val = new core_1.BitReader(new core_1.BitString(typeof value === 'bigint' ?
|
|
19
|
-
Buffer.from(value.toString(16), 'hex') :
|
|
19
|
+
Buffer.from(value.toString(16).padStart(8, '0'), 'hex') :
|
|
20
20
|
value instanceof core_1.Slice ? value.loadBuffer(4) : value, 0, 32)).loadInt(32);
|
|
21
21
|
const context = BigInt(val) ^ BigInt(networkGlobalId);
|
|
22
22
|
const bitReader = (0, core_1.beginCell)().storeInt(context, 32).endCell().beginParse();
|
|
@@ -40,6 +40,37 @@ describe('Wallet V5R1 wallet id', () => {
|
|
|
40
40
|
const actual = (0, WalletV5R1WalletId_1.loadWalletIdV5R1)((0, core_1.beginCell)().storeInt(BigInt(context) ^ BigInt(expected.networkGlobalId), 32).endCell().beginParse(), expected.networkGlobalId);
|
|
41
41
|
expect(expected).toEqual(actual);
|
|
42
42
|
});
|
|
43
|
+
it('Should deserialize correctly in all modes', async () => {
|
|
44
|
+
const getRandom = (min, max) => {
|
|
45
|
+
return Math.round(Math.random() * (max - min) + min);
|
|
46
|
+
};
|
|
47
|
+
const subwalletMax = (2 ** 15) - 1;
|
|
48
|
+
const randomSubwallet = () => getRandom(1, subwalletMax - 2);
|
|
49
|
+
const randomBunch = Array(10).fill(0).map(randomSubwallet);
|
|
50
|
+
for (let networkId of [-239, -3]) {
|
|
51
|
+
for (let testWc of [0, -1]) {
|
|
52
|
+
for (let testSubwallet of [0, subwalletMax, ...randomBunch]) {
|
|
53
|
+
const expected = {
|
|
54
|
+
networkGlobalId: networkId,
|
|
55
|
+
context: {
|
|
56
|
+
walletVersion: 'v5r1',
|
|
57
|
+
workchain: testWc,
|
|
58
|
+
subwalletNumber: testSubwallet
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const packed = (0, core_1.beginCell)().store((0, WalletV5R1WalletId_1.storeWalletIdV5R1)(expected)).endCell();
|
|
62
|
+
let unpacked = (0, WalletV5R1WalletId_1.loadWalletIdV5R1)(packed.beginParse(), networkId);
|
|
63
|
+
expect(unpacked).toEqual(expected);
|
|
64
|
+
const intVal = BigInt(packed.beginParse().loadInt(32));
|
|
65
|
+
unpacked = (0, WalletV5R1WalletId_1.loadWalletIdV5R1)(intVal, networkId);
|
|
66
|
+
expect(unpacked).toEqual(expected);
|
|
67
|
+
const buffVal = packed.beginParse().loadBuffer(4);
|
|
68
|
+
unpacked = (0, WalletV5R1WalletId_1.loadWalletIdV5R1)(buffVal, networkId);
|
|
69
|
+
expect(unpacked).toEqual(expected);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
43
74
|
it('Should serialise wallet id', () => {
|
|
44
75
|
const walletId = {
|
|
45
76
|
networkGlobalId: -3,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ton/ton",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "16.0.0",
|
|
4
4
|
"repository": "https://github.com/ton-org/ton.git",
|
|
5
5
|
"author": "Whales Corp. <developers@whalescorp.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
18
|
"@release-it/keep-a-changelog": "^5.0.0",
|
|
19
|
-
"@ton/core": "^0.
|
|
19
|
+
"@ton/core": "^0.62.0",
|
|
20
20
|
"@ton/crypto": "3.2.0",
|
|
21
21
|
"@ton/emulator": "^2.1.1",
|
|
22
22
|
"@types/jest": "^27.0.1",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"zod": "^3.21.4"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"@ton/core": ">=0.
|
|
50
|
+
"@ton/core": ">=0.62.0 <1.0.0",
|
|
51
51
|
"@ton/crypto": ">=3.2.0"
|
|
52
52
|
},
|
|
53
53
|
"publishConfig": {
|
|
@@ -1,73 +0,0 @@
|
|
|
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
|
-
const randomTestKey_1 = require("../utils/randomTestKey");
|
|
11
|
-
const testWallets_1 = require("../utils/testWallets");
|
|
12
|
-
const WalletContractV4_1 = require("./WalletContractV4");
|
|
13
|
-
const createTestClient4_1 = require("../utils/createTestClient4");
|
|
14
|
-
const core_1 = require("@ton/core");
|
|
15
|
-
describe('WalletContractV4', () => {
|
|
16
|
-
it('should has balance and correct address', async () => {
|
|
17
|
-
// Create contract
|
|
18
|
-
let client = (0, createTestClient4_1.createTestClient4)();
|
|
19
|
-
let key = (0, randomTestKey_1.randomTestKey)('v4-treasure');
|
|
20
|
-
let contract = client.open(WalletContractV4_1.WalletContractV4.create({ workchain: 0, publicKey: key.publicKey }));
|
|
21
|
-
let balance = await contract.getBalance();
|
|
22
|
-
// Check parameters
|
|
23
|
-
expect(contract.address.equals(core_1.Address.parse('EQDnBF4JTFKHTYjulEJyNd4dstLGH1m51UrLdu01_tw4z2Au'))).toBe(true);
|
|
24
|
-
expect(balance > 0n).toBe(true);
|
|
25
|
-
});
|
|
26
|
-
it('should perform transfer', async () => {
|
|
27
|
-
// Create contract
|
|
28
|
-
let client = (0, createTestClient4_1.createTestClient4)();
|
|
29
|
-
let key = (0, randomTestKey_1.randomTestKey)('v4-treasure');
|
|
30
|
-
let contract = client.open(WalletContractV4_1.WalletContractV4.create({ workchain: 0, publicKey: key.publicKey }));
|
|
31
|
-
// Prepare transfer
|
|
32
|
-
let seqno = await contract.getSeqno();
|
|
33
|
-
let transfer = contract.createTransfer({
|
|
34
|
-
seqno,
|
|
35
|
-
secretKey: key.secretKey,
|
|
36
|
-
messages: [(0, core_1.internal)({
|
|
37
|
-
to: 'kQD6oPnzaaAMRW24R8F0_nlSsJQni0cGHntR027eT9_sgtwt',
|
|
38
|
-
value: '0.1',
|
|
39
|
-
body: 'Hello world: 1'
|
|
40
|
-
}), (0, core_1.internal)({
|
|
41
|
-
to: 'kQD6oPnzaaAMRW24R8F0_nlSsJQni0cGHntR027eT9_sgtwt',
|
|
42
|
-
value: '0.1',
|
|
43
|
-
body: 'Hello world: 2'
|
|
44
|
-
})]
|
|
45
|
-
});
|
|
46
|
-
// Perform transfer
|
|
47
|
-
await contract.send(transfer);
|
|
48
|
-
// Awaiting update
|
|
49
|
-
await (0, testWallets_1.tillNextSeqno)(contract, seqno);
|
|
50
|
-
});
|
|
51
|
-
it('should perform extra currency transfer', async () => {
|
|
52
|
-
// Create contract
|
|
53
|
-
let client = (0, createTestClient4_1.createTestClient4)();
|
|
54
|
-
let key = (0, randomTestKey_1.randomTestKey)('v4-treasure');
|
|
55
|
-
let contract = client.open(WalletContractV4_1.WalletContractV4.create({ workchain: 0, publicKey: key.publicKey }));
|
|
56
|
-
// Prepare transfer
|
|
57
|
-
let seqno = await contract.getSeqno();
|
|
58
|
-
let transfer = contract.createTransfer({
|
|
59
|
-
seqno,
|
|
60
|
-
secretKey: key.secretKey,
|
|
61
|
-
messages: [(0, core_1.internal)({
|
|
62
|
-
to: 'kQD6oPnzaaAMRW24R8F0_nlSsJQni0cGHntR027eT9_sgtwt',
|
|
63
|
-
value: '0.01',
|
|
64
|
-
extracurrency: { 100: BigInt(10 ** 6) },
|
|
65
|
-
body: 'Hello extra currency v4'
|
|
66
|
-
})]
|
|
67
|
-
});
|
|
68
|
-
// Perform transfer
|
|
69
|
-
await contract.send(transfer);
|
|
70
|
-
// Awaiting update
|
|
71
|
-
await (0, testWallets_1.tillNextSeqno)(contract, seqno);
|
|
72
|
-
});
|
|
73
|
-
});
|
|
File without changes
|