@alephium/web3 0.2.0-rc.3 → 0.2.0-rc.30

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 (125) hide show
  1. package/.eslintignore +2 -2
  2. package/README.md +2 -135
  3. package/dist/alephium-web3.min.js +1 -1
  4. package/dist/alephium-web3.min.js.LICENSE.txt +0 -17
  5. package/dist/alephium-web3.min.js.map +1 -1
  6. package/dist/src/api/api-alephium.d.ts +117 -17
  7. package/dist/src/api/api-alephium.js +145 -79
  8. package/dist/src/api/api-explorer.d.ts +163 -48
  9. package/dist/src/api/api-explorer.js +157 -34
  10. package/dist/src/api/index.d.ts +3 -2
  11. package/dist/src/api/index.js +22 -3
  12. package/dist/src/api/types.d.ts +23 -0
  13. package/dist/src/api/types.js +240 -0
  14. package/dist/src/api/utils.d.ts +6 -0
  15. package/dist/{scripts/rename-gitignore.js → src/api/utils.js} +11 -6
  16. package/dist/src/contract/contract.d.ts +107 -68
  17. package/dist/src/contract/contract.js +395 -451
  18. package/dist/src/contract/events.d.ts +4 -4
  19. package/dist/src/contract/events.js +2 -1
  20. package/dist/src/contract/index.js +5 -1
  21. package/dist/src/contract/ralph.d.ts +5 -4
  22. package/dist/src/contract/ralph.js +27 -1
  23. package/dist/src/global.d.ts +4 -0
  24. package/dist/{scripts/stop-devnet.js → src/global.js} +17 -11
  25. package/dist/src/index.d.ts +2 -0
  26. package/dist/src/index.js +23 -1
  27. package/dist/src/signer/index.d.ts +0 -1
  28. package/dist/src/signer/index.js +5 -2
  29. package/dist/src/signer/signer.d.ts +25 -13
  30. package/dist/src/signer/signer.js +51 -16
  31. package/dist/src/transaction/index.d.ts +0 -1
  32. package/dist/src/transaction/index.js +5 -2
  33. package/dist/src/transaction/status.d.ts +2 -1
  34. package/dist/src/transaction/status.js +2 -1
  35. package/dist/src/utils/bs58.d.ts +1 -0
  36. package/dist/src/utils/bs58.js +13 -1
  37. package/dist/src/utils/index.d.ts +0 -1
  38. package/dist/src/utils/index.js +5 -2
  39. package/dist/src/utils/subscription.d.ts +0 -3
  40. package/dist/src/utils/subscription.js +0 -1
  41. package/dist/src/utils/utils.d.ts +4 -9
  42. package/dist/src/utils/utils.js +20 -24
  43. package/jest-config.json +11 -0
  44. package/package.json +11 -47
  45. package/src/api/api-alephium.ts +169 -25
  46. package/src/api/api-explorer.ts +234 -51
  47. package/src/api/index.ts +14 -3
  48. package/src/api/types.ts +233 -0
  49. package/{scripts/rename-gitignore.js → src/api/utils.ts} +7 -6
  50. package/src/contract/contract.ts +579 -545
  51. package/src/contract/events.ts +6 -5
  52. package/src/contract/ralph.ts +29 -4
  53. package/src/{transaction/sign-verify.ts → global.ts} +14 -15
  54. package/src/index.ts +7 -0
  55. package/src/signer/index.ts +0 -1
  56. package/src/signer/signer.ts +79 -27
  57. package/src/transaction/index.ts +0 -1
  58. package/src/transaction/status.ts +5 -2
  59. package/src/utils/bs58.ts +11 -0
  60. package/src/utils/index.ts +0 -1
  61. package/src/utils/subscription.ts +1 -3
  62. package/src/utils/utils.ts +11 -19
  63. package/.eslintrc.json +0 -21
  64. package/LICENSE +0 -165
  65. package/contracts/add/add.ral +0 -16
  66. package/contracts/greeter/greeter.ral +0 -7
  67. package/contracts/greeter/greeter_interface.ral +0 -3
  68. package/contracts/greeter_main.ral +0 -9
  69. package/contracts/main.ral +0 -6
  70. package/contracts/sub/sub.ral +0 -9
  71. package/contracts/test/metadata.ral +0 -17
  72. package/contracts/test/warnings.ral +0 -5
  73. package/dev/user.conf +0 -29
  74. package/dist/scripts/create-project.d.ts +0 -2
  75. package/dist/scripts/create-project.js +0 -125
  76. package/dist/scripts/rename-gitignore.d.ts +0 -1
  77. package/dist/scripts/start-devnet.d.ts +0 -1
  78. package/dist/scripts/start-devnet.js +0 -131
  79. package/dist/scripts/stop-devnet.d.ts +0 -1
  80. package/dist/src/signer/node-wallet.d.ts +0 -13
  81. package/dist/src/signer/node-wallet.js +0 -60
  82. package/dist/src/test/index.d.ts +0 -7
  83. package/dist/src/test/index.js +0 -41
  84. package/dist/src/test/privatekey-wallet.d.ts +0 -12
  85. package/dist/src/test/privatekey-wallet.js +0 -68
  86. package/dist/src/transaction/sign-verify.d.ts +0 -2
  87. package/dist/src/transaction/sign-verify.js +0 -58
  88. package/dist/src/utils/password-crypto.d.ts +0 -2
  89. package/dist/src/utils/password-crypto.js +0 -69
  90. package/gitignore +0 -10
  91. package/scripts/create-project.ts +0 -137
  92. package/scripts/start-devnet.js +0 -141
  93. package/scripts/stop-devnet.js +0 -32
  94. package/src/contract/ralph.test.ts +0 -178
  95. package/src/fixtures/address.json +0 -36
  96. package/src/fixtures/balance.json +0 -9
  97. package/src/fixtures/self-clique.json +0 -19
  98. package/src/fixtures/transaction.json +0 -13
  99. package/src/fixtures/transactions.json +0 -179
  100. package/src/signer/fixtures/genesis.json +0 -26
  101. package/src/signer/fixtures/wallets.json +0 -26
  102. package/src/signer/node-wallet.ts +0 -74
  103. package/src/test/index.ts +0 -32
  104. package/src/test/privatekey-wallet.ts +0 -58
  105. package/src/transaction/sign-verify.test.ts +0 -50
  106. package/src/utils/address.test.ts +0 -47
  107. package/src/utils/djb2.test.ts +0 -35
  108. package/src/utils/password-crypto.test.ts +0 -27
  109. package/src/utils/password-crypto.ts +0 -77
  110. package/src/utils/utils.test.ts +0 -161
  111. package/templates/base/README.md +0 -34
  112. package/templates/base/package.json +0 -35
  113. package/templates/base/src/greeter.ts +0 -41
  114. package/templates/base/tsconfig.json +0 -19
  115. package/templates/react/README.md +0 -34
  116. package/templates/react/config-overrides.js +0 -18
  117. package/templates/react/package.json +0 -66
  118. package/templates/react/src/App.tsx +0 -42
  119. package/templates/react/src/artifacts/greeter.ral.json +0 -26
  120. package/templates/react/src/artifacts/greeter_main.ral.json +0 -22
  121. package/templates/shared/.eslintrc.json +0 -12
  122. package/templates/shared/scripts/header.js +0 -0
  123. package/test/contract.test.ts +0 -197
  124. package/test/events.test.ts +0 -138
  125. package/test/transaction.test.ts +0 -72
@@ -28,6 +28,29 @@ export interface AddressInfo {
28
28
  txNumber: number
29
29
  }
30
30
 
31
+ export interface AssetOutput {
32
+ /** @format int32 */
33
+ hint: number
34
+
35
+ /** @format 32-byte-hash */
36
+ key: string
37
+
38
+ /** @format uint256 */
39
+ attoAlphAmount: string
40
+ address: string
41
+ tokens?: Token[]
42
+
43
+ /** @format int64 */
44
+ lockTime?: number
45
+
46
+ /** @format hex-string */
47
+ message?: string
48
+
49
+ /** @format 32-byte-hash */
50
+ spent?: string
51
+ type: string
52
+ }
53
+
31
54
  export interface BadRequest {
32
55
  detail: string
33
56
  }
@@ -76,6 +99,23 @@ export interface ConfirmedTransaction {
76
99
  type: string
77
100
  }
78
101
 
102
+ export interface ContractOutput {
103
+ /** @format int32 */
104
+ hint: number
105
+
106
+ /** @format 32-byte-hash */
107
+ key: string
108
+
109
+ /** @format uint256 */
110
+ attoAlphAmount: string
111
+ address: string
112
+ tokens?: Token[]
113
+
114
+ /** @format 32-byte-hash */
115
+ spent?: string
116
+ type: string
117
+ }
118
+
79
119
  export interface ExplorerInfo {
80
120
  releaseVersion: string
81
121
  commit: string
@@ -90,14 +130,14 @@ export interface Hashrate {
90
130
 
91
131
  export interface Input {
92
132
  outputRef: OutputRef
93
- unlockScript?: string
94
133
 
95
- /** @format 32-byte-hash */
96
- txHashRef: string
97
- address: string
134
+ /** @format hex-string */
135
+ unlockScript?: string
136
+ address?: string
98
137
 
99
138
  /** @format uint256 */
100
- amount: string
139
+ attoAlphAmount?: string
140
+ tokens?: Token[]
101
141
  }
102
142
 
103
143
  export interface InternalServerError {
@@ -110,28 +150,17 @@ export interface ListBlocks {
110
150
  blocks?: BlockEntryLite[]
111
151
  }
112
152
 
153
+ export interface LogbackValue {
154
+ name: string
155
+ level: string
156
+ }
157
+
113
158
  export interface NotFound {
114
159
  detail: string
115
160
  resource: string
116
161
  }
117
162
 
118
- export interface Output {
119
- /** @format int32 */
120
- hint: number
121
-
122
- /** @format 32-byte-hash */
123
- key: string
124
-
125
- /** @format uint256 */
126
- amount: string
127
- address: string
128
-
129
- /** @format int64 */
130
- lockTime?: number
131
-
132
- /** @format 32-byte-hash */
133
- spent?: string
134
- }
163
+ export type Output = AssetOutput | ContractOutput
135
164
 
136
165
  export interface OutputRef {
137
166
  /** @format int32 */
@@ -198,6 +227,14 @@ export interface TimedCount {
198
227
  totalCountAllChains: number
199
228
  }
200
229
 
230
+ export interface Token {
231
+ /** @format 32-byte-hash */
232
+ id: string
233
+
234
+ /** @format uint256 */
235
+ amount: string
236
+ }
237
+
201
238
  export interface TokenSupply {
202
239
  /** @format int64 */
203
240
  timestamp: number
@@ -239,20 +276,6 @@ export interface Transaction {
239
276
 
240
277
  export type TransactionLike = ConfirmedTransaction | UnconfirmedTransaction
241
278
 
242
- export interface UInput {
243
- outputRef: OutputRef
244
- unlockScript?: string
245
- }
246
-
247
- export interface UOutput {
248
- /** @format uint256 */
249
- amount: string
250
- address: string
251
-
252
- /** @format int64 */
253
- lockTime?: number
254
- }
255
-
256
279
  export interface Unauthorized {
257
280
  detail: string
258
281
  }
@@ -266,28 +289,22 @@ export interface UnconfirmedTransaction {
266
289
 
267
290
  /** @format int32 */
268
291
  chainTo: number
269
- inputs?: UInput[]
270
- outputs?: UOutput[]
292
+ inputs?: Input[]
293
+ outputs?: AssetOutput[]
271
294
 
272
295
  /** @format int32 */
273
296
  gasAmount: number
274
297
 
275
298
  /** @format uint256 */
276
299
  gasPrice: string
300
+
301
+ /** @format int64 */
302
+ lastSeen: number
277
303
  type: string
278
304
  }
279
305
 
280
306
  import 'cross-fetch/polyfill'
281
-
282
- function convertHttpResponse<T>(
283
- response: HttpResponse<T, { detail: string }> | HttpResponse<T, { detail: string }>
284
- ): T {
285
- if (response.error) {
286
- throw new Error(response.error.detail)
287
- } else {
288
- return response.data
289
- }
290
- }
307
+ import { convertHttpResponse } from './utils'
291
308
 
292
309
  export type QueryParamsType = Record<string | number, any>
293
310
  export type ResponseFormat = keyof Omit<Body, 'body' | 'bodyUsed'>
@@ -491,7 +508,6 @@ export class HttpClient<SecurityDataType = unknown> {
491
508
  this.abortControllers.delete(cancelToken)
492
509
  }
493
510
 
494
- if (!response.ok) throw data
495
511
  return data
496
512
  })
497
513
  }
@@ -570,6 +586,25 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
570
586
  ...params
571
587
  }).then(convertHttpResponse)
572
588
  }
589
+ transactionByOutputRefKey = {
590
+ /**
591
+ * @description Get a transaction from a output reference key
592
+ *
593
+ * @tags Transactions
594
+ * @name GetTransactionByOutputRefKeyOutputRefKey
595
+ * @request GET:/transaction-by-output-ref-key/{output-ref-key}
596
+ */
597
+ getTransactionByOutputRefKeyOutputRefKey: (outputRefKey: string, params: RequestParams = {}) =>
598
+ this.request<
599
+ ConfirmedTransaction,
600
+ BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable
601
+ >({
602
+ path: `/transaction-by-output-ref-key/${outputRefKey}`,
603
+ method: 'GET',
604
+ format: 'json',
605
+ ...params
606
+ }).then(convertHttpResponse)
607
+ }
573
608
  addresses = {
574
609
  /**
575
610
  * @description Get address information
@@ -621,6 +656,24 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
621
656
  ...params
622
657
  }).then(convertHttpResponse),
623
658
 
659
+ /**
660
+ * @description List unconfirmed transactions of a given address
661
+ *
662
+ * @tags Addresses
663
+ * @name GetAddressesAddressUnconfirmedTransactions
664
+ * @request GET:/addresses/{address}/unconfirmed-transactions
665
+ */
666
+ getAddressesAddressUnconfirmedTransactions: (address: string, params: RequestParams = {}) =>
667
+ this.request<
668
+ UnconfirmedTransaction[],
669
+ BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable
670
+ >({
671
+ path: `/addresses/${address}/unconfirmed-transactions`,
672
+ method: 'GET',
673
+ format: 'json',
674
+ ...params
675
+ }).then(convertHttpResponse),
676
+
624
677
  /**
625
678
  * @description Get address balance
626
679
  *
@@ -634,6 +687,75 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
634
687
  method: 'GET',
635
688
  format: 'json',
636
689
  ...params
690
+ }).then(convertHttpResponse),
691
+
692
+ /**
693
+ * @description List address tokens
694
+ *
695
+ * @tags Addresses
696
+ * @name GetAddressesAddressTokens
697
+ * @request GET:/addresses/{address}/tokens
698
+ */
699
+ getAddressesAddressTokens: (address: string, params: RequestParams = {}) =>
700
+ this.request<string[], BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable>({
701
+ path: `/addresses/${address}/tokens`,
702
+ method: 'GET',
703
+ format: 'json',
704
+ ...params
705
+ }).then(convertHttpResponse),
706
+
707
+ /**
708
+ * @description List address tokens
709
+ *
710
+ * @tags Addresses
711
+ * @name GetAddressesAddressTokensTokenIdTransactions
712
+ * @request GET:/addresses/{address}/tokens/{token-id}/transactions
713
+ */
714
+ getAddressesAddressTokensTokenIdTransactions: (
715
+ address: string,
716
+ tokenId: string,
717
+ query?: { page?: number; limit?: number; reverse?: boolean },
718
+ params: RequestParams = {}
719
+ ) =>
720
+ this.request<Transaction[], BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable>({
721
+ path: `/addresses/${address}/tokens/${tokenId}/transactions`,
722
+ method: 'GET',
723
+ query: query,
724
+ format: 'json',
725
+ ...params
726
+ }).then(convertHttpResponse),
727
+
728
+ /**
729
+ * @description Get address balance of given token
730
+ *
731
+ * @tags Addresses
732
+ * @name GetAddressesAddressTokensTokenIdBalance
733
+ * @request GET:/addresses/{address}/tokens/{token-id}/balance
734
+ */
735
+ getAddressesAddressTokensTokenIdBalance: (address: string, tokenId: string, params: RequestParams = {}) =>
736
+ this.request<AddressBalance, BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable>({
737
+ path: `/addresses/${address}/tokens/${tokenId}/balance`,
738
+ method: 'GET',
739
+ format: 'json',
740
+ ...params
741
+ }).then(convertHttpResponse)
742
+ }
743
+ addressesActive = {
744
+ /**
745
+ * @description Are the addresses active (at least 1 transaction)
746
+ *
747
+ * @tags Addresses
748
+ * @name PostAddressesActive
749
+ * @request POST:/addresses-active
750
+ */
751
+ postAddressesActive: (data?: string[], params: RequestParams = {}) =>
752
+ this.request<boolean[], BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable>({
753
+ path: `/addresses-active`,
754
+ method: 'POST',
755
+ body: data,
756
+ type: ContentType.Json,
757
+ format: 'json',
758
+ ...params
637
759
  }).then(convertHttpResponse)
638
760
  }
639
761
  infos = {
@@ -770,6 +892,66 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
770
892
  }
771
893
  ).then(convertHttpResponse)
772
894
  }
895
+ unconfirmedTransactions = {
896
+ /**
897
+ * @description list unconfirmed transactions
898
+ *
899
+ * @tags Unconfirmed Transactions
900
+ * @name GetUnconfirmedTransactions
901
+ * @request GET:/unconfirmed-transactions
902
+ */
903
+ getUnconfirmedTransactions: (
904
+ query?: { page?: number; limit?: number; reverse?: boolean },
905
+ params: RequestParams = {}
906
+ ) =>
907
+ this.request<
908
+ UnconfirmedTransaction[],
909
+ BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable
910
+ >({
911
+ path: `/unconfirmed-transactions`,
912
+ method: 'GET',
913
+ query: query,
914
+ format: 'json',
915
+ ...params
916
+ }).then(convertHttpResponse)
917
+ }
918
+ tokens = {
919
+ /**
920
+ * @description List tokens
921
+ *
922
+ * @tags Tokens
923
+ * @name GetTokens
924
+ * @request GET:/tokens
925
+ */
926
+ getTokens: (query?: { page?: number; limit?: number; reverse?: boolean }, params: RequestParams = {}) =>
927
+ this.request<string[], BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable>({
928
+ path: `/tokens`,
929
+ method: 'GET',
930
+ query: query,
931
+ format: 'json',
932
+ ...params
933
+ }).then(convertHttpResponse),
934
+
935
+ /**
936
+ * @description List token transactions
937
+ *
938
+ * @tags Tokens
939
+ * @name GetTokensTokenIdTransactions
940
+ * @request GET:/tokens/{token-id}/transactions
941
+ */
942
+ getTokensTokenIdTransactions: (
943
+ tokenId: string,
944
+ query?: { page?: number; limit?: number; reverse?: boolean },
945
+ params: RequestParams = {}
946
+ ) =>
947
+ this.request<Transaction[], BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable>({
948
+ path: `/tokens/${tokenId}/transactions`,
949
+ method: 'GET',
950
+ query: query,
951
+ format: 'json',
952
+ ...params
953
+ }).then(convertHttpResponse)
954
+ }
773
955
  charts = {
774
956
  /**
775
957
  * @description `interval-type` query param: hourly, daily
@@ -865,17 +1047,18 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
865
1047
  }).then(convertHttpResponse),
866
1048
 
867
1049
  /**
868
- * @description Update logging file, only logback.xml is accepted
1050
+ * @description Update logback values
869
1051
  *
870
1052
  * @tags Utils
871
1053
  * @name PutUtilsUpdateLogConfig
872
1054
  * @request PUT:/utils/update-log-config
873
1055
  */
874
- putUtilsUpdateLogConfig: (data: string, params: RequestParams = {}) =>
1056
+ putUtilsUpdateLogConfig: (data?: LogbackValue[], params: RequestParams = {}) =>
875
1057
  this.request<void, BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable>({
876
1058
  path: `/utils/update-log-config`,
877
1059
  method: 'PUT',
878
1060
  body: data,
1061
+ type: ContentType.Json,
879
1062
  ...params
880
1063
  }).then(convertHttpResponse)
881
1064
  }
package/src/api/index.ts CHANGED
@@ -19,9 +19,19 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
19
19
  import { Api as NodeApi } from './api-alephium'
20
20
  import { Api as ExplorerApi } from './api-explorer'
21
21
 
22
- export class NodeProvider extends NodeApi<null> {
23
- constructor(baseUrl: string) {
24
- super({ baseUrl: baseUrl })
22
+ export class NodeProvider extends NodeApi<string> {
23
+ constructor(baseUrl: string, apiKey?: string) {
24
+ // eslint-disable-next-line security/detect-possible-timing-attacks
25
+ if (apiKey === undefined) {
26
+ super({ baseUrl: baseUrl })
27
+ } else {
28
+ super({
29
+ baseUrl: baseUrl,
30
+ baseApiParams: { secure: true },
31
+ securityWorker: (accessToken) => (accessToken !== null ? { headers: { 'X-API-KEY': `${accessToken}` } } : {})
32
+ })
33
+ this.setSecurityData(apiKey)
34
+ }
25
35
  }
26
36
  }
27
37
 
@@ -33,3 +43,4 @@ export class ExplorerProvider extends ExplorerApi<null> {
33
43
 
34
44
  export * as node from './api-alephium'
35
45
  export * as explorer from './api-explorer'
46
+ export * from './types'
@@ -0,0 +1,233 @@
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
+ import { assertType, bs58, Eq } from '../utils'
20
+ import * as node from './api-alephium'
21
+
22
+ export type Number256 = number | bigint | string
23
+ export type Val = Number256 | boolean | string | Val[]
24
+ export type NamedVals = Record<string, Val>
25
+
26
+ export interface Token {
27
+ id: string
28
+ amount: Number256
29
+ }
30
+ assertType<Eq<keyof Token, keyof node.Token>>
31
+
32
+ export function toApiToken(token: Token): node.Token {
33
+ return { id: token.id, amount: toApiNumber256(token.amount) }
34
+ }
35
+
36
+ export function toApiTokens(tokens?: Token[]): node.Token[] | undefined {
37
+ return tokens?.map(toApiToken)
38
+ }
39
+
40
+ export function fromApiToken(token: node.Token): Token {
41
+ return { id: token.id, amount: fromApiNumber256(token.amount) }
42
+ }
43
+
44
+ export function fromApiTokens(tokens?: node.Token[]): Token[] | undefined {
45
+ return tokens?.map(fromApiToken)
46
+ }
47
+
48
+ export function toApiBoolean(v: Val): boolean {
49
+ if (typeof v === 'boolean') {
50
+ return v
51
+ } else {
52
+ throw new Error(`Invalid boolean value: ${v}`)
53
+ }
54
+ }
55
+
56
+ // TODO: check integer bounds
57
+ export function toApiNumber256(v: Val): string {
58
+ if ((typeof v === 'number' && Number.isInteger(v)) || typeof v === 'bigint') {
59
+ return v.toString()
60
+ } else if (typeof v === 'string') {
61
+ return v
62
+ } else {
63
+ throw new Error(`Invalid 256 bit number: ${v}`)
64
+ }
65
+ }
66
+
67
+ export function toApiNumber256Optional(v?: Val): string | undefined {
68
+ return v === undefined ? undefined : toApiNumber256(v)
69
+ }
70
+
71
+ export function fromApiNumber256(n: string): Number256 {
72
+ if (Number.isSafeInteger(Number.parseInt(n))) {
73
+ return Number(n)
74
+ } else {
75
+ return BigInt(n)
76
+ }
77
+ }
78
+
79
+ // TODO: check hex string
80
+ export function toApiByteVec(v: Val): string {
81
+ if (typeof v === 'string') {
82
+ // try to convert from address to contract id
83
+ try {
84
+ const address = bs58.decode(v)
85
+ if (address.length == 33 && address[0] == 3) {
86
+ return Buffer.from(address.slice(1)).toString('hex')
87
+ }
88
+ } catch (_) {
89
+ return v as string
90
+ }
91
+ return v as string
92
+ } else {
93
+ throw new Error(`Invalid string: ${v}`)
94
+ }
95
+ }
96
+
97
+ export function toApiAddress(v: Val): string {
98
+ if (typeof v === 'string') {
99
+ try {
100
+ bs58.decode(v)
101
+ return v as string
102
+ } catch (error) {
103
+ throw new Error(`Invalid base58 string: ${v}`)
104
+ }
105
+ } else {
106
+ throw new Error(`Invalid string: ${v}`)
107
+ }
108
+ }
109
+
110
+ export function toApiArray(tpe: string, v: Val): node.Val {
111
+ if (!Array.isArray(v)) {
112
+ throw new Error(`Expected array, got ${v}`)
113
+ }
114
+
115
+ const semiColonIndex = tpe.lastIndexOf(';')
116
+ if (semiColonIndex == -1) {
117
+ throw new Error(`Invalid Val type: ${tpe}`)
118
+ }
119
+
120
+ const subType = tpe.slice(1, semiColonIndex)
121
+ const dim = parseInt(tpe.slice(semiColonIndex + 1, -1))
122
+ if ((v as Val[]).length != dim) {
123
+ throw new Error(`Invalid val dimension: ${v}`)
124
+ } else {
125
+ return { value: (v as Val[]).map((v) => toApiVal(v, subType)), type: 'Array' }
126
+ }
127
+ }
128
+
129
+ export function toApiVal(v: Val, tpe: string): node.Val {
130
+ if (tpe === 'Bool') {
131
+ return { value: toApiBoolean(v), type: tpe }
132
+ } else if (tpe === 'U256' || tpe === 'I256') {
133
+ return { value: toApiNumber256(v), type: tpe }
134
+ } else if (tpe === 'ByteVec') {
135
+ return { value: toApiByteVec(v), type: tpe }
136
+ } else if (tpe === 'Address') {
137
+ return { value: toApiAddress(v), type: tpe }
138
+ } else {
139
+ return toApiArray(tpe, v)
140
+ }
141
+ }
142
+
143
+ function _fromApiVal(vals: node.Val[], valIndex: number, tpe: string): [result: Val, nextIndex: number] {
144
+ if (vals.length === 0) {
145
+ throw new Error('Not enough Vals')
146
+ }
147
+
148
+ const firstVal = vals[`${valIndex}`]
149
+ if (tpe === 'Bool' && firstVal.type === tpe) {
150
+ return [firstVal.value as boolean, valIndex + 1]
151
+ } else if ((tpe === 'U256' || tpe === 'I256') && firstVal.type === tpe) {
152
+ return [fromApiNumber256(firstVal.value as string), valIndex + 1]
153
+ } else if ((tpe === 'ByteVec' || tpe === 'Address') && firstVal.type === tpe) {
154
+ return [firstVal.value as string, valIndex + 1]
155
+ } else {
156
+ const [baseType, dims] = decodeArrayType(tpe)
157
+ const arraySize = dims.reduce((a, b) => a * b)
158
+ const nextIndex = valIndex + arraySize
159
+ const valsToUse = vals.slice(valIndex, nextIndex)
160
+ if (valsToUse.length == arraySize && valsToUse.every((val) => val.type === baseType)) {
161
+ const localVals = valsToUse.map((val) => fromApiVal(val, baseType))
162
+ return [foldVals(localVals, dims), nextIndex]
163
+ } else {
164
+ throw new Error(`Invalid array Val type: ${valsToUse}, ${tpe}`)
165
+ }
166
+ }
167
+ }
168
+
169
+ export function fromApiVals(vals: node.Val[], names: string[], types: string[]): NamedVals {
170
+ let valIndex = 0
171
+ const result: NamedVals = {}
172
+ types.forEach((currentType, index) => {
173
+ const currentName = names[`${index}`]
174
+ const [val, nextIndex] = _fromApiVal(vals, valIndex, currentType)
175
+ valIndex = nextIndex
176
+ result[`${currentName}`] = val
177
+ })
178
+ return result
179
+ }
180
+
181
+ export function fromApiArray(vals: node.Val[], types: string[]): Val[] {
182
+ let valIndex = 0
183
+ const result: Val[] = []
184
+ for (const currentType of types) {
185
+ const [val, nextIndex] = _fromApiVal(vals, valIndex, currentType)
186
+ result.push(val)
187
+ valIndex = nextIndex
188
+ }
189
+ return result
190
+ }
191
+
192
+ export function fromApiVal(v: node.Val, tpe: string): Val {
193
+ if (v.type === 'Bool' && v.type === tpe) {
194
+ return v.value as boolean
195
+ } else if ((v.type === 'U256' || v.type === 'I256') && v.type === tpe) {
196
+ return fromApiNumber256(v.value as string)
197
+ } else if ((v.type === 'ByteVec' || v.type === 'Address') && v.type === tpe) {
198
+ return v.value as string
199
+ } else {
200
+ throw new Error(`Invalid node.Val type: ${v}`)
201
+ }
202
+ }
203
+
204
+ function decodeArrayType(tpe: string): [baseType: string, dims: number[]] {
205
+ const semiColonIndex = tpe.lastIndexOf(';')
206
+ if (semiColonIndex === -1) {
207
+ throw new Error(`Invalid Val type: ${tpe}`)
208
+ }
209
+
210
+ const subType = tpe.slice(1, semiColonIndex)
211
+ const dim = parseInt(tpe.slice(semiColonIndex + 1, -1))
212
+ if (subType[0] == '[') {
213
+ const [baseType, subDim] = decodeArrayType(subType)
214
+ return [baseType, (subDim.unshift(dim), subDim)]
215
+ } else {
216
+ return [subType, [dim]]
217
+ }
218
+ }
219
+
220
+ function foldVals(vals: Val[], dims: number[]): Val {
221
+ if (dims.length == 1) {
222
+ return vals
223
+ } else {
224
+ const result: Val[] = []
225
+ const chunkSize = vals.length / dims[0]
226
+ const chunkDims = dims.slice(1)
227
+ for (let i = 0; i < vals.length; i += chunkSize) {
228
+ const chunk = vals.slice(i, i + chunkSize)
229
+ result.push(foldVals(chunk, chunkDims))
230
+ }
231
+ return result
232
+ }
233
+ }
@@ -16,9 +16,10 @@ 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
- const { rename } = require('fs')
20
-
21
- rename(process.argv[2], process.argv[3], function (error) {
22
- if (error) console.log(error)
23
- console.log(`Renamed ${process.argv[2]} to ${process.argv[3]}.`)
24
- })
19
+ export function convertHttpResponse<T>(response: { data: T; error?: { detail: string } }): T {
20
+ if (response.error) {
21
+ throw new Error(`[Node API Error] - ${response.error.detail}`)
22
+ } else {
23
+ return response.data
24
+ }
25
+ }