@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.
Files changed (114) hide show
  1. package/dist/alephium-web3.min.js +1 -1
  2. package/dist/alephium-web3.min.js.map +1 -1
  3. package/dist/src/{utils → address}/address.js +15 -19
  4. package/dist/src/address/index.d.ts +1 -0
  5. package/dist/src/address/index.js +34 -0
  6. package/dist/src/api/node-provider.js +10 -9
  7. package/dist/src/api/types.js +1 -1
  8. package/dist/src/codec/array-codec.d.ts +2 -3
  9. package/dist/src/codec/array-codec.js +2 -3
  10. package/dist/src/codec/asset-output-codec.d.ts +3 -4
  11. package/dist/src/codec/asset-output-codec.js +13 -15
  12. package/dist/src/codec/bigint-codec.d.ts +2 -3
  13. package/dist/src/codec/bigint-codec.js +2 -3
  14. package/dist/src/codec/bytestring-codec.d.ts +5 -6
  15. package/dist/src/codec/bytestring-codec.js +7 -7
  16. package/dist/src/codec/codec.d.ts +2 -3
  17. package/dist/src/codec/compact-int-codec.d.ts +11 -15
  18. package/dist/src/codec/compact-int-codec.js +23 -33
  19. package/dist/src/codec/contract-codec.d.ts +5 -6
  20. package/dist/src/codec/contract-codec.js +26 -26
  21. package/dist/src/codec/contract-output-codec.d.ts +2 -3
  22. package/dist/src/codec/contract-output-codec.js +9 -11
  23. package/dist/src/codec/contract-output-ref-codec.d.ts +3 -4
  24. package/dist/src/codec/contract-output-ref-codec.js +2 -2
  25. package/dist/src/codec/either-codec.d.ts +2 -3
  26. package/dist/src/codec/either-codec.js +1 -2
  27. package/dist/src/codec/hash.d.ts +2 -3
  28. package/dist/src/codec/hash.js +17 -0
  29. package/dist/src/codec/input-codec.d.ts +3 -4
  30. package/dist/src/codec/input-codec.js +6 -6
  31. package/dist/src/codec/instr-codec.d.ts +2 -3
  32. package/dist/src/codec/instr-codec.js +1 -2
  33. package/dist/src/codec/lockup-script-codec.d.ts +5 -6
  34. package/dist/src/codec/lockup-script-codec.js +1 -2
  35. package/dist/src/codec/long-codec.d.ts +2 -3
  36. package/dist/src/codec/long-codec.js +1 -2
  37. package/dist/src/codec/method-codec.d.ts +2 -3
  38. package/dist/src/codec/method-codec.js +13 -14
  39. package/dist/src/codec/option-codec.d.ts +3 -4
  40. package/dist/src/codec/option-codec.js +2 -3
  41. package/dist/src/codec/script-codec.d.ts +4 -5
  42. package/dist/src/codec/script-codec.js +2 -4
  43. package/dist/src/codec/signature-codec.d.ts +3 -4
  44. package/dist/src/codec/signature-codec.js +17 -0
  45. package/dist/src/codec/signed-int-codec.d.ts +2 -3
  46. package/dist/src/codec/signed-int-codec.js +1 -2
  47. package/dist/src/codec/token-codec.d.ts +3 -4
  48. package/dist/src/codec/token-codec.js +3 -3
  49. package/dist/src/codec/transaction-codec.d.ts +4 -5
  50. package/dist/src/codec/transaction-codec.js +12 -13
  51. package/dist/src/codec/unlock-script-codec.d.ts +5 -6
  52. package/dist/src/codec/unlock-script-codec.js +14 -15
  53. package/dist/src/codec/unsigned-tx-codec.d.ts +4 -5
  54. package/dist/src/codec/unsigned-tx-codec.js +4 -5
  55. package/dist/src/contract/contract.d.ts +10 -1
  56. package/dist/src/contract/contract.js +197 -21
  57. package/dist/src/contract/ralph.d.ts +2 -1
  58. package/dist/src/contract/ralph.js +25 -11
  59. package/dist/src/{utils → exchange}/exchange.js +5 -5
  60. package/dist/src/exchange/index.d.ts +1 -0
  61. package/dist/src/exchange/index.js +25 -0
  62. package/dist/src/index.d.ts +2 -0
  63. package/dist/src/index.js +2 -0
  64. package/dist/src/signer/signer.js +4 -5
  65. package/dist/src/signer/tx-builder.js +3 -3
  66. package/dist/src/utils/index.d.ts +0 -2
  67. package/dist/src/utils/index.js +0 -7
  68. package/dist/src/utils/sign.js +1 -1
  69. package/dist/src/utils/utils.d.ts +1 -0
  70. package/dist/src/utils/utils.js +30 -11
  71. package/dist/src/utils/webcrypto.js +3 -4
  72. package/package.json +1 -2
  73. package/src/{utils → address}/address.ts +15 -19
  74. package/src/address/index.ts +19 -0
  75. package/src/api/node-provider.ts +2 -9
  76. package/src/api/types.ts +2 -2
  77. package/src/codec/array-codec.ts +5 -6
  78. package/src/codec/asset-output-codec.ts +20 -22
  79. package/src/codec/bigint-codec.ts +4 -5
  80. package/src/codec/bytestring-codec.ts +11 -11
  81. package/src/codec/codec.ts +2 -3
  82. package/src/codec/compact-int-codec.ts +36 -50
  83. package/src/codec/contract-codec.ts +30 -29
  84. package/src/codec/contract-output-codec.ts +13 -15
  85. package/src/codec/contract-output-ref-codec.ts +5 -5
  86. package/src/codec/either-codec.ts +3 -4
  87. package/src/codec/hash.ts +2 -3
  88. package/src/codec/input-codec.ts +10 -10
  89. package/src/codec/instr-codec.ts +3 -4
  90. package/src/codec/lockup-script-codec.ts +8 -9
  91. package/src/codec/long-codec.ts +3 -4
  92. package/src/codec/method-codec.ts +16 -17
  93. package/src/codec/option-codec.ts +4 -5
  94. package/src/codec/script-codec.ts +7 -9
  95. package/src/codec/signature-codec.ts +3 -4
  96. package/src/codec/signed-int-codec.ts +3 -4
  97. package/src/codec/token-codec.ts +6 -6
  98. package/src/codec/transaction-codec.ts +17 -18
  99. package/src/codec/unlock-script-codec.ts +26 -27
  100. package/src/codec/unsigned-tx-codec.ts +10 -11
  101. package/src/contract/contract.ts +274 -9
  102. package/src/contract/ralph.ts +29 -12
  103. package/src/{utils → exchange}/exchange.ts +3 -11
  104. package/src/exchange/index.ts +19 -0
  105. package/src/index.ts +2 -0
  106. package/src/signer/signer.ts +2 -3
  107. package/src/signer/tx-builder.ts +2 -2
  108. package/src/utils/index.ts +0 -2
  109. package/src/utils/sign.ts +1 -1
  110. package/src/utils/utils.ts +29 -10
  111. package/src/utils/webcrypto.ts +3 -4
  112. package/webpack.config.js +1 -5
  113. /package/dist/src/{utils → address}/address.d.ts +0 -0
  114. /package/dist/src/{utils → exchange}/exchange.d.ts +0 -0
@@ -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(Buffer.from(bytecode, 'hex')).methods
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.encode(contract.toHalfDecoded(c))
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,
@@ -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 { Buffer } from 'buffer/'
20
- import { Val, decodeArrayType, toApiAddress, toApiBoolean, toApiByteVec, toApiNumber256 } from '../api'
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(bytes: string): Uint8Array {
155
- if (!isHexString(bytes)) {
156
- throw Error(`Given value ${bytes} is not a valid hex string`)
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 buffer0 = Buffer.from(bytes, 'hex')
160
- const buffer1 = Buffer.from(encodeI256(BigInt(buffer0.length)))
161
- return Buffer.concat([buffer1, buffer0])
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 Buffer.from(encodeScriptField(tpe, value)).toString('hex')
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(Buffer.from(value))
380
+ return compactSignedIntCodec.decodeI256(value)
382
381
  case 'U256':
383
- return compactUnsignedIntCodec.decodeU256(Buffer.from(value))
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
- AddressType,
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(Buffer.from(decoded)).script as P2SH
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
@@ -33,3 +33,5 @@ export * as codec from './codec'
33
33
  export * as utils from './utils'
34
34
  export * from './debug'
35
35
  export * from './block'
36
+ export * from './address'
37
+ export * from './exchange'
@@ -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 '../utils'
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(Buffer.from(message))
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))
@@ -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, contractIdFromAddress } from '../utils'
19
+ import { binToHex } from '../utils'
20
20
  import { fromApiNumber256, node, NodeProvider, toApiNumber256Optional, toApiTokens } from '../api'
21
- import { addressFromPublicKey } from '../utils'
21
+ import { addressFromPublicKey, contractIdFromAddress } from '../address'
22
22
  import { toApiDestinations } from './signer'
23
23
  import {
24
24
  KeyType,
@@ -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', Buffer.from(key))
34
+ const hash = createHmac('sha256', key)
35
35
  messages.forEach((m) => hash.update(m))
36
36
  return Uint8Array.from(hash.digest())
37
37
  }
@@ -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
- return Buffer.from(hex, 'hex')
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 Buffer.from(bin).toString('hex')
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
- return Buffer.from(str, 'hex').toString()
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
- const mantissaBytes = Buffer.alloc(4)
135
- mantissaBytes.writeInt32BE(Number(mantissa), 0)
136
- const bytes = new Uint8Array([size, ...mantissaBytes.slice(1)])
137
- return binToHex(bytes)
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
@@ -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 buffer = Buffer.from(array.buffer, array.byteOffset, array.byteLength)
32
+ const bytes = new Uint8Array(array.buffer, array.byteOffset, array.byteLength)
34
33
 
35
34
  if (isBrowser) {
36
- globalThis.crypto.getRandomValues(buffer)
35
+ globalThis.crypto.getRandomValues(bytes)
37
36
  } else {
38
- randomFillSync(buffer)
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