starknet 3.5.1 → 3.8.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/CHANGELOG.md +39 -0
- package/__tests__/account.test.ts +38 -20
- package/__tests__/accountContract.test.ts +0 -31
- package/__tests__/constancts.ts +2 -0
- package/__tests__/contract.test.ts +14 -21
- package/__tests__/provider.test.ts +8 -0
- package/account/default.d.ts +14 -1
- package/account/default.js +78 -14
- package/account/interface.d.ts +14 -0
- package/contract/default.d.ts +13 -3
- package/contract/default.js +36 -25
- package/contract/interface.d.ts +21 -3
- package/dist/account/default.d.ts +8 -2
- package/dist/account/default.js +57 -11
- package/dist/account/interface.d.ts +13 -1
- package/dist/contract/default.d.ts +7 -4
- package/dist/contract/default.js +27 -24
- package/dist/contract/interface.d.ts +9 -4
- package/dist/provider/default.d.ts +11 -4
- package/dist/provider/default.js +34 -30
- package/dist/provider/utils.d.ts +1 -2
- package/dist/provider/utils.js +7 -8
- package/dist/signer/index.d.ts +1 -0
- package/dist/signer/index.js +1 -0
- package/dist/signer/ledger.d.ts +12 -0
- package/dist/signer/ledger.js +138 -0
- package/dist/types/api.d.ts +60 -3
- package/package.json +5 -2
- package/provider/default.d.ts +13 -3
- package/provider/default.js +49 -42
- package/provider/utils.d.ts +1 -2
- package/provider/utils.js +7 -8
- package/signer/index.d.ts +1 -0
- package/signer/index.js +1 -0
- package/signer/ledger.d.ts +15 -0
- package/signer/ledger.js +243 -0
- package/src/account/default.ts +40 -6
- package/src/account/interface.ts +15 -0
- package/src/contract/default.ts +37 -34
- package/src/contract/interface.ts +21 -3
- package/src/provider/default.ts +31 -23
- package/src/provider/utils.ts +7 -8
- package/src/signer/index.ts +1 -0
- package/src/signer/ledger.ts +81 -0
- package/src/types/api.ts +65 -4
- package/tsconfig.json +1 -10
- package/types/api.d.ts +60 -3
- package/www/README.md +41 -0
- package/www/babel.config.js +3 -0
- package/www/code-examples/account.js +62 -0
- package/www/code-examples/amm.js +49 -0
- package/www/code-examples/erc20.js +10 -0
- package/www/code-examples/package-lock.json +336 -0
- package/www/code-examples/package.json +15 -0
- package/www/docs/API/_category_.json +5 -0
- package/www/docs/API/account.md +11 -0
- package/www/docs/API/contract.md +14 -0
- package/www/docs/API/index.md +4 -0
- package/www/docs/API/provider.md +10 -0
- package/www/docs/API/signer.md +8 -0
- package/www/docusaurus.config.js +131 -0
- package/www/guides/account.md +60 -0
- package/www/guides/cra.md +3 -0
- package/www/guides/erc20.md +88 -0
- package/www/guides/intro.md +20 -0
- package/www/package-lock.json +22285 -0
- package/www/package.json +43 -0
- package/www/sidebars.js +31 -0
- package/www/src/components/HomepageFeatures/index.tsx +67 -0
- package/www/src/components/HomepageFeatures/styles.module.css +10 -0
- package/www/src/css/custom.css +39 -0
- package/www/src/pages/index.module.css +23 -0
- package/www/src/pages/index.tsx +40 -0
- package/www/src/pages/markdown-page.md +7 -0
- package/www/static/.nojekyll +0 -0
- package/www/static/img/docusaurus.png +0 -0
- package/www/static/img/favicon.ico +0 -0
- package/www/static/img/logo.svg +17 -0
- package/www/static/img/starknet-1.png +0 -0
- package/www/static/img/starknet-2.png +0 -0
- package/www/static/img/starknet-3.png +0 -0
- package/www/static/img/tutorial/docsVersionDropdown.png +0 -0
- package/www/static/img/tutorial/localeDropdown.png +0 -0
- package/www/tsconfig.json +8 -0
package/signer/ledger.js
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
var __awaiter =
|
|
3
|
+
(this && this.__awaiter) ||
|
|
4
|
+
function (thisArg, _arguments, P, generator) {
|
|
5
|
+
function adopt(value) {
|
|
6
|
+
return value instanceof P
|
|
7
|
+
? value
|
|
8
|
+
: new P(function (resolve) {
|
|
9
|
+
resolve(value);
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
13
|
+
function fulfilled(value) {
|
|
14
|
+
try {
|
|
15
|
+
step(generator.next(value));
|
|
16
|
+
} catch (e) {
|
|
17
|
+
reject(e);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function rejected(value) {
|
|
21
|
+
try {
|
|
22
|
+
step(generator['throw'](value));
|
|
23
|
+
} catch (e) {
|
|
24
|
+
reject(e);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function step(result) {
|
|
28
|
+
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
29
|
+
}
|
|
30
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
var __generator =
|
|
34
|
+
(this && this.__generator) ||
|
|
35
|
+
function (thisArg, body) {
|
|
36
|
+
var _ = {
|
|
37
|
+
label: 0,
|
|
38
|
+
sent: function () {
|
|
39
|
+
if (t[0] & 1) throw t[1];
|
|
40
|
+
return t[1];
|
|
41
|
+
},
|
|
42
|
+
trys: [],
|
|
43
|
+
ops: [],
|
|
44
|
+
},
|
|
45
|
+
f,
|
|
46
|
+
y,
|
|
47
|
+
t,
|
|
48
|
+
g;
|
|
49
|
+
return (
|
|
50
|
+
(g = { next: verb(0), throw: verb(1), return: verb(2) }),
|
|
51
|
+
typeof Symbol === 'function' &&
|
|
52
|
+
(g[Symbol.iterator] = function () {
|
|
53
|
+
return this;
|
|
54
|
+
}),
|
|
55
|
+
g
|
|
56
|
+
);
|
|
57
|
+
function verb(n) {
|
|
58
|
+
return function (v) {
|
|
59
|
+
return step([n, v]);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function step(op) {
|
|
63
|
+
if (f) throw new TypeError('Generator is already executing.');
|
|
64
|
+
while (_)
|
|
65
|
+
try {
|
|
66
|
+
if (
|
|
67
|
+
((f = 1),
|
|
68
|
+
y &&
|
|
69
|
+
(t =
|
|
70
|
+
op[0] & 2
|
|
71
|
+
? y['return']
|
|
72
|
+
: op[0]
|
|
73
|
+
? y['throw'] || ((t = y['return']) && t.call(y), 0)
|
|
74
|
+
: y.next) &&
|
|
75
|
+
!(t = t.call(y, op[1])).done)
|
|
76
|
+
)
|
|
77
|
+
return t;
|
|
78
|
+
if (((y = 0), t)) op = [op[0] & 2, t.value];
|
|
79
|
+
switch (op[0]) {
|
|
80
|
+
case 0:
|
|
81
|
+
case 1:
|
|
82
|
+
t = op;
|
|
83
|
+
break;
|
|
84
|
+
case 4:
|
|
85
|
+
_.label++;
|
|
86
|
+
return { value: op[1], done: false };
|
|
87
|
+
case 5:
|
|
88
|
+
_.label++;
|
|
89
|
+
y = op[1];
|
|
90
|
+
op = [0];
|
|
91
|
+
continue;
|
|
92
|
+
case 7:
|
|
93
|
+
op = _.ops.pop();
|
|
94
|
+
_.trys.pop();
|
|
95
|
+
continue;
|
|
96
|
+
default:
|
|
97
|
+
if (
|
|
98
|
+
!((t = _.trys), (t = t.length > 0 && t[t.length - 1])) &&
|
|
99
|
+
(op[0] === 6 || op[0] === 2)
|
|
100
|
+
) {
|
|
101
|
+
_ = 0;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) {
|
|
105
|
+
_.label = op[1];
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
if (op[0] === 6 && _.label < t[1]) {
|
|
109
|
+
_.label = t[1];
|
|
110
|
+
t = op;
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
if (t && _.label < t[2]) {
|
|
114
|
+
_.label = t[2];
|
|
115
|
+
_.ops.push(op);
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
if (t[2]) _.ops.pop();
|
|
119
|
+
_.trys.pop();
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
op = body.call(thisArg, _);
|
|
123
|
+
} catch (e) {
|
|
124
|
+
op = [6, e];
|
|
125
|
+
y = 0;
|
|
126
|
+
} finally {
|
|
127
|
+
f = t = 0;
|
|
128
|
+
}
|
|
129
|
+
if (op[0] & 5) throw op[1];
|
|
130
|
+
return { value: op[0] ? op[1] : void 0, done: true };
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
var __importDefault =
|
|
134
|
+
(this && this.__importDefault) ||
|
|
135
|
+
function (mod) {
|
|
136
|
+
return mod && mod.__esModule ? mod : { default: mod };
|
|
137
|
+
};
|
|
138
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
139
|
+
exports.LedgerBlindSigner = void 0;
|
|
140
|
+
var hw_app_eth_1 = __importDefault(require('@ledgerhq/hw-app-eth'));
|
|
141
|
+
var hw_transport_webhid_1 = __importDefault(require('@ledgerhq/hw-transport-webhid'));
|
|
142
|
+
var encode_1 = require('../utils/encode');
|
|
143
|
+
var hash_1 = require('../utils/hash');
|
|
144
|
+
var typedData_1 = require('../utils/typedData');
|
|
145
|
+
function hexZeroPad(hash, length) {
|
|
146
|
+
var value = hash;
|
|
147
|
+
if (value.length > 2 * length + 2) {
|
|
148
|
+
throw new Error('value out of range');
|
|
149
|
+
}
|
|
150
|
+
while (value.length < 2 * length + 2) {
|
|
151
|
+
value = '0x0' + value.substring(2);
|
|
152
|
+
}
|
|
153
|
+
return value;
|
|
154
|
+
}
|
|
155
|
+
var LedgerBlindSigner = /** @class */ (function () {
|
|
156
|
+
function LedgerBlindSigner() {
|
|
157
|
+
this.derivationPath = "/2645'/579218131'/1148870696'/0'/0'/0";
|
|
158
|
+
}
|
|
159
|
+
LedgerBlindSigner.prototype.getEthApp = function () {
|
|
160
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
161
|
+
var _a, _b;
|
|
162
|
+
return __generator(this, function (_c) {
|
|
163
|
+
switch (_c.label) {
|
|
164
|
+
case 0:
|
|
165
|
+
if (!!this.transport) return [3 /*break*/, 4];
|
|
166
|
+
_c.label = 1;
|
|
167
|
+
case 1:
|
|
168
|
+
_c.trys.push([1, 3, , 4]);
|
|
169
|
+
_a = this;
|
|
170
|
+
return [4 /*yield*/, hw_transport_webhid_1.default.create()];
|
|
171
|
+
case 2:
|
|
172
|
+
_a.transport = _c.sent();
|
|
173
|
+
return [3 /*break*/, 4];
|
|
174
|
+
case 3:
|
|
175
|
+
_b = _c.sent();
|
|
176
|
+
throw new Error('Device connection error');
|
|
177
|
+
case 4:
|
|
178
|
+
return [2 /*return*/, new hw_app_eth_1.default(this.transport)];
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
};
|
|
183
|
+
LedgerBlindSigner.prototype.getPubKey = function () {
|
|
184
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
185
|
+
var eth, response, starkPub;
|
|
186
|
+
return __generator(this, function (_a) {
|
|
187
|
+
switch (_a.label) {
|
|
188
|
+
case 0:
|
|
189
|
+
return [4 /*yield*/, this.getEthApp()];
|
|
190
|
+
case 1:
|
|
191
|
+
eth = _a.sent();
|
|
192
|
+
return [4 /*yield*/, eth.starkGetPublicKey(this.derivationPath)];
|
|
193
|
+
case 2:
|
|
194
|
+
response = _a.sent();
|
|
195
|
+
starkPub = '0x' + response.slice(1, 1 + 32).toString('hex');
|
|
196
|
+
return [2 /*return*/, starkPub];
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
};
|
|
201
|
+
LedgerBlindSigner.prototype.signTransaction = function (transactions, transactionsDetail) {
|
|
202
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
203
|
+
var msgHash;
|
|
204
|
+
return __generator(this, function (_a) {
|
|
205
|
+
msgHash = (0, hash_1.hashMulticall)(
|
|
206
|
+
transactionsDetail.walletAddress,
|
|
207
|
+
transactions,
|
|
208
|
+
transactionsDetail.nonce.toString(),
|
|
209
|
+
transactionsDetail.maxFee.toString()
|
|
210
|
+
);
|
|
211
|
+
return [2 /*return*/, this.sign(msgHash)];
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
LedgerBlindSigner.prototype.signMessage = function (typedData, accountAddress) {
|
|
216
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
217
|
+
var msgHash;
|
|
218
|
+
return __generator(this, function (_a) {
|
|
219
|
+
msgHash = (0, typedData_1.getMessageHash)(typedData, accountAddress);
|
|
220
|
+
return [2 /*return*/, this.sign(msgHash)];
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
};
|
|
224
|
+
LedgerBlindSigner.prototype.sign = function (msgHash) {
|
|
225
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
226
|
+
var eth, _a, r, s;
|
|
227
|
+
return __generator(this, function (_b) {
|
|
228
|
+
switch (_b.label) {
|
|
229
|
+
case 0:
|
|
230
|
+
return [4 /*yield*/, this.getEthApp()];
|
|
231
|
+
case 1:
|
|
232
|
+
eth = _b.sent();
|
|
233
|
+
return [4 /*yield*/, eth.starkUnsafeSign(this.derivationPath, hexZeroPad(msgHash, 32))];
|
|
234
|
+
case 2:
|
|
235
|
+
(_a = _b.sent()), (r = _a.r), (s = _a.s);
|
|
236
|
+
return [2 /*return*/, [(0, encode_1.addHexPrefix)(r), (0, encode_1.addHexPrefix)(s)]];
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
};
|
|
241
|
+
return LedgerBlindSigner;
|
|
242
|
+
})();
|
|
243
|
+
exports.LedgerBlindSigner = LedgerBlindSigner;
|
package/src/account/default.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import assert from 'minimalistic-assert';
|
|
2
2
|
|
|
3
3
|
import { Provider } from '../provider';
|
|
4
|
+
import { BlockIdentifier } from '../provider/utils';
|
|
4
5
|
import { Signer, SignerInterface } from '../signer';
|
|
5
6
|
import {
|
|
6
7
|
Abi,
|
|
7
8
|
AddTransactionResponse,
|
|
8
9
|
Call,
|
|
10
|
+
EstimateFeeResponse,
|
|
9
11
|
InvocationsDetails,
|
|
10
12
|
InvokeFunctionTransaction,
|
|
11
13
|
KeyPair,
|
|
@@ -30,9 +32,10 @@ export class Account extends Provider implements AccountInterface {
|
|
|
30
32
|
|
|
31
33
|
private signer: SignerInterface;
|
|
32
34
|
|
|
33
|
-
constructor(provider: Provider, address: string,
|
|
35
|
+
constructor(provider: Provider, address: string, keyPairOrSigner: KeyPair | SignerInterface) {
|
|
34
36
|
super(provider);
|
|
35
|
-
this.signer =
|
|
37
|
+
this.signer =
|
|
38
|
+
'getPubKey' in keyPairOrSigner ? keyPairOrSigner : new Signer(keyPairOrSigner as KeyPair);
|
|
36
39
|
this.address = address;
|
|
37
40
|
}
|
|
38
41
|
|
|
@@ -44,6 +47,35 @@ export class Account extends Provider implements AccountInterface {
|
|
|
44
47
|
return toHex(toBN(result[0]));
|
|
45
48
|
}
|
|
46
49
|
|
|
50
|
+
public async estimateFee(
|
|
51
|
+
calls: Call | Call[],
|
|
52
|
+
{
|
|
53
|
+
nonce: providedNonce,
|
|
54
|
+
blockIdentifier = 'pending',
|
|
55
|
+
}: { nonce?: BigNumberish; blockIdentifier?: BlockIdentifier } = {}
|
|
56
|
+
): Promise<EstimateFeeResponse> {
|
|
57
|
+
const transactions = Array.isArray(calls) ? calls : [calls];
|
|
58
|
+
const nonce = providedNonce ?? (await this.getNonce());
|
|
59
|
+
const signerDetails = {
|
|
60
|
+
walletAddress: this.address,
|
|
61
|
+
nonce: toBN(nonce),
|
|
62
|
+
maxFee: toBN('0'),
|
|
63
|
+
};
|
|
64
|
+
const signature = await this.signer.signTransaction(transactions, signerDetails);
|
|
65
|
+
|
|
66
|
+
const calldata = [...fromCallsToExecuteCalldata(transactions), signerDetails.nonce.toString()];
|
|
67
|
+
return this.fetchEndpoint(
|
|
68
|
+
'estimate_fee',
|
|
69
|
+
{ blockIdentifier },
|
|
70
|
+
{
|
|
71
|
+
contract_address: this.address,
|
|
72
|
+
entry_point_selector: getSelectorFromName('__execute__'),
|
|
73
|
+
calldata,
|
|
74
|
+
signature: bigNumberishArrayToDecimalStringArray(signature),
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
47
79
|
/**
|
|
48
80
|
* Invoke execute function in account contract
|
|
49
81
|
*
|
|
@@ -58,23 +90,25 @@ export class Account extends Provider implements AccountInterface {
|
|
|
58
90
|
transactionsDetail: InvocationsDetails = {}
|
|
59
91
|
): Promise<AddTransactionResponse> {
|
|
60
92
|
const transactions = Array.isArray(calls) ? calls : [calls];
|
|
61
|
-
|
|
93
|
+
const nonce = toBN(transactionsDetail.nonce ?? (await this.getNonce()));
|
|
94
|
+
const maxFee =
|
|
95
|
+
transactionsDetail.maxFee ?? (await this.estimateFee(transactions, { nonce })).amount;
|
|
62
96
|
const signerDetails = {
|
|
63
97
|
walletAddress: this.address,
|
|
64
|
-
nonce
|
|
65
|
-
maxFee
|
|
98
|
+
nonce,
|
|
99
|
+
maxFee,
|
|
66
100
|
};
|
|
67
101
|
|
|
68
102
|
const signature = await this.signer.signTransaction(transactions, signerDetails, abis);
|
|
69
103
|
|
|
70
104
|
const calldata = [...fromCallsToExecuteCalldata(transactions), signerDetails.nonce.toString()];
|
|
71
|
-
|
|
72
105
|
return this.fetchEndpoint('add_transaction', undefined, {
|
|
73
106
|
type: 'INVOKE_FUNCTION',
|
|
74
107
|
contract_address: this.address,
|
|
75
108
|
entry_point_selector: getSelectorFromName('__execute__'),
|
|
76
109
|
calldata,
|
|
77
110
|
signature: bigNumberishArrayToDecimalStringArray(signature),
|
|
111
|
+
max_fee: toHex(toBN(maxFee)),
|
|
78
112
|
});
|
|
79
113
|
}
|
|
80
114
|
|
package/src/account/interface.ts
CHANGED
|
@@ -4,6 +4,8 @@ import {
|
|
|
4
4
|
AddTransactionResponse,
|
|
5
5
|
Call,
|
|
6
6
|
DeployContractPayload,
|
|
7
|
+
EstimateFeeResponse,
|
|
8
|
+
Invocation,
|
|
7
9
|
InvocationsDetails,
|
|
8
10
|
Signature,
|
|
9
11
|
} from '../types';
|
|
@@ -28,6 +30,19 @@ export abstract class AccountInterface extends ProviderInterface {
|
|
|
28
30
|
abi?: Abi
|
|
29
31
|
): Promise<AddTransactionResponse>;
|
|
30
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Estimate Fee for a method on starknet
|
|
35
|
+
*
|
|
36
|
+
* @param invocation the invocation object containing:
|
|
37
|
+
* - contractAddress - the address of the contract
|
|
38
|
+
* - entrypoint - the entrypoint of the contract
|
|
39
|
+
* - calldata - (defaults to []) the calldata
|
|
40
|
+
* - signature - (defaults to []) the signature
|
|
41
|
+
*
|
|
42
|
+
* @returns response from addTransaction
|
|
43
|
+
*/
|
|
44
|
+
public abstract estimateFee(invocation: Invocation): Promise<EstimateFeeResponse>;
|
|
45
|
+
|
|
31
46
|
/**
|
|
32
47
|
* Invoke execute function in account contract
|
|
33
48
|
*
|
package/src/contract/default.ts
CHANGED
|
@@ -3,6 +3,7 @@ import assert from 'minimalistic-assert';
|
|
|
3
3
|
|
|
4
4
|
import { AccountInterface } from '../account';
|
|
5
5
|
import { ProviderInterface, defaultProvider } from '../provider';
|
|
6
|
+
import { BlockIdentifier } from '../provider/utils';
|
|
6
7
|
import {
|
|
7
8
|
Abi,
|
|
8
9
|
AbiEntry,
|
|
@@ -13,11 +14,11 @@ import {
|
|
|
13
14
|
ContractFunction,
|
|
14
15
|
FunctionAbi,
|
|
15
16
|
Invocation,
|
|
17
|
+
Overrides,
|
|
16
18
|
ParsedStruct,
|
|
17
19
|
Result,
|
|
18
20
|
StructAbi,
|
|
19
21
|
} from '../types';
|
|
20
|
-
import { getSelectorFromName } from '../utils/hash';
|
|
21
22
|
import { BigNumberish, toBN, toFelt } from '../utils/number';
|
|
22
23
|
import { ContractInterface } from './interface';
|
|
23
24
|
|
|
@@ -528,7 +529,11 @@ export class Contract implements ContractInterface {
|
|
|
528
529
|
}, [] as Result);
|
|
529
530
|
}
|
|
530
531
|
|
|
531
|
-
public invoke(
|
|
532
|
+
public invoke(
|
|
533
|
+
method: string,
|
|
534
|
+
args: Array<any> = [],
|
|
535
|
+
options: Overrides = {}
|
|
536
|
+
): Promise<AddTransactionResponse> {
|
|
532
537
|
// ensure contract is connected
|
|
533
538
|
assert(this.address !== null, 'contract isnt connected to an address');
|
|
534
539
|
// validate method and args
|
|
@@ -541,10 +546,7 @@ export class Contract implements ContractInterface {
|
|
|
541
546
|
}
|
|
542
547
|
return acc;
|
|
543
548
|
}, 0);
|
|
544
|
-
|
|
545
|
-
if (args.length === inputsLength + 1 && Array.isArray(args[args.length - 1])) {
|
|
546
|
-
signature.push(...args.pop());
|
|
547
|
-
}
|
|
549
|
+
|
|
548
550
|
if (args.length !== inputsLength) {
|
|
549
551
|
throw Error(
|
|
550
552
|
`Invalid number of arguments, expected ${inputsLength} arguments, but got ${args.length}`
|
|
@@ -559,28 +561,34 @@ export class Contract implements ContractInterface {
|
|
|
559
561
|
entrypoint: method,
|
|
560
562
|
};
|
|
561
563
|
if ('execute' in this.providerOrAccount) {
|
|
562
|
-
return this.providerOrAccount.execute(invocation
|
|
564
|
+
return this.providerOrAccount.execute(invocation, undefined, {
|
|
565
|
+
maxFee: options.maxFee,
|
|
566
|
+
nonce: options.nonce,
|
|
567
|
+
});
|
|
563
568
|
}
|
|
569
|
+
|
|
564
570
|
return this.providerOrAccount.invokeFunction({
|
|
565
571
|
...invocation,
|
|
566
|
-
signature,
|
|
572
|
+
signature: options.signature || [],
|
|
567
573
|
});
|
|
568
574
|
}
|
|
569
575
|
|
|
570
|
-
public async call(
|
|
576
|
+
public async call(
|
|
577
|
+
method: string,
|
|
578
|
+
args: Array<any> = [],
|
|
579
|
+
{
|
|
580
|
+
blockIdentifier = 'pending',
|
|
581
|
+
}: {
|
|
582
|
+
blockIdentifier?: BlockIdentifier;
|
|
583
|
+
} = {}
|
|
584
|
+
): Promise<Result> {
|
|
571
585
|
// ensure contract is connected
|
|
572
586
|
assert(this.address !== null, 'contract isnt connected to an address');
|
|
573
587
|
|
|
574
588
|
// validate method and args
|
|
575
589
|
this.validateMethodAndArgs('CALL', method, args);
|
|
576
590
|
const { inputs } = this.abi.find((abi) => abi.name === method) as FunctionAbi;
|
|
577
|
-
|
|
578
|
-
const options = {
|
|
579
|
-
blockIdentifier: null,
|
|
580
|
-
};
|
|
581
|
-
if (args.length === inputsLength + 1 && typeof args[args.length - 1] === 'object') {
|
|
582
|
-
Object.assign(options, args.pop());
|
|
583
|
-
}
|
|
591
|
+
|
|
584
592
|
// compile calldata
|
|
585
593
|
const calldata = this.compileCalldata(args, inputs);
|
|
586
594
|
return this.providerOrAccount
|
|
@@ -590,35 +598,30 @@ export class Contract implements ContractInterface {
|
|
|
590
598
|
calldata,
|
|
591
599
|
entrypoint: method,
|
|
592
600
|
},
|
|
593
|
-
|
|
601
|
+
{ blockIdentifier }
|
|
594
602
|
)
|
|
595
603
|
.then((x) => this.parseResponse(method, x.result));
|
|
596
604
|
}
|
|
597
605
|
|
|
598
|
-
public async estimate(
|
|
606
|
+
public async estimate(method: string, args: Array<any> = []) {
|
|
599
607
|
// TODO; remove error as soon as estimate fees are supported
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
// return this.providerOrAccount.estimateFee({
|
|
611
|
-
// contractAddress: this.address as string,
|
|
612
|
-
// calldata,
|
|
613
|
-
// entrypoint: method,
|
|
614
|
-
// });
|
|
608
|
+
// ensure contract is connected
|
|
609
|
+
assert(this.address !== null, 'contract isnt connected to an address');
|
|
610
|
+
|
|
611
|
+
// validate method and args
|
|
612
|
+
this.validateMethodAndArgs('INVOKE', method, args);
|
|
613
|
+
const invocation = this.populateTransaction[method](...args);
|
|
614
|
+
if ('estimateFee' in this.providerOrAccount) {
|
|
615
|
+
return this.providerOrAccount.estimateFee(invocation);
|
|
616
|
+
}
|
|
617
|
+
throw Error('Contract must be connected to the account contract to estimate');
|
|
615
618
|
}
|
|
616
619
|
|
|
617
620
|
public populate(method: string, args: Array<any> = []): Invocation {
|
|
618
621
|
const { inputs } = this.abi.find((abi) => abi.name === method) as FunctionAbi;
|
|
619
622
|
return {
|
|
620
623
|
contractAddress: this.address,
|
|
621
|
-
entrypoint:
|
|
624
|
+
entrypoint: method,
|
|
622
625
|
calldata: this.compileCalldata(args, inputs),
|
|
623
626
|
signature: [],
|
|
624
627
|
};
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { AccountInterface } from '../account';
|
|
2
2
|
import { ProviderInterface } from '../provider';
|
|
3
|
+
import { BlockIdentifier } from '../provider/utils';
|
|
3
4
|
import {
|
|
4
5
|
Abi,
|
|
5
6
|
AddTransactionResponse,
|
|
6
7
|
AsyncContractFunction,
|
|
7
8
|
ContractFunction,
|
|
8
9
|
Invocation,
|
|
10
|
+
Overrides,
|
|
9
11
|
Result,
|
|
10
12
|
} from '../types';
|
|
11
13
|
|
|
@@ -57,7 +59,13 @@ export abstract class ContractInterface {
|
|
|
57
59
|
* @param args Array of the arguments for the call
|
|
58
60
|
* @returns Result of the call as an array with key value pars
|
|
59
61
|
*/
|
|
60
|
-
public abstract call(
|
|
62
|
+
public abstract call(
|
|
63
|
+
method: string,
|
|
64
|
+
args?: Array<any>,
|
|
65
|
+
options?: {
|
|
66
|
+
blockIdentifier?: BlockIdentifier;
|
|
67
|
+
}
|
|
68
|
+
): Promise<Result>;
|
|
61
69
|
|
|
62
70
|
/**
|
|
63
71
|
* Invokes a method on a contract
|
|
@@ -66,7 +74,11 @@ export abstract class ContractInterface {
|
|
|
66
74
|
* @param args Array of the arguments for the invoke
|
|
67
75
|
* @returns Add Transaction Response
|
|
68
76
|
*/
|
|
69
|
-
public abstract invoke(
|
|
77
|
+
public abstract invoke(
|
|
78
|
+
method: string,
|
|
79
|
+
args?: Array<any>,
|
|
80
|
+
options?: Overrides
|
|
81
|
+
): Promise<AddTransactionResponse>;
|
|
70
82
|
|
|
71
83
|
/**
|
|
72
84
|
* Calls a method on a contract
|
|
@@ -74,7 +86,13 @@ export abstract class ContractInterface {
|
|
|
74
86
|
* @param method name of the method
|
|
75
87
|
* @param args Array of the arguments for the call
|
|
76
88
|
*/
|
|
77
|
-
public abstract estimate(
|
|
89
|
+
public abstract estimate(
|
|
90
|
+
method: string,
|
|
91
|
+
args?: Array<any>,
|
|
92
|
+
options?: {
|
|
93
|
+
blockIdentifier?: BlockIdentifier;
|
|
94
|
+
}
|
|
95
|
+
): Promise<any>;
|
|
78
96
|
|
|
79
97
|
/**
|
|
80
98
|
* Calls a method on a contract
|
package/src/provider/default.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
GetContractAddressesResponse,
|
|
15
15
|
GetTransactionResponse,
|
|
16
16
|
GetTransactionStatusResponse,
|
|
17
|
+
GetTransactionTraceResponse,
|
|
17
18
|
Invocation,
|
|
18
19
|
TransactionReceipt,
|
|
19
20
|
} from '../types';
|
|
@@ -167,14 +168,18 @@ export class Provider implements ProviderInterface {
|
|
|
167
168
|
*/
|
|
168
169
|
public async callContract(
|
|
169
170
|
{ contractAddress, entrypoint, calldata = [] }: Call,
|
|
170
|
-
|
|
171
|
+
{ blockIdentifier = 'pending' }: { blockIdentifier?: BlockIdentifier } = {}
|
|
171
172
|
): Promise<CallContractResponse> {
|
|
172
|
-
return this.fetchEndpoint(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
173
|
+
return this.fetchEndpoint(
|
|
174
|
+
'call_contract',
|
|
175
|
+
{ blockIdentifier },
|
|
176
|
+
{
|
|
177
|
+
signature: [],
|
|
178
|
+
contract_address: contractAddress,
|
|
179
|
+
entry_point_selector: getSelectorFromName(entrypoint),
|
|
180
|
+
calldata,
|
|
181
|
+
}
|
|
182
|
+
);
|
|
178
183
|
}
|
|
179
184
|
|
|
180
185
|
/**
|
|
@@ -202,7 +207,7 @@ export class Provider implements ProviderInterface {
|
|
|
202
207
|
*/
|
|
203
208
|
public async getCode(
|
|
204
209
|
contractAddress: string,
|
|
205
|
-
blockIdentifier: BlockIdentifier =
|
|
210
|
+
blockIdentifier: BlockIdentifier = 'pending'
|
|
206
211
|
): Promise<GetCodeResponse> {
|
|
207
212
|
return this.fetchEndpoint('get_code', { blockIdentifier, contractAddress });
|
|
208
213
|
}
|
|
@@ -222,7 +227,7 @@ export class Provider implements ProviderInterface {
|
|
|
222
227
|
public async getStorageAt(
|
|
223
228
|
contractAddress: string,
|
|
224
229
|
key: number,
|
|
225
|
-
blockIdentifier: BlockIdentifier =
|
|
230
|
+
blockIdentifier: BlockIdentifier = 'pending'
|
|
226
231
|
): Promise<object> {
|
|
227
232
|
return this.fetchEndpoint('get_storage_at', { blockIdentifier, contractAddress, key });
|
|
228
233
|
}
|
|
@@ -277,6 +282,18 @@ export class Provider implements ProviderInterface {
|
|
|
277
282
|
return this.fetchEndpoint('get_transaction', { transactionHash: txHashHex });
|
|
278
283
|
}
|
|
279
284
|
|
|
285
|
+
/**
|
|
286
|
+
* Gets the transaction trace from a tx id.
|
|
287
|
+
*
|
|
288
|
+
*
|
|
289
|
+
* @param txHash
|
|
290
|
+
* @returns the transaction trace
|
|
291
|
+
*/
|
|
292
|
+
public async getTransactionTrace(txHash: BigNumberish): Promise<GetTransactionTraceResponse> {
|
|
293
|
+
const txHashHex = toHex(toBN(txHash));
|
|
294
|
+
return this.fetchEndpoint('get_transaction_trace', { transactionHash: txHashHex });
|
|
295
|
+
}
|
|
296
|
+
|
|
280
297
|
/**
|
|
281
298
|
* Deploys a given compiled contract (json) to starknet
|
|
282
299
|
*
|
|
@@ -325,20 +342,8 @@ export class Provider implements ProviderInterface {
|
|
|
325
342
|
});
|
|
326
343
|
}
|
|
327
344
|
|
|
328
|
-
public estimateFee(invocation: Invocation): Promise<any> {
|
|
329
|
-
return this.fetchEndpoint('estimate_fee', undefined, {
|
|
330
|
-
// TODO: change the TYPE of the call
|
|
331
|
-
type: 'INVOKE_FUNCTION',
|
|
332
|
-
contract_address: invocation.contractAddress,
|
|
333
|
-
entry_point_selector: getSelectorFromName(invocation.entrypoint),
|
|
334
|
-
calldata: bigNumberishArrayToDecimalStringArray(invocation.calldata ?? []),
|
|
335
|
-
signature: bigNumberishArrayToDecimalStringArray(invocation.signature ?? []),
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
|
|
339
345
|
public async waitForTransaction(txHash: BigNumberish, retryInterval: number = 8000) {
|
|
340
346
|
let onchain = false;
|
|
341
|
-
await wait(retryInterval);
|
|
342
347
|
|
|
343
348
|
while (!onchain) {
|
|
344
349
|
// eslint-disable-next-line no-await-in-loop
|
|
@@ -346,9 +351,12 @@ export class Provider implements ProviderInterface {
|
|
|
346
351
|
// eslint-disable-next-line no-await-in-loop
|
|
347
352
|
const res = await this.getTransactionStatus(txHash);
|
|
348
353
|
|
|
349
|
-
|
|
354
|
+
const successStates = ['ACCEPTED_ON_L1', 'ACCEPTED_ON_L2', 'PENDING'];
|
|
355
|
+
const errorStates = ['REJECTED', 'NOT_RECEIVED'];
|
|
356
|
+
|
|
357
|
+
if (successStates.includes(res.tx_status)) {
|
|
350
358
|
onchain = true;
|
|
351
|
-
} else if (
|
|
359
|
+
} else if (errorStates.includes(res.tx_status)) {
|
|
352
360
|
const message = res.tx_failure_reason
|
|
353
361
|
? `${res.tx_status}: ${res.tx_failure_reason.code}\n${res.tx_failure_reason.error_message}`
|
|
354
362
|
: res.tx_status;
|