@alephium/web3 0.43.0 → 0.45.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/codec/array-codec.js +1 -1
- package/dist/src/codec/asset-output-codec.js +3 -3
- package/dist/src/codec/bytestring-codec.js +4 -4
- package/dist/src/codec/compact-int-codec.d.ts +0 -3
- package/dist/src/codec/compact-int-codec.js +2 -12
- package/dist/src/codec/contract-codec.js +2 -2
- package/dist/src/codec/contract-output-codec.js +1 -1
- package/dist/src/codec/method-codec.js +12 -12
- package/dist/src/codec/script-codec.js +1 -1
- package/dist/src/contract/contract.d.ts +10 -1
- package/dist/src/contract/contract.js +177 -1
- package/dist/src/contract/ralph.d.ts +1 -0
- package/dist/src/contract/ralph.js +16 -1
- package/package.json +9 -3
- package/src/codec/array-codec.ts +2 -2
- package/src/codec/asset-output-codec.ts +4 -4
- package/src/codec/bytestring-codec.ts +5 -5
- package/src/codec/compact-int-codec.ts +2 -15
- package/src/codec/contract-codec.ts +2 -2
- package/src/codec/contract-output-codec.ts +2 -2
- package/src/codec/method-codec.ts +13 -13
- package/src/codec/script-codec.ts +2 -2
- package/src/contract/contract.ts +271 -2
- package/src/contract/ralph.ts +19 -1
|
@@ -17,7 +17,7 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
17
17
|
*/
|
|
18
18
|
import { Parser } from 'binary-parser'
|
|
19
19
|
import { ArrayCodec, DecodedArray } from './array-codec'
|
|
20
|
-
import { DecodedCompactInt,
|
|
20
|
+
import { DecodedCompactInt, compactSignedIntCodec } from './compact-int-codec'
|
|
21
21
|
import { Codec } from './codec'
|
|
22
22
|
import { instrsCodec, Instr } from './instr-codec'
|
|
23
23
|
|
|
@@ -82,13 +82,13 @@ export class MethodCodec implements Codec<DecodedMethod> {
|
|
|
82
82
|
.uint8('isPublic')
|
|
83
83
|
.uint8('assetModifier')
|
|
84
84
|
.nest('argsLength', {
|
|
85
|
-
type:
|
|
85
|
+
type: compactSignedIntCodec.parser
|
|
86
86
|
})
|
|
87
87
|
.nest('localsLength', {
|
|
88
|
-
type:
|
|
88
|
+
type: compactSignedIntCodec.parser
|
|
89
89
|
})
|
|
90
90
|
.nest('returnLength', {
|
|
91
|
-
type:
|
|
91
|
+
type: compactSignedIntCodec.parser
|
|
92
92
|
})
|
|
93
93
|
.nest('instrs', {
|
|
94
94
|
type: instrsCodec.parser
|
|
@@ -96,9 +96,9 @@ export class MethodCodec implements Codec<DecodedMethod> {
|
|
|
96
96
|
|
|
97
97
|
encode(input: DecodedMethod): Uint8Array {
|
|
98
98
|
const result = [input.isPublic, input.assetModifier]
|
|
99
|
-
result.push(...
|
|
100
|
-
result.push(...
|
|
101
|
-
result.push(...
|
|
99
|
+
result.push(...compactSignedIntCodec.encode(input.argsLength))
|
|
100
|
+
result.push(...compactSignedIntCodec.encode(input.localsLength))
|
|
101
|
+
result.push(...compactSignedIntCodec.encode(input.returnLength))
|
|
102
102
|
result.push(...instrsCodec.encode(input.instrs.value))
|
|
103
103
|
return new Uint8Array(result)
|
|
104
104
|
}
|
|
@@ -111,9 +111,9 @@ export class MethodCodec implements Codec<DecodedMethod> {
|
|
|
111
111
|
return {
|
|
112
112
|
isPublic: decodedMethod.isPublic === 1,
|
|
113
113
|
...decodeAssetModifier(decodedMethod.assetModifier),
|
|
114
|
-
argsLength:
|
|
115
|
-
localsLength:
|
|
116
|
-
returnLength:
|
|
114
|
+
argsLength: compactSignedIntCodec.toI32(decodedMethod.argsLength),
|
|
115
|
+
localsLength: compactSignedIntCodec.toI32(decodedMethod.localsLength),
|
|
116
|
+
returnLength: compactSignedIntCodec.toI32(decodedMethod.returnLength),
|
|
117
117
|
instrs: decodedMethod.instrs.value
|
|
118
118
|
}
|
|
119
119
|
}
|
|
@@ -122,9 +122,9 @@ export class MethodCodec implements Codec<DecodedMethod> {
|
|
|
122
122
|
return {
|
|
123
123
|
isPublic: method.isPublic ? 1 : 0,
|
|
124
124
|
assetModifier: encodeAssetModifier(method),
|
|
125
|
-
argsLength:
|
|
126
|
-
localsLength:
|
|
127
|
-
returnLength:
|
|
125
|
+
argsLength: compactSignedIntCodec.fromI32(method.argsLength),
|
|
126
|
+
localsLength: compactSignedIntCodec.fromI32(method.localsLength),
|
|
127
|
+
returnLength: compactSignedIntCodec.fromI32(method.returnLength),
|
|
128
128
|
instrs: instrsCodec.fromArray(method.instrs)
|
|
129
129
|
}
|
|
130
130
|
}
|
|
@@ -21,7 +21,7 @@ import { DecodedArray } from './array-codec'
|
|
|
21
21
|
import { Codec } from './codec'
|
|
22
22
|
import { DecodedMethod, methodsCodec, Method, MethodCodec } from './method-codec'
|
|
23
23
|
import { OptionCodec } from './option-codec'
|
|
24
|
-
import {
|
|
24
|
+
import { compactSignedIntCodec } from './compact-int-codec'
|
|
25
25
|
|
|
26
26
|
export interface DecodedScript {
|
|
27
27
|
methods: DecodedArray<DecodedMethod>
|
|
@@ -51,7 +51,7 @@ export class ScriptCodec implements Codec<DecodedScript> {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
encodeScript(inputTxScript: Script): Uint8Array {
|
|
54
|
-
const methodLength =
|
|
54
|
+
const methodLength = compactSignedIntCodec.fromI32(inputTxScript.methods.length)
|
|
55
55
|
const decodedMethods = inputTxScript.methods.map((method) => MethodCodec.fromMethod(method))
|
|
56
56
|
return this.encode({ methods: { value: decodedMethods, length: methodLength } })
|
|
57
57
|
}
|
package/src/contract/contract.ts
CHANGED
|
@@ -40,7 +40,8 @@ import {
|
|
|
40
40
|
SignDeployContractTxResult,
|
|
41
41
|
SignExecuteScriptTxParams,
|
|
42
42
|
SignerProvider,
|
|
43
|
-
Address
|
|
43
|
+
Address,
|
|
44
|
+
SignExecuteScriptTxResult
|
|
44
45
|
} from '../signer'
|
|
45
46
|
import * as ralph from './ralph'
|
|
46
47
|
import {
|
|
@@ -63,6 +64,8 @@ import * as blake from 'blakejs'
|
|
|
63
64
|
import { isContractDebugMessageEnabled } from '../debug'
|
|
64
65
|
import {
|
|
65
66
|
contract,
|
|
67
|
+
compactUnsignedIntCodec,
|
|
68
|
+
compactSignedIntCodec,
|
|
66
69
|
Method,
|
|
67
70
|
LoadLocal,
|
|
68
71
|
LoadImmFieldByIndex,
|
|
@@ -72,7 +75,19 @@ import {
|
|
|
72
75
|
ByteVecEq,
|
|
73
76
|
Assert,
|
|
74
77
|
StoreMutFieldByIndex,
|
|
75
|
-
DestroySelf
|
|
78
|
+
DestroySelf,
|
|
79
|
+
Pop,
|
|
80
|
+
byteStringCodec,
|
|
81
|
+
StoreLocal,
|
|
82
|
+
instrCodec,
|
|
83
|
+
U256Const,
|
|
84
|
+
Instr,
|
|
85
|
+
ApproveToken,
|
|
86
|
+
ApproveAlph,
|
|
87
|
+
CallExternal,
|
|
88
|
+
Dup,
|
|
89
|
+
CallerAddress,
|
|
90
|
+
ByteConst
|
|
76
91
|
} from '../codec'
|
|
77
92
|
|
|
78
93
|
const crypto = new WebCrypto()
|
|
@@ -1043,6 +1058,15 @@ export interface CallContractResult<R> {
|
|
|
1043
1058
|
debugMessages: DebugMessage[]
|
|
1044
1059
|
}
|
|
1045
1060
|
|
|
1061
|
+
export interface SignExecuteContractMethodParams<T extends Arguments = Arguments> {
|
|
1062
|
+
args: T
|
|
1063
|
+
signer: SignerProvider
|
|
1064
|
+
attoAlphAmount?: Number256
|
|
1065
|
+
tokens?: Token[]
|
|
1066
|
+
gasAmount?: number
|
|
1067
|
+
gasPrice?: Number256
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1046
1070
|
function specialContractAddress(eventIndex: number, groupIndex: number): string {
|
|
1047
1071
|
const bytes = new Uint8Array(32).fill(0)
|
|
1048
1072
|
bytes[30] = eventIndex
|
|
@@ -1606,6 +1630,251 @@ export async function callMethod<I extends ContractInstance, F extends Fields, A
|
|
|
1606
1630
|
return callResult as CallContractResult<R>
|
|
1607
1631
|
}
|
|
1608
1632
|
|
|
1633
|
+
export async function signExecuteMethod<I extends ContractInstance, F extends Fields, A extends Arguments, R>(
|
|
1634
|
+
contract: ContractFactory<I, F>,
|
|
1635
|
+
instance: ContractInstance,
|
|
1636
|
+
methodName: string,
|
|
1637
|
+
params: Optional<SignExecuteContractMethodParams<A>, 'args'>
|
|
1638
|
+
): Promise<SignExecuteScriptTxResult> {
|
|
1639
|
+
const methodIndex = contract.contract.getMethodIndex(methodName)
|
|
1640
|
+
const functionSig = contract.contract.functions[methodIndex]
|
|
1641
|
+
const usePreapprovedAssets = contract.contract.decodedMethods[methodIndex].usePreapprovedAssets
|
|
1642
|
+
const bytecodeTemplate = getBytecodeTemplate(
|
|
1643
|
+
methodIndex,
|
|
1644
|
+
usePreapprovedAssets,
|
|
1645
|
+
functionSig,
|
|
1646
|
+
contract.contract.structs,
|
|
1647
|
+
params.attoAlphAmount,
|
|
1648
|
+
params.tokens
|
|
1649
|
+
)
|
|
1650
|
+
|
|
1651
|
+
const fieldsSig = toFieldsSig(contract.contract.name, functionSig)
|
|
1652
|
+
const bytecode = ralph.buildScriptByteCode(
|
|
1653
|
+
bytecodeTemplate,
|
|
1654
|
+
{ __contract__: instance.contractId, ...params.args },
|
|
1655
|
+
fieldsSig,
|
|
1656
|
+
contract.contract.structs
|
|
1657
|
+
)
|
|
1658
|
+
|
|
1659
|
+
const signer = params.signer
|
|
1660
|
+
const selectedAccount = await signer.getSelectedAccount()
|
|
1661
|
+
const signerParams: SignExecuteScriptTxParams = {
|
|
1662
|
+
signerAddress: selectedAccount.address,
|
|
1663
|
+
signerKeyType: selectedAccount.keyType,
|
|
1664
|
+
bytecode: bytecode,
|
|
1665
|
+
attoAlphAmount: params.attoAlphAmount,
|
|
1666
|
+
tokens: params.tokens,
|
|
1667
|
+
gasAmount: params.gasAmount,
|
|
1668
|
+
gasPrice: params.gasPrice
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1671
|
+
return await signer.signAndSubmitExecuteScriptTx(signerParams)
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
function getBytecodeTemplate(
|
|
1675
|
+
methodIndex: number,
|
|
1676
|
+
usePreapprovedAssets: boolean,
|
|
1677
|
+
functionSig: FunctionSig,
|
|
1678
|
+
structs: Struct[],
|
|
1679
|
+
attoAlphAmount?: Number256,
|
|
1680
|
+
tokens?: Token[]
|
|
1681
|
+
): string {
|
|
1682
|
+
// For the default TxScript main function
|
|
1683
|
+
const numberOfMethods = '01'
|
|
1684
|
+
const isPublic = '01'
|
|
1685
|
+
const modifier = usePreapprovedAssets ? '03' : '00'
|
|
1686
|
+
const argsLength = '00'
|
|
1687
|
+
const returnsLength = '00'
|
|
1688
|
+
|
|
1689
|
+
const [templateVarStoreLocalInstrs, templateVarsLength] = getTemplateVarStoreLocalInstrs(functionSig, structs)
|
|
1690
|
+
|
|
1691
|
+
const approveAlphInstrs: string[] = getApproveAlphInstrs(usePreapprovedAssets ? attoAlphAmount : undefined)
|
|
1692
|
+
const approveTokensInstrs: string[] = getApproveTokensInstrs(usePreapprovedAssets ? tokens : undefined)
|
|
1693
|
+
const callerInstrs: string[] = getCallAddressInstrs(approveAlphInstrs.length / 2 + approveTokensInstrs.length / 3)
|
|
1694
|
+
|
|
1695
|
+
// First template var is the contract
|
|
1696
|
+
const functionArgsNum = encodeU256Const(BigInt(templateVarsLength - 1))
|
|
1697
|
+
const localsLength = encodeI32(templateVarStoreLocalInstrs.length / 2)
|
|
1698
|
+
|
|
1699
|
+
const templateVarLoadLocalInstrs = getTemplateVarLoadLocalInstrs(functionSig, structs)
|
|
1700
|
+
|
|
1701
|
+
const functionReturnTypesLength: number = functionSig.returnTypes.reduce(
|
|
1702
|
+
(acc, returnType) => acc + ralph.typeLength(returnType, structs),
|
|
1703
|
+
0
|
|
1704
|
+
)
|
|
1705
|
+
const functionReturnPopInstrs = encodeInstr(Pop).repeat(functionReturnTypesLength)
|
|
1706
|
+
const functionReturnNum = encodeU256Const(BigInt(functionReturnTypesLength))
|
|
1707
|
+
|
|
1708
|
+
const contractTemplateVar = '{0}' // always the 1st argument
|
|
1709
|
+
const externalCallInstr = encodeInstr(CallExternal(methodIndex))
|
|
1710
|
+
const numberOfInstrs = encodeI32(
|
|
1711
|
+
callerInstrs.length +
|
|
1712
|
+
approveAlphInstrs.length +
|
|
1713
|
+
approveTokensInstrs.length +
|
|
1714
|
+
templateVarStoreLocalInstrs.length +
|
|
1715
|
+
templateVarLoadLocalInstrs.length +
|
|
1716
|
+
functionReturnTypesLength +
|
|
1717
|
+
4 // functionArgsNum, functionReturnNum, contractTemplate, externalCallInstr
|
|
1718
|
+
)
|
|
1719
|
+
|
|
1720
|
+
return (
|
|
1721
|
+
numberOfMethods +
|
|
1722
|
+
isPublic +
|
|
1723
|
+
modifier +
|
|
1724
|
+
argsLength +
|
|
1725
|
+
localsLength +
|
|
1726
|
+
returnsLength +
|
|
1727
|
+
numberOfInstrs +
|
|
1728
|
+
callerInstrs.join('') +
|
|
1729
|
+
approveAlphInstrs.join('') +
|
|
1730
|
+
approveTokensInstrs.join('') +
|
|
1731
|
+
templateVarStoreLocalInstrs.join('') +
|
|
1732
|
+
templateVarLoadLocalInstrs.join('') +
|
|
1733
|
+
functionArgsNum +
|
|
1734
|
+
functionReturnNum +
|
|
1735
|
+
contractTemplateVar +
|
|
1736
|
+
externalCallInstr +
|
|
1737
|
+
functionReturnPopInstrs
|
|
1738
|
+
)
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
function getApproveAlphInstrs(attoAlphAmount?: Number256): string[] {
|
|
1742
|
+
const approveAlphInstrs: string[] = []
|
|
1743
|
+
if (attoAlphAmount) {
|
|
1744
|
+
const approvedAttoAlphAmount = encodeU256Const(BigInt(attoAlphAmount))
|
|
1745
|
+
approveAlphInstrs.push(approvedAttoAlphAmount)
|
|
1746
|
+
approveAlphInstrs.push(encodeInstr(ApproveAlph))
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
return approveAlphInstrs
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
function getApproveTokensInstrs(tokens?: Token[]): string[] {
|
|
1753
|
+
const approveTokensInstrs: string[] = []
|
|
1754
|
+
if (tokens) {
|
|
1755
|
+
tokens.forEach((token) => {
|
|
1756
|
+
const tokenIdBin = hexToBinUnsafe(token.id)
|
|
1757
|
+
approveTokensInstrs.push(
|
|
1758
|
+
encodeInstr(
|
|
1759
|
+
ByteConst({
|
|
1760
|
+
length: compactSignedIntCodec.fromI32(tokenIdBin.length),
|
|
1761
|
+
value: tokenIdBin
|
|
1762
|
+
})
|
|
1763
|
+
)
|
|
1764
|
+
)
|
|
1765
|
+
approveTokensInstrs.push(encodeU256Const(BigInt(token.amount)))
|
|
1766
|
+
approveTokensInstrs.push(encodeInstr(ApproveToken))
|
|
1767
|
+
})
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
return approveTokensInstrs
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
function getCallAddressInstrs(approveAssetsNum: number): string[] {
|
|
1774
|
+
const callerInstrs: string[] = []
|
|
1775
|
+
if (approveAssetsNum > 0) {
|
|
1776
|
+
callerInstrs.push(encodeInstr(CallerAddress))
|
|
1777
|
+
|
|
1778
|
+
const dup = encodeInstr(Dup)
|
|
1779
|
+
if (approveAssetsNum > 1) {
|
|
1780
|
+
callerInstrs.push(...new Array(approveAssetsNum - 1).fill(dup))
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
return callerInstrs
|
|
1785
|
+
}
|
|
1786
|
+
|
|
1787
|
+
function getTemplateVarStoreLocalInstrs(functionSig: FunctionSig, structs: Struct[]): [string[], number] {
|
|
1788
|
+
let templateVarIndex = 1 // Start from 1 since first one is always the contract id
|
|
1789
|
+
let localsLength = 0
|
|
1790
|
+
const templateVarStoreInstrs: string[] = []
|
|
1791
|
+
functionSig.paramTypes.forEach((paramType) => {
|
|
1792
|
+
const fieldsLength = ralph.typeLength(paramType, structs)
|
|
1793
|
+
if (fieldsLength > 1) {
|
|
1794
|
+
for (let i = 0; i < fieldsLength; i++) {
|
|
1795
|
+
templateVarStoreInstrs.push(`{${templateVarIndex + i}}`)
|
|
1796
|
+
}
|
|
1797
|
+
for (let i = 0; i < fieldsLength; i++) {
|
|
1798
|
+
templateVarStoreInstrs.push(encodeStoreLocalInstr(localsLength + (fieldsLength - i - 1)))
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1801
|
+
localsLength = localsLength + fieldsLength
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
templateVarIndex = templateVarIndex + fieldsLength
|
|
1805
|
+
})
|
|
1806
|
+
|
|
1807
|
+
return [templateVarStoreInstrs, templateVarIndex]
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1810
|
+
function getTemplateVarLoadLocalInstrs(functionSig: FunctionSig, structs: Struct[]): string[] {
|
|
1811
|
+
let templateVarIndex = 1
|
|
1812
|
+
let loadIndex = 0
|
|
1813
|
+
const templateVarLoadInstrs: string[] = []
|
|
1814
|
+
functionSig.paramTypes.forEach((paramType) => {
|
|
1815
|
+
const fieldsLength = ralph.typeLength(paramType, structs)
|
|
1816
|
+
|
|
1817
|
+
if (fieldsLength === 1) {
|
|
1818
|
+
templateVarLoadInstrs.push(`{${templateVarIndex}}`)
|
|
1819
|
+
}
|
|
1820
|
+
|
|
1821
|
+
if (fieldsLength > 1) {
|
|
1822
|
+
for (let i = 0; i < fieldsLength; i++) {
|
|
1823
|
+
templateVarLoadInstrs.push(encodeLoadLocalInstr(loadIndex + i))
|
|
1824
|
+
}
|
|
1825
|
+
|
|
1826
|
+
loadIndex = loadIndex + fieldsLength
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
templateVarIndex = templateVarIndex + fieldsLength
|
|
1830
|
+
})
|
|
1831
|
+
|
|
1832
|
+
return templateVarLoadInstrs
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
function encodeStoreLocalInstr(index: number): string {
|
|
1836
|
+
if (index < 0 || index > 0xff) {
|
|
1837
|
+
throw new Error(`StoreLocal index ${index} must be between 0 and 255 inclusive`)
|
|
1838
|
+
}
|
|
1839
|
+
return encodeInstr(StoreLocal(index))
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1842
|
+
function encodeLoadLocalInstr(index: number): string {
|
|
1843
|
+
if (index < 0 || index > 0xff) {
|
|
1844
|
+
throw new Error(`LoadLocal index ${index} must be between 0 and 255 inclusive`)
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1847
|
+
return encodeInstr(LoadLocal(index))
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
function encodeI32(value: number): string {
|
|
1851
|
+
return binToHex(compactSignedIntCodec.encodeI32(value))
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
function encodeU256Const(value: bigint): string {
|
|
1855
|
+
if (value < 0) {
|
|
1856
|
+
throw new Error(`value ${value} must be non-negative`)
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
if (value < 6) {
|
|
1860
|
+
return (BigInt(0x0c) + value).toString(16).padStart(2, '0')
|
|
1861
|
+
} else {
|
|
1862
|
+
return encodeInstr(U256Const(compactUnsignedIntCodec.fromU256(BigInt(value))))
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1866
|
+
function encodeInstr(instr: Instr): string {
|
|
1867
|
+
return binToHex(instrCodec.encode(instr))
|
|
1868
|
+
}
|
|
1869
|
+
|
|
1870
|
+
function toFieldsSig(contractName: string, functionSig: FunctionSig): FieldsSig {
|
|
1871
|
+
return {
|
|
1872
|
+
names: ['__contract__'].concat(functionSig.paramNames),
|
|
1873
|
+
types: [contractName].concat(functionSig.paramTypes),
|
|
1874
|
+
isMutable: [false].concat(functionSig.paramIsMutable)
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1609
1878
|
export async function multicallMethods<I extends ContractInstance, F extends Fields>(
|
|
1610
1879
|
contract: ContractFactory<I, F>,
|
|
1611
1880
|
instance: ContractInstance,
|
package/src/contract/ralph.ts
CHANGED
|
@@ -16,7 +16,7 @@ You should have received a copy of the GNU Lesser General Public License
|
|
|
16
16
|
along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import { Val, decodeArrayType, toApiAddress, toApiBoolean, toApiByteVec, toApiNumber256 } from '../api'
|
|
19
|
+
import { Val, decodeArrayType, toApiAddress, toApiBoolean, toApiByteVec, toApiNumber256, PrimitiveTypes } from '../api'
|
|
20
20
|
import { HexString, binToHex, bs58, concatBytes, hexToBinUnsafe, isHexString } from '../utils'
|
|
21
21
|
import { Fields, FieldsSig, Struct } from './contract'
|
|
22
22
|
import { compactSignedIntCodec, compactUnsignedIntCodec } from '../codec'
|
|
@@ -411,6 +411,24 @@ export function primitiveToByteVec(value: Val, type: string): Uint8Array {
|
|
|
411
411
|
}
|
|
412
412
|
}
|
|
413
413
|
|
|
414
|
+
export function typeLength(typ: string, structs: Struct[]): number {
|
|
415
|
+
if (PrimitiveTypes.includes(typ)) {
|
|
416
|
+
return 1
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if (typ.startsWith('[')) {
|
|
420
|
+
const [baseType, size] = decodeArrayType(typ)
|
|
421
|
+
return size * typeLength(baseType, structs)
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
const struct = structs.find((s) => s.name === typ)
|
|
425
|
+
if (struct !== undefined) {
|
|
426
|
+
return struct.fieldTypes.reduce((acc, fieldType) => acc + typeLength(fieldType, structs), 0)
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
return 1
|
|
430
|
+
}
|
|
431
|
+
|
|
414
432
|
export function flattenFields(
|
|
415
433
|
fields: Fields,
|
|
416
434
|
names: string[],
|