@alephium/web3 0.42.0 → 0.44.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/{utils → address}/address.js +15 -19
- package/dist/src/address/index.d.ts +1 -0
- package/dist/src/address/index.js +34 -0
- package/dist/src/api/node-provider.js +10 -9
- package/dist/src/api/types.js +1 -1
- package/dist/src/codec/array-codec.d.ts +2 -3
- package/dist/src/codec/array-codec.js +2 -3
- package/dist/src/codec/asset-output-codec.d.ts +3 -4
- package/dist/src/codec/asset-output-codec.js +13 -15
- package/dist/src/codec/bigint-codec.d.ts +2 -3
- package/dist/src/codec/bigint-codec.js +2 -3
- package/dist/src/codec/bytestring-codec.d.ts +5 -6
- package/dist/src/codec/bytestring-codec.js +7 -7
- package/dist/src/codec/codec.d.ts +2 -3
- package/dist/src/codec/compact-int-codec.d.ts +11 -15
- package/dist/src/codec/compact-int-codec.js +23 -33
- package/dist/src/codec/contract-codec.d.ts +5 -6
- package/dist/src/codec/contract-codec.js +26 -26
- package/dist/src/codec/contract-output-codec.d.ts +2 -3
- package/dist/src/codec/contract-output-codec.js +9 -11
- package/dist/src/codec/contract-output-ref-codec.d.ts +3 -4
- package/dist/src/codec/contract-output-ref-codec.js +2 -2
- package/dist/src/codec/either-codec.d.ts +2 -3
- package/dist/src/codec/either-codec.js +1 -2
- package/dist/src/codec/hash.d.ts +2 -3
- package/dist/src/codec/hash.js +17 -0
- package/dist/src/codec/input-codec.d.ts +3 -4
- package/dist/src/codec/input-codec.js +6 -6
- package/dist/src/codec/instr-codec.d.ts +2 -3
- package/dist/src/codec/instr-codec.js +1 -2
- package/dist/src/codec/lockup-script-codec.d.ts +5 -6
- package/dist/src/codec/lockup-script-codec.js +1 -2
- package/dist/src/codec/long-codec.d.ts +2 -3
- package/dist/src/codec/long-codec.js +1 -2
- package/dist/src/codec/method-codec.d.ts +2 -3
- package/dist/src/codec/method-codec.js +13 -14
- package/dist/src/codec/option-codec.d.ts +3 -4
- package/dist/src/codec/option-codec.js +2 -3
- package/dist/src/codec/script-codec.d.ts +4 -5
- package/dist/src/codec/script-codec.js +2 -4
- package/dist/src/codec/signature-codec.d.ts +3 -4
- package/dist/src/codec/signature-codec.js +17 -0
- package/dist/src/codec/signed-int-codec.d.ts +2 -3
- package/dist/src/codec/signed-int-codec.js +1 -2
- package/dist/src/codec/token-codec.d.ts +3 -4
- package/dist/src/codec/token-codec.js +3 -3
- package/dist/src/codec/transaction-codec.d.ts +4 -5
- package/dist/src/codec/transaction-codec.js +12 -13
- package/dist/src/codec/unlock-script-codec.d.ts +5 -6
- package/dist/src/codec/unlock-script-codec.js +14 -15
- package/dist/src/codec/unsigned-tx-codec.d.ts +4 -5
- package/dist/src/codec/unsigned-tx-codec.js +4 -5
- package/dist/src/contract/contract.d.ts +10 -1
- package/dist/src/contract/contract.js +197 -21
- package/dist/src/contract/ralph.d.ts +2 -1
- package/dist/src/contract/ralph.js +25 -11
- package/dist/src/{utils → exchange}/exchange.js +5 -5
- package/dist/src/exchange/index.d.ts +1 -0
- package/dist/src/exchange/index.js +25 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +2 -0
- package/dist/src/signer/signer.js +4 -5
- package/dist/src/signer/tx-builder.js +3 -3
- package/dist/src/utils/index.d.ts +0 -2
- package/dist/src/utils/index.js +0 -7
- package/dist/src/utils/sign.js +1 -1
- package/dist/src/utils/utils.d.ts +1 -0
- package/dist/src/utils/utils.js +30 -11
- package/dist/src/utils/webcrypto.js +3 -4
- package/package.json +1 -2
- package/src/{utils → address}/address.ts +15 -19
- package/src/address/index.ts +19 -0
- package/src/api/node-provider.ts +2 -9
- package/src/api/types.ts +2 -2
- package/src/codec/array-codec.ts +5 -6
- package/src/codec/asset-output-codec.ts +20 -22
- package/src/codec/bigint-codec.ts +4 -5
- package/src/codec/bytestring-codec.ts +11 -11
- package/src/codec/codec.ts +2 -3
- package/src/codec/compact-int-codec.ts +36 -50
- package/src/codec/contract-codec.ts +30 -29
- package/src/codec/contract-output-codec.ts +13 -15
- package/src/codec/contract-output-ref-codec.ts +5 -5
- package/src/codec/either-codec.ts +3 -4
- package/src/codec/hash.ts +2 -3
- package/src/codec/input-codec.ts +10 -10
- package/src/codec/instr-codec.ts +3 -4
- package/src/codec/lockup-script-codec.ts +8 -9
- package/src/codec/long-codec.ts +3 -4
- package/src/codec/method-codec.ts +16 -17
- package/src/codec/option-codec.ts +4 -5
- package/src/codec/script-codec.ts +7 -9
- package/src/codec/signature-codec.ts +3 -4
- package/src/codec/signed-int-codec.ts +3 -4
- package/src/codec/token-codec.ts +6 -6
- package/src/codec/transaction-codec.ts +17 -18
- package/src/codec/unlock-script-codec.ts +26 -27
- package/src/codec/unsigned-tx-codec.ts +10 -11
- package/src/contract/contract.ts +274 -9
- package/src/contract/ralph.ts +29 -12
- package/src/{utils → exchange}/exchange.ts +3 -11
- package/src/exchange/index.ts +19 -0
- package/src/index.ts +2 -0
- package/src/signer/signer.ts +2 -3
- package/src/signer/tx-builder.ts +2 -2
- package/src/utils/index.ts +0 -2
- package/src/utils/sign.ts +1 -1
- package/src/utils/utils.ts +29 -10
- package/src/utils/webcrypto.ts +3 -4
- package/webpack.config.js +1 -5
- /package/dist/src/{utils → address}/address.d.ts +0 -0
- /package/dist/src/{utils → exchange}/exchange.d.ts +0 -0
package/src/contract/contract.ts
CHANGED
|
@@ -16,7 +16,6 @@ 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 { Buffer } from 'buffer/'
|
|
20
19
|
import { promises as fsPromises } from 'fs'
|
|
21
20
|
import {
|
|
22
21
|
fromApiNumber256,
|
|
@@ -41,25 +40,23 @@ import {
|
|
|
41
40
|
SignDeployContractTxResult,
|
|
42
41
|
SignExecuteScriptTxParams,
|
|
43
42
|
SignerProvider,
|
|
44
|
-
Address
|
|
43
|
+
Address,
|
|
44
|
+
SignExecuteScriptTxResult
|
|
45
45
|
} from '../signer'
|
|
46
46
|
import * as ralph from './ralph'
|
|
47
47
|
import {
|
|
48
48
|
bs58,
|
|
49
49
|
binToHex,
|
|
50
|
-
contractIdFromAddress,
|
|
51
50
|
Subscription,
|
|
52
51
|
assertType,
|
|
53
52
|
Eq,
|
|
54
53
|
Optional,
|
|
55
|
-
groupOfAddress,
|
|
56
54
|
WebCrypto,
|
|
57
55
|
hexToBinUnsafe,
|
|
58
56
|
isDevnet,
|
|
59
|
-
addressFromContractId,
|
|
60
|
-
subContractId,
|
|
61
57
|
HexString
|
|
62
58
|
} from '../utils'
|
|
59
|
+
import { contractIdFromAddress, groupOfAddress, addressFromContractId, subContractId } from '../address'
|
|
63
60
|
import { getCurrentNodeProvider } from '../global'
|
|
64
61
|
import { EventSubscribeOptions, EventSubscription, subscribeToEvents } from './events'
|
|
65
62
|
import { ONE_ALPH, TOTAL_NUMBER_OF_GROUPS } from '../constants'
|
|
@@ -67,6 +64,8 @@ import * as blake from 'blakejs'
|
|
|
67
64
|
import { isContractDebugMessageEnabled } from '../debug'
|
|
68
65
|
import {
|
|
69
66
|
contract,
|
|
67
|
+
compactUnsignedIntCodec,
|
|
68
|
+
compactSignedIntCodec,
|
|
70
69
|
Method,
|
|
71
70
|
LoadLocal,
|
|
72
71
|
LoadImmFieldByIndex,
|
|
@@ -76,7 +75,19 @@ import {
|
|
|
76
75
|
ByteVecEq,
|
|
77
76
|
Assert,
|
|
78
77
|
StoreMutFieldByIndex,
|
|
79
|
-
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
|
|
80
91
|
} from '../codec'
|
|
81
92
|
|
|
82
93
|
const crypto = new WebCrypto()
|
|
@@ -220,7 +231,7 @@ export class Contract extends Artifact {
|
|
|
220
231
|
this.bytecodeDebug = ralph.buildDebugBytecode(this.bytecode, this.bytecodeDebugPatch)
|
|
221
232
|
this.codeHashDebug = codeHashDebug
|
|
222
233
|
|
|
223
|
-
this.decodedMethods = contract.contractCodec.decodeContract(
|
|
234
|
+
this.decodedMethods = contract.contractCodec.decodeContract(hexToBinUnsafe(bytecode)).methods
|
|
224
235
|
}
|
|
225
236
|
|
|
226
237
|
publicFunctions(): FunctionSig[] {
|
|
@@ -1047,6 +1058,15 @@ export interface CallContractResult<R> {
|
|
|
1047
1058
|
debugMessages: DebugMessage[]
|
|
1048
1059
|
}
|
|
1049
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
|
+
|
|
1050
1070
|
function specialContractAddress(eventIndex: number, groupIndex: number): string {
|
|
1051
1071
|
const bytes = new Uint8Array(32).fill(0)
|
|
1052
1072
|
bytes[30] = eventIndex
|
|
@@ -1208,7 +1228,7 @@ function genCodeForType(type: string, structs: Struct[]): { bytecode: string; co
|
|
|
1208
1228
|
fieldLength: immFields + mutFields + 1, // parentContractId
|
|
1209
1229
|
methods: [loadImmFieldByIndex, loadMutFieldByIndex, storeMutFieldByIndex, destroy]
|
|
1210
1230
|
}
|
|
1211
|
-
const bytecode = contract.contractCodec.
|
|
1231
|
+
const bytecode = contract.contractCodec.encodeContract(c)
|
|
1212
1232
|
const codeHash = blake.blake2b(bytecode, undefined, 32)
|
|
1213
1233
|
return { bytecode: binToHex(bytecode), codeHash: binToHex(codeHash) }
|
|
1214
1234
|
}
|
|
@@ -1610,6 +1630,251 @@ export async function callMethod<I extends ContractInstance, F extends Fields, A
|
|
|
1610
1630
|
return callResult as CallContractResult<R>
|
|
1611
1631
|
}
|
|
1612
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
|
+
|
|
1613
1878
|
export async function multicallMethods<I extends ContractInstance, F extends Fields>(
|
|
1614
1879
|
contract: ContractFactory<I, F>,
|
|
1615
1880
|
instance: ContractInstance,
|
package/src/contract/ralph.ts
CHANGED
|
@@ -16,9 +16,8 @@ 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 {
|
|
20
|
-
import {
|
|
21
|
-
import { HexString, binToHex, bs58, hexToBinUnsafe, isHexString } from '../utils'
|
|
19
|
+
import { Val, decodeArrayType, toApiAddress, toApiBoolean, toApiByteVec, toApiNumber256, PrimitiveTypes } from '../api'
|
|
20
|
+
import { HexString, binToHex, bs58, concatBytes, hexToBinUnsafe, isHexString } from '../utils'
|
|
22
21
|
import { Fields, FieldsSig, Struct } from './contract'
|
|
23
22
|
import { compactSignedIntCodec, compactUnsignedIntCodec } from '../codec'
|
|
24
23
|
|
|
@@ -151,14 +150,14 @@ export function encodeU256(u256: bigint): Uint8Array {
|
|
|
151
150
|
}
|
|
152
151
|
}
|
|
153
152
|
|
|
154
|
-
export function encodeByteVec(
|
|
155
|
-
if (!isHexString(
|
|
156
|
-
throw Error(`Given value ${
|
|
153
|
+
export function encodeByteVec(hex: string): Uint8Array {
|
|
154
|
+
if (!isHexString(hex)) {
|
|
155
|
+
throw Error(`Given value ${hex} is not a valid hex string`)
|
|
157
156
|
}
|
|
158
157
|
|
|
159
|
-
const
|
|
160
|
-
const
|
|
161
|
-
return
|
|
158
|
+
const bytes0 = hexToBinUnsafe(hex)
|
|
159
|
+
const bytes1 = encodeI256(BigInt(bytes0.length))
|
|
160
|
+
return concatBytes([bytes1, bytes0])
|
|
162
161
|
}
|
|
163
162
|
|
|
164
163
|
export function encodeAddress(address: string): Uint8Array {
|
|
@@ -254,7 +253,7 @@ function encodeScriptFieldU256(value: bigint): Uint8Array {
|
|
|
254
253
|
}
|
|
255
254
|
|
|
256
255
|
export function encodeScriptFieldAsString(tpe: string, value: Val): string {
|
|
257
|
-
return
|
|
256
|
+
return binToHex(encodeScriptField(tpe, value))
|
|
258
257
|
}
|
|
259
258
|
|
|
260
259
|
export function encodeScriptField(tpe: string, value: Val): Uint8Array {
|
|
@@ -378,9 +377,9 @@ export function decodePrimitive(value: Uint8Array, type: string): Val {
|
|
|
378
377
|
case 'Bool':
|
|
379
378
|
return decodeBool(value)
|
|
380
379
|
case 'I256':
|
|
381
|
-
return compactSignedIntCodec.decodeI256(
|
|
380
|
+
return compactSignedIntCodec.decodeI256(value)
|
|
382
381
|
case 'U256':
|
|
383
|
-
return compactUnsignedIntCodec.decodeU256(
|
|
382
|
+
return compactUnsignedIntCodec.decodeU256(value)
|
|
384
383
|
case 'ByteVec':
|
|
385
384
|
return binToHex(value)
|
|
386
385
|
case 'Address':
|
|
@@ -412,6 +411,24 @@ export function primitiveToByteVec(value: Val, type: string): Uint8Array {
|
|
|
412
411
|
}
|
|
413
412
|
}
|
|
414
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
|
+
|
|
415
432
|
export function flattenFields(
|
|
416
433
|
fields: Fields,
|
|
417
434
|
names: string[],
|
|
@@ -16,19 +16,11 @@ 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 {
|
|
20
|
-
|
|
21
|
-
addressFromPublicKey,
|
|
22
|
-
addressFromScript,
|
|
23
|
-
binToHex,
|
|
24
|
-
bs58,
|
|
25
|
-
hexToBinUnsafe,
|
|
26
|
-
isHexString
|
|
27
|
-
} from '../utils'
|
|
19
|
+
import { AddressType, addressFromPublicKey, addressFromScript } from '../address'
|
|
20
|
+
import { binToHex, bs58, hexToBinUnsafe, isHexString } from '../utils'
|
|
28
21
|
import { Transaction } from '../api/api-alephium'
|
|
29
22
|
import { Address } from '../signer'
|
|
30
23
|
import { P2SH, unlockScriptCodec } from '../codec/unlock-script-codec'
|
|
31
|
-
import { Buffer } from 'buffer/'
|
|
32
24
|
import { scriptCodec } from '../codec/script-codec'
|
|
33
25
|
|
|
34
26
|
export function validateExchangeAddress(address: string) {
|
|
@@ -113,7 +105,7 @@ export function getAddressFromUnlockScript(unlockScript: string): Address {
|
|
|
113
105
|
if (unlockScriptType === UnlockScriptType.P2SH) {
|
|
114
106
|
let p2sh: P2SH
|
|
115
107
|
try {
|
|
116
|
-
p2sh = unlockScriptCodec.decode(
|
|
108
|
+
p2sh = unlockScriptCodec.decode(decoded).script as P2SH
|
|
117
109
|
} catch (_) {
|
|
118
110
|
throw new Error(`Invalid p2sh unlock script: ${unlockScript}`)
|
|
119
111
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2018 - 2022 The Alephium Authors
|
|
3
|
+
This file is part of the alephium project.
|
|
4
|
+
|
|
5
|
+
The library is free software: you can redistribute it and/or modify
|
|
6
|
+
it under the terms of the GNU Lesser General Public License as published by
|
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
(at your option) any later version.
|
|
9
|
+
|
|
10
|
+
The library is distributed in the hope that it will be useful,
|
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
GNU Lesser General Public License for more details.
|
|
14
|
+
|
|
15
|
+
You should have received a copy of the GNU Lesser General Public License
|
|
16
|
+
along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export { validateExchangeAddress, isALPHTransferTx, getSenderAddress, getALPHDepositInfo } from './exchange'
|
package/src/index.ts
CHANGED
package/src/signer/signer.ts
CHANGED
|
@@ -16,7 +16,6 @@ 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 { Buffer } from 'buffer/'
|
|
20
19
|
import { createHash } from 'crypto'
|
|
21
20
|
import { ExplorerProvider, fromApiNumber256, fromApiTokens, NodeProvider, toApiNumber256, toApiTokens } from '../api'
|
|
22
21
|
import { node } from '../api'
|
|
@@ -44,7 +43,7 @@ import {
|
|
|
44
43
|
MessageHasher
|
|
45
44
|
} from './types'
|
|
46
45
|
import { TransactionBuilder } from './tx-builder'
|
|
47
|
-
import { addressFromPublicKey, groupOfAddress } from '../
|
|
46
|
+
import { addressFromPublicKey, groupOfAddress } from '../address'
|
|
48
47
|
|
|
49
48
|
export abstract class SignerProvider {
|
|
50
49
|
abstract get nodeProvider(): NodeProvider | undefined
|
|
@@ -254,7 +253,7 @@ export function hashMessage(message: string, hasher: MessageHasher): string {
|
|
|
254
253
|
return utils.binToHex(blake.blake2b(extendMessage(message), undefined, 32))
|
|
255
254
|
case 'sha256':
|
|
256
255
|
const sha256 = createHash('sha256')
|
|
257
|
-
sha256.update(
|
|
256
|
+
sha256.update(new TextEncoder().encode(message))
|
|
258
257
|
return utils.binToHex(sha256.digest())
|
|
259
258
|
case 'blake2b':
|
|
260
259
|
return utils.binToHex(blake.blake2b(message, undefined, 32))
|
package/src/signer/tx-builder.ts
CHANGED
|
@@ -16,9 +16,9 @@ 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 { binToHex
|
|
19
|
+
import { binToHex } from '../utils'
|
|
20
20
|
import { fromApiNumber256, node, NodeProvider, toApiNumber256Optional, toApiTokens } from '../api'
|
|
21
|
-
import { addressFromPublicKey } from '../
|
|
21
|
+
import { addressFromPublicKey, contractIdFromAddress } from '../address'
|
|
22
22
|
import { toApiDestinations } from './signer'
|
|
23
23
|
import {
|
|
24
24
|
KeyType,
|
package/src/utils/index.ts
CHANGED
|
@@ -17,11 +17,9 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
export * from './webcrypto'
|
|
20
|
-
export * from './address'
|
|
21
20
|
export * from './bs58'
|
|
22
21
|
export * from './djb2'
|
|
23
22
|
export * from './utils'
|
|
24
23
|
export * from './subscription'
|
|
25
24
|
export * from './sign'
|
|
26
25
|
export * from './number'
|
|
27
|
-
export { validateExchangeAddress, isALPHTransferTx, getSenderAddress, getALPHDepositInfo } from './exchange'
|
package/src/utils/sign.ts
CHANGED
|
@@ -31,7 +31,7 @@ necc.utils.sha256Sync = (...messages: Uint8Array[]): Uint8Array => {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
necc.utils.hmacSha256Sync = (key: Uint8Array, ...messages: Uint8Array[]): Uint8Array => {
|
|
34
|
-
const hash = createHmac('sha256',
|
|
34
|
+
const hash = createHmac('sha256', key)
|
|
35
35
|
messages.forEach((m) => hash.update(m))
|
|
36
36
|
return Uint8Array.from(hash.digest())
|
|
37
37
|
}
|
package/src/utils/utils.ts
CHANGED
|
@@ -18,8 +18,6 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
18
18
|
|
|
19
19
|
import { ec as EC, SignatureInput } from 'elliptic'
|
|
20
20
|
import BN from 'bn.js'
|
|
21
|
-
import { Buffer } from 'buffer/'
|
|
22
|
-
|
|
23
21
|
import { TOTAL_NUMBER_OF_GROUPS, TOTAL_NUMBER_OF_CHAINS } from '../constants'
|
|
24
22
|
|
|
25
23
|
export const networkIds = ['mainnet', 'testnet', 'devnet'] as const
|
|
@@ -73,11 +71,17 @@ export function toNonNegativeBigInt(input: string): bigint | undefined {
|
|
|
73
71
|
}
|
|
74
72
|
|
|
75
73
|
export function hexToBinUnsafe(hex: string): Uint8Array {
|
|
76
|
-
|
|
74
|
+
const bytes: number[] = []
|
|
75
|
+
for (let i = 0; i < hex.length; i += 2) {
|
|
76
|
+
bytes.push(parseInt(hex.slice(i, i + 2), 16))
|
|
77
|
+
}
|
|
78
|
+
return new Uint8Array(bytes)
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
export function binToHex(bin: Uint8Array): string {
|
|
80
|
-
return
|
|
82
|
+
return Array.from(bin)
|
|
83
|
+
.map((byte) => byte.toString(16).padStart(2, '0'))
|
|
84
|
+
.join('')
|
|
81
85
|
}
|
|
82
86
|
|
|
83
87
|
export function blockChainIndex(blockHash: HexString): { fromGroup: number; toGroup: number } {
|
|
@@ -101,7 +105,8 @@ export function hexToString(str: string): string {
|
|
|
101
105
|
if (!isHexString(str)) {
|
|
102
106
|
throw new Error(`Invalid hex string: ${str}`)
|
|
103
107
|
}
|
|
104
|
-
|
|
108
|
+
const bytes = hexToBinUnsafe(str)
|
|
109
|
+
return new TextDecoder().decode(bytes)
|
|
105
110
|
}
|
|
106
111
|
|
|
107
112
|
export function sleep(ms: number): Promise<void> {
|
|
@@ -127,14 +132,28 @@ export function difficultyToTarget(diff: bigint): HexString {
|
|
|
127
132
|
const maxBigInt = 1n << 256n
|
|
128
133
|
const target = diff === 1n ? maxBigInt - 1n : maxBigInt / diff
|
|
129
134
|
const size = Math.floor((target.toString(2).length + 7) / 8)
|
|
130
|
-
const mantissa =
|
|
135
|
+
const mantissa = Number(
|
|
131
136
|
size <= 3
|
|
132
137
|
? BigInt.asIntN(32, target) << BigInt(8 * (3 - size))
|
|
133
138
|
: BigInt.asIntN(32, target >> BigInt(8 * (size - 3)))
|
|
134
|
-
|
|
135
|
-
mantissaBytes
|
|
136
|
-
|
|
137
|
-
|
|
139
|
+
)
|
|
140
|
+
const mantissaBytes = new Uint8Array(4)
|
|
141
|
+
mantissaBytes[0] = size
|
|
142
|
+
mantissaBytes[1] = (mantissa >> 16) & 0xff
|
|
143
|
+
mantissaBytes[2] = (mantissa >> 8) & 0xff
|
|
144
|
+
mantissaBytes[3] = mantissa & 0xff
|
|
145
|
+
return binToHex(mantissaBytes)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export function concatBytes(arrays: Uint8Array[]): Uint8Array {
|
|
149
|
+
const totalLength = arrays.reduce((acc, arr) => acc + arr.length, 0)
|
|
150
|
+
const result = new Uint8Array(totalLength)
|
|
151
|
+
let offset = 0
|
|
152
|
+
for (const array of arrays) {
|
|
153
|
+
result.set(array, offset)
|
|
154
|
+
offset += array.length
|
|
155
|
+
}
|
|
156
|
+
return result
|
|
138
157
|
}
|
|
139
158
|
|
|
140
159
|
type _Eq<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false
|
package/src/utils/webcrypto.ts
CHANGED
|
@@ -16,7 +16,6 @@ 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 { Buffer } from 'buffer/'
|
|
20
19
|
import { webcrypto, randomFillSync } from 'crypto'
|
|
21
20
|
|
|
22
21
|
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined'
|
|
@@ -30,12 +29,12 @@ export class WebCrypto {
|
|
|
30
29
|
"Failed to execute 'getRandomValues' on 'Crypto': parameter 1 is not of type 'ArrayBufferView'"
|
|
31
30
|
)
|
|
32
31
|
}
|
|
33
|
-
const
|
|
32
|
+
const bytes = new Uint8Array(array.buffer, array.byteOffset, array.byteLength)
|
|
34
33
|
|
|
35
34
|
if (isBrowser) {
|
|
36
|
-
globalThis.crypto.getRandomValues(
|
|
35
|
+
globalThis.crypto.getRandomValues(bytes)
|
|
37
36
|
} else {
|
|
38
|
-
randomFillSync(
|
|
37
|
+
randomFillSync(bytes)
|
|
39
38
|
}
|
|
40
39
|
return array
|
|
41
40
|
}
|
package/webpack.config.js
CHANGED
|
@@ -25,9 +25,6 @@ module.exports = {
|
|
|
25
25
|
},
|
|
26
26
|
plugins: [
|
|
27
27
|
new webpack.SourceMapDevToolPlugin({ filename: '[file].map' }),
|
|
28
|
-
new webpack.ProvidePlugin({
|
|
29
|
-
Buffer: ['buffer', 'Buffer']
|
|
30
|
-
}),
|
|
31
28
|
new webpack.IgnorePlugin({
|
|
32
29
|
checkResource(resource) {
|
|
33
30
|
// The "bip39/src/wordlists" node module consists of json files for multiple languages. We only need English.
|
|
@@ -40,8 +37,7 @@ module.exports = {
|
|
|
40
37
|
fallback: {
|
|
41
38
|
fs: false,
|
|
42
39
|
stream: require.resolve('stream-browserify'),
|
|
43
|
-
crypto: require.resolve('crypto-browserify')
|
|
44
|
-
buffer: require.resolve('buffer/')
|
|
40
|
+
crypto: require.resolve('crypto-browserify')
|
|
45
41
|
}
|
|
46
42
|
},
|
|
47
43
|
output: {
|
|
File without changes
|
|
File without changes
|