-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Rebase * requested changes * multisig preparation * multi sig functionality * refactor * Update tests.yml Remove duplicate entry * signing test with multisig implementation * completed multisig implementation * remove multisig from polkadart_keyring * formatting * fix errors * important changes * formatting and few changes * bug fix * docs improvement * change docs * improve example * change keypair in example * improve docs and example --------- Co-authored-by: Leonardo Custodio <[email protected]>
- Loading branch information
1 parent
bed5df8
commit 017cb28
Showing
41 changed files
with
1,525 additions
and
177 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import 'package:polkadart/multisig/multisig_base.dart'; | ||
import 'package:polkadart/polkadart.dart'; | ||
import 'package:polkadart_keyring/polkadart_keyring.dart' as keyring; | ||
|
||
void main() async { | ||
// | ||
// Signatories: keypairS1, keypairS2, keypairS3 | ||
final keypairS1 = await keyring.KeyPair.sr25519.fromUri('//keypairS1'); | ||
keypairS1.ss58Format = 42; | ||
|
||
final keypairS2 = await keyring.KeyPair.sr25519.fromUri('//keypairS2'); | ||
keypairS2.ss58Format = 42; | ||
|
||
final keypairS3 = await keyring.KeyPair.sr25519.fromUri('//keypairS3'); | ||
keypairS3.ss58Format = 42; | ||
|
||
// Recipient: keypairR | ||
final keypairR = await keyring.KeyPair.sr25519.fromUri('//keypairR'); | ||
keypairR.ss58Format = 42; | ||
|
||
final provider = Provider.fromUri(Uri.parse('wss://westend-rpc.polkadot.io')); | ||
|
||
/// | ||
/// Create and Fund Multisig | ||
final multiSigResponse = await Multisig.createAndFundMultisig( | ||
depositorKeyPair: keypairS1, | ||
otherSignatoriesAddressList: [keypairS2.address, keypairS3.address], | ||
threshold: 2, | ||
recipientAddress: keypairR.address, | ||
amount: BigInt.parse('711${'0' * 10}'), // 7.11 WND | ||
provider: provider, | ||
); | ||
|
||
// Json for forwarding to other signatories. | ||
final json = multiSigResponse.toJson(); | ||
|
||
{ | ||
// Assuming keypairS2 is the first signatory who is approving. | ||
final localResponse = MultisigResponse.fromJson(json); | ||
// Approve this call by keypairS2 and forward for further approval. | ||
await Future.delayed(Duration(seconds: 15)); | ||
await localResponse.approveAsMulti(provider, keypairS2); | ||
} | ||
|
||
/** | ||
* Although keypairS3 can call `approveAsMulti` to approve this call which will then | ||
* wait for `keypairS1` to approve via `asMulti` call. | ||
* | ||
* In this case: | ||
* The last signatory (`keypairS1`) will not be able to call `approveAsMulti` as it will throw FinalApprovalException. | ||
* | ||
* So, `keypairS1` will have to call `asMulti` to approve this call. | ||
*/ | ||
|
||
{ | ||
// Assuming keypairS3 is the second signatory who is approving. | ||
final localResponse = MultisigResponse.fromJson(json); | ||
// Execute this call by keypairS3 approval. | ||
await Future.delayed(Duration(seconds: 15)); | ||
await localResponse.asMulti(provider, keypairS3); | ||
} | ||
|
||
// // Cancel this call by keypairS1 | ||
// | ||
// final localResponse = MultisigResponse.fromJson(json); | ||
// | ||
// // Cancel this call by keypairS1 | ||
// await Future.delayed(Duration(seconds: 15)); | ||
// await multiSigResponse.cancelAsMulti(provider, keypairS1); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
part of apis; | ||
|
||
/// Substrate chain API | ||
class ChainApi<P extends Provider> { | ||
final P _provider; | ||
|
||
ChainApi(this._provider); | ||
|
||
/// Returns the BlockHash for the given block number. | ||
/// | ||
/// If no block number is provided, it will return the hash of the latest block at chain height. | ||
Future<BlockHash> getBlockHash({int? blockNumber}) async { | ||
final List<dynamic> params = <dynamic>[]; | ||
if (blockNumber != null) { | ||
params.add(blockNumber); | ||
} | ||
|
||
final response = await _provider.send('chain_getBlockHash', params); | ||
|
||
if (response.error != null) { | ||
throw Exception(response.error.toString()); | ||
} | ||
|
||
return Uint8List.fromList( | ||
hex.decode((response.result as String).substring(2))); | ||
} | ||
|
||
/// Get the latest block number or specific block number by BlockHash. | ||
Future<int> getChainHeader({BlockHash? at}) async { | ||
final List<String> params = <String>[]; | ||
if (at != null) { | ||
params.add('0x${hex.encode(at)}'); | ||
} | ||
final response = await _provider.send('chain_getHeader', params); | ||
|
||
if (response.error != null) { | ||
throw Exception(response.error.toString()); | ||
} | ||
return int.parse(response.result['number']!); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import 'dart:typed_data'; | ||
|
||
abstract class Payload { | ||
final Uint8List method; // Call | ||
final int blockNumber; | ||
final int eraPeriod; // CheckMortality | ||
final int nonce; // CheckNonce | ||
final dynamic tip; // ChargeTransactionPayment | ||
final int? assetId; // ChargeAssetTxPayment | ||
|
||
const Payload({ | ||
required this.method, | ||
required this.blockNumber, | ||
required this.eraPeriod, | ||
required this.nonce, | ||
required this.tip, | ||
this.assetId, | ||
}); | ||
|
||
toEncodedMap(dynamic registry); | ||
|
||
bool usesChargeAssetTxPayment(dynamic registry) { | ||
if (registry.getSignedExtensionTypes() is Map) { | ||
return (registry.getSignedExtensionTypes() as Map) | ||
.containsKey('ChargeAssetTxPayment'); | ||
} | ||
return (registry.getSignedExtensionTypes() as List) | ||
.contains('ChargeAssetTxPayment'); | ||
} | ||
|
||
String maybeAssetIdEncoded(dynamic registry) { | ||
if (usesChargeAssetTxPayment(registry)) { | ||
// '00' and '01' refer to rust's Option variants 'None' and 'Some'. | ||
return assetId != null ? '01${assetId!.toRadixString(16)}' : '00'; | ||
} else { | ||
return ''; | ||
} | ||
} | ||
} |
Oops, something went wrong.