@alephium/web3 0.2.0-rc.35 → 0.2.0-rc.37

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/src/api/index.ts CHANGED
@@ -19,6 +19,29 @@ 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 interface ApiRequestArguments {
23
+ path: string
24
+ method: string
25
+ params: any[]
26
+ }
27
+ export type ApiRequestHandler = (args: ApiRequestArguments) => Promise<any>
28
+
29
+ function forwardRequests(api: Record<string, any>, handler: ApiRequestHandler): void {
30
+ // Update class properties to forward requests
31
+ for (const [path, pathObject] of Object.entries(api)) {
32
+ for (const method of Object.keys(pathObject)) {
33
+ pathObject[`${method}`] = async (...params: any): Promise<any> => {
34
+ return handler({ path, method, params })
35
+ }
36
+ }
37
+ }
38
+ }
39
+
40
+ async function request(provider: Record<string, any>, args: ApiRequestArguments): Promise<any> {
41
+ const call = provider[`${args.path}`][`${args.method}`] as (...any) => Promise<any>
42
+ return call(...args.params)
43
+ }
44
+
22
45
  function initializeNodeApi(baseUrl: string, apiKey?: string): NodeApi<string> {
23
46
  const nodeApi = new NodeApi<string>({
24
47
  baseUrl: baseUrl,
@@ -29,20 +52,7 @@ function initializeNodeApi(baseUrl: string, apiKey?: string): NodeApi<string> {
29
52
  return nodeApi
30
53
  }
31
54
 
32
- interface INodeProvider {
33
- readonly wallets: NodeApi<string>['wallets']
34
- readonly infos: NodeApi<string>['infos']
35
- readonly blockflow: NodeApi<string>['blockflow']
36
- readonly addresses: NodeApi<string>['addresses']
37
- readonly transactions: NodeApi<string>['transactions']
38
- readonly contracts: NodeApi<string>['contracts']
39
- readonly multisig: NodeApi<string>['multisig']
40
- readonly utils: NodeApi<string>['utils']
41
- readonly miners: NodeApi<string>['miners']
42
- readonly events: NodeApi<string>['events']
43
- }
44
-
45
- export class NodeProvider implements INodeProvider {
55
+ export class NodeProvider {
46
56
  readonly wallets: NodeApi<string>['wallets']
47
57
  readonly infos: NodeApi<string>['infos']
48
58
  readonly blockflow: NodeApi<string>['blockflow']
@@ -54,14 +64,18 @@ export class NodeProvider implements INodeProvider {
54
64
  readonly miners: NodeApi<string>['miners']
55
65
  readonly events: NodeApi<string>['events']
56
66
 
57
- constructor(provider: INodeProvider)
58
67
  constructor(baseUrl: string, apiKey?: string)
59
- constructor(param0: string | INodeProvider, apiKey?: string) {
60
- let nodeApi: INodeProvider
68
+ constructor(provider: NodeProvider)
69
+ constructor(handler: ApiRequestHandler)
70
+ constructor(param0: string | NodeProvider | ApiRequestHandler, apiKey?: string) {
71
+ let nodeApi: NodeProvider
61
72
  if (typeof param0 === 'string') {
62
73
  nodeApi = initializeNodeApi(param0, apiKey)
74
+ } else if (typeof param0 === 'function') {
75
+ nodeApi = new NodeProvider('https://1.2.3.4:0')
76
+ forwardRequests(nodeApi, param0 as ApiRequestHandler)
63
77
  } else {
64
- nodeApi = param0 as INodeProvider
78
+ nodeApi = param0 as NodeProvider
65
79
  }
66
80
 
67
81
  this.wallets = nodeApi.wallets
@@ -76,49 +90,79 @@ export class NodeProvider implements INodeProvider {
76
90
  this.events = nodeApi.events
77
91
  }
78
92
 
93
+ request = (args: ApiRequestArguments): Promise<any> => {
94
+ return request(this, args)
95
+ }
96
+
79
97
  // This can prevent the proxied node provider from being modified
80
98
  static Proxy(nodeProvider: NodeProvider): NodeProvider {
81
99
  return new NodeProvider(nodeProvider)
82
100
  }
101
+
102
+ static Remote(handler: ApiRequestHandler): NodeProvider {
103
+ return new NodeProvider(handler)
104
+ }
83
105
  }
84
106
 
85
- export interface RequestArguments {
86
- path: string
87
- method: string
88
- params?: any
107
+ function initializeExplorerApi(baseUrl: string, apiKey?: string): ExplorerApi<string> {
108
+ const explorerApi = new ExplorerApi<string>({
109
+ baseUrl: baseUrl,
110
+ baseApiParams: { secure: true },
111
+ securityWorker: (accessToken) => (accessToken !== null ? { headers: { 'X-API-KEY': `${accessToken}` } } : {})
112
+ })
113
+ explorerApi.setSecurityData(apiKey ?? null)
114
+ return explorerApi
89
115
  }
90
116
 
91
- export class RemoteNodeProvider implements INodeProvider {
92
- readonly wallets!: NodeApi<string>['wallets']
93
- readonly infos!: NodeApi<string>['infos']
94
- readonly blockflow!: NodeApi<string>['blockflow']
95
- readonly addresses!: NodeApi<string>['addresses']
96
- readonly transactions!: NodeApi<string>['transactions']
97
- readonly contracts!: NodeApi<string>['contracts']
98
- readonly multisig!: NodeApi<string>['multisig']
99
- readonly utils!: NodeApi<string>['utils']
100
- readonly miners!: NodeApi<string>['miners']
101
- readonly events!: NodeApi<string>['events']
102
-
103
- constructor(request: (request: RequestArguments) => Promise<any>) {
104
- const fakeNodeProvide = new NodeProvider('https://1.2.3.4:12973')
105
- Object.assign(this, fakeNodeProvide) // Initialize the class
106
-
107
- // Update class properties to forward requests
108
- for (const [path, pathObject] of Object.entries(this)) {
109
- for (const method of Object.keys(pathObject)) {
110
- pathObject[`${method}`] = async (params: any): Promise<any> => {
111
- return request({ path, method, params })
112
- }
113
- }
117
+ export class ExplorerProvider {
118
+ readonly blocks = ExplorerApi['blocks']
119
+ readonly transactions = ExplorerApi['transactions']
120
+ readonly transactionByOutputRefKey = ExplorerApi['transactionByOutputRefKey']
121
+ readonly addresses = ExplorerApi['addresses']
122
+ readonly addressesActive = ExplorerApi['addressesActive']
123
+ readonly infos = ExplorerApi['infos']
124
+ readonly unconfirmedTransactions = ExplorerApi['unconfirmedTransactions']
125
+ readonly tokens = ExplorerApi['tokens']
126
+ readonly charts = ExplorerApi['charts']
127
+ readonly utils = ExplorerApi['utils']
128
+
129
+ constructor(baseUrl: string, apiKey?: string)
130
+ constructor(provider: ExplorerProvider)
131
+ constructor(handler: ApiRequestHandler)
132
+ constructor(param0: string | ExplorerProvider | ApiRequestHandler, apiKey?: string) {
133
+ let explorerApi: ExplorerProvider
134
+ if (typeof param0 === 'string') {
135
+ explorerApi = initializeExplorerApi(param0, apiKey)
136
+ } else if (typeof param0 === 'function') {
137
+ explorerApi = new ExplorerProvider('https://1.2.3.4:0')
138
+ forwardRequests(explorerApi, param0 as ApiRequestHandler)
139
+ } else {
140
+ explorerApi = param0 as ExplorerProvider
114
141
  }
142
+
143
+ this.blocks = explorerApi.blocks
144
+ this.transactions = explorerApi.transactions
145
+ this.transactionByOutputRefKey = explorerApi.transactionByOutputRefKey
146
+ this.addresses = explorerApi.addresses
147
+ this.addressesActive = explorerApi.addressesActive
148
+ this.infos = explorerApi.infos
149
+ this.unconfirmedTransactions = explorerApi.unconfirmedTransactions
150
+ this.tokens = explorerApi.tokens
151
+ this.charts = explorerApi.charts
152
+ this.utils = explorerApi.utils
153
+ }
154
+
155
+ request = (args: ApiRequestArguments): Promise<any> => {
156
+ return request(this, args)
157
+ }
158
+
159
+ // This can prevent the proxied explorer provider from being modified
160
+ static Proxy(explorerProvider: ExplorerProvider): ExplorerProvider {
161
+ return new ExplorerProvider(explorerProvider)
115
162
  }
116
- }
117
163
 
118
- // TODO: use proxy provider once the endpoints are refined.
119
- export class ExplorerProvider extends ExplorerApi<null> {
120
- constructor(baseUrl: string) {
121
- super({ baseUrl: baseUrl })
164
+ static Remote(handler: ApiRequestHandler): ExplorerProvider {
165
+ return new ExplorerProvider(handler)
122
166
  }
123
167
  }
124
168
 
@@ -35,7 +35,13 @@ import {
35
35
  fromApiTokens,
36
36
  fromApiVals
37
37
  } from '../api'
38
- import { SignDeployContractTxParams, SignExecuteScriptTxParams, SignerProvider } from '../signer'
38
+ import {
39
+ SignDeployContractTxParams,
40
+ SignExecuteScriptTxParams,
41
+ SignerProvider,
42
+ SignExecuteScriptTxResult,
43
+ SignDeployContractTxResult
44
+ } from '../signer'
39
45
  import * as ralph from './ralph'
40
46
  import { bs58, binToHex, contractIdFromAddress, assertType, Eq } from '../utils'
41
47
  import { getCurrentNodeProvider } from '../global'
@@ -320,7 +326,7 @@ export class Project {
320
326
  return fsPromises.writeFile(artifactDir, compiled.artifact.toString())
321
327
  }
322
328
  for (const contract of this.contracts) {
323
- await saveToFile(contract)
329
+ saveToFile(contract)
324
330
  }
325
331
  for (const script of this.scripts) {
326
332
  await saveToFile(script)
@@ -732,7 +738,7 @@ export class Contract extends Artifact {
732
738
  }
733
739
  }
734
740
 
735
- async fromApiContractState(state: node.ContractState): Promise<ContractState> {
741
+ fromApiContractState(state: node.ContractState): ContractState {
736
742
  const contract = Project.currentProject.contractByCodeHash(state.codeHash)
737
743
  return {
738
744
  address: state.address,
@@ -758,10 +764,7 @@ export class Contract extends Artifact {
758
764
  fieldTypes: ['Address']
759
765
  }
760
766
 
761
- static async fromApiEvent(
762
- event: node.ContractEventByTxId,
763
- codeHash: string | undefined
764
- ): Promise<ContractEventByTxId> {
767
+ static fromApiEvent(event: node.ContractEventByTxId, codeHash: string | undefined): ContractEventByTxId {
765
768
  let eventSig: EventSig
766
769
 
767
770
  if (event.eventIndex == -1) {
@@ -781,7 +784,7 @@ export class Contract extends Artifact {
781
784
  }
782
785
  }
783
786
 
784
- async fromTestContractResult(methodIndex: number, result: node.TestContractResult): Promise<TestContractResult> {
787
+ fromTestContractResult(methodIndex: number, result: node.TestContractResult): TestContractResult {
785
788
  const addressToCodeHash = new Map<string, string>()
786
789
  addressToCodeHash.set(result.address, result.codeHash)
787
790
  result.contracts.forEach((contract) => addressToCodeHash.set(contract.address, contract.codeHash))
@@ -790,19 +793,17 @@ export class Contract extends Artifact {
790
793
  contractAddress: result.address,
791
794
  returns: fromApiArray(result.returns, this.functions[`${methodIndex}`].returnTypes),
792
795
  gasUsed: result.gasUsed,
793
- contracts: await Promise.all(result.contracts.map((contract) => this.fromApiContractState(contract))),
796
+ contracts: result.contracts.map((contract) => this.fromApiContractState(contract)),
794
797
  txOutputs: result.txOutputs.map(fromApiOutput),
795
- events: await Promise.all(
796
- result.events.map((event) => {
797
- const contractAddress = event.contractAddress
798
- const codeHash = addressToCodeHash.get(contractAddress)
799
- if (typeof codeHash !== 'undefined' || event.eventIndex < 0) {
800
- return Contract.fromApiEvent(event, codeHash)
801
- } else {
802
- throw Error(`Cannot find codeHash for the contract address: ${contractAddress}`)
803
- }
804
- })
805
- ),
798
+ events: result.events.map((event) => {
799
+ const contractAddress = event.contractAddress
800
+ const codeHash = addressToCodeHash.get(contractAddress)
801
+ if (typeof codeHash !== 'undefined' || event.eventIndex < 0) {
802
+ return Contract.fromApiEvent(event, codeHash)
803
+ } else {
804
+ throw Error(`Cannot find codeHash for the contract address: ${contractAddress}`)
805
+ }
806
+ }),
806
807
  debugMessages: result.debugMessages
807
808
  }
808
809
  }
@@ -827,7 +828,7 @@ export class Contract extends Artifact {
827
828
  async deploy(
828
829
  signer: SignerProvider,
829
830
  params: Omit<BuildDeployContractTx, 'signerAddress'>
830
- ): Promise<DeployContractTransaction> {
831
+ ): Promise<SignDeployContractTxResult> {
831
832
  const signerParams = await this.txParamsForDeployment(signer, params)
832
833
  return signer.signAndSubmitDeployContractTx(signerParams)
833
834
  }
@@ -912,7 +913,7 @@ export class Script extends Artifact {
912
913
  async execute(
913
914
  signer: SignerProvider,
914
915
  params: Omit<BuildExecuteScriptTx, 'signerAddress'>
915
- ): Promise<BuildScriptTxResult> {
916
+ ): Promise<SignExecuteScriptTxResult> {
916
917
  const signerParams = await this.txParamsForExecution(signer, params)
917
918
  return await signer.signAndSubmitExecuteScriptTx(signerParams)
918
919
  }
package/src/global.ts CHANGED
@@ -16,7 +16,7 @@ You should have received a copy of the GNU Lesser General Public License
16
16
  along with the library. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
 
19
- import { NodeProvider } from './api'
19
+ import { ExplorerProvider, NodeProvider } from './api'
20
20
 
21
21
  let _currentNodeProvider: NodeProvider | undefined = undefined
22
22
 
@@ -36,3 +36,21 @@ export function getCurrentNodeProvider(): NodeProvider {
36
36
  }
37
37
  return _currentNodeProvider
38
38
  }
39
+
40
+ let _currentExplorerProvider: ExplorerProvider | undefined = undefined
41
+
42
+ export function setCurrentExplorerProvider(provider: ExplorerProvider): void
43
+ export function setCurrentExplorerProvider(baseUrl: string, apiKey?: string): void
44
+ export function setCurrentExplorerProvider(provider: ExplorerProvider | string, apiKey?: string): void {
45
+ if (typeof provider == 'string') {
46
+ _currentExplorerProvider = new ExplorerProvider(provider, apiKey)
47
+ } else {
48
+ _currentExplorerProvider = provider
49
+ }
50
+ }
51
+
52
+ // Different from `NodeProvider`, this may return `undefined`
53
+ // as ExplorerProvider is not necessary for all applications
54
+ export function getCurrentExplorerProvider(): ExplorerProvider | undefined {
55
+ return _currentExplorerProvider
56
+ }
@@ -18,6 +18,7 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
18
18
 
19
19
  import { ec as EC } from 'elliptic'
20
20
  import {
21
+ ExplorerProvider,
21
22
  fromApiNumber256,
22
23
  fromApiTokens,
23
24
  NodeProvider,
@@ -145,6 +146,7 @@ export interface SubmissionResult {
145
146
 
146
147
  export interface SignerProvider {
147
148
  get nodeProvider(): NodeProvider | undefined
149
+ get explorerProvider(): ExplorerProvider | undefined
148
150
 
149
151
  getSelectedAccount(): Promise<Account>
150
152
 
@@ -161,6 +163,7 @@ export interface SignerProvider {
161
163
 
162
164
  export abstract class SignerProviderSimple implements SignerProvider {
163
165
  abstract get nodeProvider(): NodeProvider | undefined
166
+ abstract get explorerProvider(): ExplorerProvider | undefined
164
167
  abstract getSelectedAccount(): Promise<Account>
165
168
 
166
169
  private getNodeProvider(): NodeProvider {