Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f068ef76a5 | ||
|
|
e6e60ec6d0 | ||
|
|
9f9680ba92 | ||
|
|
bb63de1653 | ||
|
|
a2c2b24198 | ||
|
|
1944ffe017 | ||
|
|
d4aa36981d | ||
|
|
2c735fbc53 | ||
|
|
7038045bc8 | ||
|
|
0be5c969aa | ||
|
|
9ead2bdc41 | ||
|
|
1ae37ed2d3 | ||
|
|
7ca78c5679 | ||
|
|
cd94d01b06 | ||
|
|
dafc92809d | ||
|
|
298884d885 | ||
|
|
2a64c7c29a | ||
|
|
d2b7dc550a | ||
|
|
25f18d5455 | ||
|
|
c9c872c736 | ||
|
|
8394b7fb5a | ||
|
|
fb82db382e | ||
|
|
9f83f5cac3 | ||
|
|
45a895b64f | ||
|
|
93fbd6e13f | ||
|
|
b53490bd26 | ||
|
|
594376367a | ||
|
|
180fe57531 | ||
|
|
bddb4465fb | ||
|
|
3cdc647506 | ||
|
|
82ee7cc4f1 | ||
|
|
9f9658d6a0 | ||
|
|
1abc519297 | ||
|
|
b939bcd57d | ||
|
|
d487a27676 | ||
|
|
0525feb6f2 | ||
|
|
4ea343e369 | ||
|
|
6f2173778e | ||
|
|
bb6166e65f | ||
|
|
dec82380c3 | ||
|
|
a980d4ae11 | ||
|
|
5c194b6f5f | ||
|
|
c4662e6fd8 | ||
|
|
995de2012e | ||
|
|
b1a8c011f4 | ||
|
|
86cd550ad3 | ||
|
|
57529998f9 | ||
|
|
0e0d733e65 | ||
|
|
773618acfb | ||
|
|
c5fcb0d06b | ||
|
|
e25272c986 | ||
|
|
d389c6737e | ||
|
|
9e1313f140 | ||
|
|
d2a2887d32 | ||
|
|
b3d9549c0b | ||
|
|
240cadd045 | ||
|
|
d47faa4687 | ||
|
|
393c677a16 | ||
|
|
074ddd8632 | ||
|
|
a8a10aec0c | ||
|
|
fed93e2459 | ||
|
|
374df23011 | ||
|
|
9c098c3fbf | ||
|
|
4e799858ad | ||
|
|
ee6924324f | ||
|
|
75f86bb43e | ||
|
|
bfd3113a55 | ||
|
|
8d8d5bd7d7 |
Vendored
-55
File diff suppressed because one or more lines are too long
+55
File diff suppressed because one or more lines are too long
+1
-1
@@ -12,4 +12,4 @@ plugins:
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
|
||||
spec: "@yarnpkg/plugin-workspace-tools"
|
||||
|
||||
yarnPath: .yarn/releases/yarn-2.2.2.cjs
|
||||
yarnPath: .yarn/releases/yarn-2.3.3.cjs
|
||||
|
||||
+46
-3
@@ -1,6 +1,48 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 2.2.1 Oct 13, 2020
|
||||
## 2.4.1 Oct 26, 2020
|
||||
|
||||
Upgrade priority: Low. No breaking changes, however it does move `api-contract` forward with additional features.
|
||||
|
||||
Contributed:
|
||||
|
||||
- Add support for both `{i,u}256` types on contracts (Thanks to https://github.com/seanyoung)
|
||||
|
||||
Changes:
|
||||
|
||||
- Add `.keysAt` & `.entriesAt` to query maps at a specific blockHash
|
||||
- Adjust ordering of type injection, any `types: { ... }` definitions not have precedence
|
||||
- Correctly format Tuples in both RPC and const definitions as part of type generation
|
||||
- Add node-template to known types (tracking inside API), remove warnings for the spec
|
||||
- Add initial implementation for new Substrate `MultiAddress` type
|
||||
- Add `api.derive.chain.subscribeNewBlocks` for full block retrievals
|
||||
- Contracts identifiers to `.{exec, read}('name', ...)` now matches on both snake_case and camelCase (consistency)
|
||||
- Cleanup contracts serialization for messages to allow both to and from
|
||||
- Add deserialization of contract events against the ABI
|
||||
- Adjust contracts metadata parsing to be future-proof with type retrievals
|
||||
- Add tests for Solang into contracts, re-organize layout per type
|
||||
|
||||
|
||||
## 2.3.1 Oct 19, 2020
|
||||
|
||||
Upgrade priority: Low. Recommended for `api-contract` developers and those using large messages via Node.js WS.
|
||||
|
||||
Contributed:
|
||||
|
||||
- Adjust frame size for Node.js WebSockets (Thanks to https://github.com/mnaamani)
|
||||
- Update warnings to reflect new docs URLs (Thanks to https://github.com/aphelionz)
|
||||
|
||||
Changes:
|
||||
|
||||
- Expose `dispatch{Error, Info}` on all `.tx` results (less boilerplate on info checks)
|
||||
- Add missing primitive types inside contracts type parsing
|
||||
- Adjust api-contract to expose `Contract.{query, tx}.<message>` and `Blueprint.tx.<constructor>`
|
||||
- Rework contracts registry to be generic to all scale-info definitions
|
||||
- Allow for auto-max weight on contract read/exec (useful in estimation)
|
||||
- Fix memoization where `BigInt` params are passed
|
||||
|
||||
|
||||
## 2.2.1 Oct 12, 2020
|
||||
|
||||
Upgrade priority: Low.
|
||||
|
||||
@@ -14,10 +56,11 @@ Contributed:
|
||||
Changes:
|
||||
|
||||
- Introduce `OriginCaller` type (& apply to scheduler types)
|
||||
- Adjust `ContractInfo` struct to cater for latest Substrate
|
||||
- Adjust `ContractInfo` type for latest Substrate (contracts)
|
||||
- Adjust `Schedule` type for latest Substrate (contracts)
|
||||
- Allow snake_case to be handled transparently in structs
|
||||
- Full new api-contract developer interfaces (Code, Blueprint, Contract)
|
||||
- Rework Abi & Abi Registry use & parse (on-top-of-contributed) for efficiency & non-global clobber
|
||||
- Rework Abi & Abi Registry use & parse (based on contributed) for efficiency & non-global clobber
|
||||
- Allow `null` input on `Text` values in addition to existing `undefined`
|
||||
- Remove all documentation after move to https://github.com/polkadot-js/docs repo
|
||||
- Adjust type encoding from TypeDef, s/encodeType/encodeTypeDef/
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="initial-scale=0.5, maximum-scale=1">
|
||||
<meta http-equiv="refresh" content="0;URL='https://polkadot.js.org/docs/api/'" />
|
||||
<title>Redirecting to https://polkadot.js.org/docs/api/</title>
|
||||
</head>
|
||||
<body>
|
||||
Redirecting to <a href="https://polkadot.js.org/docs/api/">https://polkadot.js.org/docs/api/</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="initial-scale=0.5, maximum-scale=1">
|
||||
<meta http-equiv="refresh" content="0;URL='https://polkadot.js.org/docs/api/'" />
|
||||
<title>Redirecting to https://polkadot.js.org/docs/api/</title>
|
||||
</head>
|
||||
<body>
|
||||
Redirecting to <a href="https://polkadot.js.org/docs/api/">https://polkadot.js.org/docs/api/</a>
|
||||
</body>
|
||||
</html>
|
||||
+8
-12
@@ -24,18 +24,14 @@
|
||||
"test:watch": "polkadot-dev-run-test --watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.11.6",
|
||||
"@babel/register": "^7.11.5",
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@polkadot/dev": "^0.58.1",
|
||||
"@polkadot/ts": "^0.3.49",
|
||||
"@babel/core": "^7.12.3",
|
||||
"@babel/register": "^7.12.1",
|
||||
"@babel/runtime": "^7.12.1",
|
||||
"@polkadot/dev": "^0.59.6",
|
||||
"@polkadot/ts": "^0.3.51",
|
||||
"@polkadot/typegen": "workspace:packages/typegen",
|
||||
"@types/jest": "^26.0.14",
|
||||
"@vuepress/plugin-search": "^1.6.0",
|
||||
"copyfiles": "^2.4.0",
|
||||
"typedoc": "^0.19.2",
|
||||
"typedoc-plugin-markdown": "^3.0.7",
|
||||
"typedoc-plugin-no-inherit": "^1.2.0"
|
||||
"@types/jest": "^26.0.15",
|
||||
"copyfiles": "^2.4.0"
|
||||
},
|
||||
"version": "2.2.1"
|
||||
"version": "2.4.1"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/api-contract",
|
||||
"version": "2.2.1",
|
||||
"version": "2.4.1",
|
||||
"description": "Interfaces for interacting with contracts and contract ABIs",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -26,11 +26,11 @@
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-contract#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@polkadot/api": "2.2.1",
|
||||
"@polkadot/rpc-core": "2.2.1",
|
||||
"@polkadot/types": "2.2.1",
|
||||
"@polkadot/util": "^3.5.1",
|
||||
"@babel/runtime": "^7.12.1",
|
||||
"@polkadot/api": "^2.4.1",
|
||||
"@polkadot/rpc-core": "^2.4.1",
|
||||
"@polkadot/types": "^2.4.1",
|
||||
"@polkadot/util": "^3.6.1",
|
||||
"bn.js": "^5.1.3",
|
||||
"rxjs": "^6.6.3"
|
||||
}
|
||||
|
||||
@@ -7,88 +7,27 @@ import * as testContracts from '../test/contracts';
|
||||
|
||||
const abis: Record<string, any> = { ...testContracts };
|
||||
|
||||
function compare (name: string, messageIds: string[]): void {
|
||||
try {
|
||||
const inkAbi = new Abi(abis[name]);
|
||||
|
||||
expect(inkAbi.messages.map(({ identifier }) => identifier)).toEqual(messageIds);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
throw error;
|
||||
interface JSONAbi {
|
||||
spec: {
|
||||
messages: {
|
||||
name: string[] | string
|
||||
}[]
|
||||
}
|
||||
}
|
||||
|
||||
describe('Abi', (): void => {
|
||||
describe('construction', (): void => {
|
||||
it('initializes from a contract ABI (flipper)', (): void => {
|
||||
compare('flipper', ['flip', 'get']);
|
||||
});
|
||||
Object.entries(abis).forEach(([abiName, abi]) => {
|
||||
it(`initializes from a contract ABI (${abiName})`, (): void => {
|
||||
try {
|
||||
const messageIds = (abi as JSONAbi).spec.messages.map(({ name }) => Array.isArray(name) ? name[0] : name);
|
||||
const inkAbi = new Abi(abis[abiName]);
|
||||
|
||||
it('initializes from a contract ABI (incrementer)', (): void => {
|
||||
compare('incrementer', ['inc', 'get']);
|
||||
});
|
||||
expect(inkAbi.messages.map(({ identifier }) => identifier)).toEqual(messageIds);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
it('initializes from a contract ABI (erc20)', (): void => {
|
||||
compare('erc20', [
|
||||
'total_supply',
|
||||
'balance_of',
|
||||
'allowance',
|
||||
'transfer',
|
||||
'approve',
|
||||
'transfer_from'
|
||||
]);
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
|
||||
it('initializes from a contract ABI (delegator)', (): void => {
|
||||
compare('delegator', [
|
||||
'get',
|
||||
'change',
|
||||
'switch'
|
||||
]);
|
||||
});
|
||||
|
||||
it('initializes from a contract ABI (dns)', (): void => {
|
||||
compare('dns', [
|
||||
'register',
|
||||
'set_address',
|
||||
'transfer',
|
||||
'get_address'
|
||||
]);
|
||||
});
|
||||
|
||||
it('initializes from a contract ABI (erc721)', (): void => {
|
||||
compare('erc721', [
|
||||
'balance_of',
|
||||
'owner_of',
|
||||
'get_approved',
|
||||
'is_approved_for_all',
|
||||
'set_approval_for_all',
|
||||
'approve',
|
||||
'transfer',
|
||||
'transfer_from',
|
||||
'mint',
|
||||
'burn'
|
||||
]);
|
||||
});
|
||||
|
||||
it('initializes from a contract ABI (multisig_plain)', (): void => {
|
||||
compare('multisigPlain', [
|
||||
'add_owner',
|
||||
'remove_owner',
|
||||
'replace_owner',
|
||||
'change_requirement',
|
||||
'submit_transaction',
|
||||
'cancel_transaction',
|
||||
'confirm_transaction',
|
||||
'revoke_confirmation',
|
||||
'invoke_transaction',
|
||||
'eval_transaction'
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
it('stores base project as JSON', (): void => {
|
||||
expect(new Abi(abis.dns).json).toEqual(abis.dns);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
// Copyright 2017-2020 @polkadot/api-contract authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { AnyJson } from '@polkadot/types/types';
|
||||
import { ChainProperties, InkConstructorSpec, InkMessageSpec } from '@polkadot/types/interfaces';
|
||||
import { AbiConstructor, AbiMessage, AbiMessageParam } from './types';
|
||||
import { AnyJson, Codec, CodecArg } from '@polkadot/types/types';
|
||||
import { ChainProperties, ContractConstructorSpec, ContractEventSpec, ContractMessageSpec, ContractMessageParamSpec, ContractProject } from '@polkadot/types/interfaces';
|
||||
import { AbiConstructor, AbiEvent, AbiMessage, AbiParam, DecodedEvent, DecodedMessage } from './types';
|
||||
|
||||
import { assert, isNumber, isObject, isString, stringCamelCase } from '@polkadot/util';
|
||||
import { assert, compactAddLength, compactStripLength, isNumber, isObject, isString, stringCamelCase, u8aConcat, u8aToHex } from '@polkadot/util';
|
||||
|
||||
import ContractRegistry from './ContractRegistry';
|
||||
import MetaRegistry from './MetaRegistry';
|
||||
|
||||
function findMessage <T extends AbiMessage> (list: T[], messageOrId: T | string | number): T {
|
||||
const message = isNumber(messageOrId)
|
||||
? list[messageOrId]
|
||||
: isString(messageOrId)
|
||||
? list.find(({ identifier }: T) => identifier === messageOrId.toString())
|
||||
? list.find(({ identifier }) => [identifier, stringCamelCase(identifier)].includes(messageOrId.toString()))
|
||||
: messageOrId;
|
||||
|
||||
assert(message, `Attempted to call an invalid contract interface, ${JSON.stringify(messageOrId)}`);
|
||||
@@ -21,13 +21,19 @@ function findMessage <T extends AbiMessage> (list: T[], messageOrId: T | string
|
||||
return message;
|
||||
}
|
||||
|
||||
export default class Abi extends ContractRegistry {
|
||||
export default class Abi {
|
||||
readonly #events: AbiEvent[];
|
||||
|
||||
public readonly constructors: AbiConstructor[];
|
||||
|
||||
public readonly json: AnyJson;
|
||||
|
||||
public readonly messages: AbiMessage[];
|
||||
|
||||
public readonly project: ContractProject;
|
||||
|
||||
public readonly registry: MetaRegistry;
|
||||
|
||||
constructor (abiJson: AnyJson, chainProperties?: ChainProperties) {
|
||||
const json = isString(abiJson)
|
||||
? JSON.parse(abiJson) as AnyJson
|
||||
@@ -35,27 +41,62 @@ export default class Abi extends ContractRegistry {
|
||||
|
||||
assert(isObject(json) && !Array.isArray(json) && json.metadataVersion && isObject(json.spec) && !Array.isArray(json.spec) && Array.isArray(json.spec.constructors) && Array.isArray(json.spec.messages), 'Invalid JSON ABI structure supplied, expected a recent metadata version');
|
||||
|
||||
super(json, chainProperties);
|
||||
|
||||
this.json = json;
|
||||
this.constructors = this.project.spec.constructors.map((spec: InkConstructorSpec, index) =>
|
||||
this._createBase(spec, index, {
|
||||
this.registry = new MetaRegistry(chainProperties);
|
||||
this.project = this.registry.createType('ContractProject', json);
|
||||
|
||||
this.registry.setMetaTypes(this.project.types);
|
||||
|
||||
this.project.types.forEach((_, index) =>
|
||||
this.registry.getMetaTypeDef({ type: this.registry.createType('SiLookupTypeId', index + 1) })
|
||||
);
|
||||
this.constructors = this.project.spec.constructors.map((spec: ContractConstructorSpec, index) =>
|
||||
this.#createMessage(spec, index, {
|
||||
isConstructor: true
|
||||
})
|
||||
);
|
||||
this.messages = this.project.spec.messages.map((spec: InkMessageSpec, index): AbiMessage => {
|
||||
this.#events = this.project.spec.events.map((spec: ContractEventSpec, index) =>
|
||||
this.#createEvent(spec, index)
|
||||
);
|
||||
this.messages = this.project.spec.messages.map((spec: ContractMessageSpec, index): AbiMessage => {
|
||||
const typeSpec = spec.returnType.unwrapOr(null);
|
||||
|
||||
return this._createBase(spec, index, {
|
||||
return this.#createMessage(spec, index, {
|
||||
isMutating: spec.mutates.isTrue,
|
||||
isPayable: spec.payable.isTrue,
|
||||
returnType: typeSpec
|
||||
? this.typeDefAt(typeSpec.type, { displayName: typeSpec.displayName.map((s) => s.toString()).join('::') || undefined })
|
||||
? this.registry.getMetaTypeDef(typeSpec)
|
||||
: null
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Warning: Unstable API, bound to change
|
||||
*/
|
||||
public decodeEvent (data: Uint8Array): DecodedEvent {
|
||||
const index = data[0];
|
||||
const event = this.#events[index];
|
||||
|
||||
assert(event, `Unable to find event with index ${index}`);
|
||||
|
||||
return event.fromU8a(data.subarray(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Warning: Unstable API, bound to change
|
||||
*/
|
||||
public decodeConstructor (data: Uint8Array): DecodedMessage {
|
||||
return this.#decodeMessage('message', this.constructors, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Warning: Unstable API, bound to change
|
||||
*/
|
||||
public decodeMessage (data: Uint8Array): DecodedMessage {
|
||||
return this.#decodeMessage('message', this.messages, data);
|
||||
}
|
||||
|
||||
public findConstructor (constructorOrId: AbiConstructor | string | number): AbiConstructor {
|
||||
return findMessage(this.constructors, constructorOrId);
|
||||
}
|
||||
@@ -64,15 +105,14 @@ export default class Abi extends ContractRegistry {
|
||||
return findMessage(this.messages, messageOrId);
|
||||
}
|
||||
|
||||
private _createBase (spec: InkMessageSpec | InkConstructorSpec, index: number, add: Partial<AbiMessage> = {}): AbiMessage {
|
||||
const identifier = spec.name.toString();
|
||||
const args = spec.args.map((arg, index): AbiMessageParam => {
|
||||
#createArgs = (args: ContractMessageParamSpec[], spec: unknown): AbiParam[] => {
|
||||
return args.map((arg, index): AbiParam => {
|
||||
try {
|
||||
assert(isObject(arg.type), 'Invalid type definition found');
|
||||
|
||||
return {
|
||||
name: stringCamelCase(arg.name.toString()),
|
||||
type: this.typeDefAt(arg.type.type)
|
||||
type: this.registry.getMetaTypeDef(arg.type)
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`Error expanding argument ${index} in ${JSON.stringify(spec)}`);
|
||||
@@ -80,14 +120,76 @@ export default class Abi extends ContractRegistry {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
#createEvent = (spec: ContractEventSpec, index: number): AbiEvent => {
|
||||
const args = this.#createArgs(spec.args, spec);
|
||||
const event = {
|
||||
args,
|
||||
docs: spec.docs.map((doc) => doc.toString()),
|
||||
fromU8a: (data: Uint8Array): DecodedEvent => ({
|
||||
args: this.#decodeArgs(args, data),
|
||||
event
|
||||
}),
|
||||
identifier: spec.name.toString(),
|
||||
index
|
||||
};
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
#createMessage = (spec: ContractMessageSpec | ContractConstructorSpec, index: number, add: Partial<AbiMessage> = {}): AbiMessage => {
|
||||
const args = this.#createArgs(spec.args, spec);
|
||||
const message = {
|
||||
...add,
|
||||
args,
|
||||
docs: spec.docs.map((doc) => doc.toString()),
|
||||
identifier,
|
||||
fromU8a: (data: Uint8Array): DecodedMessage => ({
|
||||
args: this.#decodeArgs(args, data),
|
||||
message
|
||||
}),
|
||||
identifier: spec.name.toString(),
|
||||
index,
|
||||
selector: spec.selector
|
||||
selector: spec.selector,
|
||||
toU8a: (params: CodecArg[]) =>
|
||||
this.#encodeArgs(spec, args, params)
|
||||
};
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
#decodeArgs = (args: AbiParam[], data: Uint8Array): Codec[] => {
|
||||
// for decoding we expect the input to be just the arg data, no selectors
|
||||
// no length added (this allows use with events as well)
|
||||
let offset = 0;
|
||||
|
||||
return args.map(({ type }): Codec => {
|
||||
const value = this.registry.createType(type.type as 'Text', data.subarray(offset));
|
||||
|
||||
offset += value.encodedLength;
|
||||
|
||||
return value;
|
||||
});
|
||||
}
|
||||
|
||||
#decodeMessage = (type: 'constructor' | 'message', list: AbiMessage[], data: Uint8Array): DecodedMessage => {
|
||||
const [, trimmed] = compactStripLength(data);
|
||||
const selector = trimmed.subarray(0, 4);
|
||||
const message = list.find((m) => m.selector.eq(selector));
|
||||
|
||||
assert(message, `Unable to find ${type} with selector ${u8aToHex(selector)}`);
|
||||
|
||||
return message.fromU8a(trimmed.subarray(4));
|
||||
}
|
||||
|
||||
#encodeArgs = ({ name, selector }: ContractMessageSpec | ContractConstructorSpec, args: AbiParam[], data: CodecArg[]): Uint8Array => {
|
||||
assert(data.length === args.length, `Expected ${args.length} arguments to contract message '${name.toString()}', found ${data.length}`);
|
||||
|
||||
return compactAddLength(
|
||||
u8aConcat(
|
||||
this.registry.createType('ContractSelector', selector).toU8a(),
|
||||
...args.map(({ type }, index) => this.registry.createType(type.type as 'Text', data[index]).toU8a())
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
// Copyright 2017-2020 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
import ContractRegistry from './ContractRegistry';
|
||||
|
||||
import * as testContracts from '../test/contracts';
|
||||
|
||||
const abis: Record<string, any> = { ...testContracts };
|
||||
|
||||
function compare (name: string): void {
|
||||
const inkRegistry = new ContractRegistry(abis[name]);
|
||||
|
||||
try {
|
||||
const cmpPath = path.join(__dirname, `../test/compare/${name}.test.json`);
|
||||
|
||||
if (!fs.existsSync(cmpPath)) {
|
||||
fs.writeFileSync(cmpPath, JSON.stringify(inkRegistry.typeDefs, null, 2), { flag: 'w' });
|
||||
}
|
||||
|
||||
expect(inkRegistry.typeDefs).toEqual(require(cmpPath));
|
||||
} catch (error) {
|
||||
console.error(JSON.stringify(inkRegistry.typeDefs));
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
describe('ContractRegistry', (): void => {
|
||||
describe('construction', (): void => {
|
||||
it('initializes from a contract ABI (flipper)', (): void => {
|
||||
compare('flipper');
|
||||
});
|
||||
|
||||
it('initializes from a contract ABI (incrementer)', (): void => {
|
||||
compare('incrementer');
|
||||
});
|
||||
|
||||
it('initializes from a contract ABI (erc20)', (): void => {
|
||||
compare('erc20');
|
||||
});
|
||||
|
||||
it('initializes from a contract ABI (dns)', (): void => {
|
||||
compare('dns');
|
||||
});
|
||||
|
||||
it('initializes from a contract ABI (erc721)', (): void => {
|
||||
compare('erc721');
|
||||
});
|
||||
|
||||
it('initializes from a contract ABI (multisig_plain)', (): void => {
|
||||
compare('multisigPlain');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,226 +0,0 @@
|
||||
// Copyright 2017-2020 @polkadot/api-contract authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { ChainProperties, InkProject, MtField, MtLookupTypeId, MtType, MtTypeDefArray, MtTypeDefVariant, MtTypeDefSequence, MtTypeDefTuple, MtVariant } from '@polkadot/types/interfaces';
|
||||
import { AnyJson, Registry, TypeDef, TypeDefInfo } from '@polkadot/types/types';
|
||||
|
||||
import { assert, isUndefined } from '@polkadot/util';
|
||||
import { TypeRegistry, withTypeString } from '@polkadot/types';
|
||||
|
||||
// convert the offset into project-specific, index-1
|
||||
export function getRegistryOffset (id: MtLookupTypeId): number {
|
||||
return id.toNumber() - 1;
|
||||
}
|
||||
|
||||
export default class ContractRegistry {
|
||||
public readonly typeDefs: TypeDef[] = [];
|
||||
|
||||
public readonly registry: Registry;
|
||||
|
||||
public readonly project: InkProject;
|
||||
|
||||
constructor (json: Record<string, AnyJson>, chainProperties?: ChainProperties) {
|
||||
this.registry = new TypeRegistry();
|
||||
|
||||
if (chainProperties) {
|
||||
this.registry.setChainProperties(chainProperties);
|
||||
}
|
||||
|
||||
this.project = this.registry.createType('InkProject', json);
|
||||
|
||||
// Generate TypeDefs for each provided registry type
|
||||
this.project.types.forEach((_, index) => this.setTypeDef(this.registry.createType('MtLookupTypeId', index + 1)));
|
||||
}
|
||||
|
||||
public getAbiType (id: MtLookupTypeId): MtType {
|
||||
const offset = getRegistryOffset(id);
|
||||
const type = this.project.types[offset];
|
||||
|
||||
assert(!isUndefined(type), `getAbiType:: Unable to find ${id.toNumber()} in type values`);
|
||||
|
||||
return this.registry.createType('MtType', type);
|
||||
}
|
||||
|
||||
public typeDefAt (id: MtLookupTypeId, extra: Pick<TypeDef, never> = {}): TypeDef {
|
||||
if (!this.typeDefs[getRegistryOffset(id)]) {
|
||||
this.setTypeDef(id);
|
||||
}
|
||||
|
||||
return {
|
||||
...this.typeDefs[getRegistryOffset(id)],
|
||||
...extra
|
||||
};
|
||||
}
|
||||
|
||||
public setTypeDef (id: MtLookupTypeId): void {
|
||||
const typeDef = this.extractType(this.getAbiType(id), id) as TypeDef;
|
||||
|
||||
this.typeDefs[getRegistryOffset(id)] = typeDef;
|
||||
|
||||
// We have a displayName for non-primitives and non-results
|
||||
// FIXME here we protect against "Option: 'Option<...something...>' definitions (same with result)
|
||||
if (typeDef.displayName && typeDef.info !== TypeDefInfo.Plain && !typeDef.type.startsWith(typeDef.displayName)) {
|
||||
this.registry.register({ [typeDef.displayName]: typeDef.type });
|
||||
}
|
||||
}
|
||||
|
||||
private extractType (inkType: MtType, id: MtLookupTypeId): Pick<TypeDef, never> {
|
||||
const path = [...inkType.path];
|
||||
let typeDef;
|
||||
|
||||
if (inkType.path.join('::').startsWith('ink_env::types::') || inkType.def.isPrimitive) {
|
||||
typeDef = this.extractPrimitive(inkType);
|
||||
} else if (inkType.def.isComposite) {
|
||||
typeDef = this.extractFields(inkType.def.asComposite.fields);
|
||||
} else if (inkType.def.isVariant) {
|
||||
typeDef = this.extractVariant(inkType.def.asVariant, id);
|
||||
} else if (inkType.def.isArray) {
|
||||
typeDef = this.extractArray(inkType.def.asArray);
|
||||
} else if (inkType.def.isSequence) {
|
||||
typeDef = this.extractSequence(inkType.def.asSequence, id);
|
||||
} else if (inkType.def.isTuple) {
|
||||
typeDef = this.extractTuple(inkType.def.asTuple);
|
||||
} else {
|
||||
throw new Error(`Invalid ink! type at index ${id.toString()}`);
|
||||
}
|
||||
|
||||
const displayName = path.pop()?.toString();
|
||||
|
||||
return withTypeString({
|
||||
...(displayName
|
||||
? { displayName }
|
||||
: {}
|
||||
),
|
||||
...(path.length > 1
|
||||
? { namespace: path.map((segment) => segment.toString()).join('::') }
|
||||
: {}
|
||||
),
|
||||
...(inkType.params.length > 0
|
||||
? { params: inkType.params.map((id) => this.typeDefAt(id)) }
|
||||
: {}
|
||||
),
|
||||
...typeDef
|
||||
});
|
||||
}
|
||||
|
||||
private extractVariant ({ variants }: MtTypeDefVariant, id: MtLookupTypeId): Pick<TypeDef, never> {
|
||||
const { params, path } = this.getAbiType(id);
|
||||
const specialVariant = path[0].toString();
|
||||
|
||||
if (specialVariant === 'Option') {
|
||||
return {
|
||||
info: TypeDefInfo.Option,
|
||||
sub: this.typeDefAt(params[0])
|
||||
};
|
||||
} else if (specialVariant === 'Result') {
|
||||
return {
|
||||
info: TypeDefInfo.Result,
|
||||
sub: params.map((param, index) => ({
|
||||
name: ['Ok', 'Error'][index],
|
||||
...this.typeDefAt(param)
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
info: TypeDefInfo.Enum,
|
||||
sub: this.extractVariantSub(variants)
|
||||
};
|
||||
}
|
||||
|
||||
private extractVariantSub (variants: MtVariant[]): Pick<TypeDef, any>[] {
|
||||
const isAllUnitVariants = variants.every(({ fields }) => fields.length === 0);
|
||||
|
||||
if (isAllUnitVariants) {
|
||||
return variants.map(({ discriminant, name }) => ({
|
||||
...(
|
||||
discriminant.isSome
|
||||
? { ext: { discriminant: discriminant.unwrap().toNumber() } }
|
||||
: {}
|
||||
),
|
||||
info: TypeDefInfo.Plain,
|
||||
name: name.toString(),
|
||||
type: 'Null'
|
||||
}));
|
||||
}
|
||||
|
||||
return variants.map(({ fields, name }) => ({
|
||||
...this.extractFields(fields),
|
||||
name: name.toString()
|
||||
}));
|
||||
}
|
||||
|
||||
private extractFields (fields: MtField[]): Pick<TypeDef, any> {
|
||||
const [isStruct, isTuple] = fields.reduce(([isAllNamed, isAllUnnamed], { name }) => ([
|
||||
isAllNamed && name.isSome,
|
||||
isAllUnnamed && name.isNone
|
||||
]),
|
||||
[true, true]);
|
||||
|
||||
let info;
|
||||
|
||||
// check for tuple first (no fields may be available)
|
||||
if (isTuple) {
|
||||
info = TypeDefInfo.Tuple;
|
||||
} else if (isStruct) {
|
||||
info = TypeDefInfo.Struct;
|
||||
} else {
|
||||
throw new Error('Invalid fields type detected, expected either Tuple or Struct');
|
||||
}
|
||||
|
||||
const sub = fields.map(({ name, type }) => {
|
||||
return {
|
||||
...this.typeDefAt(type),
|
||||
...(name.isSome ? { name: name.unwrap().toString() } : {})
|
||||
};
|
||||
});
|
||||
|
||||
return isTuple && sub.length === 1
|
||||
? sub[0]
|
||||
: { info, sub };
|
||||
}
|
||||
|
||||
private extractArray ({ len: length, type }: MtTypeDefArray): Pick<TypeDef, never> {
|
||||
assert(!length || length.toNumber() <= 256, 'ContractRegistry: Only support for [Type; <length>], where length > 256');
|
||||
|
||||
return {
|
||||
info: TypeDefInfo.VecFixed,
|
||||
length: length.toNumber(),
|
||||
sub: this.typeDefAt(type)
|
||||
};
|
||||
}
|
||||
|
||||
private extractSequence ({ type }: MtTypeDefSequence, id: MtLookupTypeId): Pick<TypeDef, never> {
|
||||
assert(!!type, `ContractRegistry: Invalid sequence type found at id ${id.toString()}`);
|
||||
|
||||
return {
|
||||
info: TypeDefInfo.Vec,
|
||||
sub: this.typeDefAt(type)
|
||||
};
|
||||
}
|
||||
|
||||
private extractTuple (ids: MtTypeDefTuple): Pick<TypeDef, never> {
|
||||
return ids.length === 1
|
||||
? this.typeDefAt(ids[0])
|
||||
: {
|
||||
info: TypeDefInfo.Tuple,
|
||||
sub: ids.map((id) => this.typeDefAt(id))
|
||||
};
|
||||
}
|
||||
|
||||
private extractPrimitive (inkType: MtType): Pick<TypeDef, never> {
|
||||
if (inkType.def.isPrimitive) {
|
||||
return {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: inkType.def.asPrimitive.type.toLowerCase()
|
||||
};
|
||||
} else if (inkType.path.length > 1) {
|
||||
return {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: inkType.path[inkType.path.length - 1].toString()
|
||||
};
|
||||
}
|
||||
|
||||
throw new Error('Invalid primitive type');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright 2017-2020 @polkadot/api-contract authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
import Abi from './Abi';
|
||||
|
||||
import * as testContracts from '../test/contracts';
|
||||
|
||||
const abis: Record<string, any> = { ...testContracts };
|
||||
|
||||
describe('MetaRegistry', (): void => {
|
||||
Object.keys(abis).forEach((abiName) => {
|
||||
it(`initializes from a contract ABI (${abiName})`, (): void => {
|
||||
const abi = new Abi(abis[abiName]);
|
||||
|
||||
try {
|
||||
const cmpPath = path.join(__dirname, `../test/compare/${abiName}.test.json`);
|
||||
|
||||
if (!fs.existsSync(cmpPath)) {
|
||||
fs.writeFileSync(cmpPath, JSON.stringify(abi.registry.metaTypeDefs, null, 2), { flag: 'w' });
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
expect(abi.registry.metaTypeDefs).toEqual(require(cmpPath));
|
||||
} catch (error) {
|
||||
console.error(JSON.stringify(abi.registry.metaTypeDefs));
|
||||
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('stores base project as JSON', (): void => {
|
||||
expect(new Abi(abis.dns).json).toEqual(abis.dns);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,249 @@
|
||||
// Copyright 2017-2020 @polkadot/api-contract authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { ContractDisplayName, ChainProperties, SiField, SiLookupTypeId, SiType, SiTypeDefArray, SiTypeDefVariant, SiTypeDefSequence, SiTypeDefTuple, SiVariant } from '@polkadot/types/interfaces';
|
||||
import { InterfaceTypes, TypeDef, TypeDefInfo } from '@polkadot/types/types';
|
||||
|
||||
import { assert, isUndefined } from '@polkadot/util';
|
||||
import { TypeRegistry, withTypeString } from '@polkadot/types';
|
||||
|
||||
interface PartialTypeSpec {
|
||||
readonly type: SiLookupTypeId;
|
||||
readonly displayName?: ContractDisplayName;
|
||||
}
|
||||
|
||||
// convert the offset into project-specific, index-1
|
||||
export function getRegistryOffset (id: SiLookupTypeId): number {
|
||||
return id.toNumber() - 1;
|
||||
}
|
||||
|
||||
const PRIMITIVE_ALIAS: Record<string, keyof InterfaceTypes> = {
|
||||
Char: 'u32', // Rust char is 4-bytes
|
||||
Str: 'Text'
|
||||
};
|
||||
|
||||
export default class MetaRegistry extends TypeRegistry {
|
||||
public readonly metaTypeDefs: TypeDef[] = [];
|
||||
|
||||
#siTypes: SiType[] = [];
|
||||
|
||||
constructor (chainProperties?: ChainProperties) {
|
||||
super();
|
||||
|
||||
if (chainProperties) {
|
||||
this.setChainProperties(chainProperties);
|
||||
}
|
||||
}
|
||||
|
||||
public setMetaTypes (metaTypes: SiType[]): void {
|
||||
this.#siTypes = metaTypes;
|
||||
}
|
||||
|
||||
public getMetaTypeDef (typeSpec: PartialTypeSpec): TypeDef {
|
||||
const offset = getRegistryOffset(typeSpec.type);
|
||||
let typeDef = this.metaTypeDefs[offset];
|
||||
|
||||
if (!typeDef) {
|
||||
typeDef = this.#extract(this.#getMetaType(typeSpec.type), typeSpec.type);
|
||||
|
||||
this.metaTypeDefs[offset] = typeDef;
|
||||
}
|
||||
|
||||
if (typeSpec.displayName && typeSpec.displayName.length) {
|
||||
const displayName = typeSpec.displayName[typeSpec.displayName.length - 1].toString();
|
||||
|
||||
if (!typeDef.type.startsWith(displayName)) {
|
||||
typeDef = {
|
||||
...typeDef,
|
||||
displayName,
|
||||
type: ['Balance'].includes(displayName)
|
||||
? 'Balance'
|
||||
: typeDef.type
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Here we protect against the following cases
|
||||
// - No displayName present, these are generally known primitives
|
||||
// - displayName === type, these generate circular references
|
||||
// - displayName Option & type Option<...something...>
|
||||
if (typeDef.displayName && !this.hasType(typeDef.displayName) && !(typeDef.type === typeDef.displayName || typeDef.type.startsWith(`${typeDef.displayName}<`))) {
|
||||
this.register({ [typeDef.displayName]: typeDef.type });
|
||||
}
|
||||
|
||||
return typeDef;
|
||||
}
|
||||
|
||||
#getMetaType = (id: SiLookupTypeId): SiType => {
|
||||
const type = this.#siTypes[getRegistryOffset(id)];
|
||||
|
||||
assert(!isUndefined(type), `getMetaType:: Unable to find ${id.toNumber()} in type values`);
|
||||
|
||||
return this.createType('SiType', type);
|
||||
}
|
||||
|
||||
#extract = (type: SiType, id: SiLookupTypeId): TypeDef => {
|
||||
const path = [...type.path];
|
||||
let typeDef: Omit<TypeDef, 'type'>;
|
||||
|
||||
// TODO solang?
|
||||
if (type.path.join('::').startsWith('ink_env::types::')) {
|
||||
typeDef = this.#extractPrimitivePath(type);
|
||||
} else if (type.def.isPrimitive) {
|
||||
typeDef = this.#extractPrimitive(type);
|
||||
} else if (type.def.isComposite) {
|
||||
typeDef = this.#extractFields(type.def.asComposite.fields);
|
||||
} else if (type.def.isVariant) {
|
||||
typeDef = this.#extractVariant(type.def.asVariant, id);
|
||||
} else if (type.def.isArray) {
|
||||
typeDef = this.#extractArray(type.def.asArray);
|
||||
} else if (type.def.isSequence) {
|
||||
typeDef = this.#extractSequence(type.def.asSequence, id);
|
||||
} else if (type.def.isTuple) {
|
||||
typeDef = this.#extractTuple(type.def.asTuple);
|
||||
} else {
|
||||
throw new Error(`Invalid ink! type at index ${id.toString()}`);
|
||||
}
|
||||
|
||||
const displayName = path.pop()?.toString();
|
||||
|
||||
return withTypeString({
|
||||
...(displayName
|
||||
? { displayName }
|
||||
: {}
|
||||
),
|
||||
...(path.length > 1
|
||||
? { namespace: path.map((segment) => segment.toString()).join('::') }
|
||||
: {}
|
||||
),
|
||||
...(type.params.length > 0
|
||||
? { params: type.params.map((type) => this.getMetaTypeDef({ type })) }
|
||||
: {}
|
||||
),
|
||||
...typeDef
|
||||
});
|
||||
}
|
||||
|
||||
#extractArray = ({ len: length, type }: SiTypeDefArray): Omit<TypeDef, 'type'> => {
|
||||
assert(!length || length.toNumber() <= 256, 'MetaRegistry: Only support for [Type; <length>], where length > 256');
|
||||
|
||||
return {
|
||||
info: TypeDefInfo.VecFixed,
|
||||
length: length.toNumber(),
|
||||
sub: this.getMetaTypeDef({ type })
|
||||
};
|
||||
}
|
||||
|
||||
#extractFields = (fields: SiField[]): Omit<TypeDef, 'type'> => {
|
||||
const [isStruct, isTuple] = fields.reduce(([isAllNamed, isAllUnnamed], { name }) => ([
|
||||
isAllNamed && name.isSome,
|
||||
isAllUnnamed && name.isNone
|
||||
]),
|
||||
[true, true]);
|
||||
|
||||
let info;
|
||||
|
||||
// check for tuple first (no fields may be available)
|
||||
if (isTuple) {
|
||||
info = TypeDefInfo.Tuple;
|
||||
} else if (isStruct) {
|
||||
info = TypeDefInfo.Struct;
|
||||
} else {
|
||||
throw new Error('Invalid fields type detected, expected either Tuple or Struct');
|
||||
}
|
||||
|
||||
const sub = fields.map(({ name, type }) => {
|
||||
return {
|
||||
...this.getMetaTypeDef({ type }),
|
||||
...(name.isSome ? { name: name.unwrap().toString() } : {})
|
||||
};
|
||||
});
|
||||
|
||||
return isTuple && sub.length === 1
|
||||
? sub[0]
|
||||
: { info, sub };
|
||||
}
|
||||
|
||||
#extractPrimitive = (type: SiType): TypeDef => {
|
||||
const typeStr = type.def.asPrimitive.type.toString();
|
||||
|
||||
return {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: PRIMITIVE_ALIAS[typeStr] || typeStr.toLowerCase()
|
||||
};
|
||||
}
|
||||
|
||||
#extractPrimitivePath = (type: SiType): TypeDef => {
|
||||
return {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: type.path[type.path.length - 1].toString()
|
||||
};
|
||||
}
|
||||
|
||||
#extractSequence = ({ type }: SiTypeDefSequence, id: SiLookupTypeId): Omit<TypeDef, 'type'> => {
|
||||
assert(!!type, `ContractRegistry: Invalid sequence type found at id ${id.toString()}`);
|
||||
|
||||
return {
|
||||
info: TypeDefInfo.Vec,
|
||||
sub: this.getMetaTypeDef({ type })
|
||||
};
|
||||
}
|
||||
|
||||
#extractTuple = (ids: SiTypeDefTuple): Omit<TypeDef, 'type'> => {
|
||||
return ids.length === 1
|
||||
? this.getMetaTypeDef({ type: ids[0] })
|
||||
: {
|
||||
info: TypeDefInfo.Tuple,
|
||||
sub: ids.map((type) => this.getMetaTypeDef({ type }))
|
||||
};
|
||||
}
|
||||
|
||||
#extractVariant = ({ variants }: SiTypeDefVariant, id: SiLookupTypeId): Omit<TypeDef, 'type'> => {
|
||||
const { params, path } = this.#getMetaType(id);
|
||||
const specialVariant = path[0].toString();
|
||||
|
||||
if (specialVariant === 'Option') {
|
||||
return {
|
||||
info: TypeDefInfo.Option,
|
||||
sub: this.getMetaTypeDef({ type: params[0] })
|
||||
};
|
||||
} else if (specialVariant === 'Result') {
|
||||
return {
|
||||
info: TypeDefInfo.Result,
|
||||
sub: params.map((type, index) => ({
|
||||
name: ['Ok', 'Error'][index],
|
||||
...this.getMetaTypeDef({ type })
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
info: TypeDefInfo.Enum,
|
||||
sub: this.#extractVariantSub(variants)
|
||||
};
|
||||
}
|
||||
|
||||
#extractVariantSub = (variants: SiVariant[]): TypeDef[] => {
|
||||
const isAllUnitVariants = variants.every(({ fields }) => fields.length === 0);
|
||||
|
||||
if (isAllUnitVariants) {
|
||||
return variants.map(({ discriminant, name }) => ({
|
||||
...(
|
||||
discriminant.isSome
|
||||
? { ext: { discriminant: discriminant.unwrap().toNumber() } }
|
||||
: {}
|
||||
),
|
||||
info: TypeDefInfo.Plain,
|
||||
name: name.toString(),
|
||||
type: 'Null'
|
||||
}));
|
||||
}
|
||||
|
||||
return variants.map(({ fields, name }) =>
|
||||
withTypeString({
|
||||
...this.#extractFields(fields),
|
||||
name: name.toString()
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -6,13 +6,15 @@ import { SubmittableExtrinsic } from '@polkadot/api/submittable/types';
|
||||
import { AccountId, EventRecord, Hash } from '@polkadot/types/interfaces';
|
||||
import { AnyJson, CodecArg, ISubmittableResult } from '@polkadot/types/types';
|
||||
import { AbiConstructor } from '../types';
|
||||
import { MapConstructorExec } from './types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { SubmittableResult } from '@polkadot/api';
|
||||
import ApiBase from '@polkadot/api/base';
|
||||
import { isUndefined, stringCamelCase } from '@polkadot/util';
|
||||
|
||||
import Abi from '../Abi';
|
||||
import { applyOnEvent, encodeMessage } from '../util';
|
||||
import { applyOnEvent } from '../util';
|
||||
import Base from './Base';
|
||||
import Contract from './Contract';
|
||||
|
||||
@@ -29,19 +31,38 @@ export class BlueprintSubmittableResult<ApiType extends ApiTypes> extends Submit
|
||||
export default class Blueprint<ApiType extends ApiTypes> extends Base<ApiType> {
|
||||
public readonly codeHash: Hash;
|
||||
|
||||
readonly #tx: MapConstructorExec<ApiType> = {};
|
||||
|
||||
constructor (api: ApiBase<ApiType>, abi: AnyJson | Abi, codeHash: string | Hash | Uint8Array, decorateMethod: DecorateMethod<ApiType>) {
|
||||
super(api, abi, decorateMethod);
|
||||
|
||||
this.codeHash = this.registry.createType('Hash', codeHash);
|
||||
|
||||
this.abi.constructors.forEach((c): void => {
|
||||
const messageName = stringCamelCase(c.identifier);
|
||||
|
||||
if (isUndefined(this.#tx[messageName])) {
|
||||
this.#tx[messageName] = (endowment: BigInt | string | number | BN, gasLimit: BigInt | string | number | BN, ...params: CodecArg[]) =>
|
||||
this.#deploy(c, endowment, gasLimit, params);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public createContract (constructorOrId: AbiConstructor | string| number, endowment: BigInt | string | number | BN, gasLimit: BigInt | string | number | BN, ...params: CodecArg[]): SubmittableExtrinsic<ApiType, BlueprintSubmittableResult<ApiType>> {
|
||||
public get tx (): MapConstructorExec<ApiType> {
|
||||
return this.#tx;
|
||||
}
|
||||
|
||||
#deploy = (constructorOrId: AbiConstructor | string| number, endowment: BigInt | string | number | BN, gasLimit: BigInt | string | number | BN, params: CodecArg[]): SubmittableExtrinsic<ApiType, BlueprintSubmittableResult<ApiType>> => {
|
||||
return this.api.tx.contracts
|
||||
.instantiate(endowment, gasLimit, this.codeHash, encodeMessage(this.registry, this.abi.findConstructor(constructorOrId), params))
|
||||
.instantiate(endowment, gasLimit, this.codeHash, this.abi.findConstructor(constructorOrId).toU8a(params))
|
||||
.withResultTransform((result: ISubmittableResult) =>
|
||||
new BlueprintSubmittableResult(result, applyOnEvent(result, 'Instantiated', (record: EventRecord) =>
|
||||
new Contract<ApiType>(this.api, this.abi, record.event.data[1] as AccountId, this._decorateMethod)
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
public createContract (constructorOrId: AbiConstructor | string| number, endowment: BigInt | string | number | BN, gasLimit: BigInt | string | number | BN, ...params: CodecArg[]): SubmittableExtrinsic<ApiType, BlueprintSubmittableResult<ApiType>> {
|
||||
return this.#deploy(constructorOrId, endowment, gasLimit, params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,69 +1,90 @@
|
||||
// Copyright 2017-2020 @polkadot/api-contract authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { ApiTypes, DecorateMethod, ObsInnerType } from '@polkadot/api/types';
|
||||
import { ApiTypes, DecorateMethod } from '@polkadot/api/types';
|
||||
import { SubmittableExtrinsic } from '@polkadot/api/submittable/types';
|
||||
import { AccountId, ContractExecResult } from '@polkadot/types/interfaces';
|
||||
import { AnyJson, CodecArg, IKeyringPair } from '@polkadot/types/types';
|
||||
import { AnyJson, CodecArg } from '@polkadot/types/types';
|
||||
import { AbiMessage, ContractCallOutcome } from '../types';
|
||||
import { ContractRead, MapMessageExec, MapMessageRead } from './types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { SubmittableResult } from '@polkadot/api';
|
||||
import ApiBase from '@polkadot/api/base';
|
||||
import { assert, isFunction } from '@polkadot/util';
|
||||
import { assert, bnToBn, isFunction, isUndefined, stringCamelCase } from '@polkadot/util';
|
||||
|
||||
import Abi from '../Abi';
|
||||
import { encodeMessage, formatData } from '../util';
|
||||
import { formatData } from '../util';
|
||||
import Base from './Base';
|
||||
|
||||
type ContractCallTypes = 'tx' | 'rpc';
|
||||
|
||||
type ContractCallResultSubscription<ApiType extends ApiTypes, CallType extends ContractCallTypes> = ApiType extends 'rxjs'
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
? Observable<ContractCallResult<CallType>>
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
: Promise<ObsInnerType<ContractCallResult<CallType>>>;
|
||||
|
||||
export interface ContractRead<ApiType extends ApiTypes> {
|
||||
send (account: IKeyringPair | string | AccountId): ContractCallResultSubscription<ApiType, 'rpc'>;
|
||||
}
|
||||
|
||||
export type ContractCallResult<CallType extends ContractCallTypes> = CallType extends 'rpc'
|
||||
? Observable<ContractCallOutcome>
|
||||
: Observable<SubmittableResult>;
|
||||
const ERROR_NO_CALL = 'Your node does not expose the contracts.call RPC. This is most probably due to a runtime configuration.';
|
||||
|
||||
export default class Contract<ApiType extends ApiTypes> extends Base<ApiType> {
|
||||
public readonly address: AccountId;
|
||||
|
||||
readonly #tx: MapMessageExec<ApiType> = {};
|
||||
|
||||
readonly #query: MapMessageRead<ApiType> = {};
|
||||
|
||||
constructor (api: ApiBase<ApiType>, abi: AnyJson | Abi, address: string | AccountId, decorateMethod: DecorateMethod<ApiType>) {
|
||||
super(api, abi, decorateMethod);
|
||||
|
||||
this.address = this.registry.createType('AccountId', address);
|
||||
|
||||
this.abi.messages.forEach((m): void => {
|
||||
const messageName = stringCamelCase(m.identifier);
|
||||
|
||||
if (isUndefined(this.#tx[messageName])) {
|
||||
this.#tx[messageName] = (value: BigInt | BN | string | number, gasLimit: BigInt | BN | string | number, ...params: CodecArg[]) =>
|
||||
this.#exec(m, value, gasLimit, params);
|
||||
}
|
||||
|
||||
if (isUndefined(this.#query[messageName])) {
|
||||
this.#query[messageName] = (origin: string | AccountId | Uint8Array, value: BigInt | BN | string | number, gasLimit: BigInt | BN | string | number, ...params: CodecArg[]) =>
|
||||
this.#read(m, value, gasLimit, params).send(origin);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public get hasRpcContractsCall (): boolean {
|
||||
return isFunction(this.api.rx.rpc.contracts?.call);
|
||||
}
|
||||
|
||||
public exec (messageOrId: AbiMessage | string | number, value: BigInt | BN | string | number, gasLimit: BigInt | BN | string | number, ...params: CodecArg[]): SubmittableExtrinsic<ApiType> {
|
||||
return this.api.tx.contracts.call(this.address, value, gasLimit, encodeMessage(this.registry, this.abi.findMessage(messageOrId), params));
|
||||
public get query (): MapMessageRead<ApiType> {
|
||||
assert(this.hasRpcContractsCall, ERROR_NO_CALL);
|
||||
|
||||
return this.#query;
|
||||
}
|
||||
|
||||
public read (messageOrId: AbiMessage | string | number, value: BigInt | BN | string | number, gasLimit: BigInt | BN | string | number, ...params: CodecArg[]): ContractRead<ApiType> {
|
||||
assert(this.hasRpcContractsCall, 'Your node does not support contract RPC read calls');
|
||||
public get tx (): MapMessageExec<ApiType> {
|
||||
return this.#tx;
|
||||
}
|
||||
|
||||
#getGas = (_gasLimit: BigInt | BN | string | number): BN => {
|
||||
const gasLimit = bnToBn(_gasLimit);
|
||||
|
||||
return gasLimit.lten(0)
|
||||
? this.api.consts.system.maximumBlockWeight.muln(64).divn(100)
|
||||
: gasLimit;
|
||||
}
|
||||
|
||||
#exec = (messageOrId: AbiMessage | string | number, value: BigInt | BN | string | number, gasLimit: BigInt | BN | string | number, params: CodecArg[]): SubmittableExtrinsic<ApiType> => {
|
||||
return this.api.tx.contracts.call(this.address, value, this.#getGas(gasLimit), this.abi.findMessage(messageOrId).toU8a(params));
|
||||
}
|
||||
|
||||
#read = (messageOrId: AbiMessage | string | number, value: BigInt | BN | string | number, gasLimit: BigInt | BN | string | number, params: CodecArg[]): ContractRead<ApiType> => {
|
||||
assert(this.hasRpcContractsCall, ERROR_NO_CALL);
|
||||
|
||||
const message = this.abi.findMessage(messageOrId);
|
||||
|
||||
return {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
send: this._decorateMethod((account: string | AccountId | Uint8Array): ContractCallResult<'rpc'> =>
|
||||
send: this._decorateMethod((origin: string | AccountId | Uint8Array) =>
|
||||
this.api.rx.rpc.contracts.call({
|
||||
dest: this.address,
|
||||
gasLimit,
|
||||
inputData: encodeMessage(this.registry, message, params),
|
||||
origin: account,
|
||||
gasLimit: this.#getGas(gasLimit),
|
||||
inputData: message.toU8a(params),
|
||||
origin,
|
||||
value
|
||||
}).pipe(
|
||||
map((result: ContractExecResult): ContractCallOutcome => ({
|
||||
@@ -76,4 +97,12 @@ export default class Contract<ApiType extends ApiTypes> extends Base<ApiType> {
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
public exec (messageOrId: AbiMessage | string | number, value: BigInt | BN | string | number, gasLimit: BigInt | BN | string | number, ...params: CodecArg[]): SubmittableExtrinsic<ApiType> {
|
||||
return this.#exec(messageOrId, value, gasLimit, params);
|
||||
}
|
||||
|
||||
public read (messageOrId: AbiMessage | string | number, value: BigInt | BN | string | number, gasLimit: BigInt | BN | string | number, ...params: CodecArg[]): ContractRead<ApiType> {
|
||||
return this.#read(messageOrId, value, gasLimit, params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright 2017-2020 @polkadot/api authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export { default as Blueprint } from './Blueprint';
|
||||
export { default as Code } from './Code';
|
||||
export { default as Blueprint, BlueprintSubmittableResult } from './Blueprint';
|
||||
export { default as Code, CodeSubmittableResult } from './Code';
|
||||
export { default as Contract } from './Contract';
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright 2017-2020 @polkadot/api-contract authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { ApiTypes, ObsInnerType } from '@polkadot/api/types';
|
||||
import { SubmittableExtrinsic } from '@polkadot/api/submittable/types';
|
||||
import { AccountId } from '@polkadot/types/interfaces';
|
||||
import { CodecArg } from '@polkadot/types/types';
|
||||
import { ContractCallOutcome } from '../types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
type ContractCallResult<ApiType extends ApiTypes, T> = ApiType extends 'rxjs'
|
||||
? Observable<Observable<T>>
|
||||
: Promise<ObsInnerType<Observable<T>>>;
|
||||
|
||||
export interface ContractRead<ApiType extends ApiTypes> {
|
||||
send (account: string | AccountId | Uint8Array): ContractCallResult<ApiType, ContractCallOutcome>;
|
||||
}
|
||||
|
||||
export interface MapConstructorExec<ApiType extends ApiTypes> {
|
||||
[message: string]: (endowment: BigInt | string | number | BN, gasLimit: BigInt | string | number | BN, ...params: CodecArg[]) => SubmittableExtrinsic<ApiType>;
|
||||
}
|
||||
|
||||
export interface MapMessageExec<ApiType extends ApiTypes> {
|
||||
[message: string]: (value: BigInt | BN | string | number, gasLimit: BigInt | BN | string | number, ...params: CodecArg[]) => SubmittableExtrinsic<ApiType>;
|
||||
}
|
||||
|
||||
export interface MapMessageRead<ApiType extends ApiTypes> {
|
||||
[message: string]: (origin: AccountId | string | Uint8Array, value: BigInt | BN | string | number, gasLimit: BigInt | BN | string | number, ...params: CodecArg[]) => ContractCallResult<ApiType, ContractCallOutcome>;
|
||||
}
|
||||
@@ -1,10 +1,7 @@
|
||||
// Copyright 2017-2020 @polkadot/api-contract authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export { CodeSubmittableResult } from './base/Code';
|
||||
export { BlueprintSubmittableResult } from './base/Blueprint';
|
||||
|
||||
export { default as Abi } from './Abi';
|
||||
|
||||
export * from './rx';
|
||||
export * from './promise';
|
||||
export { Blueprint as BlueprintRx, Code as CodeRx, Contract as ContractRx } from './rx';
|
||||
export { Blueprint as BlueprintPromise, Code as CodePromise, Contract as ContractPromise } from './promise';
|
||||
|
||||
+2
-2
@@ -8,9 +8,9 @@ import { ApiPromise } from '@polkadot/api';
|
||||
import { decorateMethod } from '@polkadot/api/promise';
|
||||
|
||||
import Abi from '../Abi';
|
||||
import Blueprint from '../base/Blueprint';
|
||||
import BaseBlueprint from '../base/Blueprint';
|
||||
|
||||
export default class PromiseBlueprint extends Blueprint<'promise'> {
|
||||
export default class Blueprint extends BaseBlueprint<'promise'> {
|
||||
constructor (api: ApiPromise, abi: AnyJson | Abi, codeHash: string | Hash) {
|
||||
super(api, abi, codeHash, decorateMethod);
|
||||
}
|
||||
+2
-2
@@ -6,9 +6,9 @@ import { decorateMethod } from '@polkadot/api/promise';
|
||||
import { AnyJson } from '@polkadot/types/types';
|
||||
|
||||
import Abi from '../Abi';
|
||||
import Code from '../base/Code';
|
||||
import BaseCode from '../base/Code';
|
||||
|
||||
export default class PromiseCode extends Code<'promise'> {
|
||||
export default class Code extends BaseCode<'promise'> {
|
||||
constructor (api: ApiPromise, abi: AnyJson | Abi, wasm: Uint8Array | string | Buffer) {
|
||||
super(api, abi, wasm, decorateMethod);
|
||||
}
|
||||
+2
-2
@@ -8,9 +8,9 @@ import { ApiPromise } from '@polkadot/api';
|
||||
import { decorateMethod } from '@polkadot/api/promise';
|
||||
|
||||
import Abi from '../Abi';
|
||||
import Contract from '../base/Contract';
|
||||
import BaseContract from '../base/Contract';
|
||||
|
||||
export default class PromiseContract extends Contract<'promise'> {
|
||||
export default class Contract extends BaseContract<'promise'> {
|
||||
constructor (api: ApiPromise, abi: AnyJson | Abi, address: string | AccountId) {
|
||||
super(api, abi, address, decorateMethod);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright 2017-2020 @polkadot/api-contract authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export { default as BlueprintPromise } from './PromiseBlueprint';
|
||||
export { default as CodePromise } from './PromiseCode';
|
||||
export { default as ContractPromise } from './PromiseContract';
|
||||
export { default as Blueprint } from './Blueprint';
|
||||
export { default as Code } from './Code';
|
||||
export { default as Contract } from './Contract';
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// Copyright 2017-2020 @polkadot/api-contract authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { BlueprintSubmittableResult as BaseBlueprintSubmittableResult, CodeSubmittableResult as BaseCodeSubmittableResult } from '../base';
|
||||
|
||||
export type BlueprintSubmittableResult = BaseBlueprintSubmittableResult<'promise'>;
|
||||
export type CodeSubmittableResult = BaseCodeSubmittableResult<'promise'>;
|
||||
+2
-2
@@ -8,9 +8,9 @@ import { ApiRx } from '@polkadot/api';
|
||||
import { decorateMethod } from '@polkadot/api/rx';
|
||||
|
||||
import Abi from '../Abi';
|
||||
import Blueprint from '../base/Blueprint';
|
||||
import BaseBlueprint from '../base/Blueprint';
|
||||
|
||||
export default class RxBlueprint extends Blueprint<'rxjs'> {
|
||||
export default class Blueprint extends BaseBlueprint<'rxjs'> {
|
||||
constructor (api: ApiRx, abi: AnyJson | Abi, codeHash: string | Hash) {
|
||||
super(api, abi, codeHash, decorateMethod);
|
||||
}
|
||||
@@ -7,9 +7,9 @@ import { ApiRx } from '@polkadot/api';
|
||||
import { decorateMethod } from '@polkadot/api/rx';
|
||||
|
||||
import Abi from '../Abi';
|
||||
import Code from '../base/Code';
|
||||
import BaseCode from '../base/Code';
|
||||
|
||||
export default class RxCode extends Code<'rxjs'> {
|
||||
export default class Code extends BaseCode<'rxjs'> {
|
||||
constructor (api: ApiRx, abi: AnyJson | Abi, wasm: Uint8Array | string | Buffer) {
|
||||
super(api, abi, wasm, decorateMethod);
|
||||
}
|
||||
+2
-2
@@ -8,9 +8,9 @@ import { ApiRx } from '@polkadot/api';
|
||||
import { decorateMethod } from '@polkadot/api/rx';
|
||||
|
||||
import Abi from '../Abi';
|
||||
import Contract from '../base/Contract';
|
||||
import BaseContract from '../base/Contract';
|
||||
|
||||
export default class RxContract extends Contract<'rxjs'> {
|
||||
export default class Contract extends BaseContract<'rxjs'> {
|
||||
constructor (api: ApiRx, abi: AnyJson | Abi, address: string | AccountId) {
|
||||
super(api, abi, address, decorateMethod);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright 2017-2020 @polkadot/api-contract authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export { default as BlueprintRx } from './RxBlueprint';
|
||||
export { default as CodeRx } from './RxCode';
|
||||
export { default as ContractRx } from './RxContract';
|
||||
export { default as Blueprint } from './Blueprint';
|
||||
export { default as Code } from './Code';
|
||||
export { default as Contract } from './Contract';
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// Copyright 2017-2020 @polkadot/api-contract authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { BlueprintSubmittableResult as BaseBlueprintSubmittableResult, CodeSubmittableResult as BaseCodeSubmittableResult } from '../base';
|
||||
|
||||
export type BlueprintSubmittableResult = BaseBlueprintSubmittableResult<'promise'>;
|
||||
export type CodeSubmittableResult = BaseCodeSubmittableResult<'promise'>;
|
||||
@@ -2,8 +2,8 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { ApiTypes } from '@polkadot/api/types';
|
||||
import { ContractExecResult, InkSelector } from '@polkadot/types/interfaces';
|
||||
import { Codec, TypeDef } from '@polkadot/types/types';
|
||||
import { ContractExecResult, ContractSelector } from '@polkadot/types/interfaces';
|
||||
import { Codec, CodecArg, TypeDef } from '@polkadot/types/types';
|
||||
|
||||
import ApiBase from '@polkadot/api/base';
|
||||
import Abi from './Abi';
|
||||
@@ -16,21 +16,31 @@ export interface ContractBase<ApiType extends ApiTypes> {
|
||||
messages: AbiMessage[];
|
||||
}
|
||||
|
||||
export interface AbiMessageParam {
|
||||
export interface AbiParam {
|
||||
name: string;
|
||||
type: TypeDef;
|
||||
}
|
||||
|
||||
export interface AbiMessage {
|
||||
args: AbiMessageParam[];
|
||||
export interface AbiEvent {
|
||||
args: AbiParam[];
|
||||
docs: string[];
|
||||
fromU8a: (data: Uint8Array) => DecodedEvent;
|
||||
identifier: string;
|
||||
index: number;
|
||||
}
|
||||
|
||||
export interface AbiMessage {
|
||||
args: AbiParam[];
|
||||
docs: string[];
|
||||
fromU8a: (data: Uint8Array) => DecodedMessage;
|
||||
identifier: string;
|
||||
index: number;
|
||||
isConstructor?: boolean;
|
||||
isMutating?: boolean;
|
||||
isPayable?: boolean;
|
||||
returnType?: TypeDef | null;
|
||||
selector: InkSelector;
|
||||
selector: ContractSelector;
|
||||
toU8a: (params: CodecArg[]) => Uint8Array;
|
||||
}
|
||||
|
||||
export type AbiConstructor = AbiMessage;
|
||||
@@ -44,3 +54,13 @@ export interface ContractCallOutcome {
|
||||
output: Codec | null;
|
||||
result: ContractExecResult;
|
||||
}
|
||||
|
||||
export interface DecodedEvent {
|
||||
args: Codec[];
|
||||
event: AbiEvent;
|
||||
}
|
||||
|
||||
export interface DecodedMessage {
|
||||
args: Codec[];
|
||||
message: AbiMessage;
|
||||
}
|
||||
|
||||
@@ -3,12 +3,9 @@
|
||||
|
||||
import { SubmittableResult } from '@polkadot/api';
|
||||
import { EventRecord } from '@polkadot/types/interfaces';
|
||||
import { Codec, CodecArg, Registry, TypeDef } from '@polkadot/types/types';
|
||||
import { AbiConstructor, AbiMessage } from './types';
|
||||
import { Codec, Registry, TypeDef } from '@polkadot/types/types';
|
||||
|
||||
import { Raw, createClass, createTypeUnsafe, encodeTypeDef } from '@polkadot/types';
|
||||
|
||||
import { assert, compactAddLength } from '@polkadot/util';
|
||||
import { Raw, createTypeUnsafe } from '@polkadot/types';
|
||||
|
||||
export function formatData (registry: Registry, data: Raw, { type }: TypeDef): Codec {
|
||||
return createTypeUnsafe(registry, type, [data], true);
|
||||
@@ -25,22 +22,3 @@ export function applyOnEvent <T> (result: SubmittableResult, type: 'CodeStored'
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function encodeMessage (registry: Registry, message: AbiMessage | AbiConstructor, params: CodecArg[]): Uint8Array {
|
||||
assert(message, 'Attempted to call an invalid contract message');
|
||||
assert(params.length === message.args.length, `Expected ${message.args.length} arguments to contract message '${message.identifier}', found ${params.length}`);
|
||||
|
||||
const Clazz = createClass(registry, JSON.stringify(
|
||||
message.args.reduce((r: Record<string, any>, { name, type }): Record<string, any> => {
|
||||
r[name] = type.displayName || encodeTypeDef(type);
|
||||
|
||||
return r;
|
||||
}, { __selector: 'InkSelector' })
|
||||
));
|
||||
|
||||
return compactAddLength(new Clazz(registry, message.args.reduce((r: Record<string, CodecArg>, { name }, index): Record<string, CodecArg> => {
|
||||
r[name] = params[index];
|
||||
|
||||
return r;
|
||||
}, { __selector: message.selector })).toU8a());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
[
|
||||
{
|
||||
"displayName": "AccountId",
|
||||
"namespace": "ink_env::types",
|
||||
"info": 6,
|
||||
"type": "AccountId"
|
||||
},
|
||||
{
|
||||
"info": 12,
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
},
|
||||
"type": "[u8;32]"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
"type": "i32"
|
||||
},
|
||||
{
|
||||
"displayName": "Hash",
|
||||
"namespace": "ink_env::types",
|
||||
"info": 6,
|
||||
"type": "Hash"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u256"
|
||||
}
|
||||
]
|
||||
@@ -488,7 +488,8 @@
|
||||
{
|
||||
"info": 10,
|
||||
"sub": [],
|
||||
"name": "Confirmed"
|
||||
"name": "Confirmed",
|
||||
"type": "()"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
@@ -509,7 +510,8 @@
|
||||
{
|
||||
"info": 10,
|
||||
"sub": [],
|
||||
"name": "Confirmed"
|
||||
"name": "Confirmed",
|
||||
"type": "()"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
@@ -677,4 +679,4 @@
|
||||
},
|
||||
"type": "Option<Vec<u8>>"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
[
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u128"
|
||||
},
|
||||
{
|
||||
"displayName": "Header",
|
||||
"namespace": "ink_storage::collections::stash",
|
||||
"info": 9,
|
||||
"sub": [
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u32",
|
||||
"name": "last_vacant"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u32",
|
||||
"name": "len"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u32",
|
||||
"name": "len_entries"
|
||||
}
|
||||
],
|
||||
"type": "{\"last_vacant\":\"u32\",\"len\":\"u32\",\"len_entries\":\"u32\"}"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u32"
|
||||
},
|
||||
{
|
||||
"displayName": "Entry",
|
||||
"namespace": "ink_storage::collections::stash",
|
||||
"params": [
|
||||
{
|
||||
"displayName": "AccountId",
|
||||
"namespace": "ink_env::types",
|
||||
"info": 6,
|
||||
"type": "AccountId"
|
||||
}
|
||||
],
|
||||
"info": 3,
|
||||
"sub": [
|
||||
{
|
||||
"displayName": "VacantEntry",
|
||||
"namespace": "ink_storage::collections::stash",
|
||||
"info": 9,
|
||||
"sub": [
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u32",
|
||||
"name": "next"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u32",
|
||||
"name": "prev"
|
||||
}
|
||||
],
|
||||
"type": "{\"next\":\"u32\",\"prev\":\"u32\"}",
|
||||
"name": "Vacant"
|
||||
},
|
||||
{
|
||||
"displayName": "AccountId",
|
||||
"namespace": "ink_env::types",
|
||||
"info": 6,
|
||||
"type": "AccountId",
|
||||
"name": "Occupied"
|
||||
}
|
||||
],
|
||||
"type": "{\"_enum\":{\"Vacant\":\"VacantEntry\",\"Occupied\":\"AccountId\"}}"
|
||||
},
|
||||
{
|
||||
"displayName": "AccountId",
|
||||
"namespace": "ink_env::types",
|
||||
"info": 6,
|
||||
"type": "AccountId"
|
||||
},
|
||||
{
|
||||
"info": 12,
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
},
|
||||
"type": "[u8;32]"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"displayName": "VacantEntry",
|
||||
"namespace": "ink_storage::collections::stash",
|
||||
"info": 9,
|
||||
"sub": [
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u32",
|
||||
"name": "next"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u32",
|
||||
"name": "prev"
|
||||
}
|
||||
],
|
||||
"type": "{\"next\":\"u32\",\"prev\":\"u32\"}"
|
||||
},
|
||||
{
|
||||
"displayName": "ValueEntry",
|
||||
"namespace": "ink_storage::collections::hashmap",
|
||||
"params": [
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u128"
|
||||
}
|
||||
],
|
||||
"info": 9,
|
||||
"sub": [
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u128",
|
||||
"name": "value"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u32",
|
||||
"name": "key_index"
|
||||
}
|
||||
],
|
||||
"type": "{\"value\":\"u128\",\"key_index\":\"u32\"}"
|
||||
},
|
||||
{
|
||||
"displayName": "Entry",
|
||||
"namespace": "ink_storage::collections::stash",
|
||||
"params": [
|
||||
{
|
||||
"info": 10,
|
||||
"sub": [
|
||||
{
|
||||
"displayName": "AccountId",
|
||||
"namespace": "ink_env::types",
|
||||
"info": 6,
|
||||
"type": "AccountId"
|
||||
},
|
||||
{
|
||||
"displayName": "AccountId",
|
||||
"namespace": "ink_env::types",
|
||||
"info": 6,
|
||||
"type": "AccountId"
|
||||
}
|
||||
],
|
||||
"type": "(AccountId, AccountId)"
|
||||
}
|
||||
],
|
||||
"info": 3,
|
||||
"sub": [
|
||||
{
|
||||
"displayName": "VacantEntry",
|
||||
"namespace": "ink_storage::collections::stash",
|
||||
"info": 9,
|
||||
"sub": [
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u32",
|
||||
"name": "next"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u32",
|
||||
"name": "prev"
|
||||
}
|
||||
],
|
||||
"type": "{\"next\":\"u32\",\"prev\":\"u32\"}",
|
||||
"name": "Vacant"
|
||||
},
|
||||
{
|
||||
"info": 10,
|
||||
"sub": [
|
||||
{
|
||||
"displayName": "AccountId",
|
||||
"namespace": "ink_env::types",
|
||||
"info": 6,
|
||||
"type": "AccountId"
|
||||
},
|
||||
{
|
||||
"displayName": "AccountId",
|
||||
"namespace": "ink_env::types",
|
||||
"info": 6,
|
||||
"type": "AccountId"
|
||||
}
|
||||
],
|
||||
"type": "(AccountId, AccountId)",
|
||||
"name": "Occupied"
|
||||
}
|
||||
],
|
||||
"type": "{\"_enum\":{\"Vacant\":\"VacantEntry\",\"Occupied\":\"(AccountId, AccountId)\"}}"
|
||||
},
|
||||
{
|
||||
"info": 10,
|
||||
"sub": [
|
||||
{
|
||||
"displayName": "AccountId",
|
||||
"namespace": "ink_env::types",
|
||||
"info": 6,
|
||||
"type": "AccountId"
|
||||
},
|
||||
{
|
||||
"displayName": "AccountId",
|
||||
"namespace": "ink_env::types",
|
||||
"info": 6,
|
||||
"type": "AccountId"
|
||||
}
|
||||
],
|
||||
"type": "(AccountId, AccountId)"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
"type": "Text"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"displayName": "Option",
|
||||
"params": [
|
||||
{
|
||||
"displayName": "AccountId",
|
||||
"namespace": "ink_env::types",
|
||||
"info": 6,
|
||||
"type": "AccountId"
|
||||
}
|
||||
],
|
||||
"info": 5,
|
||||
"sub": {
|
||||
"displayName": "AccountId",
|
||||
"namespace": "ink_env::types",
|
||||
"info": 6,
|
||||
"type": "AccountId"
|
||||
},
|
||||
"type": "Option<AccountId>"
|
||||
}
|
||||
]
|
||||
@@ -1,10 +1,6 @@
|
||||
// Copyright 2017-2020 @polkadot/api-contract authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export { default as delegator } from './delegator.json';
|
||||
export { default as dns } from './dns.json';
|
||||
export { default as erc20 } from './erc20.json';
|
||||
export { default as erc721 } from './erc721.json';
|
||||
export { default as flipper } from './flipper.json';
|
||||
export { default as incrementer } from './incrementer.json';
|
||||
export { default as multisigPlain } from './multisig_plain.json';
|
||||
export * from './ink';
|
||||
export * from './solang';
|
||||
export * from './user';
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright 2017-2020 @polkadot/api-contract authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export { default as delegator } from './delegator.json';
|
||||
export { default as dns } from './dns.json';
|
||||
export { default as erc20 } from './erc20.json';
|
||||
export { default as erc721 } from './erc721.json';
|
||||
export { default as flipper } from './flipper.json';
|
||||
export { default as incrementer } from './incrementer.json';
|
||||
export { default as multisigPlain } from './multisig_plain.json';
|
||||
@@ -0,0 +1,4 @@
|
||||
// Copyright 2017-2020 @polkadot/api-contract authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export { default as ints256 } from './ints256.json';
|
||||
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"contract": {
|
||||
"authors": [
|
||||
"Sean Young <sean@mess.org>"
|
||||
],
|
||||
"description": "Test 256 bits types",
|
||||
"name": "ints256",
|
||||
"version": "0.0.1"
|
||||
},
|
||||
"metadataVersion": "0.1.0",
|
||||
"source": {
|
||||
"compiler": "solang 0.1.4",
|
||||
"hash": "0xa85fb5c61a09d71dce84c15a8bd87e6f4eafac498a1aec3869e8cf7ea4389697",
|
||||
"language": "Solidity 0.1.4"
|
||||
},
|
||||
"spec": {
|
||||
"constructors": [
|
||||
{
|
||||
"args": [],
|
||||
"docs": [
|
||||
""
|
||||
],
|
||||
"name": "new",
|
||||
"selector": "0x861731d5"
|
||||
}
|
||||
],
|
||||
"events": [],
|
||||
"messages": [
|
||||
{
|
||||
"args": [
|
||||
{
|
||||
"name": "a",
|
||||
"type": {
|
||||
"display_name": [
|
||||
"u256"
|
||||
],
|
||||
"type": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "b",
|
||||
"type": {
|
||||
"display_name": [
|
||||
"u256"
|
||||
],
|
||||
"type": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"docs": [
|
||||
"Multiply two 256 bit values\n\n"
|
||||
],
|
||||
"mutates": false,
|
||||
"name": "multiply",
|
||||
"payable": false,
|
||||
"return_type": {
|
||||
"display_name": [
|
||||
"u256"
|
||||
],
|
||||
"type": 1
|
||||
},
|
||||
"selector": "0x165c4a16"
|
||||
},
|
||||
{
|
||||
"args": [
|
||||
{
|
||||
"name": "a",
|
||||
"type": {
|
||||
"display_name": [
|
||||
"u256"
|
||||
],
|
||||
"type": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "b",
|
||||
"type": {
|
||||
"display_name": [
|
||||
"u256"
|
||||
],
|
||||
"type": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"docs": [
|
||||
"Add two 256 bit values\n\n"
|
||||
],
|
||||
"mutates": false,
|
||||
"name": "add",
|
||||
"payable": false,
|
||||
"return_type": {
|
||||
"display_name": [
|
||||
"u256"
|
||||
],
|
||||
"type": 1
|
||||
},
|
||||
"selector": "0x771602f7"
|
||||
}
|
||||
]
|
||||
},
|
||||
"storage": {
|
||||
"struct": {
|
||||
"fields": []
|
||||
}
|
||||
},
|
||||
"types": [
|
||||
{
|
||||
"def": {
|
||||
"primitive": "u256"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/// @title Test 256 bits types
|
||||
/// @author Sean Young <sean@mess.org>
|
||||
contract ints256 {
|
||||
/// Multiply two 256 bit values
|
||||
function multiply(uint256 a, uint256 b) public pure returns (uint256) {
|
||||
return a * b;
|
||||
}
|
||||
|
||||
/// Add two 256 bit values
|
||||
function add(uint256 a, uint256 b) public pure returns (uint256) {
|
||||
return a + b;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,4 @@
|
||||
// Copyright 2017-2020 @polkadot/api-contract authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export { default as withString } from './withString.json';
|
||||
@@ -0,0 +1,777 @@
|
||||
{
|
||||
"metadataVersion": "0.1.0",
|
||||
"source": {
|
||||
"hash": "0xafcd0acf1a747cca1febe5bad81a6c0244a381ceb02635ab1069a1a396adda3f",
|
||||
"language": "ink! 3.0.0-rc1",
|
||||
"compiler": "rustc 1.49.0-nightly"
|
||||
},
|
||||
"contract": {
|
||||
"name": "erc20",
|
||||
"version": "0.1.0",
|
||||
"authors": [
|
||||
"[your_name] <[your_email]>"
|
||||
]
|
||||
},
|
||||
"spec": {
|
||||
"constructors": [
|
||||
{
|
||||
"args": [
|
||||
{
|
||||
"name": "initial_supply",
|
||||
"type": {
|
||||
"displayName": [
|
||||
"Balance"
|
||||
],
|
||||
"type": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "_name",
|
||||
"type": {
|
||||
"displayName": [
|
||||
"String"
|
||||
],
|
||||
"type": 12
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "_symbol",
|
||||
"type": {
|
||||
"displayName": [
|
||||
"String"
|
||||
],
|
||||
"type": 12
|
||||
}
|
||||
}
|
||||
],
|
||||
"docs": [],
|
||||
"name": [
|
||||
"new"
|
||||
],
|
||||
"selector": "0xd183512b"
|
||||
}
|
||||
],
|
||||
"docs": [],
|
||||
"events": [
|
||||
{
|
||||
"args": [
|
||||
{
|
||||
"docs": [],
|
||||
"indexed": true,
|
||||
"name": "from",
|
||||
"type": {
|
||||
"displayName": [
|
||||
"Option"
|
||||
],
|
||||
"type": 14
|
||||
}
|
||||
},
|
||||
{
|
||||
"docs": [],
|
||||
"indexed": true,
|
||||
"name": "to",
|
||||
"type": {
|
||||
"displayName": [
|
||||
"Option"
|
||||
],
|
||||
"type": 14
|
||||
}
|
||||
},
|
||||
{
|
||||
"docs": [],
|
||||
"indexed": true,
|
||||
"name": "value",
|
||||
"type": {
|
||||
"displayName": [
|
||||
"Balance"
|
||||
],
|
||||
"type": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"docs": [],
|
||||
"name": "Transfer"
|
||||
},
|
||||
{
|
||||
"args": [
|
||||
{
|
||||
"docs": [],
|
||||
"indexed": true,
|
||||
"name": "owner",
|
||||
"type": {
|
||||
"displayName": [
|
||||
"AccountId"
|
||||
],
|
||||
"type": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"docs": [],
|
||||
"indexed": true,
|
||||
"name": "spender",
|
||||
"type": {
|
||||
"displayName": [
|
||||
"AccountId"
|
||||
],
|
||||
"type": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"docs": [],
|
||||
"indexed": true,
|
||||
"name": "value",
|
||||
"type": {
|
||||
"displayName": [
|
||||
"Balance"
|
||||
],
|
||||
"type": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"docs": [],
|
||||
"name": "Approval"
|
||||
}
|
||||
],
|
||||
"messages": [
|
||||
{
|
||||
"args": [],
|
||||
"docs": [],
|
||||
"mutates": false,
|
||||
"name": [
|
||||
"total_supply"
|
||||
],
|
||||
"payable": false,
|
||||
"returnType": {
|
||||
"displayName": [
|
||||
"Balance"
|
||||
],
|
||||
"type": 1
|
||||
},
|
||||
"selector": "0xdcb736b5"
|
||||
},
|
||||
{
|
||||
"args": [],
|
||||
"docs": [],
|
||||
"mutates": false,
|
||||
"name": [
|
||||
"name"
|
||||
],
|
||||
"payable": false,
|
||||
"returnType": {
|
||||
"displayName": [
|
||||
"String"
|
||||
],
|
||||
"type": 12
|
||||
},
|
||||
"selector": "0xa0a95494"
|
||||
},
|
||||
{
|
||||
"args": [],
|
||||
"docs": [],
|
||||
"mutates": false,
|
||||
"name": [
|
||||
"symbol"
|
||||
],
|
||||
"payable": false,
|
||||
"returnType": {
|
||||
"displayName": [
|
||||
"String"
|
||||
],
|
||||
"type": 12
|
||||
},
|
||||
"selector": "0x57178a4a"
|
||||
},
|
||||
{
|
||||
"args": [
|
||||
{
|
||||
"name": "owner",
|
||||
"type": {
|
||||
"displayName": [
|
||||
"AccountId"
|
||||
],
|
||||
"type": 5
|
||||
}
|
||||
}
|
||||
],
|
||||
"docs": [],
|
||||
"mutates": false,
|
||||
"name": [
|
||||
"balance_of"
|
||||
],
|
||||
"payable": false,
|
||||
"returnType": {
|
||||
"displayName": [
|
||||
"Balance"
|
||||
],
|
||||
"type": 1
|
||||
},
|
||||
"selector": "0x56e929b2"
|
||||
},
|
||||
{
|
||||
"args": [
|
||||
{
|
||||
"name": "owner",
|
||||
"type": {
|
||||
"displayName": [
|
||||
"AccountId"
|
||||
],
|
||||
"type": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spender",
|
||||
"type": {
|
||||
"displayName": [
|
||||
"AccountId"
|
||||
],
|
||||
"type": 5
|
||||
}
|
||||
}
|
||||
],
|
||||
"docs": [],
|
||||
"mutates": false,
|
||||
"name": [
|
||||
"allowance"
|
||||
],
|
||||
"payable": false,
|
||||
"returnType": {
|
||||
"displayName": [
|
||||
"Balance"
|
||||
],
|
||||
"type": 1
|
||||
},
|
||||
"selector": "0xf3cfff66"
|
||||
},
|
||||
{
|
||||
"args": [
|
||||
{
|
||||
"name": "to",
|
||||
"type": {
|
||||
"displayName": [
|
||||
"AccountId"
|
||||
],
|
||||
"type": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"type": {
|
||||
"displayName": [
|
||||
"Balance"
|
||||
],
|
||||
"type": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"docs": [],
|
||||
"mutates": true,
|
||||
"name": [
|
||||
"transfer"
|
||||
],
|
||||
"payable": false,
|
||||
"returnType": {
|
||||
"displayName": [
|
||||
"bool"
|
||||
],
|
||||
"type": 13
|
||||
},
|
||||
"selector": "0xfae3a09d"
|
||||
},
|
||||
{
|
||||
"args": [
|
||||
{
|
||||
"name": "spender",
|
||||
"type": {
|
||||
"displayName": [
|
||||
"AccountId"
|
||||
],
|
||||
"type": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"type": {
|
||||
"displayName": [
|
||||
"Balance"
|
||||
],
|
||||
"type": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"docs": [],
|
||||
"mutates": true,
|
||||
"name": [
|
||||
"approve"
|
||||
],
|
||||
"payable": false,
|
||||
"returnType": {
|
||||
"displayName": [
|
||||
"bool"
|
||||
],
|
||||
"type": 13
|
||||
},
|
||||
"selector": "0x03d0e114"
|
||||
},
|
||||
{
|
||||
"args": [
|
||||
{
|
||||
"name": "from",
|
||||
"type": {
|
||||
"displayName": [
|
||||
"AccountId"
|
||||
],
|
||||
"type": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "to",
|
||||
"type": {
|
||||
"displayName": [
|
||||
"AccountId"
|
||||
],
|
||||
"type": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"type": {
|
||||
"displayName": [
|
||||
"Balance"
|
||||
],
|
||||
"type": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"docs": [],
|
||||
"mutates": true,
|
||||
"name": [
|
||||
"transfer_from"
|
||||
],
|
||||
"payable": false,
|
||||
"returnType": {
|
||||
"displayName": [
|
||||
"bool"
|
||||
],
|
||||
"type": 13
|
||||
},
|
||||
"selector": "0xfcfb2ccd"
|
||||
}
|
||||
]
|
||||
},
|
||||
"storage": {
|
||||
"struct": {
|
||||
"fields": [
|
||||
{
|
||||
"layout": {
|
||||
"cell": {
|
||||
"key": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"ty": 1
|
||||
}
|
||||
},
|
||||
"name": "total_supply"
|
||||
},
|
||||
{
|
||||
"layout": {
|
||||
"struct": {
|
||||
"fields": [
|
||||
{
|
||||
"layout": {
|
||||
"struct": {
|
||||
"fields": [
|
||||
{
|
||||
"layout": {
|
||||
"cell": {
|
||||
"key": "0x0100000000000000000000000000000000000000000000000000000000000000",
|
||||
"ty": 2
|
||||
}
|
||||
},
|
||||
"name": "header"
|
||||
},
|
||||
{
|
||||
"layout": {
|
||||
"struct": {
|
||||
"fields": [
|
||||
{
|
||||
"layout": {
|
||||
"cell": {
|
||||
"key": "0x0200000000000000000000000000000000000000000000000000000000000000",
|
||||
"ty": 3
|
||||
}
|
||||
},
|
||||
"name": "len"
|
||||
},
|
||||
{
|
||||
"layout": {
|
||||
"array": {
|
||||
"cellsPerElem": 1,
|
||||
"layout": {
|
||||
"cell": {
|
||||
"key": "0x0200000001000000000000000000000000000000000000000000000000000000",
|
||||
"ty": 4
|
||||
}
|
||||
},
|
||||
"len": 4294967295,
|
||||
"offset": "0x0300000000000000000000000000000000000000000000000000000000000000"
|
||||
}
|
||||
},
|
||||
"name": "elems"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": "entries"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": "keys"
|
||||
},
|
||||
{
|
||||
"layout": {
|
||||
"hash": {
|
||||
"layout": {
|
||||
"cell": {
|
||||
"key": "0x0300000001000000000000000000000000000000000000000000000000000000",
|
||||
"ty": 9
|
||||
}
|
||||
},
|
||||
"offset": "0x0200000001000000000000000000000000000000000000000000000000000000",
|
||||
"strategy": {
|
||||
"hasher": "Blake2x256",
|
||||
"postfix": "",
|
||||
"prefix": "0x696e6b20686173686d6170"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "values"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": "balances"
|
||||
},
|
||||
{
|
||||
"layout": {
|
||||
"struct": {
|
||||
"fields": [
|
||||
{
|
||||
"layout": {
|
||||
"struct": {
|
||||
"fields": [
|
||||
{
|
||||
"layout": {
|
||||
"cell": {
|
||||
"key": "0x0300000001000000000000000000000000000000000000000000000000000000",
|
||||
"ty": 2
|
||||
}
|
||||
},
|
||||
"name": "header"
|
||||
},
|
||||
{
|
||||
"layout": {
|
||||
"struct": {
|
||||
"fields": [
|
||||
{
|
||||
"layout": {
|
||||
"cell": {
|
||||
"key": "0x0400000001000000000000000000000000000000000000000000000000000000",
|
||||
"ty": 3
|
||||
}
|
||||
},
|
||||
"name": "len"
|
||||
},
|
||||
{
|
||||
"layout": {
|
||||
"array": {
|
||||
"cellsPerElem": 1,
|
||||
"layout": {
|
||||
"cell": {
|
||||
"key": "0x0400000002000000000000000000000000000000000000000000000000000000",
|
||||
"ty": 10
|
||||
}
|
||||
},
|
||||
"len": 4294967295,
|
||||
"offset": "0x0500000001000000000000000000000000000000000000000000000000000000"
|
||||
}
|
||||
},
|
||||
"name": "elems"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": "entries"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": "keys"
|
||||
},
|
||||
{
|
||||
"layout": {
|
||||
"hash": {
|
||||
"layout": {
|
||||
"cell": {
|
||||
"key": "0x0500000002000000000000000000000000000000000000000000000000000000",
|
||||
"ty": 9
|
||||
}
|
||||
},
|
||||
"offset": "0x0400000002000000000000000000000000000000000000000000000000000000",
|
||||
"strategy": {
|
||||
"hasher": "Blake2x256",
|
||||
"postfix": "",
|
||||
"prefix": "0x696e6b20686173686d6170"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "values"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": "allowances"
|
||||
},
|
||||
{
|
||||
"layout": {
|
||||
"cell": {
|
||||
"key": "0x0500000002000000000000000000000000000000000000000000000000000000",
|
||||
"ty": 12
|
||||
}
|
||||
},
|
||||
"name": "name"
|
||||
},
|
||||
{
|
||||
"layout": {
|
||||
"cell": {
|
||||
"key": "0x0600000002000000000000000000000000000000000000000000000000000000",
|
||||
"ty": 12
|
||||
}
|
||||
},
|
||||
"name": "symbol"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"types": [
|
||||
{
|
||||
"def": {
|
||||
"primitive": "u128"
|
||||
}
|
||||
},
|
||||
{
|
||||
"def": {
|
||||
"composite": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "last_vacant",
|
||||
"type": 3
|
||||
},
|
||||
{
|
||||
"name": "len",
|
||||
"type": 3
|
||||
},
|
||||
{
|
||||
"name": "len_entries",
|
||||
"type": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"path": [
|
||||
"ink_storage",
|
||||
"collections",
|
||||
"stash",
|
||||
"Header"
|
||||
]
|
||||
},
|
||||
{
|
||||
"def": {
|
||||
"primitive": "u32"
|
||||
}
|
||||
},
|
||||
{
|
||||
"def": {
|
||||
"variant": {
|
||||
"variants": [
|
||||
{
|
||||
"fields": [
|
||||
{
|
||||
"type": 8
|
||||
}
|
||||
],
|
||||
"name": "Vacant"
|
||||
},
|
||||
{
|
||||
"fields": [
|
||||
{
|
||||
"type": 5
|
||||
}
|
||||
],
|
||||
"name": "Occupied"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"params": [
|
||||
5
|
||||
],
|
||||
"path": [
|
||||
"ink_storage",
|
||||
"collections",
|
||||
"stash",
|
||||
"Entry"
|
||||
]
|
||||
},
|
||||
{
|
||||
"def": {
|
||||
"composite": {
|
||||
"fields": [
|
||||
{
|
||||
"type": 6
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"path": [
|
||||
"ink_env",
|
||||
"types",
|
||||
"AccountId"
|
||||
]
|
||||
},
|
||||
{
|
||||
"def": {
|
||||
"array": {
|
||||
"len": 32,
|
||||
"type": 7
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"def": {
|
||||
"primitive": "u8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"def": {
|
||||
"composite": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "next",
|
||||
"type": 3
|
||||
},
|
||||
{
|
||||
"name": "prev",
|
||||
"type": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"path": [
|
||||
"ink_storage",
|
||||
"collections",
|
||||
"stash",
|
||||
"VacantEntry"
|
||||
]
|
||||
},
|
||||
{
|
||||
"def": {
|
||||
"composite": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "value",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"name": "key_index",
|
||||
"type": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"params": [
|
||||
1
|
||||
],
|
||||
"path": [
|
||||
"ink_storage",
|
||||
"collections",
|
||||
"hashmap",
|
||||
"ValueEntry"
|
||||
]
|
||||
},
|
||||
{
|
||||
"def": {
|
||||
"variant": {
|
||||
"variants": [
|
||||
{
|
||||
"fields": [
|
||||
{
|
||||
"type": 8
|
||||
}
|
||||
],
|
||||
"name": "Vacant"
|
||||
},
|
||||
{
|
||||
"fields": [
|
||||
{
|
||||
"type": 11
|
||||
}
|
||||
],
|
||||
"name": "Occupied"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"params": [
|
||||
11
|
||||
],
|
||||
"path": [
|
||||
"ink_storage",
|
||||
"collections",
|
||||
"stash",
|
||||
"Entry"
|
||||
]
|
||||
},
|
||||
{
|
||||
"def": {
|
||||
"tuple": [
|
||||
5,
|
||||
5
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"def": {
|
||||
"primitive": "str"
|
||||
}
|
||||
},
|
||||
{
|
||||
"def": {
|
||||
"primitive": "bool"
|
||||
}
|
||||
},
|
||||
{
|
||||
"def": {
|
||||
"variant": {
|
||||
"variants": [
|
||||
{
|
||||
"name": "None"
|
||||
},
|
||||
{
|
||||
"fields": [
|
||||
{
|
||||
"type": 5
|
||||
}
|
||||
],
|
||||
"name": "Some"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"params": [
|
||||
5
|
||||
],
|
||||
"path": [
|
||||
"Option"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/api-derive",
|
||||
"version": "2.2.1",
|
||||
"version": "2.4.1",
|
||||
"description": "Common functions used across Polkadot, derived from RPC calls and storage queries.",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -27,18 +27,18 @@
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-derive#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@polkadot/api": "2.2.1",
|
||||
"@polkadot/rpc-core": "2.2.1",
|
||||
"@polkadot/rpc-provider": "2.2.1",
|
||||
"@polkadot/types": "2.2.1",
|
||||
"@polkadot/util": "^3.5.1",
|
||||
"@polkadot/util-crypto": "^3.5.1",
|
||||
"@babel/runtime": "^7.12.1",
|
||||
"@polkadot/api": "^2.4.1",
|
||||
"@polkadot/rpc-core": "^2.4.1",
|
||||
"@polkadot/rpc-provider": "^2.4.1",
|
||||
"@polkadot/types": "^2.4.1",
|
||||
"@polkadot/util": "^3.6.1",
|
||||
"@polkadot/util-crypto": "^3.6.1",
|
||||
"bn.js": "^5.1.3",
|
||||
"memoizee": "^0.4.14",
|
||||
"rxjs": "^6.6.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/keyring": "^3.5.1"
|
||||
"@polkadot/keyring": "^3.6.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,4 +5,5 @@ export * from './bestNumber';
|
||||
export * from './bestNumberFinalized';
|
||||
export * from './bestNumberLag';
|
||||
export * from './getHeader';
|
||||
export * from './subscribeNewBlocks';
|
||||
export * from './subscribeNewHeads';
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { EventRecord, Hash, SignedBlock } from '@polkadot/types/interfaces';
|
||||
import { FullNewBlock } from '../types';
|
||||
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
/**
|
||||
* @name subscribeNewBlocks
|
||||
* @returns The latest block & events for that block
|
||||
*/
|
||||
export function subscribeNewBlocks (instanceId: string, api: ApiInterfaceRx): () => Observable<FullNewBlock> {
|
||||
return memo(instanceId, (): Observable<FullNewBlock> =>
|
||||
api.derive.chain.subscribeNewHeads().pipe(
|
||||
switchMap((header): Observable<[Hash, EventRecord[], SignedBlock]> => {
|
||||
const blockHash = header.hash;
|
||||
|
||||
return combineLatest(
|
||||
of(blockHash),
|
||||
api.query.system.events.at(blockHash),
|
||||
api.rpc.chain.getBlock(header.hash)
|
||||
);
|
||||
}),
|
||||
map(([blockHash, events, block]) => ({ block: block.block, blockHash, blockNumber: block.block.header.number.unwrap(), events, justification: block.justification }))
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import { memo } from '../util';
|
||||
|
||||
/**
|
||||
* @name subscribeNewHeads
|
||||
* @returns An array containing the block header and the block author
|
||||
* @returns A header with the current header (including extracted author)
|
||||
* @description An observable of the current block header and it's author
|
||||
* @example
|
||||
* <BR>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { Block, BlockNumber, EventRecord, Hash, Justification } from '@polkadot/types/interfaces';
|
||||
|
||||
export interface FullNewBlock {
|
||||
block: Block;
|
||||
blockHash: Hash;
|
||||
blockNumber: BlockNumber;
|
||||
events: EventRecord[];
|
||||
justification: Justification;
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import { AccountId, Balance, BalanceLock, BalanceLockTo212, BalanceOf, Bid, BidK
|
||||
import { u32 } from '@polkadot/types';
|
||||
|
||||
export * from './accounts/types';
|
||||
export * from './chain/types';
|
||||
export * from './council/types';
|
||||
export * from './democracy/types';
|
||||
export * from './elections/types';
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import createMemo from 'memoizee';
|
||||
import { Observable, Observer, TeardownLogic } from 'rxjs';
|
||||
import { drr } from '@polkadot/rpc-core/rxjs';
|
||||
import normalizer from '@polkadot/rpc-core/normalizer';
|
||||
|
||||
type ObsFn <T> = (...params: any[]) => Observable<T>;
|
||||
|
||||
@@ -24,8 +25,7 @@ export function memo <T> (instanceId: string, inner: ObsFn<T>): ObsFn<T> {
|
||||
}).pipe(drr()),
|
||||
{
|
||||
// Normalize via JSON.stringify, allow e.g. AccountId -> ss58
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
normalizer: (args) => instanceId + JSON.stringify(args)
|
||||
normalizer: normalizer(instanceId)
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
+12
-12
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/api",
|
||||
"version": "2.2.1",
|
||||
"version": "2.4.1",
|
||||
"description": "Promise and RxJS wrappers around the Polkadot JS RPC",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -26,21 +26,21 @@
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@polkadot/api-derive": "2.2.1",
|
||||
"@polkadot/keyring": "^3.5.1",
|
||||
"@polkadot/metadata": "2.2.1",
|
||||
"@polkadot/rpc-core": "2.2.1",
|
||||
"@polkadot/rpc-provider": "2.2.1",
|
||||
"@polkadot/types": "2.2.1",
|
||||
"@polkadot/types-known": "2.2.1",
|
||||
"@polkadot/util": "^3.5.1",
|
||||
"@polkadot/util-crypto": "^3.5.1",
|
||||
"@babel/runtime": "^7.12.1",
|
||||
"@polkadot/api-derive": "^2.4.1",
|
||||
"@polkadot/keyring": "^3.6.1",
|
||||
"@polkadot/metadata": "^2.4.1",
|
||||
"@polkadot/rpc-core": "^2.4.1",
|
||||
"@polkadot/rpc-provider": "^2.4.1",
|
||||
"@polkadot/types": "^2.4.1",
|
||||
"@polkadot/types-known": "^2.4.1",
|
||||
"@polkadot/util": "^3.6.1",
|
||||
"@polkadot/util-crypto": "^3.6.1",
|
||||
"bn.js": "^5.1.3",
|
||||
"eventemitter3": "^4.0.7",
|
||||
"rxjs": "^6.6.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/keyring": "^3.5.1"
|
||||
"@polkadot/keyring": "^3.6.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,11 +153,11 @@ declare module '@polkadot/rpc-core/types.jsonrpc' {
|
||||
/**
|
||||
* Get offchain local storage under given key and prefix
|
||||
**/
|
||||
localStorageGet: AugmentedRpc<(kind: StorageKind | '__UNUSED' | 'PERSISTENT' | 'LOCAL' | number | Uint8Array, key: Bytes | string | Uint8Array) => Observable<Option<Bytes>>>;
|
||||
localStorageGet: AugmentedRpc<(kind: StorageKind | '__UNUSED'|'PERSISTENT'|'LOCAL' | number | Uint8Array, key: Bytes | string | Uint8Array) => Observable<Option<Bytes>>>;
|
||||
/**
|
||||
* Set offchain local storage under given key and prefix
|
||||
**/
|
||||
localStorageSet: AugmentedRpc<(kind: StorageKind | '__UNUSED' | 'PERSISTENT' | 'LOCAL' | number | Uint8Array, key: Bytes | string | Uint8Array, value: Bytes | string | Uint8Array) => Observable<Null>>;
|
||||
localStorageSet: AugmentedRpc<(kind: StorageKind | '__UNUSED'|'PERSISTENT'|'LOCAL' | number | Uint8Array, key: Bytes | string | Uint8Array, value: Bytes | string | Uint8Array) => Observable<Null>>;
|
||||
};
|
||||
payment: {
|
||||
/**
|
||||
|
||||
@@ -359,7 +359,11 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
||||
if (creator.iterKey && (creator.meta.type.isMap || creator.meta.type.isDoubleMap)) {
|
||||
decorated.entries = decorateMethod(
|
||||
memo(this.#instanceId, (doubleMapArg?: Arg): Observable<[StorageKey, Codec][]> =>
|
||||
this._retrieveMapEntries(creator, doubleMapArg)));
|
||||
this._retrieveMapEntries(creator, null, doubleMapArg)));
|
||||
|
||||
decorated.entriesAt = decorateMethod(
|
||||
memo(this.#instanceId, (hash: Hash | Uint8Array | string, doubleMapArg?: Arg): Observable<[StorageKey, Codec][]> =>
|
||||
this._retrieveMapEntries(creator, hash, doubleMapArg)));
|
||||
|
||||
decorated.entriesPaged = decorateMethod(
|
||||
memo(this.#instanceId, (opts: PaginationOptions): Observable<[StorageKey, Codec][]> =>
|
||||
@@ -367,7 +371,11 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
||||
|
||||
decorated.keys = decorateMethod(
|
||||
memo(this.#instanceId, (doubleMapArg?: Arg): Observable<StorageKey[]> =>
|
||||
this._retrieveMapKeys(creator, doubleMapArg)));
|
||||
this._retrieveMapKeys(creator, null, doubleMapArg)));
|
||||
|
||||
decorated.keysAt = decorateMethod(
|
||||
memo(this.#instanceId, (hash: Hash | Uint8Array | string, doubleMapArg?: Arg): Observable<StorageKey[]> =>
|
||||
this._retrieveMapKeys(creator, hash, doubleMapArg)));
|
||||
|
||||
decorated.keysPaged = decorateMethod(
|
||||
memo(this.#instanceId, (opts: PaginationOptions): Observable<StorageKey[]> =>
|
||||
@@ -416,15 +424,18 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
||||
));
|
||||
}
|
||||
|
||||
private _retrieveMapKeys ({ iterKey, meta }: StorageEntry, arg?: Arg): Observable<StorageKey[]> {
|
||||
private _retrieveMapKeys ({ iterKey, meta }: StorageEntry, at: Hash | Uint8Array | string | null, arg?: Arg): Observable<StorageKey[]> {
|
||||
assert(iterKey && (meta.type.isMap || meta.type.isDoubleMap), 'keys can only be retrieved on maps, linked maps and double maps');
|
||||
|
||||
const headKey = iterKey(arg).toHex();
|
||||
const startSubject = new BehaviorSubject<string>(headKey);
|
||||
const query = at
|
||||
? (startKey: string) => this._rpcCore.state.getKeysPaged(headKey, PAGE_SIZE_KEYS, startKey, at)
|
||||
: (startKey: string) => this._rpcCore.state.getKeysPaged(headKey, PAGE_SIZE_KEYS, startKey);
|
||||
|
||||
return startSubject.pipe(
|
||||
switchMap((startKey) =>
|
||||
this._rpcCore.state.getKeysPaged(headKey, PAGE_SIZE_KEYS, startKey).pipe(
|
||||
query(startKey).pipe(
|
||||
map((keys) => keys.map((key) => key.setMeta(meta)))
|
||||
)
|
||||
),
|
||||
@@ -448,21 +459,23 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
||||
);
|
||||
}
|
||||
|
||||
private _retrieveMapEntries (entry: StorageEntry, arg?: Arg): Observable<[StorageKey, Codec][]> {
|
||||
return this._retrieveMapKeys(entry, arg).pipe(
|
||||
private _retrieveMapEntries (entry: StorageEntry, at: Hash | Uint8Array | string | null, arg?: Arg): Observable<[StorageKey, Codec][]> {
|
||||
const query = at
|
||||
? this._rpcCore.state.queryStorageAt
|
||||
? (keyset: StorageKey[]) => this._rpcCore.state.queryStorageAt<Codec[]>(keyset, at)
|
||||
: (keyset: StorageKey[]) => this._rpcCore.state.queryStorageAt<Codec[]>(keyset)
|
||||
// this is horrible, but need older support (which now doesn't work with at)
|
||||
: (keyset: StorageKey[]) => this._rpcCore.state.subscribeStorage<Codec[]>(keyset).pipe(take(1));
|
||||
|
||||
return this._retrieveMapKeys(entry, at, arg).pipe(
|
||||
switchMap((keys) =>
|
||||
combineLatest<[StorageKey[], ...Codec[][]]>([
|
||||
of(keys),
|
||||
...Array(Math.ceil(keys.length / PAGE_SIZE_VALS))
|
||||
.fill(0)
|
||||
.map((_, index): Observable<Codec[]> => {
|
||||
const keyset = keys.slice(index * PAGE_SIZE_VALS, (index * PAGE_SIZE_VALS) + PAGE_SIZE_VALS);
|
||||
|
||||
return this._rpcCore.state.queryStorageAt
|
||||
? this._rpcCore.state.queryStorageAt<Codec[]>(keyset)
|
||||
// this is horrible, but need older support
|
||||
: this._rpcCore.state.subscribeStorage<Codec[]>(keyset).pipe(take(1));
|
||||
})
|
||||
.map((_, index): Observable<Codec[]> =>
|
||||
query(keys.slice(index * PAGE_SIZE_VALS, (index * PAGE_SIZE_VALS) + PAGE_SIZE_VALS))
|
||||
)
|
||||
])
|
||||
),
|
||||
map(([keys, ...valsArr]): [StorageKey, Codec][] =>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
// Simple non-runnable checks to test type definitions in the editor itself
|
||||
|
||||
import { Balance, Header, Index } from '@polkadot/types/interfaces';
|
||||
import { AccountId, Balance, Header, Index } from '@polkadot/types/interfaces';
|
||||
import { IExtrinsic, IMethod } from '@polkadot/types/types';
|
||||
|
||||
import { ApiPromise } from '@polkadot/api';
|
||||
@@ -71,6 +71,20 @@ async function query (api: ApiPromise, keyring: TestKeyringMap): Promise<void> {
|
||||
|
||||
console.log(multiRes);
|
||||
|
||||
// events destructing
|
||||
await api.query.system.events((records): void => {
|
||||
records.forEach(({ event, phase }): void => {
|
||||
if (phase.isApplyExtrinsic) {
|
||||
// Dunno... this should work
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const [accountId, value]: [AccountId, Balance] = event.data;
|
||||
|
||||
console.log(`${accountId.toString()} has ${value.toHuman()}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// at queries
|
||||
const events = await api.query.system.events.at('0x12345');
|
||||
|
||||
|
||||
@@ -1,16 +1,44 @@
|
||||
// Copyright 2017-2020 @polkadot/api authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { ExtrinsicStatus, EventRecord } from '@polkadot/types/interfaces';
|
||||
import { DispatchError, DispatchInfo, ExtrinsicStatus, EventRecord } from '@polkadot/types/interfaces';
|
||||
import { AnyJson, ISubmittableResult } from '@polkadot/types/types';
|
||||
import { SubmittableResultValue } from './types';
|
||||
|
||||
const recordIdentity = (record: EventRecord) => record;
|
||||
|
||||
function filterAndApply <T> (events: EventRecord[], section: string, methods: string[], onFound: (record: EventRecord) => T): T[] {
|
||||
return events
|
||||
.filter(({ event }) => section === event.section && methods.includes(event.method))
|
||||
.map((record) => onFound(record));
|
||||
}
|
||||
|
||||
function extractError (events: EventRecord[] = []): DispatchError | undefined {
|
||||
return filterAndApply(events, 'system', ['ExtrinsicFailed'], ({ event: { data } }) =>
|
||||
data[0] as DispatchError
|
||||
)[0];
|
||||
}
|
||||
|
||||
function extractInfo (events: EventRecord[] = []): DispatchInfo | undefined {
|
||||
return filterAndApply(events, 'system', ['ExtrinsicFailed', 'ExtrinsicSuccess'], ({ event: { data, method } }) =>
|
||||
method === 'ExtrinsicSuccess'
|
||||
? data[0] as DispatchInfo
|
||||
: data[1] as DispatchInfo
|
||||
)[0];
|
||||
}
|
||||
|
||||
export default class SubmittableResult implements ISubmittableResult {
|
||||
public readonly dispatchError?: DispatchError;
|
||||
|
||||
public readonly dispatchInfo?: DispatchInfo;
|
||||
|
||||
public readonly events: EventRecord[];
|
||||
|
||||
public readonly status: ExtrinsicStatus;
|
||||
|
||||
constructor ({ events, status }: SubmittableResultValue) {
|
||||
constructor ({ dispatchError, dispatchInfo, events, status }: SubmittableResultValue) {
|
||||
this.dispatchError = dispatchError || extractError(events);
|
||||
this.dispatchInfo = dispatchInfo || extractInfo(events);
|
||||
this.events = events || [];
|
||||
this.status = status;
|
||||
}
|
||||
@@ -39,18 +67,14 @@ export default class SubmittableResult implements ISubmittableResult {
|
||||
* @description Filters EventRecords for the specified method & section (there could be multiple)
|
||||
*/
|
||||
public filterRecords (section: string, method: string): EventRecord[] {
|
||||
return this.events.filter(({ event }): boolean =>
|
||||
event.section === section && event.method === method
|
||||
);
|
||||
return filterAndApply(this.events, section, [method], recordIdentity);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Finds an EventRecord for the specified method & section
|
||||
*/
|
||||
public findRecord (section: string, method: string): EventRecord | undefined {
|
||||
return this.events.find(({ event }): boolean =>
|
||||
event.section === section && event.method === method
|
||||
);
|
||||
return this.filterRecords(section, method)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,6 +82,8 @@ export default class SubmittableResult implements ISubmittableResult {
|
||||
*/
|
||||
public toHuman (isExtended?: boolean): AnyJson {
|
||||
return {
|
||||
dispatchError: this.dispatchError?.toHuman(),
|
||||
dispatchInfo: this.dispatchInfo?.toHuman(),
|
||||
events: this.events.map((event) => event.toHuman(isExtended)),
|
||||
status: this.status.toHuman(isExtended)
|
||||
};
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
// Copyright 2017-2020 @polkadot/api authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { AccountId, Address, Extrinsic, ExtrinsicStatus, EventRecord, Hash, RuntimeDispatchInfo } from '@polkadot/types/interfaces';
|
||||
import { AccountId, Address, DispatchError, DispatchInfo, Extrinsic, ExtrinsicStatus, EventRecord, Hash, RuntimeDispatchInfo } from '@polkadot/types/interfaces';
|
||||
import { AnyNumber, Callback, Codec, IExtrinsicEra, IKeyringPair, Signer, ISubmittableResult } from '@polkadot/types/types';
|
||||
import { ApiTypes } from '../types';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface SubmittableResultValue {
|
||||
dispatchError?: DispatchError;
|
||||
dispatchInfo?: DispatchInfo;
|
||||
events?: EventRecord[];
|
||||
status: ExtrinsicStatus;
|
||||
}
|
||||
|
||||
@@ -40,11 +40,13 @@ export interface StorageEntryBase<ApiType extends ApiTypes, F extends AnyFunctio
|
||||
at: <T extends Codec | any = ObsInnerType<ReturnType<F>>>(hash: Hash | Uint8Array | string, ...args: Parameters<F>) => PromiseOrObs<ApiType, T>;
|
||||
creator: StorageEntry;
|
||||
entries: <T extends Codec | any = ObsInnerType<ReturnType<F>>>(arg?: Parameters<F>[0]) => PromiseOrObs<ApiType, [StorageKey, T][]>;
|
||||
entriesAt: <T extends Codec | any = ObsInnerType<ReturnType<F>>>(hash: Hash | Uint8Array | string, arg?: Parameters<F>[0]) => PromiseOrObs<ApiType, [StorageKey, T][]>;
|
||||
entriesPaged: <T extends Codec | any = ObsInnerType<ReturnType<F>>>(opts: PaginationOptions<Parameters<F>[0]>) => PromiseOrObs<ApiType, [StorageKey, T][]>;
|
||||
hash: (...args: Parameters<F>) => PromiseOrObs<ApiType, Hash>;
|
||||
key: (...args: Parameters<F>) => string;
|
||||
keyPrefix: () => string;
|
||||
keys: (arg?: any) => PromiseOrObs<ApiType, StorageKey[]>;
|
||||
keysAt: (hash: Hash | Uint8Array | string, arg?: any) => PromiseOrObs<ApiType, StorageKey[]>;
|
||||
keysPaged: (opts: PaginationOptions<Parameters<F>[0]>) => PromiseOrObs<ApiType, StorageKey[]>;
|
||||
range: <T extends Codec | any = ObsInnerType<ReturnType<F>>>([from, to]: [Hash | Uint8Array | string, Hash | Uint8Array | string | undefined] | [Hash | Uint8Array | string], ...args: Parameters<F>) => PromiseOrObs<ApiType, [Hash, T][]>;
|
||||
size: (...args: Parameters<F>) => PromiseOrObs<ApiType, u64>;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/metadata",
|
||||
"version": "2.2.1",
|
||||
"version": "2.4.1",
|
||||
"description": "Helpers to extract information from runtime metadata",
|
||||
"main": "index.js",
|
||||
"publishConfig": {
|
||||
@@ -26,14 +26,14 @@
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/type-metadata#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@polkadot/types": "2.2.1",
|
||||
"@polkadot/types-known": "2.2.1",
|
||||
"@polkadot/util": "^3.5.1",
|
||||
"@polkadot/util-crypto": "^3.5.1",
|
||||
"@babel/runtime": "^7.12.1",
|
||||
"@polkadot/types": "^2.4.1",
|
||||
"@polkadot/types-known": "^2.4.1",
|
||||
"@polkadot/util": "^3.6.1",
|
||||
"@polkadot/util-crypto": "^3.6.1",
|
||||
"bn.js": "^5.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/keyring": "^3.5.1"
|
||||
"@polkadot/keyring": "^3.6.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/rpc-core",
|
||||
"version": "2.2.1",
|
||||
"version": "2.4.1",
|
||||
"description": "A JavaScript wrapper for the Polkadot JsonRPC interface",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -26,15 +26,15 @@
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/rpc-core#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@polkadot/metadata": "2.2.1",
|
||||
"@polkadot/rpc-provider": "2.2.1",
|
||||
"@polkadot/types": "2.2.1",
|
||||
"@polkadot/util": "^3.5.1",
|
||||
"@babel/runtime": "^7.12.1",
|
||||
"@polkadot/metadata": "^2.4.1",
|
||||
"@polkadot/rpc-provider": "^2.4.1",
|
||||
"@polkadot/types": "^2.4.1",
|
||||
"@polkadot/util": "^3.6.1",
|
||||
"memoizee": "^0.4.14",
|
||||
"rxjs": "^6.6.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/keyring": "^3.5.1"
|
||||
"@polkadot/keyring": "^3.6.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import jsonrpc from '@polkadot/types/interfaces/jsonrpc';
|
||||
import { Option, StorageKey, Vec, createClass, createTypeUnsafe } from '@polkadot/types';
|
||||
import { assert, hexToU8a, isFunction, isNull, isUndefined, logger, u8aToU8a } from '@polkadot/util';
|
||||
|
||||
import normalizer from './normalizer';
|
||||
import { drr, refCountDelay } from './rxjs';
|
||||
|
||||
interface StorageChangeSetJSON {
|
||||
@@ -267,7 +268,7 @@ export default class Rpc implements RpcInterface {
|
||||
|
||||
memoized = memoizee(this._createMethodWithRaw(creator), {
|
||||
length: false,
|
||||
normalizer: (args) => this.#instanceId + JSON.stringify(args)
|
||||
normalizer: normalizer(this.#instanceId)
|
||||
});
|
||||
|
||||
return memoized;
|
||||
@@ -355,8 +356,7 @@ export default class Rpc implements RpcInterface {
|
||||
// Normalize args so that different args that should be cached
|
||||
// together are cached together.
|
||||
// E.g.: `query.my.method('abc') === query.my.method(createType('AccountId', 'abc'));`
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
normalizer: (args) => this.#instanceId + JSON.stringify(args)
|
||||
normalizer: normalizer(this.#instanceId)
|
||||
});
|
||||
|
||||
return memoized;
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright 2017-2020 @polkadot/rpc-core authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import normalizer from './normalizer';
|
||||
|
||||
describe('normalizer', (): void => {
|
||||
it('works when BigInt is in the data (object)', (): void => {
|
||||
expect(
|
||||
normalizer('instance')({ a: 'bar', b: 1234567890987654321n, c: 123 })
|
||||
).toEqual('instance{"a":"bar","b":"1234567890987654321","c":123}');
|
||||
});
|
||||
|
||||
it('works when BigInt is in the data (array)', (): void => {
|
||||
expect(
|
||||
normalizer('instance')(['bar', 1234567890987654321n, 123])
|
||||
).toEqual('instance["bar","1234567890987654321",123]');
|
||||
});
|
||||
|
||||
it('works when BigInt is in the data (single)', (): void => {
|
||||
expect(
|
||||
normalizer('instance')(1234567890987654321n)
|
||||
).toEqual('instance"1234567890987654321"');
|
||||
});
|
||||
|
||||
it('works when BigInt is in the data (nested)', (): void => {
|
||||
expect(
|
||||
normalizer('instance')({ a: 'bar', b: { foo: 1234567890987654321n }, c: 123 })
|
||||
).toEqual('instance{"a":"bar","b":{"foo":"1234567890987654321"},"c":123}');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright 2017-2020 @polkadot/rpc-core authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { isBigInt } from '@polkadot/util';
|
||||
|
||||
export default function normalizer (instanceId: string): (value: unknown) => string {
|
||||
return (value: unknown) =>
|
||||
instanceId + JSON.stringify(value, (_, value: unknown) =>
|
||||
isBigInt(value)
|
||||
? value.toString()
|
||||
: value
|
||||
);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/rpc-provider",
|
||||
"version": "2.2.1",
|
||||
"version": "2.4.1",
|
||||
"description": "Transport providers for the API",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -26,18 +26,18 @@
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/rpc-provider#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@polkadot/metadata": "2.2.1",
|
||||
"@polkadot/types": "2.2.1",
|
||||
"@polkadot/util": "^3.5.1",
|
||||
"@polkadot/util-crypto": "^3.5.1",
|
||||
"@polkadot/x-fetch": "^0.3.2",
|
||||
"@polkadot/x-ws": "^0.3.2",
|
||||
"@babel/runtime": "^7.12.1",
|
||||
"@polkadot/metadata": "^2.4.1",
|
||||
"@polkadot/types": "^2.4.1",
|
||||
"@polkadot/util": "^3.6.1",
|
||||
"@polkadot/util-crypto": "^3.6.1",
|
||||
"@polkadot/x-fetch": "^0.3.4",
|
||||
"@polkadot/x-ws": "^0.3.4",
|
||||
"bn.js": "^5.1.3",
|
||||
"eventemitter3": "^4.0.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/keyring": "^3.5.1",
|
||||
"@polkadot/keyring": "^3.6.1",
|
||||
"mock-socket": "^9.0.3",
|
||||
"nock": "^13.0.4"
|
||||
}
|
||||
|
||||
@@ -150,7 +150,12 @@ export default class WsProvider implements ProviderInterface {
|
||||
? new WS(this.#endpoints[this.#endpointIndex])
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore - WS may be an instance of w3cwebsocket, which supports headers
|
||||
: new WS(this.#endpoints[this.#endpointIndex], undefined, undefined, this.#headers);
|
||||
: new WS(this.#endpoints[this.#endpointIndex], undefined, undefined, this.#headers, undefined, {
|
||||
// default: true
|
||||
fragmentOutgoingMessages: true,
|
||||
// default: 16K
|
||||
fragmentationThreshold: 256 * 1024
|
||||
});
|
||||
|
||||
this.#websocket.onclose = this.#onSocketClose;
|
||||
this.#websocket.onerror = this.#onSocketError;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/typegen",
|
||||
"version": "2.2.1",
|
||||
"version": "2.4.1",
|
||||
"description": "Type generation scripts",
|
||||
"main": "index.js",
|
||||
"bin": {
|
||||
@@ -33,20 +33,20 @@
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/typegen#readme",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.11.6",
|
||||
"@babel/register": "^7.11.5",
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@polkadot/api": "2.2.1",
|
||||
"@polkadot/metadata": "2.2.1",
|
||||
"@polkadot/rpc-provider": "2.2.1",
|
||||
"@polkadot/types": "2.2.1",
|
||||
"@polkadot/util": "^3.5.1",
|
||||
"@babel/core": "^7.12.3",
|
||||
"@babel/register": "^7.12.1",
|
||||
"@babel/runtime": "^7.12.1",
|
||||
"@polkadot/api": "^2.4.1",
|
||||
"@polkadot/metadata": "^2.4.1",
|
||||
"@polkadot/rpc-provider": "^2.4.1",
|
||||
"@polkadot/types": "^2.4.1",
|
||||
"@polkadot/util": "^3.6.1",
|
||||
"handlebars": "^4.7.6",
|
||||
"websocket": "^1.0.32",
|
||||
"yargs": "^16.0.3"
|
||||
"yargs": "^16.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/websocket": "^1.0.1",
|
||||
"@types/yargs": "^15.0.7"
|
||||
"@types/yargs": "^15.0.9"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { TypeRegistry } from '@polkadot/types/create';
|
||||
import * as defaultDefs from '@polkadot/types/interfaces/definitions';
|
||||
import { stringCamelCase } from '@polkadot/util';
|
||||
|
||||
import { createImports, compareName, readTemplate, registerDefinitions, setImports, writeFile } from '../util';
|
||||
import { createImports, compareName, formatType, readTemplate, registerDefinitions, setImports, writeFile } from '../util';
|
||||
|
||||
const template = readTemplate('consts');
|
||||
const generateForMetaTemplate = Handlebars.compile(template);
|
||||
@@ -34,12 +34,14 @@ function generateForMeta (meta: Metadata, dest: string, extraTypes: Record<strin
|
||||
const items = constants
|
||||
.sort(compareName)
|
||||
.map(({ documentation, name, type }) => {
|
||||
setImports(allDefs, imports, [type.toString()]);
|
||||
const returnType = formatType(allDefs, type.toString(), imports);
|
||||
|
||||
setImports(allDefs, imports, [returnType]);
|
||||
|
||||
return {
|
||||
docs: documentation,
|
||||
name: stringCamelCase(name.toString()),
|
||||
type: type.toString()
|
||||
type: returnType
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -28,12 +28,12 @@ export function generateInterfaceTypes (importDefinitions: { [importPath: string
|
||||
|
||||
const imports = createImports(importDefinitions);
|
||||
const definitions = imports.definitions;
|
||||
|
||||
const items: string[] = [];
|
||||
|
||||
// first we create imports for our known classes from the API
|
||||
Object
|
||||
.keys(primitiveClasses)
|
||||
.filter((name): boolean => !!name.indexOf('Generic'))
|
||||
.filter((name) => !name.includes('Generic'))
|
||||
.forEach((primitiveName) => {
|
||||
setImports(definitions, imports, [primitiveName]);
|
||||
|
||||
@@ -42,7 +42,14 @@ export function generateInterfaceTypes (importDefinitions: { [importPath: string
|
||||
|
||||
const existingTypes: Record<string, boolean> = {};
|
||||
|
||||
Object.entries(definitions).forEach(([, { types }]) => {
|
||||
// ensure we have everything registered since we will get the definition
|
||||
// form the available types (so any unknown should show after this)
|
||||
Object.values(definitions).forEach(({ types }) => {
|
||||
registry.register(types as Record<string, string>);
|
||||
});
|
||||
|
||||
// create imports for everything that we have available
|
||||
Object.values(definitions).forEach(({ types }) => {
|
||||
setImports(definitions, imports, Object.keys(types));
|
||||
|
||||
const uniqueTypes = Object.keys(types).filter((type) => !existingTypes[type]);
|
||||
|
||||
@@ -19,7 +19,7 @@ import { ModuleTypes } from '../util/imports';
|
||||
// From a storage entry metadata, we return [args, returnType]
|
||||
/** @internal */
|
||||
function entrySignature (allDefs: Record<string, ModuleTypes>, registry: Registry, storageEntry: StorageEntryMetadataLatest, imports: TypeImports): [string, string] {
|
||||
const format = (type: string): string => formatType(allDefs, type, imports);
|
||||
const format = (type: string) => formatType(allDefs, type, imports);
|
||||
const outputType = unwrapStorageType(storageEntry.type, storageEntry.modifier.isOptional);
|
||||
|
||||
if (storageEntry.type.isPlain) {
|
||||
|
||||
@@ -17,11 +17,10 @@ const generateRpcTypesTemplate = Handlebars.compile(template);
|
||||
/** @internal */
|
||||
export function generateRpcTypes (importDefinitions: { [importPath: string]: Record<string, Definitions> }, dest: string): void {
|
||||
writeFile(dest, (): string => {
|
||||
const format = (type: string) => formatType(allDefs, type, imports);
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
const imports = createImports(importDefinitions);
|
||||
const definitions = imports.definitions as Record<string, Definitions>;
|
||||
|
||||
const allDefs = Object.entries(importDefinitions).reduce((defs, [path, obj]) => {
|
||||
return Object.entries(obj).reduce((defs, [key, value]) => ({ ...defs, [`${path}/${key}`]: value }), defs);
|
||||
}, {});
|
||||
@@ -73,7 +72,7 @@ export function generateRpcTypes (importDefinitions: { [importPath: string]: Rec
|
||||
|
||||
setImports(allDefs, imports, [param.type, ...similarTypes]);
|
||||
|
||||
return `${param.name}${param.isOptional ? '?' : ''}: ${similarTypes.join(' | ')}`;
|
||||
return `${param.name}${param.isOptional ? '?' : ''}: ${similarTypes.map(format).join(' | ')}`;
|
||||
});
|
||||
|
||||
type = formatType(allDefs, def.type, imports);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
export function writeFile (dest: string, generator: () => string, noLog?: boolean): void {
|
||||
!noLog && console.log(`${dest}\n\tGenerating`);
|
||||
@@ -19,6 +20,6 @@ export function writeFile (dest: string, generator: () => string, noLog?: boolea
|
||||
!noLog && console.log('');
|
||||
}
|
||||
|
||||
export function readTemplate (path: string): string {
|
||||
return fs.readFileSync(`${__dirname}/../templates/${path}.hbs`).toString();
|
||||
export function readTemplate (template: string): string {
|
||||
return fs.readFileSync(path.join(__dirname, `../templates/${template}.hbs`)).toString();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/types-known",
|
||||
"version": "2.2.1",
|
||||
"version": "2.4.1",
|
||||
"description": "A JavaScript wrapper for the Polkadot JsonRPC interface",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -26,9 +26,9 @@
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/types-known#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@polkadot/types": "2.2.1",
|
||||
"@polkadot/util": "^3.5.1",
|
||||
"@babel/runtime": "^7.12.1",
|
||||
"@polkadot/types": "^2.4.1",
|
||||
"@polkadot/util": "^3.6.1",
|
||||
"bn.js": "^5.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -12,7 +12,6 @@ import typesChain from './chain';
|
||||
import typesModules from './modules';
|
||||
import typesSpec from './spec';
|
||||
import upgrades from './upgrades';
|
||||
import warnings from './warnings';
|
||||
|
||||
// flatten a VersionedType[] into a Record<string, string>
|
||||
/** @internal */
|
||||
@@ -46,15 +45,18 @@ export function getSpecTypes ({ knownTypes }: Registry, chainName: Text | string
|
||||
const _specName = specName.toString();
|
||||
const _specVersion = bnToBn(specVersion).toNumber();
|
||||
|
||||
(warnings[_specName] || []).forEach((warning) => console.warn(`*** ${warning}`));
|
||||
|
||||
// The order here is always, based on -
|
||||
// - spec then chain
|
||||
// - typesBundle takes higher precedence
|
||||
// - types is the final catch-all override
|
||||
return {
|
||||
...filterVersions(typesSpec[_specName], _specVersion),
|
||||
...filterVersions(typesChain[_chainName], _specVersion),
|
||||
...filterVersions(knownTypes.typesBundle?.spec?.[_specName]?.types, _specVersion),
|
||||
...filterVersions(knownTypes.typesBundle?.chain?.[_chainName]?.types, _specVersion),
|
||||
...(knownTypes.typesSpec?.[_specName] || {}),
|
||||
...(knownTypes.typesChain?.[_chainName] || {})
|
||||
...(knownTypes.typesChain?.[_chainName] || {}),
|
||||
...(knownTypes.types || {})
|
||||
};
|
||||
}
|
||||
|
||||
@@ -78,10 +80,11 @@ export function getSpecAlias ({ knownTypes }: Registry, chainName: Text | string
|
||||
const _chainName = chainName.toString();
|
||||
const _specName = specName.toString();
|
||||
|
||||
// as per versions, first spec, then chain then finally non-versioned
|
||||
return {
|
||||
...(knownTypes.typesAlias || {}),
|
||||
...(knownTypes.typesBundle?.spec?.[_specName]?.alias || {}),
|
||||
...(knownTypes.typesBundle?.chain?.[_chainName]?.alias || {})
|
||||
...(knownTypes.typesBundle?.chain?.[_chainName]?.alias || {}),
|
||||
...(knownTypes.typesAlias || {})
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { OverrideVersionedType } from '@polkadot/types/types';
|
||||
|
||||
import centrifugeChain from './centrifuge-chain';
|
||||
import kusama from './kusama';
|
||||
import nodeTemplate from './node-template';
|
||||
import polkadot from './polkadot';
|
||||
import rococo from './rococo';
|
||||
import westend from './westend';
|
||||
@@ -13,6 +14,7 @@ import westend from './westend';
|
||||
const typesSpec: Record<string, OverrideVersionedType[]> = {
|
||||
'centrifuge-chain': centrifugeChain,
|
||||
kusama,
|
||||
'node-template': nodeTemplate,
|
||||
polkadot,
|
||||
rococo,
|
||||
westend
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2017-2020 @polkadot/types-known authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { OverrideVersionedType } from '@polkadot/types/types';
|
||||
|
||||
const versioned: OverrideVersionedType[] = [
|
||||
{
|
||||
minmax: [0, undefined],
|
||||
types: {
|
||||
Address: 'AccountId',
|
||||
LookupSource: 'AccountId'
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
export default versioned;
|
||||
@@ -13,7 +13,7 @@ const upgrades: ChainUpgradesRaw = {
|
||||
[1472960, 1052], [1475648, 1053], [1491596, 1054], [1574408, 1055], [2064961, 1058],
|
||||
[2201991, 1062], [2671528, 2005], [2704202, 2007], [2728002, 2008], [2832534, 2011],
|
||||
[2962294, 2012], [3240000, 2013], [3274408, 2015], [3323565, 2019], [3534175, 2022],
|
||||
[3860281, 2023], [4143129, 2024]
|
||||
[3860281, 2023], [4143129, 2024], [4401242, 2025]
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ const upgrades: ChainUpgradesRaw = {
|
||||
[0, 0], [29231, 1], [188836, 5], [199405, 6], [214264, 7],
|
||||
[244358, 8], [303079, 9], [314201, 10], [342400, 11], [443963, 12],
|
||||
[528470, 13], [687751, 14], [746085, 15], [787923, 16], [799302, 17],
|
||||
[1205128, 18], [1603423, 23], [1733218, 24]
|
||||
[1205128, 18], [1603423, 23], [1733218, 24], [2005673, 25]
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ const upgrades: ChainUpgradesRaw = {
|
||||
[214356, 4], [392764, 7], [409740, 8], [809976, 20], [877581, 24],
|
||||
[879238, 25], [889472, 26], [902937, 27], [932751, 28], [991142, 29],
|
||||
[1030162, 31], [1119657, 32], [1199282, 33], [1342534, 34], [1392263, 35],
|
||||
[1431703, 36], [1433369, 37], [1490972, 41], [2087397, 43], [2316688, 44]
|
||||
[1431703, 36], [1433369, 37], [1490972, 41], [2087397, 43], [2316688, 44],
|
||||
[2549864, 45]
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
// Copyright 2017-2020 @polkadot/types-known authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Type overrides for specific spec types & versions as given in runtimeVersion
|
||||
const warnings: Record<string, string[]> = {
|
||||
'node-template': [
|
||||
'',
|
||||
'You are using the node-template, depending on your config and age of the template, you may',
|
||||
'have some unexpected results without applying the correct config for your node type:',
|
||||
'',
|
||||
'- If you have trouble sending txs, apply https://polkadot.js.org/api/start/FAQ.html#i-cannot-send-transactions-from-my-node-template-based-chain',
|
||||
'- If you have trouble parsing events, apply https://polkadot.js.org/api/start/FAQ.html#using-a-non-current-master-node-i-have-issues-parsing-events',
|
||||
''
|
||||
]
|
||||
};
|
||||
|
||||
export default warnings;
|
||||
@@ -1,66 +1,3 @@
|
||||
# @polkadot/types
|
||||
|
||||
Implementation of the types and their (de-)serialisation via SCALE codec.<br>
|
||||
On the Rust side, the codec types and primitive types are implemented via the [parity-codec](https://github.com/paritytech/parity-codec).
|
||||
|
||||
|
||||
## Codec types
|
||||
|
||||
These are the base types of the codec. They are typically not used directly, but rather inherited from to create specific types. They are the building blocks for declaring custom types:
|
||||
|
||||
| **Types** | |
|
||||
| --- | --- |
|
||||
| [[Compact]] | A compact length-encoding codec wrapper. Mostly used by other types to add length-prefixed encoding |
|
||||
| [[Enum]] | A codec wrapper for an enum. Enums are encoded as a single byte, where the byte is a zero-indexed value |
|
||||
| [[Int]] | A generic signed integer codec |
|
||||
| [[Option]] | An Option is an optional field. The first byte indicates that there is a value to follow |
|
||||
| [[Set]] | An Set is an array of string values, represented an an encoded type by a bitwise representation of the values |
|
||||
| [[Struct]] | A Struct defines an Object with key-value pairs - where the values are Codec values. |
|
||||
| [[Tuple]] | A Tuple defines an anonymous fixed-length array, where each element has its own type |
|
||||
| [[Raw]] | A basic wrapper around Uint8Array. It will consume the full Uint8Array as passed to it |
|
||||
| [[U8aFixed]] | A U8a that manages a a sequence of bytes up to the specified bitLength |
|
||||
| [[UInt]] | A generic unsigned integer codec. It handles the encoding and decoding of Little Endian encoded numbers in Substrate |
|
||||
| [[Vec]] | This manages codec arrays. Internally it keeps track of the length (as decoded) |
|
||||
| [[VecAny]] | This manages codec arrays, assuming that the inputs are already of type Codec |
|
||||
|
||||
|
||||
## Primitive types
|
||||
|
||||
These primitive types are available:
|
||||
|
||||
| **Types** | |
|
||||
| --- | --- |
|
||||
| [[AccountId]] | A wrapper around an AccountId/PublicKey representation |
|
||||
| [[AccountIndex]] | A wrapper around an AccountIndex, which is a shortened, variable-length encoding for an Account |
|
||||
| [[Address]] | A wrapper around an AccountId and/or AccountIndex that is encoded with a prefix |
|
||||
| [[bool]] | Representation for a boolean value in the system |
|
||||
| [[Bytes]] | A Bytes wrapper for `Vec<u8>` |
|
||||
| [[Call]] | Extrinsic function descriptor, as defined in [the extrinsic format for a node](https://github.com/paritytech/wiki/blob/master/Extrinsic.md#the-extrinsic-format-for-node) |
|
||||
| [[Event]] | Wrapper for the actual data that forms part of an [[Event]] |
|
||||
| [[EventRecord]] | A record for an [[Event]] (as specified by [[Metadata]]) with the specific [[Phase]] of application |
|
||||
| [[Extrinsic]] | Representation of an Extrinsic in the system |
|
||||
| [[ExtrinsicEra]] | The era for an extrinsic, indicating either a mortal or immortal extrinsic |
|
||||
| [[ExtrinsicPayload]] | A signing payload for an [[Extrinsic]]. For the final encoding, it is variable length based on the contents included |
|
||||
| [[H160]] | Hash containing 160 bits (20 bytes), typically used in blocks, extrinsics and as a sane default |
|
||||
| [[H256]] | Hash containing 256 bits (32 bytes), typically used in blocks, extrinsics and as a sane default |
|
||||
| [[H512]] | Hash containing 512 bits (64 bytes), typically used for signatures |
|
||||
| [[Hash]] | The default hash that is used accross the system. It is just a thin wrapper around [[H256]]
|
||||
| [[i8]] | An 8-bit signed integer |
|
||||
| [[i16]] | A 16-bit signed integer |
|
||||
| [[i32]] | A 32-bit signed integer |
|
||||
| [[i64]] | A 64-bit signed integer |
|
||||
| [[i128]] | A 128-bit signed integer |
|
||||
| [[i256]] | A 256-bit signed integer |
|
||||
| [[Moment]] | A wrapper around seconds/timestamps. Internally the representation only has second precicion (aligning with Rust) |
|
||||
| [[Null]] | Implements a type that does not contain anything (apart from `null`) |
|
||||
| [[Signature]] | The default signature that is used accross the system |
|
||||
| [[StorageData]] | Data retrieved via Storage queries and data for key-value pairs |
|
||||
| [[StorageKey]] | A representation of a storage key (typically hashed) in the system |
|
||||
| [[Text]] | This is a string wrapper, along with the length. |
|
||||
| [[Type]] | This is a extended version of String, specifically to handle types |
|
||||
| [[u8]] | An 8-bit unsigned integer |
|
||||
| [[u16]] | A 16-bit unsigned integer |
|
||||
| [[u32]] | A 32-bit unsigned integer |
|
||||
| [[u64]] | A 64-bit unsigned integer |
|
||||
| [[u128]] | A 128-bit unsigned integer |
|
||||
| [[u256]] | A 256-bit unsigned integer |
|
||||
Implementation of the types and their (de-)serialisation via SCALE codec. On the Rust side, the codec types and primitive types are implemented via the [parity-codec](https://github.com/paritytech/parity-codec).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/types",
|
||||
"version": "2.2.1",
|
||||
"version": "2.4.1",
|
||||
"description": "Implementation of the Parity codec",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -26,17 +26,17 @@
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/types#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@polkadot/metadata": "2.2.1",
|
||||
"@polkadot/util": "^3.5.1",
|
||||
"@polkadot/util-crypto": "^3.5.1",
|
||||
"@babel/runtime": "^7.12.1",
|
||||
"@polkadot/metadata": "^2.4.1",
|
||||
"@polkadot/util": "^3.6.1",
|
||||
"@polkadot/util-crypto": "^3.6.1",
|
||||
"@types/bn.js": "^4.11.6",
|
||||
"bn.js": "^5.1.3",
|
||||
"memoizee": "^0.4.14",
|
||||
"rxjs": "^6.6.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/keyring": "^3.5.1",
|
||||
"@polkadot/keyring": "^3.6.1",
|
||||
"@types/memoizee": "^0.4.4"
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user