@alephium/web3 2.0.0-rc.2 → 2.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/alephium-web3.min.js +1 -1
- package/dist/alephium-web3.min.js.map +1 -1
- package/dist/src/api/api-alephium.d.ts +25 -3
- package/dist/src/api/api-alephium.js +1 -1
- package/dist/src/api/types.d.ts +1 -0
- package/dist/src/api/types.js +24 -1
- package/dist/src/contract/contract.d.ts +2 -0
- package/dist/src/contract/contract.js +45 -3
- package/dist/src/contract/ralph.js +23 -0
- package/dist/src/signer/tx-builder.js +2 -1
- package/dist/src/signer/types.d.ts +8 -2
- package/dist/src/signer/types.js +14 -3
- package/dist/src/utils/sign.js +1 -1
- package/package.json +2 -2
- package/src/api/api-alephium.ts +25 -2
- package/src/api/types.ts +20 -0
- package/src/contract/contract.ts +54 -5
- package/src/contract/ralph.ts +37 -1
- package/src/signer/tx-builder.ts +2 -1
- package/src/signer/types.ts +17 -4
- package/src/utils/sign.ts +1 -1
|
@@ -131,6 +131,7 @@ export interface BlockEntry {
|
|
|
131
131
|
/** @format hex-string */
|
|
132
132
|
target: string;
|
|
133
133
|
ghostUncles: GhostUncleBlockEntry[];
|
|
134
|
+
conflictedTxs?: string[];
|
|
134
135
|
}
|
|
135
136
|
/** BlockHeaderEntry */
|
|
136
137
|
export interface BlockHeaderEntry {
|
|
@@ -250,6 +251,8 @@ export interface BuildExecuteScriptTx {
|
|
|
250
251
|
group?: number;
|
|
251
252
|
/** @format double */
|
|
252
253
|
gasEstimationMultiplier?: number;
|
|
254
|
+
/** @format uint256 */
|
|
255
|
+
dustAmount?: string;
|
|
253
256
|
}
|
|
254
257
|
/** BuildExecuteScriptTxResult */
|
|
255
258
|
export type BuildExecuteScriptTxResult = BuildGrouplessExecuteScriptTxResult | BuildSimpleExecuteScriptTxResult;
|
|
@@ -610,6 +613,20 @@ export interface Confirmed {
|
|
|
610
613
|
toGroupConfirmations: number;
|
|
611
614
|
type: string;
|
|
612
615
|
}
|
|
616
|
+
/** Conflicted */
|
|
617
|
+
export interface Conflicted {
|
|
618
|
+
/** @format block-hash */
|
|
619
|
+
blockHash: string;
|
|
620
|
+
/** @format int32 */
|
|
621
|
+
txIndex: number;
|
|
622
|
+
/** @format int32 */
|
|
623
|
+
chainConfirmations: number;
|
|
624
|
+
/** @format int32 */
|
|
625
|
+
fromGroupConfirmations: number;
|
|
626
|
+
/** @format int32 */
|
|
627
|
+
toGroupConfirmations: number;
|
|
628
|
+
type: string;
|
|
629
|
+
}
|
|
613
630
|
/** Constant */
|
|
614
631
|
export interface Constant {
|
|
615
632
|
name: string;
|
|
@@ -958,6 +975,8 @@ export interface RichAssetInput {
|
|
|
958
975
|
/** @format address */
|
|
959
976
|
address: string;
|
|
960
977
|
tokens: Token[];
|
|
978
|
+
/** @format 32-byte-hash */
|
|
979
|
+
outputRefTxId: string;
|
|
961
980
|
}
|
|
962
981
|
/** RichBlockAndEvents */
|
|
963
982
|
export interface RichBlockAndEvents {
|
|
@@ -988,6 +1007,7 @@ export interface RichBlockEntry {
|
|
|
988
1007
|
/** @format hex-string */
|
|
989
1008
|
target: string;
|
|
990
1009
|
ghostUncles: GhostUncleBlockEntry[];
|
|
1010
|
+
conflictedTxs?: string[];
|
|
991
1011
|
}
|
|
992
1012
|
/** RichBlocksAndEventsPerTimeStampRange */
|
|
993
1013
|
export interface RichBlocksAndEventsPerTimeStampRange {
|
|
@@ -1004,6 +1024,8 @@ export interface RichContractInput {
|
|
|
1004
1024
|
/** @format address */
|
|
1005
1025
|
address: string;
|
|
1006
1026
|
tokens: Token[];
|
|
1027
|
+
/** @format 32-byte-hash */
|
|
1028
|
+
outputRefTxId: string;
|
|
1007
1029
|
}
|
|
1008
1030
|
/** RichTransaction */
|
|
1009
1031
|
export interface RichTransaction {
|
|
@@ -1235,7 +1257,7 @@ export interface TxNotFound {
|
|
|
1235
1257
|
type: string;
|
|
1236
1258
|
}
|
|
1237
1259
|
/** TxStatus */
|
|
1238
|
-
export type TxStatus = Confirmed | MemPooled | TxNotFound;
|
|
1260
|
+
export type TxStatus = Confirmed | Conflicted | MemPooled | TxNotFound;
|
|
1239
1261
|
/** UTXO */
|
|
1240
1262
|
export interface UTXO {
|
|
1241
1263
|
ref: OutputRef;
|
|
@@ -1421,7 +1443,7 @@ export declare class HttpClient<SecurityDataType = unknown> {
|
|
|
1421
1443
|
}
|
|
1422
1444
|
/**
|
|
1423
1445
|
* @title Alephium API
|
|
1424
|
-
* @version
|
|
1446
|
+
* @version 4.2.0
|
|
1425
1447
|
* @baseUrl ../
|
|
1426
1448
|
*/
|
|
1427
1449
|
export declare class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDataType> {
|
|
@@ -2040,7 +2062,7 @@ export declare class Api<SecurityDataType extends unknown> extends HttpClient<Se
|
|
|
2040
2062
|
fromGroup?: number;
|
|
2041
2063
|
/** @format int32 */
|
|
2042
2064
|
toGroup?: number;
|
|
2043
|
-
}, params?: RequestParams) => Promise<Confirmed | MemPooled | TxNotFound>;
|
|
2065
|
+
}, params?: RequestParams) => Promise<Confirmed | Conflicted | MemPooled | TxNotFound>;
|
|
2044
2066
|
/**
|
|
2045
2067
|
* No description
|
|
2046
2068
|
*
|
package/dist/src/api/types.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export declare function toApiAddress(v0: Val): string;
|
|
|
22
22
|
export declare function toApiArray(tpe: string, v: Val): node.Val;
|
|
23
23
|
export declare function toApiVal(v: Val, tpe: string): node.Val;
|
|
24
24
|
export declare function fromApiPrimitiveVal(value: node.Val, tpe: string, systemEvent?: boolean): Val;
|
|
25
|
+
export declare function decodeTupleType(tpe: string): string[];
|
|
25
26
|
export declare function decodeArrayType(tpe: string): [string, number];
|
|
26
27
|
export declare function getDefaultPrimitiveValue(tpe: string): Val;
|
|
27
28
|
export interface ApiRequestArguments {
|
package/dist/src/api/types.js
CHANGED
|
@@ -17,7 +17,7 @@ You should have received a copy of the GNU Lesser General Public License
|
|
|
17
17
|
along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
18
18
|
*/
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.StdInterfaceIds = exports.request = exports.requestWithLog = exports.forwardRequests = exports.getDefaultPrimitiveValue = exports.decodeArrayType = exports.fromApiPrimitiveVal = exports.toApiVal = exports.toApiArray = exports.toApiAddress = exports.toApiByteVec = exports.fromApiNumber256 = exports.toApiNumber256Optional = exports.toApiNumber256 = exports.toApiBoolean = exports.fromApiTokens = exports.fromApiToken = exports.toApiTokens = exports.toApiToken = exports.PrimitiveTypes = void 0;
|
|
20
|
+
exports.StdInterfaceIds = exports.request = exports.requestWithLog = exports.forwardRequests = exports.getDefaultPrimitiveValue = exports.decodeArrayType = exports.decodeTupleType = exports.fromApiPrimitiveVal = exports.toApiVal = exports.toApiArray = exports.toApiAddress = exports.toApiByteVec = exports.fromApiNumber256 = exports.toApiNumber256Optional = exports.toApiNumber256 = exports.toApiBoolean = exports.fromApiTokens = exports.fromApiToken = exports.toApiTokens = exports.toApiToken = exports.PrimitiveTypes = void 0;
|
|
21
21
|
const address_1 = require("../address");
|
|
22
22
|
const constants_1 = require("../constants");
|
|
23
23
|
const debug_1 = require("../debug");
|
|
@@ -159,6 +159,29 @@ function fromApiPrimitiveVal(value, tpe, systemEvent = false) {
|
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
exports.fromApiPrimitiveVal = fromApiPrimitiveVal;
|
|
162
|
+
function decodeTupleType(tpe) {
|
|
163
|
+
const str = tpe.slice(1, -1);
|
|
164
|
+
const types = [];
|
|
165
|
+
let current = '';
|
|
166
|
+
let depth = 0;
|
|
167
|
+
for (const char of str) {
|
|
168
|
+
if (char === ',' && depth === 0) {
|
|
169
|
+
types.push(current);
|
|
170
|
+
current = '';
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
if (char === '(')
|
|
174
|
+
depth++;
|
|
175
|
+
if (char === ')')
|
|
176
|
+
depth--;
|
|
177
|
+
current += char;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (current !== '')
|
|
181
|
+
types.push(current);
|
|
182
|
+
return types;
|
|
183
|
+
}
|
|
184
|
+
exports.decodeTupleType = decodeTupleType;
|
|
162
185
|
function decodeArrayType(tpe) {
|
|
163
186
|
const semiColonIndex = tpe.lastIndexOf(';');
|
|
164
187
|
if (semiColonIndex === -1) {
|
|
@@ -216,6 +216,7 @@ export interface ExecuteScriptParams<P extends Fields = Fields> {
|
|
|
216
216
|
tokens?: Token[];
|
|
217
217
|
gasAmount?: number;
|
|
218
218
|
gasPrice?: Number256;
|
|
219
|
+
dustAmount?: Number256;
|
|
219
220
|
}
|
|
220
221
|
export interface ExecuteScriptResult {
|
|
221
222
|
groupIndex: number;
|
|
@@ -259,6 +260,7 @@ export interface SignExecuteContractMethodParams<T extends Arguments = Arguments
|
|
|
259
260
|
tokens?: Token[];
|
|
260
261
|
gasAmount?: number;
|
|
261
262
|
gasPrice?: Number256;
|
|
263
|
+
dustAmount?: Number256;
|
|
262
264
|
}
|
|
263
265
|
export declare const CreateContractEventAddresses: string[];
|
|
264
266
|
export declare const DestroyContractEventAddresses: string[];
|
|
@@ -43,6 +43,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
43
43
|
exports.getContractCodeByCodeHash = exports.getTokenIdFromUnsignedTx = exports.getContractIdFromUnsignedTx = exports.getContractEventsCurrentCount = exports.multicallMethods = exports.signExecuteMethod = exports.callMethod = exports.subscribeContractEvents = exports.subscribeContractEvent = exports.decodeEvent = exports.subscribeContractDestroyedEvent = exports.subscribeContractCreatedEvent = exports.fetchContractState = exports.ContractInstance = exports.getMapItem = exports.RalphMap = exports.printDebugMessagesFromTx = exports.getDebugMessagesFromTx = exports.testMethod = exports.extractMapsFromApiResult = exports.addStdIdToFields = exports.subscribeEventsFromContract = exports.decodeContractDestroyedEvent = exports.decodeContractCreatedEvent = exports.DestroyContractEventAddresses = exports.CreateContractEventAddresses = exports.ExecutableScript = exports.ContractFactory = exports.randomTxId = exports.fromApiEventFields = exports.fromApiArray = exports.getDefaultValue = exports.fromApiFields = exports.Script = exports.Contract = exports.Artifact = exports.Struct = exports.DEFAULT_COMPILER_OPTIONS = exports.DEFAULT_NODE_COMPILER_OPTIONS = exports.StdIdFieldName = void 0;
|
|
44
44
|
const fs_1 = require("fs");
|
|
45
45
|
const api_1 = require("../api");
|
|
46
|
+
const signer_1 = require("../signer");
|
|
46
47
|
const ralph = __importStar(require("./ralph"));
|
|
47
48
|
const utils_1 = require("../utils");
|
|
48
49
|
const address_1 = require("../address");
|
|
@@ -53,6 +54,7 @@ const blake = __importStar(require("blakejs"));
|
|
|
53
54
|
const debug_1 = require("../debug");
|
|
54
55
|
const codec_1 = require("../codec");
|
|
55
56
|
const error_1 = require("../error");
|
|
57
|
+
const script_codec_1 = require("../codec/script-codec");
|
|
56
58
|
const crypto = new utils_1.WebCrypto();
|
|
57
59
|
exports.StdIdFieldName = '__stdInterfaceId';
|
|
58
60
|
exports.DEFAULT_NODE_COMPILER_OPTIONS = {
|
|
@@ -522,14 +524,18 @@ class Script extends Artifact {
|
|
|
522
524
|
}
|
|
523
525
|
async txParamsForExecution(params) {
|
|
524
526
|
const selectedAccount = await params.signer.getSelectedAccount();
|
|
527
|
+
const bytecode = this.buildByteCodeToDeploy(params.initialFields ?? {});
|
|
528
|
+
const group = getGroupFromTxScript(bytecode, selectedAccount);
|
|
525
529
|
const signerParams = {
|
|
526
530
|
signerAddress: selectedAccount.address,
|
|
527
531
|
signerKeyType: selectedAccount.keyType,
|
|
528
|
-
bytecode
|
|
532
|
+
bytecode,
|
|
529
533
|
attoAlphAmount: params.attoAlphAmount,
|
|
530
534
|
tokens: params.tokens,
|
|
531
535
|
gasAmount: params.gasAmount,
|
|
532
|
-
gasPrice: params.gasPrice
|
|
536
|
+
gasPrice: params.gasPrice,
|
|
537
|
+
group,
|
|
538
|
+
dustAmount: params.dustAmount
|
|
533
539
|
};
|
|
534
540
|
return signerParams;
|
|
535
541
|
}
|
|
@@ -543,6 +549,33 @@ class Script extends Artifact {
|
|
|
543
549
|
}
|
|
544
550
|
}
|
|
545
551
|
exports.Script = Script;
|
|
552
|
+
function getGroupFromTxScript(bytecode, account) {
|
|
553
|
+
if ((0, signer_1.isGroupedAccount)(account))
|
|
554
|
+
return account.group;
|
|
555
|
+
const script = script_codec_1.scriptCodec.decode((0, utils_1.hexToBinUnsafe)(bytecode));
|
|
556
|
+
const instrs = script.methods.flatMap((method) => method.instrs);
|
|
557
|
+
for (let index = 0; index < instrs.length - 1; index += 1) {
|
|
558
|
+
const instr = instrs[`${index}`];
|
|
559
|
+
const nextInstr = instrs[index + 1];
|
|
560
|
+
if (instr.name === 'BytesConst' &&
|
|
561
|
+
instr.value.length === 32 &&
|
|
562
|
+
(nextInstr.name === 'CallExternal' || nextInstr.name === 'CallExternalBySelector')) {
|
|
563
|
+
const groupIndex = instr.value[instr.value.length - 1];
|
|
564
|
+
if (groupIndex >= 0 && groupIndex < constants_1.TOTAL_NUMBER_OF_GROUPS) {
|
|
565
|
+
return groupIndex;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
for (const instr of instrs) {
|
|
570
|
+
if (instr.name === 'BytesConst' && instr.value.length === 32) {
|
|
571
|
+
const groupIndex = instr.value[instr.value.length - 1];
|
|
572
|
+
if (groupIndex >= 0 && groupIndex < constants_1.TOTAL_NUMBER_OF_GROUPS) {
|
|
573
|
+
return groupIndex;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
return (0, address_1.groupOfAddress)(account.address);
|
|
578
|
+
}
|
|
546
579
|
function fromApiFields(immFields, mutFields, fieldsSig, structs) {
|
|
547
580
|
let [immIndex, mutIndex] = [0, 0];
|
|
548
581
|
const func = (type, isMutable) => {
|
|
@@ -562,6 +595,13 @@ function buildVal(isMutable, type, structs, func) {
|
|
|
562
595
|
const [baseType, size] = (0, api_1.decodeArrayType)(type);
|
|
563
596
|
return Array.from(Array(size).keys()).map(() => buildVal(isMutable, baseType, structs, func));
|
|
564
597
|
}
|
|
598
|
+
if (type.startsWith('(')) {
|
|
599
|
+
const tuple = (0, api_1.decodeTupleType)(type);
|
|
600
|
+
return tuple.reduce((acc, fieldType) => {
|
|
601
|
+
acc.push(buildVal(isMutable, fieldType, structs, func));
|
|
602
|
+
return acc;
|
|
603
|
+
}, []);
|
|
604
|
+
}
|
|
565
605
|
const struct = structs.find((s) => s.name === type);
|
|
566
606
|
if (struct !== undefined) {
|
|
567
607
|
return struct.fieldNames.reduce((acc, name, index) => {
|
|
@@ -1265,7 +1305,9 @@ async function signExecuteMethod(contract, instance, methodName, params) {
|
|
|
1265
1305
|
attoAlphAmount: params.attoAlphAmount,
|
|
1266
1306
|
tokens: params.tokens,
|
|
1267
1307
|
gasAmount: params.gasAmount,
|
|
1268
|
-
gasPrice: params.gasPrice
|
|
1308
|
+
gasPrice: params.gasPrice,
|
|
1309
|
+
group: instance.groupIndex,
|
|
1310
|
+
dustAmount: params.dustAmount
|
|
1269
1311
|
};
|
|
1270
1312
|
const result = (await signer.signAndSubmitExecuteScriptTx(signerParams));
|
|
1271
1313
|
if ((0, debug_1.isContractDebugMessageEnabled)() && isDevnet) {
|
|
@@ -178,6 +178,16 @@ function calcFieldSize(type, isMutable, structs) {
|
|
|
178
178
|
const base = calcFieldSize(baseType, isMutable, structs);
|
|
179
179
|
return { immFields: base.immFields * size, mutFields: base.mutFields * size };
|
|
180
180
|
}
|
|
181
|
+
if (type.startsWith('(')) {
|
|
182
|
+
const tuple = (0, api_1.decodeTupleType)(type);
|
|
183
|
+
return tuple.reduce((acc, fieldType) => {
|
|
184
|
+
const subFieldSize = calcFieldSize(fieldType, isMutable, structs);
|
|
185
|
+
return {
|
|
186
|
+
immFields: acc.immFields + subFieldSize.immFields,
|
|
187
|
+
mutFields: acc.mutFields + subFieldSize.mutFields
|
|
188
|
+
};
|
|
189
|
+
}, { immFields: 0, mutFields: 0 });
|
|
190
|
+
}
|
|
181
191
|
return isMutable ? { immFields: 0, mutFields: 1 } : { immFields: 1, mutFields: 0 };
|
|
182
192
|
}
|
|
183
193
|
exports.calcFieldSize = calcFieldSize;
|
|
@@ -251,6 +261,10 @@ function typeLength(typ, structs) {
|
|
|
251
261
|
const [baseType, size] = (0, api_1.decodeArrayType)(typ);
|
|
252
262
|
return size * typeLength(baseType, structs);
|
|
253
263
|
}
|
|
264
|
+
if (typ.startsWith('(')) {
|
|
265
|
+
const tuple = (0, api_1.decodeTupleType)(typ);
|
|
266
|
+
return tuple.reduce((acc, fieldType) => acc + typeLength(fieldType, structs), 0);
|
|
267
|
+
}
|
|
254
268
|
const struct = structs.find((s) => s.name === typ);
|
|
255
269
|
if (struct !== undefined) {
|
|
256
270
|
return struct.fieldTypes.reduce((acc, fieldType) => acc + typeLength(fieldType, structs), 0);
|
|
@@ -277,6 +291,15 @@ function flattenField(isMutable, name, type, value, structs) {
|
|
|
277
291
|
return flattenField(isMutable, `${name}[${index}]`, baseType, item, structs);
|
|
278
292
|
});
|
|
279
293
|
}
|
|
294
|
+
if (Array.isArray(value) && type.startsWith('(')) {
|
|
295
|
+
const tuple = (0, api_1.decodeTupleType)(type);
|
|
296
|
+
if (value.length !== tuple.length) {
|
|
297
|
+
throw Error(`Invalid tuple length, expected ${tuple.length}, got ${value.length}`);
|
|
298
|
+
}
|
|
299
|
+
return tuple.flatMap((fieldType, index) => {
|
|
300
|
+
return flattenField(isMutable, `${name}._${index}`, fieldType, value[`${index}`], structs);
|
|
301
|
+
});
|
|
302
|
+
}
|
|
280
303
|
const struct = structs.find((s) => s.name === type);
|
|
281
304
|
if (struct !== undefined) {
|
|
282
305
|
if (typeof value !== 'object') {
|
|
@@ -149,13 +149,14 @@ class TransactionBuilder {
|
|
|
149
149
|
}
|
|
150
150
|
buildExecuteScriptTxParams(params, publicKey) {
|
|
151
151
|
TransactionBuilder.validatePublicKey(params, publicKey, params.signerKeyType);
|
|
152
|
-
const { attoAlphAmount, tokens, gasPrice, ...rest } = params;
|
|
152
|
+
const { attoAlphAmount, tokens, gasPrice, dustAmount, ...rest } = params;
|
|
153
153
|
return {
|
|
154
154
|
fromPublicKey: publicKey,
|
|
155
155
|
fromPublicKeyType: params.signerKeyType,
|
|
156
156
|
attoAlphAmount: (0, api_1.toApiNumber256Optional)(attoAlphAmount),
|
|
157
157
|
tokens: (0, api_1.toApiTokens)(tokens),
|
|
158
158
|
gasPrice: (0, api_1.toApiNumber256Optional)(gasPrice),
|
|
159
|
+
dustAmount: (0, api_1.toApiNumber256Optional)(dustAmount),
|
|
159
160
|
...rest
|
|
160
161
|
};
|
|
161
162
|
}
|
|
@@ -11,8 +11,11 @@ export interface Destination {
|
|
|
11
11
|
lockTime?: number;
|
|
12
12
|
message?: string;
|
|
13
13
|
}
|
|
14
|
-
export
|
|
15
|
-
export
|
|
14
|
+
export declare const groupedKeyTypes: readonly ["default", "bip340-schnorr"];
|
|
15
|
+
export declare const grouplessKeyTypes: readonly ["gl-secp256k1", "gl-secp256r1", "gl-ed25519", "gl-webauthn"];
|
|
16
|
+
export declare const keyTypes: readonly ["default", "bip340-schnorr", "gl-secp256k1", "gl-secp256r1", "gl-ed25519", "gl-webauthn"];
|
|
17
|
+
export type GroupedKeyType = (typeof groupedKeyTypes)[number];
|
|
18
|
+
export type GrouplessKeyType = (typeof grouplessKeyTypes)[number];
|
|
16
19
|
export type KeyType = GroupedKeyType | GrouplessKeyType;
|
|
17
20
|
export interface GroupedAccount {
|
|
18
21
|
keyType: GroupedKeyType;
|
|
@@ -26,6 +29,8 @@ export interface GrouplessAccount {
|
|
|
26
29
|
publicKey: string;
|
|
27
30
|
}
|
|
28
31
|
export type Account = GroupedAccount | GrouplessAccount;
|
|
32
|
+
export declare function isGroupedKeyType(keyType: KeyType): keyType is GroupedKeyType;
|
|
33
|
+
export declare function isGrouplessKeyType(keyType: KeyType): keyType is GrouplessKeyType;
|
|
29
34
|
export declare function isGroupedAccount(account: Account): account is GroupedAccount;
|
|
30
35
|
export declare function isGrouplessAccount(account: Account): account is GrouplessAccount;
|
|
31
36
|
export type SignerAddress = {
|
|
@@ -82,6 +87,7 @@ export interface SignExecuteScriptTxParams {
|
|
|
82
87
|
gasPrice?: Number256;
|
|
83
88
|
gasEstimationMultiplier?: number;
|
|
84
89
|
group?: number;
|
|
90
|
+
dustAmount?: Number256;
|
|
85
91
|
}
|
|
86
92
|
export interface SignExecuteScriptTxResult {
|
|
87
93
|
groupIndex: number;
|
package/dist/src/signer/types.js
CHANGED
|
@@ -17,15 +17,26 @@ You should have received a copy of the GNU Lesser General Public License
|
|
|
17
17
|
along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
18
18
|
*/
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.isGrouplessAccount = exports.isGroupedAccount = void 0;
|
|
20
|
+
exports.isGrouplessAccount = exports.isGroupedAccount = exports.isGrouplessKeyType = exports.isGroupedKeyType = exports.keyTypes = exports.grouplessKeyTypes = exports.groupedKeyTypes = void 0;
|
|
21
21
|
const utils_1 = require("../utils");
|
|
22
22
|
utils_1.assertType;
|
|
23
|
+
exports.groupedKeyTypes = ['default', 'bip340-schnorr'];
|
|
24
|
+
exports.grouplessKeyTypes = ['gl-secp256k1', 'gl-secp256r1', 'gl-ed25519', 'gl-webauthn'];
|
|
25
|
+
exports.keyTypes = [...exports.groupedKeyTypes, ...exports.grouplessKeyTypes];
|
|
26
|
+
function isGroupedKeyType(keyType) {
|
|
27
|
+
return keyType === 'default' || keyType === 'bip340-schnorr';
|
|
28
|
+
}
|
|
29
|
+
exports.isGroupedKeyType = isGroupedKeyType;
|
|
30
|
+
function isGrouplessKeyType(keyType) {
|
|
31
|
+
return keyType !== 'default' && keyType !== 'bip340-schnorr';
|
|
32
|
+
}
|
|
33
|
+
exports.isGrouplessKeyType = isGrouplessKeyType;
|
|
23
34
|
function isGroupedAccount(account) {
|
|
24
|
-
return account.keyType
|
|
35
|
+
return isGroupedKeyType(account.keyType);
|
|
25
36
|
}
|
|
26
37
|
exports.isGroupedAccount = isGroupedAccount;
|
|
27
38
|
function isGrouplessAccount(account) {
|
|
28
|
-
return account.keyType
|
|
39
|
+
return isGrouplessKeyType(account.keyType);
|
|
29
40
|
}
|
|
30
41
|
exports.isGrouplessAccount = isGrouplessAccount;
|
|
31
42
|
(0, utils_1.assertType)();
|
package/dist/src/utils/sign.js
CHANGED
|
@@ -59,7 +59,7 @@ necc.utils.hmacSha256Sync = (key, ...messages) => {
|
|
|
59
59
|
};
|
|
60
60
|
function checkKeyType(keyType) {
|
|
61
61
|
if (keyType !== 'default' && keyType !== 'bip340-schnorr' && keyType !== 'gl-secp256k1') {
|
|
62
|
-
throw new Error(`Invalid key type ${keyType}`);
|
|
62
|
+
throw new Error(`Invalid key type ${keyType}, only supports secp256k1 and schnorr for now`);
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
// hash has to be 32 bytes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alephium/web3",
|
|
3
|
-
"version": "2.0.0
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "A JS/TS library to interact with the Alephium platform",
|
|
5
5
|
"license": "GPL",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
"author": "Alephium dev <dev@alephium.org>",
|
|
35
35
|
"config": {
|
|
36
|
-
"alephium_version": "
|
|
36
|
+
"alephium_version": "4.2.0",
|
|
37
37
|
"explorer_backend_version": "2.3.2"
|
|
38
38
|
},
|
|
39
39
|
"type": "commonjs",
|
package/src/api/api-alephium.ts
CHANGED
|
@@ -155,6 +155,7 @@ export interface BlockEntry {
|
|
|
155
155
|
/** @format hex-string */
|
|
156
156
|
target: string
|
|
157
157
|
ghostUncles: GhostUncleBlockEntry[]
|
|
158
|
+
conflictedTxs?: string[]
|
|
158
159
|
}
|
|
159
160
|
|
|
160
161
|
/** BlockHeaderEntry */
|
|
@@ -292,6 +293,8 @@ export interface BuildExecuteScriptTx {
|
|
|
292
293
|
group?: number
|
|
293
294
|
/** @format double */
|
|
294
295
|
gasEstimationMultiplier?: number
|
|
296
|
+
/** @format uint256 */
|
|
297
|
+
dustAmount?: string
|
|
295
298
|
}
|
|
296
299
|
|
|
297
300
|
/** BuildExecuteScriptTxResult */
|
|
@@ -684,6 +687,21 @@ export interface Confirmed {
|
|
|
684
687
|
type: string
|
|
685
688
|
}
|
|
686
689
|
|
|
690
|
+
/** Conflicted */
|
|
691
|
+
export interface Conflicted {
|
|
692
|
+
/** @format block-hash */
|
|
693
|
+
blockHash: string
|
|
694
|
+
/** @format int32 */
|
|
695
|
+
txIndex: number
|
|
696
|
+
/** @format int32 */
|
|
697
|
+
chainConfirmations: number
|
|
698
|
+
/** @format int32 */
|
|
699
|
+
fromGroupConfirmations: number
|
|
700
|
+
/** @format int32 */
|
|
701
|
+
toGroupConfirmations: number
|
|
702
|
+
type: string
|
|
703
|
+
}
|
|
704
|
+
|
|
687
705
|
/** Constant */
|
|
688
706
|
export interface Constant {
|
|
689
707
|
name: string
|
|
@@ -1085,6 +1103,8 @@ export interface RichAssetInput {
|
|
|
1085
1103
|
/** @format address */
|
|
1086
1104
|
address: string
|
|
1087
1105
|
tokens: Token[]
|
|
1106
|
+
/** @format 32-byte-hash */
|
|
1107
|
+
outputRefTxId: string
|
|
1088
1108
|
}
|
|
1089
1109
|
|
|
1090
1110
|
/** RichBlockAndEvents */
|
|
@@ -1117,6 +1137,7 @@ export interface RichBlockEntry {
|
|
|
1117
1137
|
/** @format hex-string */
|
|
1118
1138
|
target: string
|
|
1119
1139
|
ghostUncles: GhostUncleBlockEntry[]
|
|
1140
|
+
conflictedTxs?: string[]
|
|
1120
1141
|
}
|
|
1121
1142
|
|
|
1122
1143
|
/** RichBlocksAndEventsPerTimeStampRange */
|
|
@@ -1135,6 +1156,8 @@ export interface RichContractInput {
|
|
|
1135
1156
|
/** @format address */
|
|
1136
1157
|
address: string
|
|
1137
1158
|
tokens: Token[]
|
|
1159
|
+
/** @format 32-byte-hash */
|
|
1160
|
+
outputRefTxId: string
|
|
1138
1161
|
}
|
|
1139
1162
|
|
|
1140
1163
|
/** RichTransaction */
|
|
@@ -1394,7 +1417,7 @@ export interface TxNotFound {
|
|
|
1394
1417
|
}
|
|
1395
1418
|
|
|
1396
1419
|
/** TxStatus */
|
|
1397
|
-
export type TxStatus = Confirmed | MemPooled | TxNotFound
|
|
1420
|
+
export type TxStatus = Confirmed | Conflicted | MemPooled | TxNotFound
|
|
1398
1421
|
|
|
1399
1422
|
/** UTXO */
|
|
1400
1423
|
export interface UTXO {
|
|
@@ -1754,7 +1777,7 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
1754
1777
|
|
|
1755
1778
|
/**
|
|
1756
1779
|
* @title Alephium API
|
|
1757
|
-
* @version
|
|
1780
|
+
* @version 4.2.0
|
|
1758
1781
|
* @baseUrl ../
|
|
1759
1782
|
*/
|
|
1760
1783
|
export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDataType> {
|
package/src/api/types.ts
CHANGED
|
@@ -160,6 +160,26 @@ export function fromApiPrimitiveVal(value: node.Val, tpe: string, systemEvent =
|
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
+
export function decodeTupleType(tpe: string): string[] {
|
|
164
|
+
const str = tpe.slice(1, -1)
|
|
165
|
+
const types: string[] = []
|
|
166
|
+
let current = ''
|
|
167
|
+
let depth = 0
|
|
168
|
+
|
|
169
|
+
for (const char of str) {
|
|
170
|
+
if (char === ',' && depth === 0) {
|
|
171
|
+
types.push(current)
|
|
172
|
+
current = ''
|
|
173
|
+
} else {
|
|
174
|
+
if (char === '(') depth++
|
|
175
|
+
if (char === ')') depth--
|
|
176
|
+
current += char
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (current !== '') types.push(current)
|
|
180
|
+
return types
|
|
181
|
+
}
|
|
182
|
+
|
|
163
183
|
export function decodeArrayType(tpe: string): [string, number] {
|
|
164
184
|
const semiColonIndex = tpe.lastIndexOf(';')
|
|
165
185
|
if (semiColonIndex === -1) {
|
package/src/contract/contract.ts
CHANGED
|
@@ -33,7 +33,8 @@ import {
|
|
|
33
33
|
PrimitiveTypes,
|
|
34
34
|
decodeArrayType,
|
|
35
35
|
fromApiPrimitiveVal,
|
|
36
|
-
tryGetCallResult
|
|
36
|
+
tryGetCallResult,
|
|
37
|
+
decodeTupleType
|
|
37
38
|
} from '../api'
|
|
38
39
|
import {
|
|
39
40
|
SignDeployContractTxParams,
|
|
@@ -41,7 +42,9 @@ import {
|
|
|
41
42
|
SignExecuteScriptTxParams,
|
|
42
43
|
SignerProvider,
|
|
43
44
|
Address,
|
|
44
|
-
SignExecuteScriptTxResult
|
|
45
|
+
SignExecuteScriptTxResult,
|
|
46
|
+
Account,
|
|
47
|
+
isGroupedAccount
|
|
45
48
|
} from '../signer'
|
|
46
49
|
import * as ralph from './ralph'
|
|
47
50
|
import {
|
|
@@ -97,6 +100,7 @@ import {
|
|
|
97
100
|
} from '../codec'
|
|
98
101
|
import { TraceableError } from '../error'
|
|
99
102
|
import { SimulationResult } from '../api/api-alephium'
|
|
103
|
+
import { scriptCodec } from '../codec/script-codec'
|
|
100
104
|
|
|
101
105
|
const crypto = new WebCrypto()
|
|
102
106
|
|
|
@@ -794,14 +798,18 @@ export class Script extends Artifact {
|
|
|
794
798
|
|
|
795
799
|
async txParamsForExecution<P extends Fields>(params: ExecuteScriptParams<P>): Promise<SignExecuteScriptTxParams> {
|
|
796
800
|
const selectedAccount = await params.signer.getSelectedAccount()
|
|
801
|
+
const bytecode = this.buildByteCodeToDeploy(params.initialFields ?? {})
|
|
802
|
+
const group = getGroupFromTxScript(bytecode, selectedAccount)
|
|
797
803
|
const signerParams: SignExecuteScriptTxParams = {
|
|
798
804
|
signerAddress: selectedAccount.address,
|
|
799
805
|
signerKeyType: selectedAccount.keyType,
|
|
800
|
-
bytecode
|
|
806
|
+
bytecode,
|
|
801
807
|
attoAlphAmount: params.attoAlphAmount,
|
|
802
808
|
tokens: params.tokens,
|
|
803
809
|
gasAmount: params.gasAmount,
|
|
804
|
-
gasPrice: params.gasPrice
|
|
810
|
+
gasPrice: params.gasPrice,
|
|
811
|
+
group,
|
|
812
|
+
dustAmount: params.dustAmount
|
|
805
813
|
}
|
|
806
814
|
return signerParams
|
|
807
815
|
}
|
|
@@ -815,6 +823,36 @@ export class Script extends Artifact {
|
|
|
815
823
|
}
|
|
816
824
|
}
|
|
817
825
|
|
|
826
|
+
function getGroupFromTxScript(bytecode: string, account: Account): number {
|
|
827
|
+
if (isGroupedAccount(account)) return account.group
|
|
828
|
+
|
|
829
|
+
const script = scriptCodec.decode(hexToBinUnsafe(bytecode))
|
|
830
|
+
const instrs = script.methods.flatMap((method) => method.instrs)
|
|
831
|
+
for (let index = 0; index < instrs.length - 1; index += 1) {
|
|
832
|
+
const instr = instrs[`${index}`]
|
|
833
|
+
const nextInstr = instrs[index + 1]
|
|
834
|
+
if (
|
|
835
|
+
instr.name === 'BytesConst' &&
|
|
836
|
+
instr.value.length === 32 &&
|
|
837
|
+
(nextInstr.name === 'CallExternal' || nextInstr.name === 'CallExternalBySelector')
|
|
838
|
+
) {
|
|
839
|
+
const groupIndex = instr.value[instr.value.length - 1]
|
|
840
|
+
if (groupIndex >= 0 && groupIndex < TOTAL_NUMBER_OF_GROUPS) {
|
|
841
|
+
return groupIndex
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
for (const instr of instrs) {
|
|
846
|
+
if (instr.name === 'BytesConst' && instr.value.length === 32) {
|
|
847
|
+
const groupIndex = instr.value[instr.value.length - 1]
|
|
848
|
+
if (groupIndex >= 0 && groupIndex < TOTAL_NUMBER_OF_GROUPS) {
|
|
849
|
+
return groupIndex
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
return groupOfAddress(account.address)
|
|
854
|
+
}
|
|
855
|
+
|
|
818
856
|
export function fromApiFields(
|
|
819
857
|
immFields: node.Val[],
|
|
820
858
|
mutFields: node.Val[],
|
|
@@ -845,6 +883,13 @@ function buildVal(
|
|
|
845
883
|
const [baseType, size] = decodeArrayType(type)
|
|
846
884
|
return Array.from(Array(size).keys()).map(() => buildVal(isMutable, baseType, structs, func))
|
|
847
885
|
}
|
|
886
|
+
if (type.startsWith('(')) {
|
|
887
|
+
const tuple = decodeTupleType(type)
|
|
888
|
+
return tuple.reduce<Val[]>((acc, fieldType) => {
|
|
889
|
+
acc.push(buildVal(isMutable, fieldType, structs, func))
|
|
890
|
+
return acc
|
|
891
|
+
}, [])
|
|
892
|
+
}
|
|
848
893
|
const struct = structs.find((s) => s.name === type)
|
|
849
894
|
if (struct !== undefined) {
|
|
850
895
|
return struct.fieldNames.reduce((acc, name, index) => {
|
|
@@ -1190,6 +1235,7 @@ export interface ExecuteScriptParams<P extends Fields = Fields> {
|
|
|
1190
1235
|
tokens?: Token[]
|
|
1191
1236
|
gasAmount?: number
|
|
1192
1237
|
gasPrice?: Number256
|
|
1238
|
+
dustAmount?: Number256
|
|
1193
1239
|
}
|
|
1194
1240
|
|
|
1195
1241
|
export interface ExecuteScriptResult {
|
|
@@ -1239,6 +1285,7 @@ export interface SignExecuteContractMethodParams<T extends Arguments = Arguments
|
|
|
1239
1285
|
tokens?: Token[]
|
|
1240
1286
|
gasAmount?: number
|
|
1241
1287
|
gasPrice?: Number256
|
|
1288
|
+
dustAmount?: Number256
|
|
1242
1289
|
}
|
|
1243
1290
|
|
|
1244
1291
|
function specialContractAddress(eventIndex: number, groupIndex: number): string {
|
|
@@ -1963,7 +2010,9 @@ export async function signExecuteMethod<I extends ContractInstance, F extends Fi
|
|
|
1963
2010
|
attoAlphAmount: params.attoAlphAmount,
|
|
1964
2011
|
tokens: params.tokens,
|
|
1965
2012
|
gasAmount: params.gasAmount,
|
|
1966
|
-
gasPrice: params.gasPrice
|
|
2013
|
+
gasPrice: params.gasPrice,
|
|
2014
|
+
group: instance.groupIndex,
|
|
2015
|
+
dustAmount: params.dustAmount
|
|
1967
2016
|
}
|
|
1968
2017
|
|
|
1969
2018
|
const result = (await signer.signAndSubmitExecuteScriptTx(signerParams)) as SignExecuteScriptTxResult
|