Resolve "feat(Docs): Add BlockchainElectrum Tool"
This commit is contained in:
@@ -207,29 +207,16 @@ export default withMermaid({
|
|||||||
text: 'Stack',
|
text: 'Stack',
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
items: [
|
items: [
|
||||||
/*
|
|
||||||
{
|
{
|
||||||
text: 'Blockchain',
|
text: 'Blockchain',
|
||||||
link: '/tools/stack/blockchain',
|
link: '/tools/stack/blockchain',
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
text: 'Electrum',
|
text: 'Electrum',
|
||||||
link: '/tools/stack/blockchain#encryption',
|
link: '/tools/stack/blockchain#electrum',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
text: 'Utils',
|
|
||||||
link: '/tools/stack/utils',
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
text: 'Encrypter',
|
|
||||||
link: '/tools/stack/utils#encrypter',
|
|
||||||
},
|
|
||||||
{ text: 'Hasher', link: '/tools/stack/utils#hasher' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -75,7 +75,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button type="submit" class="gradient-button" @click="() => executeMethod(state.selectedMethod.callback(state.primitive, state.selectedMethod.models))">Execute Method</button>
|
<button type="submit" class="gradient-button" @click="() => executeMethod(state.selectedMethod?.callback(state.primitive, state.selectedMethod.models))">Execute Method</button>
|
||||||
</div>
|
</div>
|
||||||
<!-- Result -->
|
<!-- Result -->
|
||||||
<div>
|
<div>
|
||||||
@@ -135,7 +135,7 @@ export interface Method<Primitive> {
|
|||||||
error?: string;
|
error?: string;
|
||||||
|
|
||||||
// Function that takes the models and returns the primitive
|
// Function that takes the models and returns the primitive
|
||||||
callback: (primitive: Primitive, value: Array<any>) => string;
|
callback: (primitive: Primitive, value: Array<any>) => string | Promise<string>;
|
||||||
|
|
||||||
// Whether the input is extended onto a new line
|
// Whether the input is extended onto a new line
|
||||||
extendedInput?: boolean
|
extendedInput?: boolean
|
||||||
@@ -185,13 +185,13 @@ const state: Ref<{
|
|||||||
primitive: undefined,
|
primitive: undefined,
|
||||||
})
|
})
|
||||||
|
|
||||||
async function setPrimitive(functionToExecute: () => Primitive | Promise<Primitive>): void {
|
async function setPrimitive(functionToExecute: () => Primitive | Promise<Primitive>): Promise<void> {
|
||||||
try {
|
try {
|
||||||
state.value.primitive = await functionToExecute();
|
state.value.primitive = await functionToExecute();
|
||||||
state.value.error = undefined;
|
state.value.error = undefined;
|
||||||
|
|
||||||
state.value.toFunctions.forEach((wrappedMethod, i) => {
|
state.value.toFunctions.forEach(async (wrappedMethod, i) => {
|
||||||
state.value.toFunctions[i].result = wrappedMethod.callback(state.value.primitive)
|
state.value.toFunctions[i].result = await wrappedMethod.callback(state.value.primitive)
|
||||||
});
|
});
|
||||||
|
|
||||||
state.value.methods.forEach((method, i) => {
|
state.value.methods.forEach((method, i) => {
|
||||||
@@ -218,7 +218,7 @@ function getPrimitive(functionToExecute: () => string): string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function executeMethod(wrappedMethod: () => string | Promise<string>): string {
|
async function executeMethod(wrappedMethod: () => string | Promise<string>): Promise<void | string> {
|
||||||
try {
|
try {
|
||||||
if(!state.value.primitive) {
|
if(!state.value.primitive) {
|
||||||
return '';
|
return '';
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import { BlockchainElectrum, encodeExtendedJson, Transaction } from '@xocash/stack';
|
||||||
|
|
||||||
|
export const electrumClient = {
|
||||||
|
from: [
|
||||||
|
{
|
||||||
|
label: 'From Servers',
|
||||||
|
inputs: ['Servers'],
|
||||||
|
models: ['bch.imaginary.cash, cashnode.bch.ninja, electrum.imaginary.cash'],
|
||||||
|
callback: async (args: [string]) => {
|
||||||
|
const electrum = await BlockchainElectrum.from({
|
||||||
|
opts: {
|
||||||
|
servers: args[0].replaceAll(' ', '').split(','),
|
||||||
|
application: 'XO-tools',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return electrum;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
to: [],
|
||||||
|
methods: [
|
||||||
|
{
|
||||||
|
label: 'Fetch Unspents',
|
||||||
|
inputs: ['Address'],
|
||||||
|
models: ['Address'],
|
||||||
|
callback: async (electrum: BlockchainElectrum, args: [string]) => {
|
||||||
|
const unspents = await electrum.fetchUnspents(args[0]);
|
||||||
|
return encodeExtendedJson(unspents.toArray(), 2);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Fetch Transaction',
|
||||||
|
inputs: ['Transaction Hash'],
|
||||||
|
models: ['Transaction Hash'],
|
||||||
|
callback: async (electrum: BlockchainElectrum, args: [string]) => {
|
||||||
|
const transaction = await electrum.fetchTransaction(args[0]);
|
||||||
|
return encodeExtendedJson(transaction, 2);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Fetch Transactions',
|
||||||
|
inputs: ['Address'],
|
||||||
|
models: ['Address'],
|
||||||
|
callback: async (electrum: BlockchainElectrum, args: [string]) => {
|
||||||
|
const transactions = await electrum.fetchTransactions(args[0]);
|
||||||
|
return encodeExtendedJson(transactions.toArray(), 2);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Broadcast Transaction',
|
||||||
|
inputs: ['Transaction'],
|
||||||
|
models: ['Transaction'],
|
||||||
|
callback: async (electrum: BlockchainElectrum, args: [string]) => {
|
||||||
|
const tx = Transaction.from(args[0]);
|
||||||
|
return await electrum.broadcastTransaction(tx);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
aside: false
|
||||||
|
---
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import PrimitiveToolVue, { type FromFunction, type ToFunction } from '@theme/components/PrimitiveTool.vue'
|
||||||
|
|
||||||
|
// Import our tool functions
|
||||||
|
import {
|
||||||
|
electrumClient,
|
||||||
|
} from './blockchain-functions.ts'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Resume Markdown parsing -->
|
||||||
|
|
||||||
|
# Blockchain
|
||||||
|
|
||||||
|
## Electrum Client
|
||||||
|
|
||||||
|
<div class="tool">
|
||||||
|
<p>A connection to Electrum servers.</p>
|
||||||
|
<p>Mutliple servers can be provided, and the client will attempt to fallback to the next server in case of failure.</p>
|
||||||
|
<p>Servers can be provided as a comma separated list.</p>
|
||||||
|
|
||||||
|
<PrimitiveToolVue
|
||||||
|
:fromFunctions="electrumClient.from"
|
||||||
|
:toFunctions="electrumClient.to"
|
||||||
|
:methods="electrumClient.methods"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
@@ -48,6 +48,11 @@ export type BlockchainElectrumOpts = {
|
|||||||
application: string;
|
application: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type BlockchainElectrumParams = {
|
||||||
|
store?: BaseStore;
|
||||||
|
opts?: Partial<BlockchainElectrumOpts>;
|
||||||
|
};
|
||||||
|
|
||||||
export class BlockchainElectrum extends BaseBlockchain {
|
export class BlockchainElectrum extends BaseBlockchain {
|
||||||
// Composables.
|
// Composables.
|
||||||
electrumClient!: ElectrumClient<ElectrumProtocolEvents>;
|
electrumClient!: ElectrumClient<ElectrumProtocolEvents>;
|
||||||
@@ -60,18 +65,43 @@ export class BlockchainElectrum extends BaseBlockchain {
|
|||||||
addressSubscriptions: Map<string, Set<AddressCallback>> = new Map();
|
addressSubscriptions: Map<string, Set<AddressCallback>> = new Map();
|
||||||
transactionSubscriptions: Map<string, Set<TransactionCallback>> = new Map();
|
transactionSubscriptions: Map<string, Set<TransactionCallback>> = new Map();
|
||||||
|
|
||||||
|
// Options
|
||||||
|
store: BaseStore;
|
||||||
|
opts: BlockchainElectrumOpts;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public readonly store: BaseStore = new StoreInMemory(),
|
public readonly params: BlockchainElectrumParams = {},
|
||||||
public readonly opts: BlockchainElectrumOpts = {
|
) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// Set the store, or use the memory store by default.
|
||||||
|
this.store = params.store ?? new StoreInMemory();
|
||||||
|
|
||||||
|
// Combine provided options with default options.
|
||||||
|
this.opts = {
|
||||||
servers: [
|
servers: [
|
||||||
'bch.imaginary.cash',
|
'bch.imaginary.cash',
|
||||||
'cashnode.bch.ninja',
|
'cashnode.bch.ninja',
|
||||||
'electrum.imaginary.cash',
|
'electrum.imaginary.cash',
|
||||||
],
|
],
|
||||||
application: 'XOApp',
|
application: 'XOApp',
|
||||||
},
|
...params.opts,
|
||||||
) {
|
};
|
||||||
super();
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new BlockchainElectrum instance.
|
||||||
|
* @param {BlockchainElectrumParams} params - The parameters for the BlockchainElectrum instance.
|
||||||
|
* @returns {BlockchainElectrum} A new BlockchainElectrum instance.
|
||||||
|
*/
|
||||||
|
static async from(
|
||||||
|
params: BlockchainElectrumParams = {},
|
||||||
|
): Promise<BlockchainElectrum> {
|
||||||
|
const blockchain = new BlockchainElectrum(params);
|
||||||
|
|
||||||
|
await blockchain.start();
|
||||||
|
|
||||||
|
return blockchain;
|
||||||
}
|
}
|
||||||
|
|
||||||
async start() {
|
async start() {
|
||||||
|
|||||||
Reference in New Issue
Block a user