tap

package module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 12, 2026 License: MIT Imports: 6 Imported by: 0

README

tap-go

Go library for the Transaction Authorization Protocol (TAP) — typed message wrappers for all 20 TAP message types, built on go-didcomm.

Installation

Library
go get github.com/TransactionAuthorizationProtocol/tap-go
CLI
go install github.com/TransactionAuthorizationProtocol/tap-go/cmd/tap@latest

How It Works

tap-go sits on top of go-didcomm, which handles DIDComm v2 message packing (signing, encryption) and unpacking. This library adds TAP-specific typed bodies, validation, and parsing.

┌─────────────────────────────────────────────────┐
│                  Your Application                │
├─────────────────────────────────────────────────┤
│  tap-go                                         │
│  • Typed body structs (TransferBody, etc.)      │
│  • Constructors with validation                 │
│  • ParseBody() dispatch                         │
│  • tap.Client.Receive() for typed parsing       │
├─────────────────────────────────────────────────┤
│  go-didcomm                                     │
│  • didcomm.Message (ID, Type, From, To, Body)   │
│  • Pack: Signed / Anoncrypt / Authcrypt → []byte│
│  • Unpack: []byte → UnpackResult                │
│  • DID resolution, key management               │
└─────────────────────────────────────────────────┘

Every New*Message() constructor returns a *didcomm.Message — the standard go-didcomm type — with the TAP body serialized into msg.Body as json.RawMessage. You can then use go-didcomm's PackSigned, PackAnoncrypt, or PackAuthcrypt to send it, and Unpack + ParseBody (or tap.Client.Receive) to receive it.

Quick Start

Sending: Create and pack a TAP message
package main

import (
    "context"
    "fmt"

    tap "github.com/TransactionAuthorizationProtocol/tap-go"
    didcomm "github.com/Notabene-id/go-didcomm"
)

func main() {
    // 1. Create a TAP message (returns a *didcomm.Message)
    msg, err := tap.NewTransferMessage(
        "did:web:originator.vasp",                    // from
        []string{"did:web:beneficiary.vasp"},          // to
        &tap.TransferBody{
            Asset:  "eip155:1/slip44:60",
            Amount: "1.23",
            Originator:  &tap.Party{ID: "did:eg:bob"},
            Beneficiary: &tap.Party{ID: "did:eg:alice"},
            Agents: []tap.Agent{
                {ID: "did:web:originator.vasp", For: tap.NewForField("did:eg:bob")},
                {ID: "did:web:beneficiary.vasp", For: tap.NewForField("did:eg:alice")},
            },
        },
    )
    if err != nil {
        panic(err)
    }

    // 2. Pack with go-didcomm for transport (signed, encrypted, or both)
    dc := didcomm.NewClient(resolver, secrets)

    // Option A: Sign only (sender authenticated, not encrypted)
    envelope, err := dc.PackSigned(context.Background(), msg)

    // Option B: Encrypt only (anonymous, no sender identification)
    envelope, err = dc.PackAnoncrypt(context.Background(), msg)

    // Option C: Sign then encrypt (authenticated + encrypted)
    envelope, err = dc.PackAuthcrypt(context.Background(), msg)

    // 3. Send envelope ([]byte) over any transport (HTTP, WebSocket, etc.)
    fmt.Printf("Sending %d bytes\n", len(envelope))
}
Receiving: Unpack and parse a TAP message
// Option A: Two-step — unpack with go-didcomm, then parse with tap-go
dc := didcomm.NewClient(resolver, secrets)
result, err := dc.Unpack(ctx, envelope)  // → *didcomm.UnpackResult
if err != nil { /* handle */ }

// Check if it's a TAP message
if tap.IsTAPMessage(result.Message) {
    body, err := tap.ParseBody(result.Message)
    if err != nil { /* handle */ }

    switch b := body.(type) {
    case *tap.TransferBody:
        fmt.Printf("Transfer of %s %s\n", b.Amount, b.Asset)
    case *tap.PaymentBody:
        fmt.Printf("Payment of %s %s\n", b.Amount, b.Currency)
    case *tap.AuthorizeBody:
        fmt.Println("Transaction authorized")
    // ... handle all 20 types
    }
}

// Option B: One-step — tap.Client does both unpack + parse
client := tap.NewClient(dc)
tapResult, err := client.Receive(ctx, envelope)  // → *tap.TAPResult
if err != nil { /* handle */ }

fmt.Printf("Type: %s\n", tapResult.Message.Type)
fmt.Printf("Encrypted: %v, Signed: %v\n", tapResult.Encrypted, tapResult.Signed)

if transfer, ok := tapResult.Body.(*tap.TransferBody); ok {
    fmt.Printf("Transfer: %s %s\n", transfer.Amount, transfer.Asset)
}
Replying to a message (thread-based messages)

Authorization flow and agent management messages reference an existing thread via thid:

// Original transfer message starts a thread
transferMsg, _ := tap.NewTransferMessage(from, to, transferBody)

// Reply messages reference the original via thid
authorizeMsg, _ := tap.NewAuthorizeMessage(
    "did:web:beneficiary.vasp",                  // from (replier)
    []string{"did:web:originator.vasp"},          // to (original sender)
    transferMsg.ID,                               // thid — links to original
    &tap.AuthorizeBody{
        SettlementAddress: "eip155:1:0x1234a96D359eC26a11e2C2b3d8f8B8942d5Bfcdb",
    },
)

// Pack and send the reply the same way
envelope, _ := dc.PackAuthcrypt(ctx, authorizeMsg)

Message Types

Transaction Messages
Constructor Body Struct TAIP Required Fields
NewTransferMessage TransferBody TAIP-3 asset, agents
NewPaymentMessage PaymentBody TAIP-14 amount, merchant, agents, asset or currency
NewRFQMessage RFQBody TAIP-18 fromAssets, toAssets, requester, agents, fromAmount or toAmount
NewQuoteMessage QuoteBody TAIP-18 fromAsset, toAsset, fromAmount, toAmount, provider, agents, expiresAt
NewLockMessage LockBody TAIP-17 amount, originator, beneficiary, expiry, agents, asset or currency
Authorization Flow Messages
Constructor Body Struct TAIP Required Fields
NewAuthorizeMessage AuthorizeBody TAIP-4 (all optional)
NewAuthorizationRequiredMessage AuthorizationRequiredBody TAIP-4 authorizationUrl, expires
NewSettleMessage SettleBody TAIP-4 settlementAddress
NewRejectMessage RejectBody TAIP-4 (all optional)
NewCancelMessage CancelBody TAIP-4 by
NewRevertMessage RevertBody TAIP-4 settlementAddress, reason
NewCaptureMessage CaptureBody TAIP-17 (all optional)
Agent Management Messages
Constructor Body Struct TAIP Required Fields
NewUpdateAgentMessage UpdateAgentBody TAIP-5 agent
NewUpdatePartyMessage UpdatePartyBody TAIP-6 party, role
NewAddAgentsMessage AddAgentsBody TAIP-5 agents
NewReplaceAgentMessage ReplaceAgentBody TAIP-5 original, replacement
NewRemoveAgentMessage RemoveAgentBody TAIP-5 agent
Relationship Messages
Constructor Body Struct TAIP Required Fields
NewConfirmRelationshipMessage ConfirmRelationshipBody TAIP-9 @id, for
NewUpdatePoliciesMessage UpdatePoliciesBody TAIP-7 policies
NewConnectMessage ConnectBody TAIP-15 requester, principal, agents, constraints

Shared Types

Party

Represents a real-world entity (legal or natural person):

party := tap.Party{
    ID:   "did:eg:bob",       // required — DID or IRI
    Type: "Party",            // optional — JSON-LD type
    Name: "Bob's Exchange",   // optional
    MCC:  "5734",             // optional — Merchant Category Code
}
Agent

Represents software acting on behalf of a participant:

agent := tap.Agent{
    ID:   "did:web:originator.vasp",              // required
    For:  tap.NewForField("did:eg:bob"),           // DID(s) of represented party
    Role: "SettlementAddress",                     // optional
    Policies: []tap.Policy{                        // optional
        {Type: "RequireAuthorization", FromAgent: "beneficiary"},
    },
}
ForField

The Agent.For field handles both single DIDs and arrays:

// Single DID — marshals as "did:eg:alice"
single := tap.NewForField("did:eg:alice")

// Multiple DIDs — marshals as ["did:eg:alice", "did:eg:bob"]
multi := tap.NewForField("did:eg:alice", "did:eg:bob")

// Access values
single.String()   // "did:eg:alice"
multi.Values()    // ["did:eg:alice", "did:eg:bob"]
single.IsEmpty()  // false
Policy
policy := tap.Policy{
    Type:                   "RequirePresentation",
    FromAgent:              "beneficiary",
    AboutParty:             "beneficiary",
    Purpose:                "FATF Travel Rule Compliance",
    PresentationDefinition: "https://tap.rsvp/presentation-definitions/ivms-101/eu/tfr",
}
TransactionConstraints

Used in Connect messages to define boundaries:

constraints := tap.TransactionConstraints{
    Purposes:         []string{"BEXP", "SUPP"},
    CategoryPurposes: []string{"CASH"},
    Limits: &tap.Limits{
        PerTransaction: "10000.00",
        PerDay:         "50000.00",
        Currency:       "USD",
    },
    AllowedAssets: []string{"eip155:1/slip44:60"},
}

Utility Functions

// Check if a DIDComm message is a TAP message
tap.IsTAPMessage(msg) // bool

// Get all known TAP type URLs
tap.AllTypes() // []string (20 types)

// Parse body into typed struct
body, err := tap.ParseBody(msg) // (TAPBody, error)
body.TAPType() // e.g. "https://tap.rsvp/schema/1.0#Transfer"

CLI

The tap CLI wraps all go-didcomm CLI commands and adds TAP-specific message creation and receiving.

Commands
tap did generate-key [--output-dir <dir>]
tap did generate-web --domain <d> [--path <p>] [--service-endpoint <url>] [--output-dir <dir>]
tap pack signed    --key-file <f> [--send] [--did-doc <f>] [--message <m>]
tap pack anoncrypt [--send] [--did-doc <f>] [--message <m>]
tap pack authcrypt --key-file <f> [--send] [--did-doc <f>] [--message <m>]
tap unpack         --key-file <f> [--did-doc <f>] [--message <m>]
tap send           --to <url> [--message <m>]
tap message <type> --from <did> --to <did> [--thid <id>] [--body <json>]
tap receive        --key-file <f> [--did-doc <f>] [--message <m>]
Create and pack a TAP message
# Generate identities
tap did generate-key --output-dir alice
tap did generate-key --output-dir bob

ALICE=$(jq -r .id alice/did-doc.json)
BOB=$(jq -r .id bob/did-doc.json)

# Create a TAP transfer message
tap message transfer --from $ALICE --to $BOB \
  --body '{"asset":"eip155:1/slip44:60","amount":"1.5","agents":[{"@id":"'$ALICE'","role":"OriginatingVASP"}]}'

# Pipe: create → pack → send
tap message transfer --from $ALICE --to $BOB --body @body.json | \
  tap pack authcrypt --key-file alice/keys.json
Receive a TAP message
# Unpack a DIDComm envelope and parse the TAP body
echo '<packed-message>' | tap receive --key-file bob/keys.json

The receive command outputs JSON with the unpacked message, typed body, and envelope metadata (encrypted, signed, anonymous).

TAP message types

Initiating (no --thid): transfer, payment, rfq, lock, connect

Reply (require --thid): authorize, authorization-required, settle, reject, cancel, revert, capture, quote, add-agents, remove-agent, replace-agent, update-agent, update-party, update-policies, confirm-relationship

Body input (--body flag)
  • '{"json"}' — inline JSON string
  • @file.json — read from file
  • - — read from stdin
  • (omitted) — defaults to {}

The body JSON should contain only message-specific fields (e.g. asset, amount, agents). The CLI automatically sets @context and @type.

Error Handling

import "errors"

msg, err := tap.NewTransferMessage(from, to, body)
if errors.Is(err, tap.ErrInvalidBody) {
    // missing required fields
}

body, err := tap.ParseBody(msg)
if errors.Is(err, tap.ErrUnknownMessageType) {
    // not a recognized TAP message type
}
if errors.Is(err, tap.ErrInvalidBody) {
    // body JSON could not be unmarshaled
}

License

MIT

Documentation

Overview

Package tap provides typed Go wrappers for all 20 TAP (Transaction Authorization Protocol) message types, built on top of the go-didcomm library.

TAP defines a DIDComm v2-based protocol for multi-party transaction authorization before blockchain settlement. This package provides:

  • Typed body structs for each message type (TransferBody, PaymentBody, etc.)
  • Constructor functions that validate required fields and produce didcomm.Message values
  • A ParseBody dispatcher that unmarshals any TAP message body into its typed struct
  • A Client wrapper around didcomm.Client that combines unpacking and parsing

Message Types

TAP defines 20 message types organized into four categories:

Transaction messages initiate financial operations:

  • Transfer (TAIP-3) — asset transfer between parties
  • Payment (TAIP-14) — merchant payment request
  • RFQ (TAIP-18) — request for quote on an asset exchange
  • Quote (TAIP-18) — exchange price quote response
  • Lock (TAIP-17) — hold funds in escrow

Authorization flow messages manage transaction lifecycle:

  • Authorize (TAIP-4) — approve a transaction
  • AuthorizationRequired (TAIP-4) — request interactive authorization
  • Settle (TAIP-4) — announce blockchain settlement
  • Reject (TAIP-4) — reject a transaction
  • Cancel (TAIP-4) — cancel a transaction
  • Revert (TAIP-4) — request reversal of settled transaction
  • Capture (TAIP-17) — release locked funds

Agent management messages modify transaction participants:

  • UpdateAgent (TAIP-5) — update agent information
  • UpdateParty (TAIP-6) — update party information
  • AddAgents (TAIP-5) — add new agents
  • ReplaceAgent (TAIP-5) — replace an existing agent
  • RemoveAgent (TAIP-5) — remove an agent

Relationship messages manage agent connections:

  • ConfirmRelationship (TAIP-9) — confirm a relationship between parties
  • UpdatePolicies (TAIP-7) — update agent policies
  • Connect (TAIP-15) — establish agent connection with constraints

Usage

Create a message with a constructor:

msg, err := tap.NewTransferMessage(
    "did:web:originator.vasp",
    []string{"did:web:beneficiary.vasp"},
    &tap.TransferBody{
        Asset:  "eip155:1/slip44:60",
        Amount: "1.23",
        Agents: []tap.Agent{{ID: "did:web:originator.vasp", For: tap.NewForField("did:eg:bob")}},
    },
)

Parse a received message:

body, err := tap.ParseBody(msg)
switch b := body.(type) {
case *tap.TransferBody:
    fmt.Printf("Transfer of %s %s\n", b.Amount, b.Asset)
case *tap.PaymentBody:
    fmt.Printf("Payment of %s\n", b.Amount)
}

Use the Client for end-to-end DIDComm + TAP parsing:

client := tap.NewClient(didcommClient)
result, err := client.Receive(ctx, envelope)
// result.Body is a typed TAPBody, result.Encrypted/Signed are set

Specifications

TAP is defined by the TAIPs (Transaction Authorization Improvement Proposals): https://tap.rsvp

All message bodies use the JSON-LD context "https://tap.rsvp/schema/1.0" and type URLs of the form "https://tap.rsvp/schema/1.0#MessageType".

Index

Constants

View Source
const (
	// TAPContext is the JSON-LD context for all TAP messages.
	TAPContext = "https://tap.rsvp/schema/1.0"

	// TypeAgent is the JSON-LD type for an Agent payload (TAIP-5). It is not a
	// message type; it is the body @type of a ConfirmRelationship message.
	TypeAgent = "https://tap.rsvp/schema/1.0#Agent"

	// Transaction message types
	TypeTransfer = "https://tap.rsvp/schema/1.0#Transfer"
	TypePayment  = "https://tap.rsvp/schema/1.0#Payment"
	TypeRFQ      = "https://tap.rsvp/schema/1.0#RFQ"
	TypeQuote    = "https://tap.rsvp/schema/1.0#Quote"
	TypeLock     = "https://tap.rsvp/schema/1.0#Lock"

	// Authorization flow message types
	TypeAuthorize             = "https://tap.rsvp/schema/1.0#Authorize"
	TypeAuthorizationRequired = "https://tap.rsvp/schema/1.0#AuthorizationRequired"
	TypeSettle                = "https://tap.rsvp/schema/1.0#Settle"
	TypeReject                = "https://tap.rsvp/schema/1.0#Reject"
	TypeCancel                = "https://tap.rsvp/schema/1.0#Cancel"
	TypeRevert                = "https://tap.rsvp/schema/1.0#Revert"
	TypeCapture               = "https://tap.rsvp/schema/1.0#Capture"

	// Agent management message types
	TypeUpdateAgent  = "https://tap.rsvp/schema/1.0#UpdateAgent"
	TypeUpdateParty  = "https://tap.rsvp/schema/1.0#UpdateParty"
	TypeAddAgents    = "https://tap.rsvp/schema/1.0#AddAgents"
	TypeReplaceAgent = "https://tap.rsvp/schema/1.0#ReplaceAgent"
	TypeRemoveAgent  = "https://tap.rsvp/schema/1.0#RemoveAgent"

	// Relationship message types
	TypeConfirmRelationship = "https://tap.rsvp/schema/1.0#ConfirmRelationship"
	TypeUpdatePolicies      = "https://tap.rsvp/schema/1.0#UpdatePolicies"
	TypeConnect             = "https://tap.rsvp/schema/1.0#Connect"
)

Variables

View Source
var (
	// ErrInvalidBody is returned when a message body is missing required fields or malformed.
	ErrInvalidBody = errors.New("tap: invalid body")

	// ErrUnknownMessageType is returned when a message type is not recognized as a TAP type.
	ErrUnknownMessageType = errors.New("tap: unknown message type")
)

Functions

func AllTypes

func AllTypes() []string

AllTypes returns all known TAP message types.

func IsTAPMessage

func IsTAPMessage(msg *didcomm.Message) bool

IsTAPMessage returns true if the DIDComm message type is a known TAP type.

func NewAddAgentsMessage

func NewAddAgentsMessage(from string, to []string, thid string, body *AddAgentsBody) (*didcomm.Message, error)

NewAddAgentsMessage creates a new DIDComm message with an AddAgents body.

func NewAuthorizationRequiredMessage

func NewAuthorizationRequiredMessage(from string, to []string, thid string, body *AuthorizationRequiredBody) (*didcomm.Message, error)

NewAuthorizationRequiredMessage creates a new DIDComm message with an AuthorizationRequired body.

func NewAuthorizeMessage

func NewAuthorizeMessage(from string, to []string, thid string, body *AuthorizeBody) (*didcomm.Message, error)

NewAuthorizeMessage creates a new DIDComm message with an Authorize body.

func NewCancelMessage

func NewCancelMessage(from string, to []string, thid string, body *CancelBody) (*didcomm.Message, error)

NewCancelMessage creates a new DIDComm message with a Cancel body.

func NewCaptureMessage

func NewCaptureMessage(from string, to []string, thid string, body *CaptureBody) (*didcomm.Message, error)

NewCaptureMessage creates a new DIDComm message with a Capture body.

func NewConfirmRelationshipMessage

func NewConfirmRelationshipMessage(from string, to []string, thid string, body *ConfirmRelationshipBody) (*didcomm.Message, error)

NewConfirmRelationshipMessage creates a new DIDComm message with a ConfirmRelationship body.

func NewConnectMessage

func NewConnectMessage(from string, to []string, body *ConnectBody) (*didcomm.Message, error)

NewConnectMessage creates a new DIDComm message with a Connect body.

func NewLockMessage added in v0.3.0

func NewLockMessage(from string, to []string, body *LockBody) (*didcomm.Message, error)

NewLockMessage creates a new DIDComm message with a Lock body.

func NewPaymentMessage

func NewPaymentMessage(from string, to []string, body *PaymentBody) (*didcomm.Message, error)

NewPaymentMessage creates a new DIDComm message with a Payment body.

func NewQuoteMessage

func NewQuoteMessage(from string, to []string, thid string, body *QuoteBody) (*didcomm.Message, error)

NewQuoteMessage creates a new DIDComm message with a Quote body.

func NewRFQMessage added in v0.3.0

func NewRFQMessage(from string, to []string, body *RFQBody) (*didcomm.Message, error)

NewRFQMessage creates a new DIDComm message with an RFQ body.

func NewRejectMessage

func NewRejectMessage(from string, to []string, thid string, body *RejectBody) (*didcomm.Message, error)

NewRejectMessage creates a new DIDComm message with a Reject body.

func NewRemoveAgentMessage

func NewRemoveAgentMessage(from string, to []string, thid string, body *RemoveAgentBody) (*didcomm.Message, error)

NewRemoveAgentMessage creates a new DIDComm message with a RemoveAgent body.

func NewReplaceAgentMessage

func NewReplaceAgentMessage(from string, to []string, thid string, body *ReplaceAgentBody) (*didcomm.Message, error)

NewReplaceAgentMessage creates a new DIDComm message with a ReplaceAgent body.

func NewRevertMessage

func NewRevertMessage(from string, to []string, thid string, body *RevertBody) (*didcomm.Message, error)

NewRevertMessage creates a new DIDComm message with a Revert body.

func NewSettleMessage

func NewSettleMessage(from string, to []string, thid string, body *SettleBody) (*didcomm.Message, error)

NewSettleMessage creates a new DIDComm message with a Settle body.

func NewTransferMessage

func NewTransferMessage(from string, to []string, body *TransferBody) (*didcomm.Message, error)

NewTransferMessage creates a new DIDComm message with a Transfer body.

func NewUpdateAgentMessage

func NewUpdateAgentMessage(from string, to []string, thid string, body *UpdateAgentBody) (*didcomm.Message, error)

NewUpdateAgentMessage creates a new DIDComm message with an UpdateAgent body.

func NewUpdatePartyMessage

func NewUpdatePartyMessage(from string, to []string, thid string, body *UpdatePartyBody) (*didcomm.Message, error)

NewUpdatePartyMessage creates a new DIDComm message with an UpdateParty body.

func NewUpdatePoliciesMessage

func NewUpdatePoliciesMessage(from string, to []string, thid string, body *UpdatePoliciesBody) (*didcomm.Message, error)

NewUpdatePoliciesMessage creates a new DIDComm message with an UpdatePolicies body.

Types

type AddAgentsBody

type AddAgentsBody struct {
	Context string  `json:"@context"`
	Type    string  `json:"@type"`
	Agents  []Agent `json:"agents"`
}

AddAgentsBody represents the body of a TAP AddAgents message (TAIP-5).

func (*AddAgentsBody) TAPType

func (b *AddAgentsBody) TAPType() string

type Agent

type Agent struct {
	ID          string   `json:"@id"`
	Type        string   `json:"@type,omitempty"`
	Role        string   `json:"role,omitempty"`
	For         ForField `json:"for,omitempty"`
	Name        string   `json:"name,omitempty"`
	NameHash    string   `json:"nameHash,omitempty"`
	LEICode     string   `json:"lei:leiCode,omitempty"`
	Policies    []Policy `json:"policies,omitempty"`
	URL         string   `json:"url,omitempty"`
	Description string   `json:"description,omitempty"`
	Email       string   `json:"email,omitempty"`
	Telephone   string   `json:"telephone,omitempty"`
	ServiceURL  string   `json:"serviceUrl,omitempty"`
}

Agent represents software acting on behalf of a participant.

type AuthorizationRequiredBody

type AuthorizationRequiredBody struct {
	Context          string `json:"@context"`
	Type             string `json:"@type"`
	AuthorizationURL string `json:"authorizationUrl"`
	Expires          string `json:"expires"`
	From             string `json:"from,omitempty"`
}

AuthorizationRequiredBody represents the body of a TAP AuthorizationRequired message (TAIP-4).

func (*AuthorizationRequiredBody) TAPType

func (b *AuthorizationRequiredBody) TAPType() string

type AuthorizeBody

type AuthorizeBody struct {
	Context           string `json:"@context"`
	Type              string `json:"@type"`
	SettlementAddress string `json:"settlementAddress,omitempty"`
	SettlementAsset   string `json:"settlementAsset,omitempty"`
	Amount            string `json:"amount,omitempty"`
	Expiry            string `json:"expiry,omitempty"`
}

AuthorizeBody represents the body of a TAP Authorize message (TAIP-4).

func (*AuthorizeBody) TAPType

func (b *AuthorizeBody) TAPType() string

type CancelBody

type CancelBody struct {
	Context string `json:"@context"`
	Type    string `json:"@type"`
	By      string `json:"by"`
	Reason  string `json:"reason,omitempty"`
}

CancelBody represents the body of a TAP Cancel message (TAIP-4).

func (*CancelBody) TAPType

func (b *CancelBody) TAPType() string

type CaptureBody

type CaptureBody struct {
	Context           string `json:"@context"`
	Type              string `json:"@type"`
	Amount            string `json:"amount,omitempty"`
	SettlementAddress string `json:"settlementAddress,omitempty"`
}

CaptureBody represents the body of a TAP Capture message (TAIP-17).

func (*CaptureBody) TAPType

func (b *CaptureBody) TAPType() string

type Client

type Client struct {
	DIDComm *didcomm.Client
}

Client wraps a didcomm.Client and adds TAP-specific typed message parsing.

func NewClient

func NewClient(dc *didcomm.Client) *Client

NewClient creates a new TAP client wrapping the given DIDComm client.

func (*Client) Receive

func (c *Client) Receive(ctx context.Context, envelope []byte) (*TAPResult, error)

Receive unpacks a DIDComm envelope and parses the TAP body into a typed struct.

type ConfirmRelationshipBody

type ConfirmRelationshipBody struct {
	Context string   `json:"@context"`
	Type    string   `json:"@type"`
	ID      string   `json:"@id"` // the agent being confirmed
	For     ForField `json:"for"` // the entity it acts on behalf of
	Role    string   `json:"role,omitempty"`
}

ConfirmRelationshipBody is the body of a ConfirmRelationship message (TAIP-9): the Agent payload, asserting that @id acts for the entity in "for".

func (*ConfirmRelationshipBody) TAPType

func (b *ConfirmRelationshipBody) TAPType() string

type ConnectBody

type ConnectBody struct {
	Context     string                  `json:"@context"`
	Type        string                  `json:"@type"`
	Requester   *Party                  `json:"requester"`
	Principal   *Party                  `json:"principal"`
	Agents      []Agent                 `json:"agents"`
	Constraints *TransactionConstraints `json:"constraints"`
	Agreement   string                  `json:"agreement,omitempty"`
	Expiry      string                  `json:"expiry,omitempty"`
}

ConnectBody represents the body of a TAP Connect message (TAIP-15).

func (*ConnectBody) TAPType

func (b *ConnectBody) TAPType() string

type DocumentReference

type DocumentReference struct {
	ID           string `json:"id"`
	DocumentType string `json:"documentType,omitempty"`
	URL          string `json:"url,omitempty"`
}

DocumentReference represents a reference to an additional document.

type ForField

type ForField struct {
	// contains filtered or unexported fields
}

ForField represents the "for" field on an Agent, which can be a single DID string or an array of DID strings.

func NewForField

func NewForField(dids ...string) ForField

NewForField creates a ForField from one or more DID strings.

func (ForField) IsEmpty

func (f ForField) IsEmpty() bool

IsEmpty returns true if the ForField has no values.

func (ForField) MarshalJSON

func (f ForField) MarshalJSON() ([]byte, error)

MarshalJSON marshals the ForField as a string (single value) or array (multiple values).

func (ForField) String

func (f ForField) String() string

String returns the first DID or empty string.

func (*ForField) UnmarshalJSON

func (f *ForField) UnmarshalJSON(data []byte) error

UnmarshalJSON unmarshals the ForField from a string or array of strings.

func (ForField) Values

func (f ForField) Values() []string

Values returns the DID strings in the ForField.

type Invoice

type Invoice struct {
	ID                          string              `json:"id"`
	IssueDate                   string              `json:"issueDate"`
	CurrencyCode                string              `json:"currencyCode"`
	LineItems                   []LineItem          `json:"lineItems"`
	Total                       float64             `json:"total"`
	SubTotal                    *float64            `json:"subTotal,omitempty"`
	TaxTotal                    *TaxTotal           `json:"taxTotal,omitempty"`
	DueDate                     string              `json:"dueDate,omitempty"`
	Note                        string              `json:"note,omitempty"`
	PaymentTerms                string              `json:"paymentTerms,omitempty"`
	AccountingCost              string              `json:"accountingCost,omitempty"`
	OrderReference              *OrderReference     `json:"orderReference,omitempty"`
	AdditionalDocumentReference []DocumentReference `json:"additionalDocumentReference,omitempty"`
}

Invoice represents a structured invoice for payment information.

type Limits

type Limits struct {
	PerTransaction string `json:"per_transaction,omitempty"`
	PerDay         string `json:"per_day,omitempty"`
	PerWeek        string `json:"per_week,omitempty"`
	PerMonth       string `json:"per_month,omitempty"`
	PerYear        string `json:"per_year,omitempty"`
	Currency       string `json:"currency"`
}

Limits defines financial limits for transactions.

type LineItem

type LineItem struct {
	ID          string       `json:"id"`
	Description string       `json:"description"`
	Name        string       `json:"name,omitempty"`
	Image       string       `json:"image,omitempty"`
	URL         string       `json:"url,omitempty"`
	Quantity    float64      `json:"quantity"`
	UnitCode    string       `json:"unitCode,omitempty"`
	UnitPrice   float64      `json:"unitPrice"`
	LineTotal   float64      `json:"lineTotal"`
	TaxCategory *TaxCategory `json:"taxCategory,omitempty"`
}

LineItem represents an individual item in an invoice.

type LockBody added in v0.3.0

type LockBody struct {
	Context     string  `json:"@context"`
	Type        string  `json:"@type"`
	Asset       string  `json:"asset,omitempty"`
	Currency    string  `json:"currency,omitempty"`
	Amount      string  `json:"amount"`
	Originator  *Party  `json:"originator"`
	Beneficiary *Party  `json:"beneficiary"`
	Expiry      string  `json:"expiry"`
	Agents      []Agent `json:"agents"`
	Agreement   string  `json:"agreement,omitempty"`
}

LockBody represents the body of a TAP Lock message (TAIP-17).

func (*LockBody) TAPType added in v0.3.0

func (b *LockBody) TAPType() string

type OrderReference

type OrderReference struct {
	ID        string `json:"id"`
	IssueDate string `json:"issueDate,omitempty"`
}

OrderReference represents information about a related order.

type Party

type Party struct {
	ID          string           `json:"@id"`
	Type        string           `json:"@type,omitempty"`
	Name        string           `json:"name,omitempty"`
	NameHash    string           `json:"nameHash,omitempty"`
	LEICode     string           `json:"lei:leiCode,omitempty"`
	IVMS101     *json.RawMessage `json:"ivms101,omitempty"`
	MCC         string           `json:"mcc,omitempty"`
	Account     string           `json:"account,omitempty"`
	URL         string           `json:"url,omitempty"`
	Description string           `json:"description,omitempty"`
	Email       string           `json:"email,omitempty"`
	Telephone   string           `json:"telephone,omitempty"`
}

Party represents a real-world entity (legal or natural person) involved in a transaction.

type PaymentBody

type PaymentBody struct {
	Context                     string   `json:"@context"`
	Type                        string   `json:"@type"`
	Amount                      string   `json:"amount"`
	Asset                       string   `json:"asset,omitempty"`
	Currency                    string   `json:"currency,omitempty"`
	Merchant                    *Party   `json:"merchant"`
	Customer                    *Party   `json:"customer,omitempty"`
	Agents                      []Agent  `json:"agents"`
	SupportedAssets             []any    `json:"supportedAssets,omitempty"`
	FallbackSettlementAddresses []string `json:"fallbackSettlementAddresses,omitempty"`
	Expiry                      string   `json:"expiry,omitempty"`
	Invoice                     any      `json:"invoice,omitempty"`
	Policies                    []Policy `json:"policies,omitempty"`
}

PaymentBody represents the body of a TAP Payment message (TAIP-14).

func (*PaymentBody) TAPType

func (b *PaymentBody) TAPType() string

type Policy

type Policy struct {
	Type                   string   `json:"@type"`
	Context                any      `json:"@context,omitempty"`
	From                   string   `json:"from,omitempty"`
	FromAgent              string   `json:"fromAgent,omitempty"`
	FromRole               string   `json:"fromRole,omitempty"`
	AboutParty             string   `json:"aboutParty,omitempty"`
	Purpose                string   `json:"purpose,omitempty"`
	PresentationDefinition string   `json:"presentationDefinition,omitempty"`
	Nonce                  any      `json:"nonce,omitempty"`
	Codes                  []string `json:"codes,omitempty"`
}

Policy represents a policy enforced by an agent.

type QuoteBody

type QuoteBody struct {
	Context    string  `json:"@context"`
	Type       string  `json:"@type"`
	FromAsset  string  `json:"fromAsset"`
	ToAsset    string  `json:"toAsset"`
	FromAmount string  `json:"fromAmount"`
	ToAmount   string  `json:"toAmount"`
	Provider   *Party  `json:"provider"`
	Agents     []Agent `json:"agents"`
	ExpiresAt  string  `json:"expiresAt"`
}

QuoteBody represents the body of a TAP Quote message (TAIP-18).

func (*QuoteBody) TAPType

func (b *QuoteBody) TAPType() string

type RFQBody added in v0.3.0

type RFQBody struct {
	Context    string   `json:"@context"`
	Type       string   `json:"@type"`
	FromAssets []string `json:"fromAssets"`
	ToAssets   []string `json:"toAssets"`
	FromAmount string   `json:"fromAmount,omitempty"`
	ToAmount   string   `json:"toAmount,omitempty"`
	Requester  *Party   `json:"requester"`
	Provider   *Party   `json:"provider,omitempty"`
	Agents     []Agent  `json:"agents"`
	Policies   []Policy `json:"policies,omitempty"`
}

RFQBody represents the body of a TAP RFQ (Request for Quote) message (TAIP-18).

func (*RFQBody) TAPType added in v0.3.0

func (b *RFQBody) TAPType() string

type RejectBody

type RejectBody struct {
	Context string `json:"@context"`
	Type    string `json:"@type"`
	Reason  string `json:"reason,omitempty"`
}

RejectBody represents the body of a TAP Reject message (TAIP-4).

func (*RejectBody) TAPType

func (b *RejectBody) TAPType() string

type RemoveAgentBody

type RemoveAgentBody struct {
	Context string `json:"@context"`
	Type    string `json:"@type"`
	Agent   string `json:"agent"`
}

RemoveAgentBody represents the body of a TAP RemoveAgent message (TAIP-5).

func (*RemoveAgentBody) TAPType

func (b *RemoveAgentBody) TAPType() string

type ReplaceAgentBody

type ReplaceAgentBody struct {
	Context     string `json:"@context"`
	Type        string `json:"@type"`
	Original    string `json:"original"`
	Replacement *Agent `json:"replacement"`
}

ReplaceAgentBody represents the body of a TAP ReplaceAgent message (TAIP-5).

func (*ReplaceAgentBody) TAPType

func (b *ReplaceAgentBody) TAPType() string

type RevertBody

type RevertBody struct {
	Context           string `json:"@context"`
	Type              string `json:"@type"`
	SettlementAddress string `json:"settlementAddress"`
	Reason            string `json:"reason"`
}

RevertBody represents the body of a TAP Revert message (TAIP-4).

func (*RevertBody) TAPType

func (b *RevertBody) TAPType() string

type SettleBody

type SettleBody struct {
	Context           string `json:"@context"`
	Type              string `json:"@type"`
	SettlementAddress string `json:"settlementAddress"`
	SettlementID      string `json:"settlementId,omitempty"`
	Amount            string `json:"amount,omitempty"`
}

SettleBody represents the body of a TAP Settle message (TAIP-4).

func (*SettleBody) TAPType

func (b *SettleBody) TAPType() string

type SupportedAssetPricing

type SupportedAssetPricing struct {
	Asset   string `json:"asset"`
	Amount  string `json:"amount"`
	Expires string `json:"expires,omitempty"`
}

SupportedAssetPricing represents an asset with pricing information for payments.

type TAPBody

type TAPBody interface {
	TAPType() string
}

TAPBody is the interface implemented by all TAP message body types.

func ParseBody

func ParseBody(msg *didcomm.Message) (TAPBody, error)

ParseBody unmarshals a DIDComm message body into the appropriate typed TAP body struct based on the message type.

type TAPResult

type TAPResult struct {
	Message *didcomm.Message
	Body    TAPBody

	// DIDComm envelope metadata
	Encrypted bool
	Signed    bool
	Anonymous bool
}

TAPResult contains a typed TAP message after unpacking and parsing.

type TaxCategory

type TaxCategory struct {
	ID        string  `json:"id"`
	Percent   float64 `json:"percent"`
	TaxScheme string  `json:"taxScheme"`
}

TaxCategory represents tax information for a line item.

type TaxSubtotal

type TaxSubtotal struct {
	TaxableAmount float64     `json:"taxableAmount"`
	TaxAmount     float64     `json:"taxAmount"`
	TaxCategory   TaxCategory `json:"taxCategory"`
}

TaxSubtotal represents a tax breakdown by category.

type TaxTotal

type TaxTotal struct {
	TaxAmount   float64       `json:"taxAmount"`
	TaxSubtotal []TaxSubtotal `json:"taxSubtotal,omitempty"`
}

TaxTotal represents aggregate tax information for an invoice.

type TransactionConstraints

type TransactionConstraints struct {
	Purposes                   []string `json:"purposes,omitempty"`
	CategoryPurposes           []string `json:"categoryPurposes,omitempty"`
	Limits                     *Limits  `json:"limits,omitempty"`
	AllowedBeneficiaries       []Party  `json:"allowedBeneficiaries,omitempty"`
	AllowedSettlementAddresses []string `json:"allowedSettlementAddresses,omitempty"`
	AllowedAssets              []string `json:"allowedAssets,omitempty"`
}

TransactionConstraints defines boundaries for transactions in a connection.

type TransactionValue added in v0.3.0

type TransactionValue struct {
	// Amount is the decimal string representation of the fiat amount.
	Amount string `json:"amount"`
	// Currency is the ISO 4217 3-letter currency code (e.g. "USD", "EUR").
	Currency string `json:"currency"`
}

TransactionValue represents the fiat equivalent value of a transfer for compliance purposes such as Travel Rule threshold determination (TAIP-3).

type TransferBody

type TransferBody struct {
	Context          string            `json:"@context"`
	Type             string            `json:"@type"`
	Asset            string            `json:"asset"`
	Amount           string            `json:"amount,omitempty"`
	Originator       *Party            `json:"originator,omitempty"`
	Beneficiary      *Party            `json:"beneficiary,omitempty"`
	Agents           []Agent           `json:"agents"`
	SettlementID     string            `json:"settlementId,omitempty"`
	Memo             string            `json:"memo,omitempty"`
	Expiry           string            `json:"expiry,omitempty"`
	TransactionValue *TransactionValue `json:"transactionValue,omitempty"`
}

TransferBody represents the body of a TAP Transfer message (TAIP-3).

func (*TransferBody) TAPType

func (b *TransferBody) TAPType() string

type UpdateAgentBody

type UpdateAgentBody struct {
	Context     string `json:"@context"`
	Type        string `json:"@type"`
	Agent       *Agent `json:"agent"`
	PreviousDID string `json:"previousDid,omitempty"`
	Reason      string `json:"reason,omitempty"`
	Effective   string `json:"effective,omitempty"`
}

UpdateAgentBody represents the body of a TAP UpdateAgent message (TAIP-5).

func (*UpdateAgentBody) TAPType

func (b *UpdateAgentBody) TAPType() string

type UpdatePartyBody

type UpdatePartyBody struct {
	Context       string `json:"@context"`
	Type          string `json:"@type"`
	Party         *Party `json:"party"`
	Role          string `json:"role"`
	PreviousParty *Party `json:"previousParty,omitempty"`
	Reason        string `json:"reason,omitempty"`
	Effective     string `json:"effective,omitempty"`
}

UpdatePartyBody represents the body of a TAP UpdateParty message (TAIP-6).

func (*UpdatePartyBody) TAPType

func (b *UpdatePartyBody) TAPType() string

type UpdatePoliciesBody

type UpdatePoliciesBody struct {
	Context  string   `json:"@context"`
	Type     string   `json:"@type"`
	Policies []Policy `json:"policies"`
}

UpdatePoliciesBody represents the body of a TAP UpdatePolicies message (TAIP-7).

func (*UpdatePoliciesBody) TAPType

func (b *UpdatePoliciesBody) TAPType() string

Directories

Path Synopsis
cmd
tap command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL