@meshsdk/contract 1.6.0-alpha.11

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.
Files changed (73) hide show
  1. package/README.md +5 -0
  2. package/package.json +37 -0
  3. package/src/common.ts +186 -0
  4. package/src/coupon-bond-guaranteed/aiken-workspace/readme.md +0 -0
  5. package/src/coupon-bond-guaranteed/offchain.ts +3 -0
  6. package/src/coupon-bond-guaranteed/readme.md +3 -0
  7. package/src/escrow/aiken-workspace/aiken.lock +26 -0
  8. package/src/escrow/aiken-workspace/aiken.toml +19 -0
  9. package/src/escrow/aiken-workspace/lib/escrow/types.ak +21 -0
  10. package/src/escrow/aiken-workspace/lib/escrow/validators/escrow.ak +122 -0
  11. package/src/escrow/aiken-workspace/plutus.json +238 -0
  12. package/src/escrow/aiken-workspace/readme.md +55 -0
  13. package/src/escrow/aiken-workspace/validators/escrow.ak +9 -0
  14. package/src/escrow/aiken-workspace/validators/tests/escrow.ak +462 -0
  15. package/src/escrow/index.ts +1 -0
  16. package/src/escrow/offchain.ts +254 -0
  17. package/src/escrow/readme.md +38 -0
  18. package/src/giftcard/aiken-workspace/aiken.lock +26 -0
  19. package/src/giftcard/aiken-workspace/aiken.toml +19 -0
  20. package/src/giftcard/aiken-workspace/plutus.json +138 -0
  21. package/src/giftcard/aiken-workspace/readme.md +55 -0
  22. package/src/giftcard/aiken-workspace/validators/oneshot.ak +173 -0
  23. package/src/giftcard/index.ts +1 -0
  24. package/src/giftcard/offchain.ts +184 -0
  25. package/src/giftcard/readme.md +36 -0
  26. package/src/hello-world/aiken-workspace/README.md +19 -0
  27. package/src/hello-world/aiken-workspace/aiken.lock +15 -0
  28. package/src/hello-world/aiken-workspace/aiken.toml +14 -0
  29. package/src/hello-world/aiken-workspace/contract.md +27 -0
  30. package/src/hello-world/aiken-workspace/plutus.json +69 -0
  31. package/src/hello-world/aiken-workspace/validators/hello_world.ak +24 -0
  32. package/src/hello-world/index.ts +1 -0
  33. package/src/hello-world/offchain.ts +24 -0
  34. package/src/hello-world/readme.md +1 -0
  35. package/src/index.ts +6 -0
  36. package/src/marketplace/aiken-workspace/aiken.lock +26 -0
  37. package/src/marketplace/aiken-workspace/aiken.toml +19 -0
  38. package/src/marketplace/aiken-workspace/lib/marketplace/types.ak +15 -0
  39. package/src/marketplace/aiken-workspace/lib/marketplace/validators/marketplace.ak +52 -0
  40. package/src/marketplace/aiken-workspace/plutus.json +204 -0
  41. package/src/marketplace/aiken-workspace/readme.md +55 -0
  42. package/src/marketplace/aiken-workspace/validators/marketplace.ak +14 -0
  43. package/src/marketplace/aiken-workspace/validators/tests/marketplace.ak +218 -0
  44. package/src/marketplace/index.ts +1 -0
  45. package/src/marketplace/offchain.ts +248 -0
  46. package/src/marketplace/readme.md +45 -0
  47. package/src/payment-splitter/aiken-workspace/aiken.lock +15 -0
  48. package/src/payment-splitter/aiken-workspace/aiken.toml +14 -0
  49. package/src/payment-splitter/aiken-workspace/plutus.json +83 -0
  50. package/src/payment-splitter/aiken-workspace/validators/payment-splitter.ak +329 -0
  51. package/src/payment-splitter/index.ts +1 -0
  52. package/src/payment-splitter/offchain.ts +143 -0
  53. package/src/payment-splitter/readme.md +100 -0
  54. package/src/swap/aiken-workspace/aiken.lock +26 -0
  55. package/src/swap/aiken-workspace/aiken.toml +19 -0
  56. package/src/swap/aiken-workspace/plutus.json +208 -0
  57. package/src/swap/aiken-workspace/readme.md +55 -0
  58. package/src/swap/aiken-workspace/validators/swap.ak +188 -0
  59. package/src/swap/index.ts +1 -0
  60. package/src/swap/offchain.ts +139 -0
  61. package/src/swap/readme.md +35 -0
  62. package/src/vesting/aiken-workspace/README.md +24 -0
  63. package/src/vesting/aiken-workspace/aiken.lock +26 -0
  64. package/src/vesting/aiken-workspace/aiken.toml +19 -0
  65. package/src/vesting/aiken-workspace/lib/vesting/types.ak +8 -0
  66. package/src/vesting/aiken-workspace/lib/vesting/validators/vesting.ak +19 -0
  67. package/src/vesting/aiken-workspace/plutus.json +67 -0
  68. package/src/vesting/aiken-workspace/validators/tests/vesting.ak +108 -0
  69. package/src/vesting/aiken-workspace/validators/vesting.ak +9 -0
  70. package/src/vesting/index.ts +1 -0
  71. package/src/vesting/offchain.ts +117 -0
  72. package/src/vesting/readme.md +36 -0
  73. package/tsconfig.json +5 -0
@@ -0,0 +1,19 @@
1
+ name = "meshjs/vesting"
2
+ version = "0.0.0"
3
+ license = "Apache-2.0"
4
+ description = "Aiken contracts for project 'meshjs/vesting'"
5
+
6
+ [repository]
7
+ user = "meshjs"
8
+ project = "vesting"
9
+ platform = "github"
10
+
11
+ [[dependencies]]
12
+ name = "aiken-lang/stdlib"
13
+ version = "1.9.0"
14
+ source = "github"
15
+
16
+ [[dependencies]]
17
+ name = "sidan-lab/aiken-utils"
18
+ version = "0.1.6-beta"
19
+ source = "github"
@@ -0,0 +1,8 @@
1
+ pub type VestingDatum {
2
+ /// POSIX time in second, e.g. 1672843961000
3
+ lock_until: Int,
4
+ /// Owner's credentials
5
+ owner: ByteArray,
6
+ /// Beneficiary's credentials
7
+ beneficiary: ByteArray,
8
+ }
@@ -0,0 +1,19 @@
1
+ use aiken/transaction.{ScriptContext, Spend, Transaction}
2
+ use sidan_utils/extra_signatories.{key_signed}
3
+ use sidan_utils/validity_range.{valid_after}
4
+ use vesting/types.{VestingDatum}
5
+
6
+ pub fn vesting_logic(datum: VestingDatum, ctx: ScriptContext) {
7
+ // In principle, scripts can be used for different purpose (e.g. minting
8
+ // assets). Here we make sure it's only used when 'spending' from a eUTxO
9
+ when ctx.purpose is {
10
+ Spend(_) -> or {
11
+ key_signed(ctx.transaction.extra_signatories, datum.owner),
12
+ and {
13
+ key_signed(ctx.transaction.extra_signatories, datum.beneficiary),
14
+ valid_after(ctx.transaction.validity_range, datum.lock_until),
15
+ },
16
+ }
17
+ _ -> False
18
+ }
19
+ }
@@ -0,0 +1,67 @@
1
+ {
2
+ "preamble": {
3
+ "title": "meshjs/vesting",
4
+ "description": "Aiken contracts for project 'meshjs/vesting'",
5
+ "version": "0.0.0",
6
+ "plutusVersion": "v2",
7
+ "compiler": {
8
+ "name": "Aiken",
9
+ "version": "v1.0.29-alpha+unknown"
10
+ },
11
+ "license": "Apache-2.0"
12
+ },
13
+ "validators": [
14
+ {
15
+ "title": "vesting.vesting",
16
+ "datum": {
17
+ "title": "datum",
18
+ "schema": {
19
+ "$ref": "#/definitions/vesting~1types~1VestingDatum"
20
+ }
21
+ },
22
+ "redeemer": {
23
+ "title": "_redeemer",
24
+ "schema": {
25
+ "$ref": "#/definitions/ByteArray"
26
+ }
27
+ },
28
+ "compiledCode": "5901c801000032323232323232232232253330063232323253323300b3001300c3754600a601a6ea801854ccc02ccc010dd6180198069baa3002300d375400c6eb8c014c034dd50050a511533300b3300437586006601a6ea8c008c034dd50031bae301030113011300d3754014266446464646464a666024601060266ea80084c94ccc04c0104cdc40038008011bad301730143754004002264a666024601060266ea80084c94ccc04c0100084cdc48038009bad3017301437540040022940c054008cdc42400060206ea8c050c054004cc048c04c004cc048ccc038cdc424000601e6ea8c04cc05000530103d87a80004c0103d87980004bd7018079baa3004300f375400460206022602260226022602260226022601a6ea8c008c034dd50031bad3002300d37540142940dc3a400429408c03c0048c038c03cc03cc03cc03cc03cc03cc03cc03c00488c8cc00400400c894ccc038004528099299980619b8f375c602200400829444cc00c00c004c0440048c030c03400452613656375c002a66600466e1d2000300337540022646464646464a666016601c0042930b1bae300c001300c002375c601400260140046eb4c020004c010dd50008b2b9a5573aaae7955cfaba05742ae89",
29
+ "hash": "5978a5118ecb36ad827390a21769bfa680ffc499d364bad913b4dffa"
30
+ }
31
+ ],
32
+ "definitions": {
33
+ "ByteArray": {
34
+ "dataType": "bytes"
35
+ },
36
+ "Int": {
37
+ "dataType": "integer"
38
+ },
39
+ "vesting/types/VestingDatum": {
40
+ "title": "VestingDatum",
41
+ "anyOf": [
42
+ {
43
+ "title": "VestingDatum",
44
+ "dataType": "constructor",
45
+ "index": 0,
46
+ "fields": [
47
+ {
48
+ "title": "lock_until",
49
+ "description": "POSIX time in second, e.g. 1672843961000",
50
+ "$ref": "#/definitions/Int"
51
+ },
52
+ {
53
+ "title": "owner",
54
+ "description": "Owner's credentials",
55
+ "$ref": "#/definitions/ByteArray"
56
+ },
57
+ {
58
+ "title": "beneficiary",
59
+ "description": "Beneficiary's credentials",
60
+ "$ref": "#/definitions/ByteArray"
61
+ }
62
+ ]
63
+ }
64
+ ]
65
+ }
66
+ }
67
+ }
@@ -0,0 +1,108 @@
1
+ use aiken/transaction.{ScriptContext, Spend}
2
+ use sidan_placeholder/builder.{
3
+ complete, invalid_before, new_tx_tester, required_signer_hash,
4
+ }
5
+ use sidan_placeholder/key_hex.{mock_pub_key_hex}
6
+ use sidan_placeholder/output_reference.{mock_utxo_ref}
7
+ use vesting/types.{VestingDatum}
8
+ use vesting/validators/vesting.{vesting_logic}
9
+
10
+ type TestCase {
11
+ is_owner_signed: Bool,
12
+ is_beneficiary_signed: Bool,
13
+ is_lock_time_passed: Bool,
14
+ }
15
+
16
+ fn get_test_tx(test_case: TestCase) {
17
+ let TestCase { is_owner_signed, is_beneficiary_signed, is_lock_time_passed } =
18
+ test_case
19
+
20
+ new_tx_tester()
21
+ |> required_signer_hash(is_owner_signed, mock_pub_key_hex(1))
22
+ |> required_signer_hash(is_beneficiary_signed, mock_pub_key_hex(2))
23
+ |> invalid_before(is_lock_time_passed, 1672843961001)
24
+ |> complete()
25
+ }
26
+
27
+ fn vesting_datum() {
28
+ VestingDatum {
29
+ lock_until: 1672843961000,
30
+ owner: mock_pub_key_hex(1),
31
+ beneficiary: mock_pub_key_hex(2),
32
+ }
33
+ }
34
+
35
+ test success_unlocking() {
36
+ let output_reference = mock_utxo_ref(0, 1)
37
+ let datum = vesting_datum()
38
+ let test_case =
39
+ TestCase {
40
+ is_owner_signed: True,
41
+ is_beneficiary_signed: True,
42
+ is_lock_time_passed: True,
43
+ }
44
+
45
+ let tx = get_test_tx(test_case)
46
+ let ctx = ScriptContext { purpose: Spend(output_reference), transaction: tx }
47
+ vesting_logic(datum, ctx)
48
+ }
49
+
50
+ test success_unlocking_with_only_owner_signature() {
51
+ let output_reference = mock_utxo_ref(0, 1)
52
+ let datum = vesting_datum()
53
+ let test_case =
54
+ TestCase {
55
+ is_owner_signed: True,
56
+ is_beneficiary_signed: False,
57
+ is_lock_time_passed: False,
58
+ }
59
+
60
+ let tx = get_test_tx(test_case)
61
+ let ctx = ScriptContext { purpose: Spend(output_reference), transaction: tx }
62
+ vesting_logic(datum, ctx)
63
+ }
64
+
65
+ test success_unlocking_with_beneficiary_signature_and_time_passed() {
66
+ let output_reference = mock_utxo_ref(0, 1)
67
+ let datum = vesting_datum()
68
+ let test_case =
69
+ TestCase {
70
+ is_owner_signed: False,
71
+ is_beneficiary_signed: True,
72
+ is_lock_time_passed: True,
73
+ }
74
+
75
+ let tx = get_test_tx(test_case)
76
+ let ctx = ScriptContext { purpose: Spend(output_reference), transaction: tx }
77
+ vesting_logic(datum, ctx)
78
+ }
79
+
80
+ test fail_unlocking_with_only_beneficiary_signature() {
81
+ let output_reference = mock_utxo_ref(0, 1)
82
+ let datum = vesting_datum()
83
+ let test_case =
84
+ TestCase {
85
+ is_owner_signed: False,
86
+ is_beneficiary_signed: True,
87
+ is_lock_time_passed: False,
88
+ }
89
+
90
+ let tx = get_test_tx(test_case)
91
+ let ctx = ScriptContext { purpose: Spend(output_reference), transaction: tx }
92
+ !vesting_logic(datum, ctx)
93
+ }
94
+
95
+ test fail_unlocking_with_only_time_passed() {
96
+ let output_reference = mock_utxo_ref(0, 1)
97
+ let datum = vesting_datum()
98
+ let test_case =
99
+ TestCase {
100
+ is_owner_signed: False,
101
+ is_beneficiary_signed: False,
102
+ is_lock_time_passed: True,
103
+ }
104
+
105
+ let tx = get_test_tx(test_case)
106
+ let ctx = ScriptContext { purpose: Spend(output_reference), transaction: tx }
107
+ !vesting_logic(datum, ctx)
108
+ }
@@ -0,0 +1,9 @@
1
+ use aiken/transaction.{ScriptContext}
2
+ use vesting/types.{VestingDatum}
3
+ use vesting/validators/vesting.{vesting_logic}
4
+
5
+ validator {
6
+ fn vesting(datum: VestingDatum, _redeemer: ByteArray, ctx: ScriptContext) {
7
+ vesting_logic(datum, ctx)
8
+ }
9
+ }
@@ -0,0 +1 @@
1
+ export * from './offchain';
@@ -0,0 +1,117 @@
1
+ import {
2
+ BuiltinByteString,
3
+ ConStr0,
4
+ Integer,
5
+ mConStr0,
6
+ SLOT_CONFIG_NETWORK,
7
+ unixTimeToEnclosingSlot,
8
+ } from "@meshsdk/common";
9
+ import {
10
+ Asset,
11
+ deserializeAddress,
12
+ deserializeDatum,
13
+ serializePlutusScript,
14
+ UTxO,
15
+ } from "@meshsdk/core";
16
+ import { applyParamsToScript } from "@meshsdk/core-csl";
17
+
18
+ import { MeshTxInitiator, MeshTxInitiatorInput } from "../common";
19
+ import blueprint from "./aiken-workspace/plutus.json";
20
+
21
+ export const MeshVestingBlueprint = blueprint;
22
+
23
+ export type VestingDatum = ConStr0<
24
+ [Integer, BuiltinByteString, BuiltinByteString]
25
+ >;
26
+
27
+ export class MeshVestingContract extends MeshTxInitiator {
28
+ scriptCbor = applyParamsToScript(blueprint.validators[0]!.compiledCode, []);
29
+
30
+ constructor(inputs: MeshTxInitiatorInput) {
31
+ super(inputs);
32
+ }
33
+
34
+ depositFund = async (
35
+ amount: Asset[],
36
+ lockUntilTimeStampMs: number,
37
+ beneficiary: string,
38
+ ): Promise<string> => {
39
+ const { utxos, walletAddress } = await this.getWalletInfoForTx();
40
+
41
+ const scriptAddr = serializePlutusScript(
42
+ { code: this.scriptCbor, version: "V2" },
43
+ undefined,
44
+ 0,
45
+ ).address;
46
+ const { pubKeyHash: ownerPubKeyHash } = deserializeAddress(walletAddress);
47
+ const { pubKeyHash: beneficiaryPubKeyHash } =
48
+ deserializeAddress(beneficiary);
49
+
50
+ await this.mesh
51
+ .txOut(scriptAddr, amount)
52
+ .txOutInlineDatumValue(
53
+ mConStr0([
54
+ lockUntilTimeStampMs,
55
+ ownerPubKeyHash,
56
+ beneficiaryPubKeyHash,
57
+ ]),
58
+ )
59
+ .changeAddress(walletAddress)
60
+ .selectUtxosFrom(utxos)
61
+ .complete();
62
+ return this.mesh.txHex;
63
+ };
64
+
65
+ withdrawFund = async (vestingUtxo: UTxO): Promise<string> => {
66
+ const { utxos, walletAddress, collateral } =
67
+ await this.getWalletInfoForTx();
68
+ const { input: collateralInput, output: collateralOutput } = collateral;
69
+ const scriptAddr = serializePlutusScript(
70
+ { code: this.scriptCbor, version: "V2" },
71
+ undefined,
72
+ 0,
73
+ ).address;
74
+ const { pubKeyHash } = deserializeAddress(walletAddress);
75
+
76
+ const datum = deserializeDatum<VestingDatum>(
77
+ vestingUtxo.output.plutusData!,
78
+ );
79
+
80
+ const invalidBefore =
81
+ unixTimeToEnclosingSlot(
82
+ Math.min(datum.fields[0].int as number, Date.now() - 15000),
83
+ this.networkId === 0
84
+ ? SLOT_CONFIG_NETWORK.preprod
85
+ : SLOT_CONFIG_NETWORK.mainnet,
86
+ ) + 1;
87
+
88
+ await this.mesh
89
+ .spendingPlutusScriptV2()
90
+ .txIn(
91
+ vestingUtxo.input.txHash,
92
+ vestingUtxo.input.outputIndex,
93
+ vestingUtxo.output.amount,
94
+ scriptAddr,
95
+ )
96
+ .spendingReferenceTxInInlineDatumPresent()
97
+ .spendingReferenceTxInRedeemerValue("")
98
+ .txInScript(this.scriptCbor)
99
+ .txOut(walletAddress, [])
100
+ .txInCollateral(
101
+ collateralInput.txHash,
102
+ collateralInput.outputIndex,
103
+ collateralOutput.amount,
104
+ collateralOutput.address,
105
+ )
106
+ .invalidBefore(invalidBefore)
107
+ .requiredSignerHash(pubKeyHash)
108
+ .changeAddress(walletAddress)
109
+ .selectUtxosFrom(utxos)
110
+ .complete();
111
+ return this.mesh.txHex;
112
+ };
113
+
114
+ getUtxoByTxHash = async (txHash: string): Promise<UTxO | undefined> => {
115
+ return await this._getUtxoByTxHash(this.scriptCbor, txHash);
116
+ };
117
+ }
@@ -0,0 +1,36 @@
1
+ # Vesting Contract
2
+
3
+ Vesting contract is a smart contract that locks up funds for a period of time and allows the owner to withdraw the funds after the lockup period.
4
+
5
+ [Demo](https://meshjs.dev/smart-contracts/vesting)
6
+
7
+ When a new employee joins an organization, they typically receive a promise of compensation to be disbursed after a specified duration of employment. This arrangement often involves the organization depositing the funds into a vesting contract, with the employee gaining access to the funds upon the completion of a predetermined lockup period. Through the utilization of vesting contracts, organizations establish a mechanism to encourage employee retention by linking financial rewards to tenure.
8
+
9
+ There are 2 actions (or endpoints) available to interact with this smart contract:
10
+
11
+ - deposit asset
12
+ - withdraw asset
13
+
14
+ To initialize the escrow, we need to initialize a provider, MeshTxBuilder and MeshVestingContract.
15
+
16
+ ```
17
+ import { BlockfrostProvider, MeshTxBuilder } from '@meshsdk/core';
18
+ import { MeshVestingContract } from '@meshsdk/contracts';
19
+ import { useWallet } from '@meshsdk/react';
20
+
21
+ const { connected, wallet } = useWallet();
22
+
23
+ const blockchainProvider = new BlockfrostProvider(APIKEY);
24
+
25
+ const meshTxBuilder = new MeshTxBuilder({
26
+ fetcher: blockchainProvider,
27
+ submitter: blockchainProvider,
28
+ });
29
+
30
+ const contract = new MeshVestingContract({
31
+ mesh: meshTxBuilder,
32
+ fetcher: blockchainProvider,
33
+ wallet: wallet,
34
+ networkId: 0,
35
+ });
36
+ ```
package/tsconfig.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": "@meshsdk/typescript-config/base.json",
3
+ "include": ["src/**/*"],
4
+ "exclude": ["dist", "node_modules"]
5
+ }