@d9-network/ink 1.2.6 → 1.3.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/index.cjs +91 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -7
- package/dist/index.d.mts +18 -7
- package/dist/index.mjs +92 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -570,15 +570,26 @@ type InkMessageResult<T$1> = {
|
|
|
570
570
|
value: unknown;
|
|
571
571
|
};
|
|
572
572
|
/**
|
|
573
|
-
*
|
|
574
|
-
*
|
|
575
|
-
*
|
|
573
|
+
* Runtime Result type emitted by Variant codecs.
|
|
574
|
+
* The generated TypeScript types often use `success/value`, while dynamic decoders
|
|
575
|
+
* return `{ type: "Ok" | "Err", value }`.
|
|
576
576
|
*/
|
|
577
|
-
type
|
|
577
|
+
type InkVariantResult<T$1> = {
|
|
578
|
+
type: "Ok";
|
|
579
|
+
value: T$1;
|
|
580
|
+
} | {
|
|
581
|
+
type: "Err";
|
|
582
|
+
value: unknown;
|
|
583
|
+
};
|
|
584
|
+
/**
|
|
585
|
+
* Recursively unwrap Result-like payloads from both generated descriptor types and
|
|
586
|
+
* runtime Variant codec output.
|
|
587
|
+
*/
|
|
588
|
+
type NormalizeResultPayload<T$1> = T$1 extends InkMessageResult<infer U> ? NormalizeResultPayload<Exclude<U, InkLangError>> : T$1 extends InkVariantResult<infer U> ? NormalizeResultPayload<U> : T$1;
|
|
578
589
|
/**
|
|
579
590
|
* Type helper to extract message response type (with MessageResult unwrapped)
|
|
580
591
|
*/
|
|
581
|
-
type MessageResponse<M$1 extends InkCallableDescriptor, K$1 extends keyof M$1> =
|
|
592
|
+
type MessageResponse<M$1 extends InkCallableDescriptor, K$1 extends keyof M$1> = NormalizeResultPayload<M$1[K$1]["response"]>;
|
|
582
593
|
/**
|
|
583
594
|
* D9 Ink Contract interface
|
|
584
595
|
*
|
|
@@ -885,10 +896,10 @@ interface D9InkSdkWithRpc extends D9InkSdk {
|
|
|
885
896
|
* });
|
|
886
897
|
*
|
|
887
898
|
* if (result.success) {
|
|
888
|
-
* console.log("Balance:", result.value
|
|
899
|
+
* console.log("Balance:", result.value);
|
|
889
900
|
*
|
|
890
901
|
* // Send transaction from the query result
|
|
891
|
-
* const txResult = await result.
|
|
902
|
+
* const txResult = await result.send().signAndSubmit(aliceSigner);
|
|
892
903
|
* }
|
|
893
904
|
*
|
|
894
905
|
* // Or send directly
|
package/dist/index.d.mts
CHANGED
|
@@ -570,15 +570,26 @@ type InkMessageResult<T$1> = {
|
|
|
570
570
|
value: unknown;
|
|
571
571
|
};
|
|
572
572
|
/**
|
|
573
|
-
*
|
|
574
|
-
*
|
|
575
|
-
*
|
|
573
|
+
* Runtime Result type emitted by Variant codecs.
|
|
574
|
+
* The generated TypeScript types often use `success/value`, while dynamic decoders
|
|
575
|
+
* return `{ type: "Ok" | "Err", value }`.
|
|
576
576
|
*/
|
|
577
|
-
type
|
|
577
|
+
type InkVariantResult<T$1> = {
|
|
578
|
+
type: "Ok";
|
|
579
|
+
value: T$1;
|
|
580
|
+
} | {
|
|
581
|
+
type: "Err";
|
|
582
|
+
value: unknown;
|
|
583
|
+
};
|
|
584
|
+
/**
|
|
585
|
+
* Recursively unwrap Result-like payloads from both generated descriptor types and
|
|
586
|
+
* runtime Variant codec output.
|
|
587
|
+
*/
|
|
588
|
+
type NormalizeResultPayload<T$1> = T$1 extends InkMessageResult<infer U> ? NormalizeResultPayload<Exclude<U, InkLangError>> : T$1 extends InkVariantResult<infer U> ? NormalizeResultPayload<U> : T$1;
|
|
578
589
|
/**
|
|
579
590
|
* Type helper to extract message response type (with MessageResult unwrapped)
|
|
580
591
|
*/
|
|
581
|
-
type MessageResponse<M$1 extends InkCallableDescriptor, K$1 extends keyof M$1> =
|
|
592
|
+
type MessageResponse<M$1 extends InkCallableDescriptor, K$1 extends keyof M$1> = NormalizeResultPayload<M$1[K$1]["response"]>;
|
|
582
593
|
/**
|
|
583
594
|
* D9 Ink Contract interface
|
|
584
595
|
*
|
|
@@ -885,10 +896,10 @@ interface D9InkSdkWithRpc extends D9InkSdk {
|
|
|
885
896
|
* });
|
|
886
897
|
*
|
|
887
898
|
* if (result.success) {
|
|
888
|
-
* console.log("Balance:", result.value
|
|
899
|
+
* console.log("Balance:", result.value);
|
|
889
900
|
*
|
|
890
901
|
* // Send transaction from the query result
|
|
891
|
-
* const txResult = await result.
|
|
902
|
+
* const txResult = await result.send().signAndSubmit(aliceSigner);
|
|
892
903
|
* }
|
|
893
904
|
*
|
|
894
905
|
* // Or send directly
|
package/dist/index.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import { ss58Decode } from "@polkadot-labs/hdkd-helpers";
|
|
|
6
6
|
import { HexSink, Src } from "@subsquid/scale-codec";
|
|
7
7
|
import { AccountId, Bytes as Bytes$1, Option, Struct, Tuple, Variant, Vector, _void, bool, i128, i16, i32, i64, i8, str, u128, u16, u32, u64, u8 } from "@polkadot-api/substrate-bindings";
|
|
8
8
|
import { blake2b } from "@noble/hashes/blake2.js";
|
|
9
|
-
import { AbortedError, AbortedError as AbortedError$1, ContractError, ContractError as ContractError$1, ContractExecutionError, D9_SS58_PREFIX, DecodeError, DecodeError as DecodeError$1, EncodeError, LangError, LangError as LangError$1, MetadataError, MetadataError as MetadataError$1, NetworkError, SignerError, TimeoutError, TimeoutError as TimeoutError$1, TransactionError, TransactionError as TransactionError$1, isContractError, isErrorType, toD9Address } from "@d9-network/spec";
|
|
9
|
+
import { AbortedError, AbortedError as AbortedError$1, ContractError, ContractError as ContractError$1, ContractExecutionError, ContractExecutionError as ContractExecutionError$1, D9_SS58_PREFIX, DecodeError, DecodeError as DecodeError$1, EncodeError, LangError, LangError as LangError$1, MetadataError, MetadataError as MetadataError$1, NetworkError, SignerError, TimeoutError, TimeoutError as TimeoutError$1, TransactionError, TransactionError as TransactionError$1, isContractError, isErrorType, toD9Address } from "@d9-network/spec";
|
|
10
10
|
import { catchError, filter, from, map, mergeMap, of, share } from "rxjs";
|
|
11
11
|
|
|
12
12
|
//#region src/encode.ts
|
|
@@ -993,6 +993,88 @@ function createTypedRpc(client) {
|
|
|
993
993
|
} });
|
|
994
994
|
}
|
|
995
995
|
|
|
996
|
+
//#endregion
|
|
997
|
+
//#region src/result-normalization.ts
|
|
998
|
+
function getTypeEntry(types, typeId) {
|
|
999
|
+
const entry = types.find((item) => item.id === typeId);
|
|
1000
|
+
if (!entry) throw new Error(`Type ${typeId} not found in metadata`);
|
|
1001
|
+
return entry;
|
|
1002
|
+
}
|
|
1003
|
+
function getResultTypeIds(typeEntry) {
|
|
1004
|
+
const path = typeEntry.type.path;
|
|
1005
|
+
if (!path || path[0] !== "Result") return null;
|
|
1006
|
+
const params = typeEntry.type.params;
|
|
1007
|
+
if (!params || params.length < 2) return null;
|
|
1008
|
+
const okTypeId = params[0]?.type;
|
|
1009
|
+
const errTypeId = params[1]?.type;
|
|
1010
|
+
if (okTypeId === void 0 || errTypeId === void 0) return null;
|
|
1011
|
+
return {
|
|
1012
|
+
okTypeId,
|
|
1013
|
+
errTypeId
|
|
1014
|
+
};
|
|
1015
|
+
}
|
|
1016
|
+
function hasOkErrVariants(typeEntry) {
|
|
1017
|
+
const variants = typeEntry.type.def.variant?.variants;
|
|
1018
|
+
if (!variants) return false;
|
|
1019
|
+
const names = new Set(variants.map((variant) => variant.name));
|
|
1020
|
+
return names.has("Ok") && names.has("Err");
|
|
1021
|
+
}
|
|
1022
|
+
function isRecord(value) {
|
|
1023
|
+
return typeof value === "object" && value !== null;
|
|
1024
|
+
}
|
|
1025
|
+
function isRuntimeResult(value) {
|
|
1026
|
+
if (!isRecord(value)) return false;
|
|
1027
|
+
if ("success" in value) return typeof value.success === "boolean" && "value" in value;
|
|
1028
|
+
if ("type" in value) return (value.type === "Ok" || value.type === "Err") && "value" in value;
|
|
1029
|
+
return false;
|
|
1030
|
+
}
|
|
1031
|
+
function isRuntimeResultSuccess(value) {
|
|
1032
|
+
if ("success" in value) return value.success;
|
|
1033
|
+
return value.type === "Ok";
|
|
1034
|
+
}
|
|
1035
|
+
function analyzeMessageReturn(metadata, messageLabel) {
|
|
1036
|
+
const types = metadata.types;
|
|
1037
|
+
const message = metadata.spec.messages.find((item) => item.label === messageLabel);
|
|
1038
|
+
if (!message) throw new Error(`Message "${messageLabel}" not found in metadata`);
|
|
1039
|
+
let currentTypeId = getResultTypeIds(getTypeEntry(types, message.returnType.type))?.okTypeId ?? message.returnType.type;
|
|
1040
|
+
let businessResultDepth = 0;
|
|
1041
|
+
while (true) {
|
|
1042
|
+
const currentType = getTypeEntry(types, currentTypeId);
|
|
1043
|
+
const resultTypeIds = getResultTypeIds(currentType);
|
|
1044
|
+
if (!resultTypeIds || !hasOkErrVariants(currentType)) break;
|
|
1045
|
+
businessResultDepth += 1;
|
|
1046
|
+
currentTypeId = resultTypeIds.okTypeId;
|
|
1047
|
+
}
|
|
1048
|
+
return {
|
|
1049
|
+
businessResultDepth,
|
|
1050
|
+
finalTypeId: currentTypeId
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
1053
|
+
function buildMessageReturnAnalysisMap(metadata) {
|
|
1054
|
+
const analysisMap = /* @__PURE__ */ new Map();
|
|
1055
|
+
const messages = metadata.spec.messages;
|
|
1056
|
+
for (const message of messages) analysisMap.set(message.label, analyzeMessageReturn(metadata, message.label));
|
|
1057
|
+
return analysisMap;
|
|
1058
|
+
}
|
|
1059
|
+
function normalizeDecodedResponse(value, businessResultDepth) {
|
|
1060
|
+
let current = value;
|
|
1061
|
+
for (let index = 0; index < businessResultDepth; index += 1) {
|
|
1062
|
+
if (!isRuntimeResult(current)) return {
|
|
1063
|
+
success: false,
|
|
1064
|
+
error: /* @__PURE__ */ new Error(`Expected Result payload at depth ${index + 1}, received ${typeof current}`)
|
|
1065
|
+
};
|
|
1066
|
+
if (!isRuntimeResultSuccess(current)) return {
|
|
1067
|
+
success: false,
|
|
1068
|
+
error: current.value
|
|
1069
|
+
};
|
|
1070
|
+
current = current.value;
|
|
1071
|
+
}
|
|
1072
|
+
return {
|
|
1073
|
+
success: true,
|
|
1074
|
+
value: current
|
|
1075
|
+
};
|
|
1076
|
+
}
|
|
1077
|
+
|
|
996
1078
|
//#endregion
|
|
997
1079
|
//#region src/contract.ts
|
|
998
1080
|
/**
|
|
@@ -1104,6 +1186,7 @@ function createD9InkContract(descriptor, address, options) {
|
|
|
1104
1186
|
const addressBytes = ss58ToBytes(address);
|
|
1105
1187
|
const rpc = createTypedRpc(client);
|
|
1106
1188
|
const messageCodecCache = /* @__PURE__ */ new Map();
|
|
1189
|
+
const messageReturnAnalysis = buildMessageReturnAnalysisMap(patchedMetadata);
|
|
1107
1190
|
function getMessageCodec(label) {
|
|
1108
1191
|
const cached = messageCodecCache.get(label);
|
|
1109
1192
|
if (cached) return cached;
|
|
@@ -1176,9 +1259,14 @@ function createD9InkContract(descriptor, address, options) {
|
|
|
1176
1259
|
};
|
|
1177
1260
|
decodedResponse = fallbackResult.value;
|
|
1178
1261
|
}
|
|
1262
|
+
const normalizedResponse = normalizeDecodedResponse(decodedResponse, messageReturnAnalysis.get(method)?.businessResultDepth ?? 0);
|
|
1263
|
+
if (!normalizedResponse.success) return {
|
|
1264
|
+
success: false,
|
|
1265
|
+
error: normalizedResponse.error instanceof Error ? new DecodeError$1(method, normalizedResponse.error.message, normalizedResponse.error) : new ContractExecutionError$1(method, normalizedResponse.error)
|
|
1266
|
+
};
|
|
1179
1267
|
return {
|
|
1180
1268
|
success: true,
|
|
1181
|
-
value:
|
|
1269
|
+
value: normalizedResponse.value,
|
|
1182
1270
|
events: [],
|
|
1183
1271
|
gasConsumed: callResult.gas.gasConsumed,
|
|
1184
1272
|
gasRequired: callResult.gas.gasRequired,
|
|
@@ -1364,10 +1452,10 @@ function createD9InkContract(descriptor, address, options) {
|
|
|
1364
1452
|
* });
|
|
1365
1453
|
*
|
|
1366
1454
|
* if (result.success) {
|
|
1367
|
-
* console.log("Balance:", result.value
|
|
1455
|
+
* console.log("Balance:", result.value);
|
|
1368
1456
|
*
|
|
1369
1457
|
* // Send transaction from the query result
|
|
1370
|
-
* const txResult = await result.
|
|
1458
|
+
* const txResult = await result.send().signAndSubmit(aliceSigner);
|
|
1371
1459
|
* }
|
|
1372
1460
|
*
|
|
1373
1461
|
* // Or send directly
|