cashscript 0.13.0-next.2 → 0.13.0-next.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Contract.d.ts +16 -8
- package/dist/Contract.js +23 -13
- package/dist/interfaces.d.ts +4 -2
- package/dist/libauth-template/LibauthTemplate.js +1 -1
- package/dist/network/BitcoinRpcNetworkProvider.d.ts +1 -0
- package/dist/network/BitcoinRpcNetworkProvider.js +3 -0
- package/dist/network/ElectrumNetworkProvider.d.ts +1 -0
- package/dist/network/ElectrumNetworkProvider.js +13 -19
- package/dist/network/FullStackNetworkProvider.d.ts +1 -0
- package/dist/network/FullStackNetworkProvider.js +3 -0
- package/dist/network/MockNetworkProvider.d.ts +1 -0
- package/dist/network/MockNetworkProvider.js +6 -2
- package/dist/network/NetworkProvider.d.ts +6 -0
- package/dist/utils.d.ts +3 -3
- package/dist/utils.js +7 -5
- package/dist/walletconnect-utils.js +2 -3
- package/package.json +3 -3
package/dist/Contract.d.ts
CHANGED
|
@@ -1,30 +1,38 @@
|
|
|
1
|
-
import { Artifact
|
|
1
|
+
import { Artifact } from '@cashscript/utils';
|
|
2
2
|
import { ConstructorArgument } from './Argument.js';
|
|
3
|
-
import { Unlocker, ContractOptions, Utxo,
|
|
3
|
+
import { Unlocker, ContractOptions, Utxo, ContractType } from './interfaces.js';
|
|
4
4
|
import NetworkProvider from './network/NetworkProvider.js';
|
|
5
5
|
import { ParamsToTuple, AbiToFunctionMap } from './types/type-inference.js';
|
|
6
|
-
|
|
6
|
+
type ResolvedConstraint = {
|
|
7
7
|
constructorInputs: ConstructorArgument[];
|
|
8
8
|
unlock: Record<string, any>;
|
|
9
|
-
}
|
|
9
|
+
};
|
|
10
|
+
type DefaultResolved<TArtifact extends Artifact> = {
|
|
10
11
|
constructorInputs: ParamsToTuple<TArtifact['constructorInputs']>;
|
|
11
12
|
unlock: AbiToFunctionMap<TArtifact['abi'], Unlocker>;
|
|
12
|
-
}
|
|
13
|
+
};
|
|
14
|
+
declare class ContractInternal<TArtifact extends Artifact, TResolved extends ResolvedConstraint, TContractType extends ContractType> {
|
|
13
15
|
artifact: TArtifact;
|
|
14
16
|
private options;
|
|
15
17
|
name: string;
|
|
16
18
|
address: string;
|
|
17
19
|
tokenAddress: string;
|
|
20
|
+
lockingBytecode: string;
|
|
18
21
|
bytecode: string;
|
|
19
22
|
bytesize: number;
|
|
20
23
|
opcount: number;
|
|
21
24
|
unlock: TResolved['unlock'];
|
|
22
|
-
redeemScript: Script;
|
|
23
25
|
provider: NetworkProvider;
|
|
24
|
-
|
|
26
|
+
contractType: TContractType;
|
|
25
27
|
encodedConstructorArgs: Uint8Array[];
|
|
26
|
-
constructor(artifact: TArtifact, constructorArgs: TResolved['constructorInputs'], options: ContractOptions);
|
|
28
|
+
constructor(artifact: TArtifact, constructorArgs: TResolved['constructorInputs'], options: ContractOptions<TContractType>);
|
|
27
29
|
getBalance(): Promise<bigint>;
|
|
28
30
|
getUtxos(): Promise<Utxo[]>;
|
|
29
31
|
private createUnlocker;
|
|
30
32
|
}
|
|
33
|
+
export type Contract<TArtifact extends Artifact = Artifact, TResolved extends ResolvedConstraint = DefaultResolved<TArtifact>, TContractType extends ContractType = ContractType> = [TContractType] extends ['p2s'] ? Omit<ContractInternal<TArtifact, TResolved, TContractType>, 'address' | 'tokenAddress'> : ContractInternal<TArtifact, TResolved, TContractType>;
|
|
34
|
+
interface ContractConstructor {
|
|
35
|
+
new <TArtifact extends Artifact = Artifact, TResolved extends ResolvedConstraint = DefaultResolved<TArtifact>, TContractType extends ContractType = 'p2sh32'>(artifact: TArtifact, constructorArgs: TResolved['constructorInputs'], options: ContractOptions<TContractType>): Contract<TArtifact, TResolved, TContractType>;
|
|
36
|
+
}
|
|
37
|
+
export declare const Contract: ContractConstructor;
|
|
38
|
+
export {};
|
package/dist/Contract.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import { binToHex } from '@bitauth/libauth';
|
|
2
|
-
import { asmToScript, calculateBytesize, countOpcodes,
|
|
1
|
+
import { binToHex, hexToBin } from '@bitauth/libauth';
|
|
2
|
+
import { asmToScript, calculateBytesize, countOpcodes, generateContractBytecodeScript, hash256, scriptToBytecode, } from '@cashscript/utils';
|
|
3
3
|
import { encodeFunctionArgument, encodeConstructorArguments, } from './Argument.js';
|
|
4
|
-
import { addressToLockScript,
|
|
4
|
+
import { addressToLockScript, createUnlockingBytecode, createSighashPreimage, scriptToAddress, } from './utils.js';
|
|
5
5
|
import SignatureTemplate from './SignatureTemplate.js';
|
|
6
6
|
import semver from 'semver';
|
|
7
|
-
|
|
7
|
+
class ContractInternal {
|
|
8
8
|
constructor(artifact, constructorArgs, options) {
|
|
9
9
|
this.artifact = artifact;
|
|
10
10
|
this.options = options;
|
|
11
11
|
this.provider = this.options.provider;
|
|
12
|
-
|
|
12
|
+
// Note: technically, it is possible to instantiate a Contract like this, which breaks the type safety,
|
|
13
|
+
// but it seems unreasonable for anyone to do this
|
|
14
|
+
// new Contract<any, any, 'p2s'>(artifact), [], { provider })
|
|
15
|
+
this.contractType = this.options.contractType ?? 'p2sh32';
|
|
13
16
|
const expectedProperties = ['abi', 'bytecode', 'constructorInputs', 'contractName', 'compiler'];
|
|
14
17
|
if (!expectedProperties.every((property) => property in artifact)) {
|
|
15
18
|
throw new Error('Invalid or incomplete artifact provided');
|
|
@@ -22,7 +25,6 @@ export class Contract {
|
|
|
22
25
|
}
|
|
23
26
|
// Encode arguments (this also performs type checking)
|
|
24
27
|
this.encodedConstructorArgs = encodeConstructorArguments(artifact, constructorArgs);
|
|
25
|
-
this.redeemScript = generateRedeemScript(asmToScript(this.artifact.bytecode), this.encodedConstructorArgs);
|
|
26
28
|
// Populate the 'unlock' object with the contract's functions
|
|
27
29
|
// (with a special case for single function, which has no "function selector")
|
|
28
30
|
this.unlock = {};
|
|
@@ -37,18 +39,25 @@ export class Contract {
|
|
|
37
39
|
this.unlock[f.name] = this.createUnlocker(f, i);
|
|
38
40
|
});
|
|
39
41
|
}
|
|
42
|
+
const contractBytecodeScript = generateContractBytecodeScript(asmToScript(this.artifact.bytecode), this.encodedConstructorArgs);
|
|
43
|
+
if (this.contractType !== 'p2s') {
|
|
44
|
+
this.address = scriptToAddress(contractBytecodeScript, this.provider.network, this.contractType, false);
|
|
45
|
+
this.tokenAddress = scriptToAddress(contractBytecodeScript, this.provider.network, this.contractType, true);
|
|
46
|
+
}
|
|
40
47
|
this.name = artifact.contractName;
|
|
41
|
-
this.
|
|
42
|
-
this.
|
|
43
|
-
this.
|
|
44
|
-
this.
|
|
45
|
-
this.opcount = countOpcodes(this.redeemScript);
|
|
48
|
+
this.bytecode = binToHex(scriptToBytecode(contractBytecodeScript));
|
|
49
|
+
this.lockingBytecode = this.contractType === 'p2s' ? this.bytecode : binToHex(addressToLockScript(this.address));
|
|
50
|
+
this.bytesize = calculateBytesize(contractBytecodeScript);
|
|
51
|
+
this.opcount = countOpcodes(contractBytecodeScript);
|
|
46
52
|
}
|
|
47
53
|
async getBalance() {
|
|
48
54
|
const utxos = await this.getUtxos();
|
|
49
55
|
return utxos.reduce((acc, utxo) => acc + utxo.satoshis, 0n);
|
|
50
56
|
}
|
|
51
57
|
async getUtxos() {
|
|
58
|
+
if (this.contractType === 'p2s') {
|
|
59
|
+
return this.provider.getUtxosForLockingBytecode(this.bytecode);
|
|
60
|
+
}
|
|
52
61
|
return this.provider.getUtxos(this.address);
|
|
53
62
|
}
|
|
54
63
|
createUnlocker(abiFunction, selector) {
|
|
@@ -56,7 +65,7 @@ export class Contract {
|
|
|
56
65
|
if (abiFunction.inputs.length !== args.length) {
|
|
57
66
|
throw new Error(`Incorrect number of arguments passed to function ${abiFunction.name}. Expected ${abiFunction.inputs.length} arguments (${abiFunction.inputs.map((input) => input.type)}) but got ${args.length}`);
|
|
58
67
|
}
|
|
59
|
-
const bytecode =
|
|
68
|
+
const bytecode = hexToBin(this.bytecode);
|
|
60
69
|
const encodedArgs = args
|
|
61
70
|
.map((arg, i) => encodeFunctionArgument(arg, abiFunction.inputs[i].type));
|
|
62
71
|
const generateUnlockingBytecode = ({ transaction, sourceOutputs, inputIndex }) => {
|
|
@@ -68,7 +77,7 @@ export class Contract {
|
|
|
68
77
|
const sighash = hash256(preimage);
|
|
69
78
|
return arg.generateSignature(sighash);
|
|
70
79
|
});
|
|
71
|
-
const unlockingBytecode =
|
|
80
|
+
const unlockingBytecode = createUnlockingBytecode(this.contractType, hexToBin(this.bytecode), completeArgs, selector);
|
|
72
81
|
return unlockingBytecode;
|
|
73
82
|
};
|
|
74
83
|
const generateLockingBytecode = () => addressToLockScript(this.address);
|
|
@@ -76,4 +85,5 @@ export class Contract {
|
|
|
76
85
|
};
|
|
77
86
|
}
|
|
78
87
|
}
|
|
88
|
+
export const Contract = ContractInternal;
|
|
79
89
|
//# sourceMappingURL=Contract.js.map
|
package/dist/interfaces.d.ts
CHANGED
|
@@ -43,6 +43,7 @@ export type StandardUnlocker = ContractUnlocker | P2PKHUnlocker;
|
|
|
43
43
|
export type PlaceholderP2PKHUnlocker = Unlocker & {
|
|
44
44
|
placeholder: true;
|
|
45
45
|
};
|
|
46
|
+
export type ContractFunctionUnlocker = (...args: FunctionArgument[]) => ContractUnlocker;
|
|
46
47
|
export declare function isContractUnlocker(unlocker: Unlocker): unlocker is ContractUnlocker;
|
|
47
48
|
export declare function isP2PKHUnlocker(unlocker: Unlocker): unlocker is P2PKHUnlocker;
|
|
48
49
|
export declare function isStandardUnlocker(unlocker: Unlocker): unlocker is StandardUnlocker;
|
|
@@ -114,9 +115,10 @@ export interface TransactionDetails extends Transaction {
|
|
|
114
115
|
txid: string;
|
|
115
116
|
hex: string;
|
|
116
117
|
}
|
|
117
|
-
export interface ContractOptions {
|
|
118
|
+
export interface ContractOptions<TContractType extends ContractType = ContractType> {
|
|
118
119
|
provider: NetworkProvider;
|
|
119
|
-
|
|
120
|
+
contractType?: TContractType;
|
|
120
121
|
}
|
|
122
|
+
export type ContractType = 'p2sh20' | 'p2sh32' | 'p2s';
|
|
121
123
|
export type AddressType = 'p2sh20' | 'p2sh32';
|
|
122
124
|
export type VmResourceUsage = AuthenticationProgramStateResourceLimits['metrics'];
|
|
@@ -180,7 +180,7 @@ const generateTemplateScriptsP2SH = (contract, abiFunction, encodedFunctionArgs,
|
|
|
180
180
|
};
|
|
181
181
|
const generateTemplateLockScript = (contract, constructorArguments) => {
|
|
182
182
|
return {
|
|
183
|
-
lockingType: contract.
|
|
183
|
+
lockingType: contract.contractType === 'p2s' ? 'standard' : contract.contractType,
|
|
184
184
|
name: contract.artifact.contractName,
|
|
185
185
|
script: [
|
|
186
186
|
`// "${contract.artifact.contractName}" contract constructor parameters`,
|
|
@@ -9,6 +9,7 @@ export default class BitcoinRpcNetworkProvider implements NetworkProvider {
|
|
|
9
9
|
rpcPassword: string;
|
|
10
10
|
});
|
|
11
11
|
getUtxos(address: string): Promise<Utxo[]>;
|
|
12
|
+
getUtxosForLockingBytecode(_lockingBytecode: Uint8Array | string): Promise<Utxo[]>;
|
|
12
13
|
getBlockHeight(): Promise<number>;
|
|
13
14
|
getRawTransaction(txid: string): Promise<string>;
|
|
14
15
|
sendRawTransaction(txHex: string): Promise<string>;
|
|
@@ -13,6 +13,9 @@ export default class BitcoinRpcNetworkProvider {
|
|
|
13
13
|
}));
|
|
14
14
|
return utxos;
|
|
15
15
|
}
|
|
16
|
+
async getUtxosForLockingBytecode(_lockingBytecode) {
|
|
17
|
+
throw new Error('BitcoinRpcNetworkProvider does not support getUtxosForLockingBytecode');
|
|
18
|
+
}
|
|
16
19
|
async getBlockHeight() {
|
|
17
20
|
return this.rpcClient.request('getblockcount');
|
|
18
21
|
}
|
|
@@ -20,6 +20,7 @@ export default class ElectrumNetworkProvider implements NetworkProvider {
|
|
|
20
20
|
private instantiateElectrumClient;
|
|
21
21
|
private getServerForNetwork;
|
|
22
22
|
getUtxos(address: string): Promise<Utxo[]>;
|
|
23
|
+
getUtxosForLockingBytecode(lockingBytecode: Uint8Array | string): Promise<Utxo[]>;
|
|
23
24
|
getBlockHeight(): Promise<number>;
|
|
24
25
|
getRawTransaction(txid: string): Promise<string>;
|
|
25
26
|
sendRawTransaction(txHex: string): Promise<string>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { binToHex } from '@bitauth/libauth';
|
|
1
|
+
import { binToHex, hexToBin, isHex } from '@bitauth/libauth';
|
|
2
2
|
import { sha256 } from '@cashscript/utils';
|
|
3
3
|
import { ElectrumClient, } from '@electrum-cash/network';
|
|
4
4
|
import { Network } from '../interfaces.js';
|
|
@@ -32,9 +32,17 @@ export default class ElectrumNetworkProvider {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
async getUtxos(address) {
|
|
35
|
-
const
|
|
35
|
+
const lockingBytecode = addressToLockScript(address);
|
|
36
|
+
return this.getUtxosForLockingBytecode(lockingBytecode);
|
|
37
|
+
}
|
|
38
|
+
async getUtxosForLockingBytecode(lockingBytecode) {
|
|
39
|
+
if (typeof lockingBytecode === 'string' && !isHex(lockingBytecode)) {
|
|
40
|
+
throw new Error(`Invalid locking bytecode: ${lockingBytecode} is not a valid hex string`);
|
|
41
|
+
}
|
|
42
|
+
const lockingBytecodeBin = typeof lockingBytecode === 'string' ? hexToBin(lockingBytecode) : lockingBytecode;
|
|
43
|
+
const scriptHash = lockingBytecodeToElectrumScriptHash(lockingBytecodeBin);
|
|
36
44
|
const filteringOption = 'include_tokens';
|
|
37
|
-
const result = await this.performRequest('blockchain.scripthash.listunspent',
|
|
45
|
+
const result = await this.performRequest('blockchain.scripthash.listunspent', scriptHash, filteringOption);
|
|
38
46
|
const utxos = result.map((utxo) => ({
|
|
39
47
|
txid: utxo.tx_hash,
|
|
40
48
|
vout: utxo.tx_pos,
|
|
@@ -105,23 +113,9 @@ export default class ElectrumNetworkProvider {
|
|
|
105
113
|
return true;
|
|
106
114
|
}
|
|
107
115
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
* This is necessary to support electrum versions lower than 1.4.3, which do not
|
|
111
|
-
* support addresses, only script hashes.
|
|
112
|
-
*
|
|
113
|
-
* @param address Address to convert to an electrum scripthash
|
|
114
|
-
*
|
|
115
|
-
* @returns The corresponding script hash in an electrum-cash compatible format
|
|
116
|
-
*/
|
|
117
|
-
function addressToElectrumScriptHash(address) {
|
|
118
|
-
// Retrieve locking script
|
|
119
|
-
const lockScript = addressToLockScript(address);
|
|
120
|
-
// Hash locking script
|
|
121
|
-
const scriptHash = sha256(lockScript);
|
|
122
|
-
// Reverse scripthash
|
|
116
|
+
function lockingBytecodeToElectrumScriptHash(lockingBytecode) {
|
|
117
|
+
const scriptHash = sha256(lockingBytecode);
|
|
123
118
|
scriptHash.reverse();
|
|
124
|
-
// Return scripthash as a hex string
|
|
125
119
|
return binToHex(scriptHash);
|
|
126
120
|
}
|
|
127
121
|
//# sourceMappingURL=ElectrumNetworkProvider.js.map
|
|
@@ -13,6 +13,7 @@ export default class FullStackNetworkProvider implements NetworkProvider {
|
|
|
13
13
|
*/
|
|
14
14
|
constructor(network: Network, bchjs: BCHJS);
|
|
15
15
|
getUtxos(address: string): Promise<Utxo[]>;
|
|
16
|
+
getUtxosForLockingBytecode(_lockingBytecode: Uint8Array | string): Promise<Utxo[]>;
|
|
16
17
|
getBlockHeight(): Promise<number>;
|
|
17
18
|
getRawTransaction(txid: string): Promise<string>;
|
|
18
19
|
sendRawTransaction(txHex: string): Promise<string>;
|
|
@@ -20,6 +20,9 @@ export default class FullStackNetworkProvider {
|
|
|
20
20
|
}));
|
|
21
21
|
return utxos;
|
|
22
22
|
}
|
|
23
|
+
async getUtxosForLockingBytecode(_lockingBytecode) {
|
|
24
|
+
throw new Error('FullStackNetworkProvider does not support getUtxosForLockingBytecode');
|
|
25
|
+
}
|
|
23
26
|
async getBlockHeight() {
|
|
24
27
|
return this.bchjs.Blockchain.getBlockCount();
|
|
25
28
|
}
|
|
@@ -13,6 +13,7 @@ export default class MockNetworkProvider implements NetworkProvider {
|
|
|
13
13
|
vmTarget: VmTarget;
|
|
14
14
|
constructor(options?: Partial<MockNetworkProviderOptions>);
|
|
15
15
|
getUtxos(address: string): Promise<Utxo[]>;
|
|
16
|
+
getUtxosForLockingBytecode(lockingBytecode: Uint8Array | string): Promise<Utxo[]>;
|
|
16
17
|
setBlockHeight(newBlockHeight: number): void;
|
|
17
18
|
getBlockHeight(): Promise<number>;
|
|
18
19
|
getRawTransaction(txid: string): Promise<string>;
|
|
@@ -14,8 +14,12 @@ export default class MockNetworkProvider {
|
|
|
14
14
|
this.vmTarget = this.options.vmTarget ?? DEFAULT_VM_TARGET;
|
|
15
15
|
}
|
|
16
16
|
async getUtxos(address) {
|
|
17
|
-
const addressLockingBytecode =
|
|
18
|
-
return this.
|
|
17
|
+
const addressLockingBytecode = addressToLockScript(address);
|
|
18
|
+
return this.getUtxosForLockingBytecode(addressLockingBytecode);
|
|
19
|
+
}
|
|
20
|
+
async getUtxosForLockingBytecode(lockingBytecode) {
|
|
21
|
+
const lockingBytecodeHex = typeof lockingBytecode === 'string' ? lockingBytecode : binToHex(lockingBytecode);
|
|
22
|
+
return this.utxoSet.filter(([key]) => key === lockingBytecodeHex).map(([, utxo]) => utxo);
|
|
19
23
|
}
|
|
20
24
|
setBlockHeight(newBlockHeight) {
|
|
21
25
|
this.blockHeight = newBlockHeight;
|
|
@@ -10,6 +10,12 @@ export default interface NetworkProvider {
|
|
|
10
10
|
* @returns List of UTXOs spendable by the provided address.
|
|
11
11
|
*/
|
|
12
12
|
getUtxos(address: string): Promise<Utxo[]>;
|
|
13
|
+
/**
|
|
14
|
+
* Retrieve all UTXOs (confirmed and unconfirmed) for a given locking bytecode.
|
|
15
|
+
* @param lockingBytecode The locking bytecode for which we wish to retrieve UTXOs.
|
|
16
|
+
* @returns List of UTXOs spendable by the provided locking bytecode.
|
|
17
|
+
*/
|
|
18
|
+
getUtxosForLockingBytecode(lockingBytecode: Uint8Array | string): Promise<Utxo[]>;
|
|
13
19
|
/**
|
|
14
20
|
* @returns The current block height.
|
|
15
21
|
*/
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Transaction } from '@bitauth/libauth';
|
|
2
2
|
import { Script } from '@cashscript/utils';
|
|
3
|
-
import { Utxo, Output, LibauthOutput, TokenDetails, AddressType, UnlockableUtxo, LibauthTokenDetails } from './interfaces.js';
|
|
3
|
+
import { Utxo, Output, LibauthOutput, TokenDetails, AddressType, UnlockableUtxo, LibauthTokenDetails, ContractType } from './interfaces.js';
|
|
4
4
|
export declare function validateInput(utxo: Utxo): void;
|
|
5
5
|
export declare function validateOutput(output: Output): void;
|
|
6
6
|
export declare function calculateDust(output: Output): number;
|
|
@@ -12,12 +12,12 @@ export declare function libauthTokenDetailsToCashScriptTokenDetails(token: Libau
|
|
|
12
12
|
export declare function generateLibauthSourceOutputs(inputs: UnlockableUtxo[]): LibauthOutput[];
|
|
13
13
|
export declare function getInputSize(inputScript: Uint8Array): number;
|
|
14
14
|
export declare function getTxSizeWithoutInputs(outputs: Output[]): number;
|
|
15
|
-
export declare function
|
|
15
|
+
export declare function createUnlockingBytecode(contractType: ContractType, contractBytecode: Uint8Array, encodedArgs: Uint8Array[], selector?: number): Uint8Array;
|
|
16
16
|
export declare function createOpReturnOutput(opReturnData: string[]): Output;
|
|
17
17
|
export declare function createSighashPreimage(transaction: Transaction, sourceOutputs: LibauthOutput[], inputIndex: number, coveredBytecode: Uint8Array, hashtype: number): Uint8Array;
|
|
18
18
|
export declare function toRegExp(reasons: string[]): RegExp;
|
|
19
19
|
export declare function scriptToAddress(script: Script, network: string, addressType: AddressType, tokenSupport: boolean): string;
|
|
20
|
-
export declare function
|
|
20
|
+
export declare function scriptToP2SHLockingBytecode(script: Script, addressType: AddressType): Uint8Array;
|
|
21
21
|
export declare function publicKeyToP2PKHLockingBytecode(publicKey: Uint8Array): Uint8Array;
|
|
22
22
|
export declare function utxoComparator(a: Utxo, b: Utxo): number;
|
|
23
23
|
export declare function utxoTokenComparator(a: Utxo, b: Utxo): number;
|
package/dist/utils.js
CHANGED
|
@@ -123,13 +123,15 @@ export function getTxSizeWithoutInputs(outputs) {
|
|
|
123
123
|
return size;
|
|
124
124
|
}
|
|
125
125
|
// ////////// BUILD OBJECTS ///////////////////////////////////////////////////
|
|
126
|
-
export function
|
|
127
|
-
// Create unlock script / redeemScriptSig (add potential selector)
|
|
126
|
+
export function createUnlockingBytecode(contractType, contractBytecode, encodedArgs, selector) {
|
|
128
127
|
const unlockScript = [...encodedArgs].reverse();
|
|
129
128
|
if (selector !== undefined)
|
|
130
129
|
unlockScript.push(encodeInt(BigInt(selector)));
|
|
130
|
+
// P2S inputs do not need to provide the redeem script
|
|
131
|
+
if (contractType === 'p2s')
|
|
132
|
+
return scriptToBytecode(unlockScript);
|
|
131
133
|
// Create input script and compile it to bytecode
|
|
132
|
-
const inputScript = [...unlockScript,
|
|
134
|
+
const inputScript = [...unlockScript, contractBytecode];
|
|
133
135
|
return scriptToBytecode(inputScript);
|
|
134
136
|
}
|
|
135
137
|
export function createOpReturnOutput(opReturnData) {
|
|
@@ -154,14 +156,14 @@ export function toRegExp(reasons) {
|
|
|
154
156
|
return new RegExp(reasons.join('|').replace(/\(/g, '\\(').replace(/\)/g, '\\)'));
|
|
155
157
|
}
|
|
156
158
|
export function scriptToAddress(script, network, addressType, tokenSupport) {
|
|
157
|
-
const bytecode =
|
|
159
|
+
const bytecode = scriptToP2SHLockingBytecode(script, addressType);
|
|
158
160
|
const prefix = getNetworkPrefix(network);
|
|
159
161
|
const result = lockingBytecodeToCashAddress({ bytecode, prefix, tokenSupport });
|
|
160
162
|
if (typeof result === 'string')
|
|
161
163
|
throw new Error(result);
|
|
162
164
|
return result.address;
|
|
163
165
|
}
|
|
164
|
-
export function
|
|
166
|
+
export function scriptToP2SHLockingBytecode(script, addressType) {
|
|
165
167
|
const scriptBytecode = scriptToBytecode(script);
|
|
166
168
|
const scriptHash = (addressType === 'p2sh20') ? hash160(scriptBytecode) : hash256(scriptBytecode);
|
|
167
169
|
const addressContents = { payload: scriptHash, type: LockingBytecodeType[addressType] };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { isContractUnlocker } from './interfaces.js';
|
|
2
|
-
import {
|
|
3
|
-
import { cashAddressToLockingBytecode } from '@bitauth/libauth';
|
|
2
|
+
import { cashAddressToLockingBytecode, hexToBin } from '@bitauth/libauth';
|
|
4
3
|
export function getWcContractInfo(input) {
|
|
5
4
|
// If the input does not have a contract unlocker, return an empty object
|
|
6
5
|
if (!(isContractUnlocker(input.unlocker)))
|
|
@@ -14,7 +13,7 @@ export function getWcContractInfo(input) {
|
|
|
14
13
|
const wcContractObj = {
|
|
15
14
|
contract: {
|
|
16
15
|
abiFunction: abiFunction,
|
|
17
|
-
redeemScript:
|
|
16
|
+
redeemScript: hexToBin(contract.bytecode),
|
|
18
17
|
artifact: contract.artifact,
|
|
19
18
|
},
|
|
20
19
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cashscript",
|
|
3
|
-
"version": "0.13.0-next.
|
|
3
|
+
"version": "0.13.0-next.4",
|
|
4
4
|
"description": "Easily write and interact with Bitcoin Cash contracts",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bitcoin cash",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@bitauth/libauth": "^3.1.0-next.8",
|
|
45
|
-
"@cashscript/utils": "^0.13.0-next.
|
|
45
|
+
"@cashscript/utils": "^0.13.0-next.4",
|
|
46
46
|
"@electrum-cash/network": "^4.1.3",
|
|
47
47
|
"@mr-zwets/bchn-api-wrapper": "^1.0.1",
|
|
48
48
|
"fflate": "^0.8.2",
|
|
@@ -56,5 +56,5 @@
|
|
|
56
56
|
"typescript": "^5.9.2",
|
|
57
57
|
"vitest": "^4.0.15"
|
|
58
58
|
},
|
|
59
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "a9b4062bda82a2d80adf1bf21b846a62d7592e5b"
|
|
60
60
|
}
|