Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
cmd committed Oct 13, 2023
1 parent 255ec92 commit 2f53376
Show file tree
Hide file tree
Showing 30 changed files with 275 additions and 699 deletions.
2 changes: 1 addition & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const MIN_DEADLINE = _MIN * 30
export const MAX_EFFECT = _DAY * 30
export const MIN_EXPIRY = _HOUR * 2
export const MAX_EXPIRY = _DAY * 30
export const MIN_WINDOW = _HOUR * 2
export const MIN_WINDOW = _MIN * 10
export const MAX_WINDOW = _DAY * 30
export const GRACE_PERIOD = _DAY * 2
export const MAX_MULTISIG = 100
Expand Down
76 changes: 23 additions & 53 deletions src/lib/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,16 @@ import { Bytes } from '@cmdcode/buff'
import { Signer } from '@cmdcode/signer'
import { hash340 } from '@cmdcode/crypto-tools/hash'
import { DEFAULT_DEADLINE } from '../config.js'
import { create_signed_tx } from './spend.js'
import { create_session } from './session.js'
import { create_settlment } from './spend.js'
import { now } from './util.js'

import {
parse_deposit_req,
parse_txvin
} from './deposit.js'

import {
get_path_templates,
get_pay_total,
get_prop_id
} from './proposal.js'

import {
create_agent_session,
create_session_psigs
} from './session.js'

import {
eval_stack,
init_vm,
Expand All @@ -29,10 +20,7 @@ import {

import {
ContractConfig,
ContractContext,
ContractData,
Covenant,
DepositRecord,
ProposalData
} from '../types/index.js'

Expand All @@ -43,45 +31,28 @@ export function create_contract (
proposal : ProposalData,
options ?: Partial<ContractConfig>
) : ContractData {
const context = get_contract_ctx(proposal, options)
const session = create_agent_session(agent, context)
const { aux = [], fees = [], published = now() } = options ?? {}
const cid = get_contract_id(published, proposal, ...aux)

return {
...context,
session,
covenants : [],
effective : null,
cid,
fees,
published,
activated : null,
deadline : get_deadline(proposal, published),
expires : null,
funds : [],
session : create_session(agent, cid),
state : null,
status : 'published',
total : 0,
templates : get_path_templates(proposal, fees),
terms : proposal,
tx : null,
value : proposal.value + get_pay_total(fees),
witness : []
}
}

export function get_contract_ctx (
proposal : ProposalData,
options ?: Partial<ContractConfig>
) : ContractContext {
const { aux = [], fees = [], created_at = now() } = options ?? {}
const cid = get_contract_id(created_at, proposal, ...aux)
const deadline = get_deadline(proposal, created_at)
const subtotal = proposal.value + get_pay_total(fees)
const templates = get_path_templates(proposal, fees)
const terms = proposal
return { cid, created_at, deadline, fees, subtotal, templates, terms }
}

export function create_covenant (
contract : ContractData,
record : DepositRecord,
signer : Signer
) : Covenant {
const deposit = parse_deposit_req(record)
const session = create_session_psigs(contract, deposit, signer)
return { ...record, ...session }
}

export function get_contract_id (
created : number,
proposal : ProposalData,
Expand Down Expand Up @@ -110,10 +81,10 @@ export function update_contract (
) {
const { deadline, expires, state, status, terms, witness } = contract
if (status === 'published') {
if (check_covenants(contract)) {
if (check_deposits(contract)) {
activate_contract(contract, timestamp)
} else if (timestamp >= deadline) {
contract.status = 'canceled'
contract.status = 'cancelled'
}
} else if (status === 'active') {
assert.ok(state !== null)
Expand All @@ -135,7 +106,7 @@ export function activate_contract (
) {
const { cid, terms } = contract
// We should validate the deposits here:
if (!check_covenants(contract)) {
if (!check_deposits(contract)) {
throw new Error('Not enough valid deposits to cover contract value.')
}
return {
Expand All @@ -160,13 +131,12 @@ export function close_contract (
contract : ContractData,
pathname : string
) {
return create_signed_tx(agent, contract, pathname)
return create_settlment(agent, contract, pathname)
}

export function check_covenants (contract : ContractData) {
const { covenants, subtotal } = contract
const conf = covenants.filter(e => e.confirmed).map(x => parse_txvin(x.txvin))
export function check_deposits (contract : ContractData) {
const { funds, value } = contract
const conf = funds.filter(e => e.confirmed).map(x => x.txinput)
const total = conf.reduce((p, n) => p + Number(n.prevout.value), 0)
return total >= subtotal
return true
return total >= value
}
79 changes: 19 additions & 60 deletions src/lib/deposit.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Buff, Bytes } from '@cmdcode/buff'
import { Bytes } from '@cmdcode/buff'
import { Signer } from '@cmdcode/signer'
import { P2TR } from '@scrow/tapscript/address'
import { tap_pubkey } from '@scrow/tapscript/tapkey'
Expand All @@ -16,35 +16,29 @@ import {
TxPrevout
} from '@scrow/tapscript'

import {
decode_tx,
encode_tx
} from '@scrow/tapscript/tx'

import {
create_recovery_tx,
get_recovery_script
} from './recovery.js'

import {
Deposit,
DepositContext,
DepositData,
DepositRecord,
DepositRequest
DepositData
} from '../types/index.js'

export function get_deposit_ctx (
depo_key : Bytes,
sign_key : Bytes,
sequence : number
deposit_key : Bytes,
signing_key : Bytes,
sequence : number
) : DepositContext {
const members = [ depo_key, sign_key ]
const script = get_recovery_script(sign_key, sequence)
const members = [ deposit_key, signing_key ]
const script = get_recovery_script(signing_key, sequence)
const int_data = get_key_ctx(members)
const tap_data = tap_pubkey(int_data.group_pubkey, { script })
const key_data = tweak_key_ctx(int_data, [ tap_data.taptweak ])

return { depo_key, sign_key, sequence, script, tap_data, key_data }
return { deposit_key, signing_key, sequence, script, tap_data, key_data }
}

export function get_deposit_address (
Expand All @@ -55,7 +49,7 @@ export function get_deposit_address (
return P2TR.encode(tap_data.tapkey, network)
}

export function get_deposit_vin (
export function get_deposit_input (
context : DepositContext,
txdata : TxBytes | TxData
) {
Expand All @@ -72,52 +66,17 @@ export function create_deposit (
signer : Signer,
txinput : TxPrevout
) : DepositData {
const { depo_key, sequence, sign_key } = context
const recovery = create_recovery_tx(context, signer, txinput)
return { depo_key, recovery, sequence, sign_key, txinput }
const { deposit_key, sequence, signing_key } = context
const recovery_tx = create_recovery_tx(context, signer, txinput)
return { deposit_key, recovery_tx, sequence, signing_key, txinput }
}

export function create_deposit_req (
data : DepositData,
) : DepositRequest {
const { depo_key, recovery, sequence, sign_key, txinput } = data
export function init_deposit (data : DepositData) : Deposit {
return {
sequence,
depo_key : Buff.bytes(depo_key).hex,
recovery : encode_tx(recovery).hex,
sign_key : Buff.bytes(sign_key).hex,
txvin : Buff.json(txinput).to_bech32m('txvin')
...data,
confirmed : false,
covenant : null,
expires_at : null,
updated_at : null
}
}

export function create_deposit_rec (
request : DepositRequest,
) : DepositRecord {
const { txvin } = request
const txid = parse_txvin(txvin).txid
return { ...request, txid, confirmed : false, updated : 0 }
}

export function parse_deposit_req (
req : DepositRequest | DepositRecord
) : DepositData {
const { depo_key, recovery, sequence, sign_key, txvin } = req
return {
sequence,
recovery : decode_tx(recovery),
depo_key : Buff.hex(depo_key),
sign_key : Buff.hex(sign_key),
txinput : parse_txvin(txvin)
}
}

export function parse_txvin (txvin : string) : TxPrevout {
return Buff.bech32m(txvin).to_json()
}

export function validate_deposit (
data : DepositData
) {
console.log('deposit:', data)
return true
}
4 changes: 2 additions & 2 deletions src/lib/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,6 @@ export function parse_vm (state : MachineState) : ContractState {
export function parse_witness (witness : WitnessEntry) : WitnessData {
const wit = schema.contract.witness
const [ stamp, action, path, prog_id, ...args ] = wit.parse(witness)
const id = Buff.json(witness.slice(0, 4)).digest.hex
return { action, args, id, path, prog_id, stamp }
const wid = Buff.json(witness.slice(0, 4)).digest.hex
return { action, args, wid, path, prog_id, stamp }
}
8 changes: 1 addition & 7 deletions src/lib/proposal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,10 @@ import * as schema from '../schema/index.js'

type PathTotal = [ path: string, total : number ]

export function create_proposal (
template : Record<string, any>
) : ProposalData {
return schema.proposal.parse(template)
}

export function parse_proposal (
proposal : Record<string, any>
) : ProposalData {
return schema.proposal.parse(proposal)
return schema.proposal.data.parse(proposal)
}

export function filter_path (
Expand Down
3 changes: 2 additions & 1 deletion src/lib/recovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ import {
import { DepositContext } from '../types/index.js'

import * as assert from '../assert.js'
import { taproot, verify_tx } from '@scrow/tapscript/sighash'

// import { taproot, verify_tx } from '@scrow/tapscript/sighash'

interface RecoverConfig {
txfee : number
Expand Down
25 changes: 12 additions & 13 deletions src/lib/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,37 +23,36 @@ import {

import {
AgentSession,
ContractContext,
ContractData,
CovenantData,
DepositContext,
DepositData,
MuPathContext,
MuPathEntry
} from '../types/index.js'

export function create_agent_session (
agent : Signer,
context : ContractContext
export function create_session (
agent : Signer,
cid : string
) : AgentSession {
const { cid } = context
return {
id : Buff.bytes(agent.pubkey).digest.hex,
pubkey : agent.pubkey.hex,
pnonce : get_session_pnonce(cid, agent).hex
agent_id : Buff.bytes(agent.pubkey).digest.hex,
pubkey : agent.pubkey.hex,
pnonce : get_session_pnonce(cid, agent).hex
}
}

export function create_session_psigs (
export function create_covenant (
contract : ContractData,
deposit : DepositData,
signer : Signer
) {
) : CovenantData {
const { cid, session } = contract
const pnonce = get_session_pnonce(cid, signer)
const pnonces = [ pnonce, session.pnonce ]
const mupaths = get_mupath_entries(contract, deposit, pnonces)
const psigs = create_path_psigs(mupaths, signer)
return { pnonce : pnonce.hex, psigs }
return { cid, pnonce : pnonce.hex, psigs }
}

export function get_mupath_entries (
Expand All @@ -62,8 +61,8 @@ export function get_mupath_entries (
pnonces : Bytes[]
) : MuPathEntry[] {
const { cid, templates } = contract
const { depo_key, sign_key, sequence, txinput } = deposit
const context = get_deposit_ctx(depo_key, sign_key, sequence)
const { deposit_key, signing_key, sequence, txinput } = deposit
const context = get_deposit_ctx(deposit_key, signing_key, sequence)
return templates.map(([ label, templ ]) => {
const mupath = get_mupath_ctx(cid, context, pnonces, templ, txinput)
return [ label, mupath ]
Expand Down
Loading

0 comments on commit 2f53376

Please sign in to comment.