@alephium/web3 0.25.2 → 0.27.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/api/api-explorer.d.ts +85 -8
- package/dist/src/api/api-explorer.js +85 -10
- package/dist/src/utils/exchange.d.ts +7 -3
- package/dist/src/utils/exchange.js +49 -33
- package/dist/src/utils/index.d.ts +1 -1
- package/dist/src/utils/index.js +5 -4
- package/package.json +2 -2
- package/src/api/api-explorer.ts +137 -11
- package/src/utils/exchange.ts +49 -29
- package/src/utils/index.ts +4 -3
package/src/api/api-explorer.ts
CHANGED
|
@@ -136,6 +136,15 @@ export interface ExplorerInfo {
|
|
|
136
136
|
lastFinalizedInputTime: number
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
export interface FungibleTokenMetadata {
|
|
140
|
+
/** @format 32-byte-hash */
|
|
141
|
+
id: string
|
|
142
|
+
symbol: string
|
|
143
|
+
name: string
|
|
144
|
+
/** @format uint256 */
|
|
145
|
+
decimals: string
|
|
146
|
+
}
|
|
147
|
+
|
|
139
148
|
export interface Hashrate {
|
|
140
149
|
/** @format int64 */
|
|
141
150
|
timestamp: number
|
|
@@ -193,6 +202,22 @@ export interface MempoolTransaction {
|
|
|
193
202
|
lastSeen: number
|
|
194
203
|
}
|
|
195
204
|
|
|
205
|
+
export interface NFTCollectionMetadata {
|
|
206
|
+
/** @format address */
|
|
207
|
+
address: string
|
|
208
|
+
collectionUri: string
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export interface NFTMetadata {
|
|
212
|
+
/** @format 32-byte-hash */
|
|
213
|
+
id: string
|
|
214
|
+
tokenUri: string
|
|
215
|
+
/** @format 32-byte-hash */
|
|
216
|
+
collectionId: string
|
|
217
|
+
/** @format uint256 */
|
|
218
|
+
nftIndex: string
|
|
219
|
+
}
|
|
220
|
+
|
|
196
221
|
export interface NotFound {
|
|
197
222
|
detail: string
|
|
198
223
|
resource: string
|
|
@@ -284,6 +309,19 @@ export interface Token {
|
|
|
284
309
|
amount: string
|
|
285
310
|
}
|
|
286
311
|
|
|
312
|
+
export interface TokenInfo {
|
|
313
|
+
/** @format 32-byte-hash */
|
|
314
|
+
token: string
|
|
315
|
+
/** Raw interface id, e.g. 0001 */
|
|
316
|
+
stdInterfaceId?: TokenStdInterfaceId | string
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
export enum TokenStdInterfaceId {
|
|
320
|
+
Fungible = 'fungible',
|
|
321
|
+
NonFungible = 'non-fungible',
|
|
322
|
+
NonStandard = 'non-standard'
|
|
323
|
+
}
|
|
324
|
+
|
|
287
325
|
export interface TokenSupply {
|
|
288
326
|
/** @format int64 */
|
|
289
327
|
timestamp: number
|
|
@@ -358,6 +396,14 @@ export interface ValU256 {
|
|
|
358
396
|
type: string
|
|
359
397
|
}
|
|
360
398
|
|
|
399
|
+
export enum MaxSizeTokens {
|
|
400
|
+
Value80 = 80
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
export enum MaxSizeAddresses {
|
|
404
|
+
Value80 = 80
|
|
405
|
+
}
|
|
406
|
+
|
|
361
407
|
import 'cross-fetch/polyfill'
|
|
362
408
|
import { convertHttpResponse } from './utils'
|
|
363
409
|
|
|
@@ -845,6 +891,7 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
|
|
|
845
891
|
* @tags Addresses
|
|
846
892
|
* @name GetAddressesAddressTokens
|
|
847
893
|
* @request GET:/addresses/{address}/tokens
|
|
894
|
+
* @deprecated
|
|
848
895
|
*/
|
|
849
896
|
getAddressesAddressTokens: (
|
|
850
897
|
address: string,
|
|
@@ -1223,7 +1270,7 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
|
|
|
1223
1270
|
}
|
|
1224
1271
|
tokens = {
|
|
1225
1272
|
/**
|
|
1226
|
-
* @description List
|
|
1273
|
+
* @description List token information
|
|
1227
1274
|
*
|
|
1228
1275
|
* @tags Tokens
|
|
1229
1276
|
* @name GetTokens
|
|
@@ -1241,10 +1288,15 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
|
|
|
1241
1288
|
* @format int32
|
|
1242
1289
|
*/
|
|
1243
1290
|
limit?: number
|
|
1291
|
+
/**
|
|
1292
|
+
* fungible, non-fungible, non-standard or any interface id in hex-string format, e.g: 0001
|
|
1293
|
+
* @format string
|
|
1294
|
+
*/
|
|
1295
|
+
'interface-id'?: TokenStdInterfaceId | string
|
|
1244
1296
|
},
|
|
1245
1297
|
params: RequestParams = {}
|
|
1246
1298
|
) =>
|
|
1247
|
-
this.request<
|
|
1299
|
+
this.request<TokenInfo[], BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable>({
|
|
1248
1300
|
path: `/tokens`,
|
|
1249
1301
|
method: 'GET',
|
|
1250
1302
|
query: query,
|
|
@@ -1252,6 +1304,23 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
|
|
|
1252
1304
|
...params
|
|
1253
1305
|
}).then(convertHttpResponse),
|
|
1254
1306
|
|
|
1307
|
+
/**
|
|
1308
|
+
* @description list given tokens information
|
|
1309
|
+
*
|
|
1310
|
+
* @tags Tokens
|
|
1311
|
+
* @name PostTokens
|
|
1312
|
+
* @request POST:/tokens
|
|
1313
|
+
*/
|
|
1314
|
+
postTokens: (data?: string[], params: RequestParams = {}) =>
|
|
1315
|
+
this.request<TokenInfo[], BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable>({
|
|
1316
|
+
path: `/tokens`,
|
|
1317
|
+
method: 'POST',
|
|
1318
|
+
body: data,
|
|
1319
|
+
type: ContentType.Json,
|
|
1320
|
+
format: 'json',
|
|
1321
|
+
...params
|
|
1322
|
+
}).then(convertHttpResponse),
|
|
1323
|
+
|
|
1255
1324
|
/**
|
|
1256
1325
|
* @description List token transactions
|
|
1257
1326
|
*
|
|
@@ -1281,6 +1350,63 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
|
|
|
1281
1350
|
query: query,
|
|
1282
1351
|
format: 'json',
|
|
1283
1352
|
...params
|
|
1353
|
+
}).then(convertHttpResponse),
|
|
1354
|
+
|
|
1355
|
+
/**
|
|
1356
|
+
* @description Return metadata for the given fungible tokens, if metadata doesn't exist or token isn't a fungible, it won't be in the output list
|
|
1357
|
+
*
|
|
1358
|
+
* @tags Tokens
|
|
1359
|
+
* @name PostTokensFungibleMetadata
|
|
1360
|
+
* @request POST:/tokens/fungible-metadata
|
|
1361
|
+
*/
|
|
1362
|
+
postTokensFungibleMetadata: (data?: string[], params: RequestParams = {}) =>
|
|
1363
|
+
this.request<
|
|
1364
|
+
FungibleTokenMetadata[],
|
|
1365
|
+
BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable
|
|
1366
|
+
>({
|
|
1367
|
+
path: `/tokens/fungible-metadata`,
|
|
1368
|
+
method: 'POST',
|
|
1369
|
+
body: data,
|
|
1370
|
+
type: ContentType.Json,
|
|
1371
|
+
format: 'json',
|
|
1372
|
+
...params
|
|
1373
|
+
}).then(convertHttpResponse),
|
|
1374
|
+
|
|
1375
|
+
/**
|
|
1376
|
+
* @description Return metadata for the given nft tokens, if metadata doesn't exist or token isn't a nft, it won't be in the output list
|
|
1377
|
+
*
|
|
1378
|
+
* @tags Tokens
|
|
1379
|
+
* @name PostTokensNftMetadata
|
|
1380
|
+
* @request POST:/tokens/nft-metadata
|
|
1381
|
+
*/
|
|
1382
|
+
postTokensNftMetadata: (data?: string[], params: RequestParams = {}) =>
|
|
1383
|
+
this.request<NFTMetadata[], BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable>({
|
|
1384
|
+
path: `/tokens/nft-metadata`,
|
|
1385
|
+
method: 'POST',
|
|
1386
|
+
body: data,
|
|
1387
|
+
type: ContentType.Json,
|
|
1388
|
+
format: 'json',
|
|
1389
|
+
...params
|
|
1390
|
+
}).then(convertHttpResponse),
|
|
1391
|
+
|
|
1392
|
+
/**
|
|
1393
|
+
* @description Return metadata for the given nft collection addresses, if metadata doesn't exist or address isn't a nft collection, it won't be in the output list
|
|
1394
|
+
*
|
|
1395
|
+
* @tags Tokens
|
|
1396
|
+
* @name PostTokensNftCollectionMetadata
|
|
1397
|
+
* @request POST:/tokens/nft-collection-metadata
|
|
1398
|
+
*/
|
|
1399
|
+
postTokensNftCollectionMetadata: (data?: string[], params: RequestParams = {}) =>
|
|
1400
|
+
this.request<
|
|
1401
|
+
NFTCollectionMetadata[],
|
|
1402
|
+
BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable
|
|
1403
|
+
>({
|
|
1404
|
+
path: `/tokens/nft-collection-metadata`,
|
|
1405
|
+
method: 'POST',
|
|
1406
|
+
body: data,
|
|
1407
|
+
type: ContentType.Json,
|
|
1408
|
+
format: 'json',
|
|
1409
|
+
...params
|
|
1284
1410
|
}).then(convertHttpResponse)
|
|
1285
1411
|
}
|
|
1286
1412
|
charts = {
|
|
@@ -1467,12 +1593,12 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
|
|
|
1467
1593
|
* @description Get contract parent address if exist
|
|
1468
1594
|
*
|
|
1469
1595
|
* @tags Contracts
|
|
1470
|
-
* @name
|
|
1471
|
-
* @request GET:/contracts/{
|
|
1596
|
+
* @name GetContractsContractAddressParent
|
|
1597
|
+
* @request GET:/contracts/{contract_address}/parent
|
|
1472
1598
|
*/
|
|
1473
|
-
|
|
1599
|
+
getContractsContractAddressParent: (contractAddress: string, params: RequestParams = {}) =>
|
|
1474
1600
|
this.request<ContractParent, BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable>({
|
|
1475
|
-
path: `/contracts/${
|
|
1601
|
+
path: `/contracts/${contractAddress}/parent`,
|
|
1476
1602
|
method: 'GET',
|
|
1477
1603
|
format: 'json',
|
|
1478
1604
|
...params
|
|
@@ -1482,11 +1608,11 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
|
|
|
1482
1608
|
* @description Get sub contract addresses
|
|
1483
1609
|
*
|
|
1484
1610
|
* @tags Contracts
|
|
1485
|
-
* @name
|
|
1486
|
-
* @request GET:/contracts/{
|
|
1611
|
+
* @name GetContractsContractAddressSubContracts
|
|
1612
|
+
* @request GET:/contracts/{contract_address}/sub-contracts
|
|
1487
1613
|
*/
|
|
1488
|
-
|
|
1489
|
-
|
|
1614
|
+
getContractsContractAddressSubContracts: (
|
|
1615
|
+
contractAddress: string,
|
|
1490
1616
|
query?: {
|
|
1491
1617
|
/**
|
|
1492
1618
|
* Page number
|
|
@@ -1502,7 +1628,7 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
|
|
|
1502
1628
|
params: RequestParams = {}
|
|
1503
1629
|
) =>
|
|
1504
1630
|
this.request<SubContracts, BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable>({
|
|
1505
|
-
path: `/contracts/${
|
|
1631
|
+
path: `/contracts/${contractAddress}/sub-contracts`,
|
|
1506
1632
|
method: 'GET',
|
|
1507
1633
|
query: query,
|
|
1508
1634
|
format: 'json',
|
package/src/utils/exchange.ts
CHANGED
|
@@ -37,16 +37,35 @@ export function validateExchangeAddress(address: string) {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
export function
|
|
41
|
-
return
|
|
40
|
+
export function isSimpleALPHTransferTx(tx: Transaction): boolean {
|
|
41
|
+
return isSimpleTransferTx(tx) && checkALPHOutput(tx)
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
export function
|
|
45
|
-
|
|
44
|
+
export function isSimpleTransferTokenTx(tx: Transaction): boolean {
|
|
45
|
+
const isTransferTx = isSimpleTransferTx(tx)
|
|
46
|
+
if (isTransferTx) {
|
|
47
|
+
const senderAddress = getSenderAddress(tx)
|
|
48
|
+
const targetAddress = tx.unsigned.fixedOutputs.find((o) => o.address !== senderAddress)!.address
|
|
49
|
+
return checkTokenOutput(tx, targetAddress)
|
|
50
|
+
}
|
|
51
|
+
return false
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// we assume that the tx is a simple transfer tx, i.e. isSimpleTransferALPHTx(tx) == true
|
|
55
|
+
export function getALPHDepositInfo(tx: Transaction): { targetAddress: Address; depositAmount: bigint } {
|
|
56
|
+
const senderAddress = getSenderAddress(tx)
|
|
57
|
+
const targetAddress = tx.unsigned.fixedOutputs.find((o) => o.address !== senderAddress)!.address
|
|
58
|
+
let depositAmount = 0n
|
|
59
|
+
tx.unsigned.fixedOutputs.forEach((o) => {
|
|
60
|
+
if (o.address === targetAddress) {
|
|
61
|
+
depositAmount += BigInt(o.attoAlphAmount)
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
return { targetAddress, depositAmount }
|
|
46
65
|
}
|
|
47
66
|
|
|
48
|
-
// we assume that the tx is
|
|
49
|
-
export function
|
|
67
|
+
// we assume that the tx is a simple transfer tx, i.e. isSimpleTransferALPHTx(tx) == true
|
|
68
|
+
export function getSenderAddress(tx: Transaction): Address {
|
|
50
69
|
return getAddressFromUnlockScript(tx.unsigned.inputs[0].unlockScript)
|
|
51
70
|
}
|
|
52
71
|
|
|
@@ -77,31 +96,17 @@ export function getAddressFromUnlockScript(unlockScript: string): Address {
|
|
|
77
96
|
}
|
|
78
97
|
}
|
|
79
98
|
|
|
80
|
-
function
|
|
99
|
+
function getSenderAddressAnyTx(tx: Transaction): Address | undefined {
|
|
81
100
|
try {
|
|
82
101
|
const inputAddresses = tx.unsigned.inputs.map((i) => getAddressFromUnlockScript(i.unlockScript))
|
|
83
102
|
// we have checked that the inputs is not empty
|
|
84
|
-
const
|
|
85
|
-
return inputAddresses.slice(1).every((addr) => addr ===
|
|
103
|
+
const sender = inputAddresses[0]
|
|
104
|
+
return inputAddresses.slice(1).every((addr) => addr === sender) ? sender : undefined
|
|
86
105
|
} catch (_) {
|
|
87
106
|
return undefined
|
|
88
107
|
}
|
|
89
108
|
}
|
|
90
109
|
|
|
91
|
-
function checkOutputAddress(tx: Transaction, from: Address, to: Address): boolean {
|
|
92
|
-
let fromCount = 0
|
|
93
|
-
let toCount = 0
|
|
94
|
-
tx.unsigned.fixedOutputs.forEach((o) => {
|
|
95
|
-
if (o.address === from) {
|
|
96
|
-
fromCount += 1
|
|
97
|
-
} else if (o.address === to) {
|
|
98
|
-
toCount += 1
|
|
99
|
-
}
|
|
100
|
-
})
|
|
101
|
-
const outputCount = tx.unsigned.fixedOutputs.length
|
|
102
|
-
return toCount === 1 && fromCount === outputCount - 1
|
|
103
|
-
}
|
|
104
|
-
|
|
105
110
|
function checkALPHOutput(tx: Transaction): boolean {
|
|
106
111
|
const outputs = tx.unsigned.fixedOutputs
|
|
107
112
|
return outputs.every((o) => o.tokens.length === 0)
|
|
@@ -109,11 +114,17 @@ function checkALPHOutput(tx: Transaction): boolean {
|
|
|
109
114
|
|
|
110
115
|
function checkTokenOutput(tx: Transaction, to: Address): boolean {
|
|
111
116
|
// we have checked the output address
|
|
112
|
-
const
|
|
113
|
-
|
|
117
|
+
const outputs = tx.unsigned.fixedOutputs.filter((o) => o.address === to)
|
|
118
|
+
if (outputs[0].tokens.length === 0) {
|
|
119
|
+
return false
|
|
120
|
+
}
|
|
121
|
+
const tokenId = outputs[0].tokens[0].id
|
|
122
|
+
return outputs.every(
|
|
123
|
+
(o) => BigInt(o.attoAlphAmount) === DUST_AMOUNT && o.tokens.length === 1 && o.tokens[0].id === tokenId
|
|
124
|
+
)
|
|
114
125
|
}
|
|
115
126
|
|
|
116
|
-
function
|
|
127
|
+
function isSimpleTransferTx(tx: Transaction): boolean {
|
|
117
128
|
if (
|
|
118
129
|
tx.contractInputs.length !== 0 ||
|
|
119
130
|
tx.generatedOutputs.length !== 0 ||
|
|
@@ -122,9 +133,18 @@ function isDepositTransaction(tx: Transaction, exchangeAddress: string): boolean
|
|
|
122
133
|
) {
|
|
123
134
|
return false
|
|
124
135
|
}
|
|
125
|
-
const
|
|
126
|
-
if (
|
|
136
|
+
const sender = getSenderAddressAnyTx(tx)
|
|
137
|
+
if (sender === undefined) {
|
|
127
138
|
return false
|
|
128
139
|
}
|
|
129
|
-
|
|
140
|
+
const outputAddresses: Address[] = []
|
|
141
|
+
tx.unsigned.fixedOutputs.forEach((o) => {
|
|
142
|
+
if (!outputAddresses.includes(o.address)) {
|
|
143
|
+
outputAddresses.push(o.address)
|
|
144
|
+
}
|
|
145
|
+
})
|
|
146
|
+
return (
|
|
147
|
+
(outputAddresses.length === 1 && outputAddresses[0] !== sender) ||
|
|
148
|
+
(outputAddresses.length === 2 && outputAddresses.includes(sender))
|
|
149
|
+
)
|
|
130
150
|
}
|
package/src/utils/index.ts
CHANGED
|
@@ -26,7 +26,8 @@ export * from './sign'
|
|
|
26
26
|
export * from './number'
|
|
27
27
|
export {
|
|
28
28
|
validateExchangeAddress,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
isSimpleALPHTransferTx,
|
|
30
|
+
isSimpleTransferTokenTx,
|
|
31
|
+
getSenderAddress,
|
|
32
|
+
getALPHDepositInfo
|
|
32
33
|
} from './exchange'
|