agent

package module
v0.5.2 Latest Latest
Warning

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

Go to latest
Published: Sep 25, 2024 License: Apache-2.0 Imports: 25 Imported by: 15

README

Go Agent for the Internet Computer

Go Version GoDoc Reference

go get github.com/aviate-labs/agent-go

Getting Started

The agent is a library that allows you to talk to the Internet Computer.

package main

import (
	"github.com/aviate-labs/agent-go"
	"github.com/aviate-labs/agent-go/ic"
	"log"
)

type (
	Account struct {
		Account string `ic:"account"`
	}

	Balance struct {
		E8S uint64 `ic:"e8s"`
	}
)

func main() {
	a, _ := agent.New(agent.DefaultConfig)

	var balance Balance
	if err := a.Query(
		ic.LEDGER_PRINCIPAL, "account_balance_dfx",
		[]any{Account{"9523dc824aa062dcd9c91b98f4594ff9c6af661ac96747daef2090b7fe87037d"}},
		[]any{&balance},
	); err != nil {
		log.Fatal(err)
	}

	_ = balance // Balance{E8S: 0}
}

Using an Identity

Supported identities are Ed25519 and Secp256k1. By default, the agent uses the anonymous identity.

id, _ := identity.NewEd25519Identity(publicKey, privateKey)
config := agent.Config{
    Identity: id,
}
Using the Local Replica

If you are running a local replica, you can use the FetchRootKey option to fetch the root key from the replica.

u, _ := url.Parse("http://localhost:8000")
config := agent.Config{
    ClientConfig: &agent.ClientConfig{Host: u},
    FetchRootKey: true,
    DisableSignedQueryVerification: true,
}

Packages

You can find the documentation for each package in the links below. Examples can be found throughout the documentation.

Package Name Links Description
agent README DOC A library to talk directly to the Replica.
candid DOC A Candid library for Golang.
certification DOC A Certification library for Golang.
gen DOC A library to generate Golang clients.
ic DOC Multiple auto-generated sub-modules to talk to the Internet Computer services
identity DOC A library that creates/manages identities.
pocketic DOC A client library to talk to the PocketIC Server.
principal DOC Generic Identifiers for the Internet Computer
registry DOC A client to interact with the registry canister.

More dependencies in the go.mod file.

CLI

go install github.com/aviate-labs/agent-go/cmd/goic@latest

Read more here

Testing

This repository contains two types of tests: standard Go tests and PocketIC -dependent tests. The test suite runs a local PocketIC server using the installed pocket-ic-server to execute some end-to-end (e2e) tests. If pocket-ic-server is not installed, those specific tests will be skipped.

go test -v ./...

Reference Implementations

Documentation

Overview

Example (Anonymous_query)
a, _ := agent.New(agent.DefaultConfig)
type Account struct {
	Account string `ic:"account"`
}
var balance struct {
	E8S uint64 `ic:"e8s"`
}
_ = a.Query(ic.LEDGER_PRINCIPAL, "account_balance_dfx", []any{
	Account{"9523dc824aa062dcd9c91b98f4594ff9c6af661ac96747daef2090b7fe87037d"},
}, []any{&balance})
fmt.Println(balance.E8S)
Output:

0
Example (Json)
raw := `{"e8s":1}`
var balance struct {
	// Tags can be combined with json tags.
	E8S uint64 `ic:"e8s" json:"e8s"`
}
_ = json.Unmarshal([]byte(raw), &balance)
fmt.Println(balance.E8S)

a, _ := agent.New(agent.DefaultConfig)
if err := a.Query(ic.LEDGER_PRINCIPAL, "account_balance_dfx", []any{struct {
	Account string `json:"account"`
}{
	Account: "9523dc824aa062dcd9c91b98f4594ff9c6af661ac96747daef2090b7fe87037d",
}}, []any{&balance}); err != nil {
	fmt.Println(err)
}
rawJSON, _ := json.Marshal(balance)
fmt.Println(string(rawJSON))
Output:

1
{"e8s":0}
Example (Query_ed25519)
id, _ := identity.NewRandomEd25519Identity()
ledgerID, _ := principal.Decode("ryjl3-tyaaa-aaaaa-aaaba-cai")
a, _ := agent.New(agent.Config{Identity: id})
var balance struct {
	E8S uint64 `ic:"e8s"`
}
_ = a.Query(ledgerID, "account_balance_dfx", []any{map[string]any{
	"account": "9523dc824aa062dcd9c91b98f4594ff9c6af661ac96747daef2090b7fe87037d",
}}, []any{&balance})
fmt.Println(balance.E8S)
Output:

0
Example (Query_prime256v1)
id, _ := identity.NewRandomPrime256v1Identity()
ledgerID, _ := principal.Decode("ryjl3-tyaaa-aaaaa-aaaba-cai")
a, _ := agent.New(agent.Config{Identity: id})
var balance struct {
	E8S uint64 `ic:"e8s"`
}
_ = a.Query(ledgerID, "account_balance_dfx", []any{map[string]any{
	"account": "9523dc824aa062dcd9c91b98f4594ff9c6af661ac96747daef2090b7fe87037d",
}}, []any{&balance})
fmt.Println(balance.E8S)
Output:

0
Example (Query_secp256k1)
id, _ := identity.NewRandomSecp256k1Identity()
ledgerID, _ := principal.Decode("ryjl3-tyaaa-aaaaa-aaaba-cai")
a, _ := agent.New(agent.Config{Identity: id})
var balance struct {
	E8S uint64 `ic:"e8s"`
}
_ = a.Query(ledgerID, "account_balance_dfx", []any{map[string]any{
	"account": "9523dc824aa062dcd9c91b98f4594ff9c6af661ac96747daef2090b7fe87037d",
}}, []any{&balance})
fmt.Println(balance.E8S)
Output:

0

Index

Examples

Constants

This section is empty.

Variables

View Source
var DefaultConfig = Config{}

DefaultConfig is the default configuration for an Agent.

Functions

This section is empty.

Types

type APIRequest added in v0.5.0

type APIRequest[In, Out any] struct {
	// contains filtered or unexported fields
}

func (APIRequest[_, _]) Call added in v0.5.0

func (c APIRequest[_, _]) Call() error

Call calls a method on a canister, it does not wait for the result.

func (APIRequest[_, Out]) CallAndWait added in v0.5.0

func (c APIRequest[_, Out]) CallAndWait(out Out) error

CallAndWait calls a method on a canister and waits for the result.

func (APIRequest[In, Out]) Query added in v0.5.0

func (q APIRequest[In, Out]) Query(out Out, skipVerification bool) error

Query calls a method on a canister and unmarshals the result into the given values.

func (APIRequest[_, Out]) Wait added in v0.5.0

func (c APIRequest[_, Out]) Wait(out Out) error

Wait waits for the result of the Call and unmarshals it into the given values.

func (*APIRequest[In, Out]) WithEffectiveCanisterID added in v0.5.0

func (c *APIRequest[In, Out]) WithEffectiveCanisterID(canisterID principal.Principal) *APIRequest[In, Out]

WithEffectiveCanisterID sets the effective canister ID for the Call.

type Agent

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

Agent is a client for the Internet Computer.

func New

func New(cfg Config) (*Agent, error)

New returns a new Agent based on the given configuration.

func (Agent) Call

func (a Agent) Call(canisterID principal.Principal, methodName string, in []any, out []any) error

Call calls a method on a canister and unmarshals the result into the given values.

func (Agent) CallProto added in v0.4.5

func (a Agent) CallProto(canisterID principal.Principal, methodName string, in, out proto.Message) error

CallProto calls a method on a canister and unmarshals the result into the given proto message.

func (Agent) Client added in v0.4.4

func (a Agent) Client() *Client

Client returns the underlying Client of the Agent.

func (*Agent) CreateCandidAPIRequest added in v0.5.0

func (a *Agent) CreateCandidAPIRequest(typ RequestType, canisterID principal.Principal, methodName string, args ...any) (*CandidAPIRequest, error)

CreateCandidAPIRequest creates a new api request to the given canister and method.

func (*Agent) CreateProtoAPIRequest added in v0.5.0

func (a *Agent) CreateProtoAPIRequest(typ RequestType, canisterID principal.Principal, methodName string, message proto.Message) (*ProtoAPIRequest, error)

CreateProtoAPIRequest creates a new api request to the given canister and method.

func (Agent) GetCanisterControllers

func (a Agent) GetCanisterControllers(canisterID principal.Principal) ([]principal.Principal, error)

GetCanisterControllers returns the list of principals that can control the given canister.

func (Agent) GetCanisterInfo

func (a Agent) GetCanisterInfo(canisterID principal.Principal, subPath string) ([]byte, error)

GetCanisterInfo returns the raw certificate for the given canister based on the given sub-path.

func (Agent) GetCanisterMetadata added in v0.3.1

func (a Agent) GetCanisterMetadata(canisterID principal.Principal, subPath string) ([]byte, error)

func (Agent) GetCanisterModuleHash

func (a Agent) GetCanisterModuleHash(canisterID principal.Principal) ([]byte, error)

GetCanisterModuleHash returns the module hash for the given canister.

func (Agent) GetRootKey added in v0.3.1

func (a Agent) GetRootKey() []byte

GetRootKey returns the root key of the host.

func (Agent) GetSubnetMetrics added in v0.5.0

func (a Agent) GetSubnetMetrics(subnetID principal.Principal) (*SubnetMetrics, error)

func (Agent) GetSubnets added in v0.5.0

func (a Agent) GetSubnets() ([]principal.Principal, error)

func (Agent) GetSubnetsInfo added in v0.5.0

func (a Agent) GetSubnetsInfo() ([]SubnetInfo, error)

func (Agent) Query

func (a Agent) Query(canisterID principal.Principal, methodName string, in, out []any) error

Query calls a method on a canister and unmarshals the result into the given values.

func (Agent) QueryProto added in v0.4.5

func (a Agent) QueryProto(canisterID principal.Principal, methodName string, in, out proto.Message) error

QueryProto calls a method on a canister and unmarshals the result into the given proto message.

func (Agent) ReadStateCertificate added in v0.4.4

func (a Agent) ReadStateCertificate(canisterID principal.Principal, path [][]hashtree.Label) (hashtree.Node, error)

ReadStateCertificate reads the certificate state of the given canister at the given path.

func (Agent) RequestStatus

func (a Agent) RequestStatus(ecID principal.Principal, requestID RequestID) ([]byte, hashtree.Node, error)

RequestStatus returns the status of the request with the given ID.

func (Agent) Sender

func (a Agent) Sender() principal.Principal

Sender returns the principal that is sending the requests.

type CandidAPIRequest added in v0.5.0

type CandidAPIRequest = APIRequest[[]any, []any]

type Client

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

Client is a client for the IC agent.

func NewClient

func NewClient(cfg ClientConfig) Client

NewClient creates a new client based on the given configuration.

func NewClientWithLogger added in v0.4.0

func NewClientWithLogger(cfg ClientConfig, logger Logger) Client

NewClientWithLogger creates a new client based on the given configuration and logger.

func (Client) Call added in v0.4.4

func (c Client) Call(ctx context.Context, canisterID principal.Principal, data []byte) ([]byte, error)

func (Client) Query added in v0.4.4

func (c Client) Query(ctx context.Context, canisterID principal.Principal, data []byte) ([]byte, error)

func (Client) ReadState added in v0.4.4

func (c Client) ReadState(ctx context.Context, canisterID principal.Principal, data []byte) ([]byte, error)

func (Client) ReadSubnetState added in v0.5.0

func (c Client) ReadSubnetState(ctx context.Context, subnetID principal.Principal, data []byte) ([]byte, error)

func (Client) Status

func (c Client) Status() (*Status, error)

Status returns the status of the IC.

Example
package main

import (
	"fmt"
	"net/url"

	"github.com/aviate-labs/agent-go"
)

var ic0URL, _ = url.Parse("https://ic0.app/")

func main() {
	c := agent.NewClient(agent.ClientConfig{Host: ic0URL})
	status, _ := c.Status()
	fmt.Println(status.Version)
}
Output:

0.18.0

type ClientConfig

type ClientConfig struct {
	Host *url.URL
}

ClientConfig is the configuration for a client.

type Config added in v0.2.0

type Config struct {
	// Identity is the identity used by the Agent.
	Identity identity.Identity
	// IngressExpiry is the duration for which an ingress message is valid.
	// The default is set to 5 minutes.
	IngressExpiry time.Duration
	// ClientConfig is the configuration for the underlying Client.
	ClientConfig *ClientConfig
	// FetchRootKey determines whether the root key should be fetched from the IC.
	FetchRootKey bool
	// Logger is the logger used by the Agent.
	Logger Logger
	// PollDelay is the delay between polling for a response.
	PollDelay time.Duration
	// PollTimeout is the timeout for polling for a response.
	PollTimeout time.Duration
	// DisableSignedQueryVerification disables the verification of signed queries.
	DisableSignedQueryVerification bool
}

Config is the configuration for an Agent.

type Envelope

type Envelope struct {
	Content      Request `cbor:"content,omitempty"`
	SenderPubKey []byte  `cbor:"sender_pubkey,omitempty"`
	SenderSig    []byte  `cbor:"sender_sig,omitempty"`
}

Envelope is a wrapper for a Request that includes the sender's public key and signature.

type Implementation

type Implementation struct {
	// Source is the canonical location of the source code.
	Source string
	// Version is the version number of the implementation.
	Version string
	// Revision is the precise git revision of the implementation.
	Revision string
}

Implementation identifies the implementation of the Internet Computer.

type Logger added in v0.4.0

type Logger interface {
	Printf(format string, v ...any)
}

type NodeInfo added in v0.5.0

type NodeInfo struct {
	NodeID    principal.Principal
	PublicKey []byte
}

type NoopLogger added in v0.4.3

type NoopLogger struct{}

func (NoopLogger) Printf added in v0.4.3

func (l NoopLogger) Printf(format string, v ...any)

type ProtoAPIRequest added in v0.5.0

type ProtoAPIRequest = APIRequest[proto.Message, proto.Message]

type Request

type Request struct {
	// The type of the request. This is used to distinguish between query, call and read_state requests.
	Type RequestType
	// The user who issued the request.
	Sender principal.Principal
	// Arbitrary user-provided data, typically randomly generated. This can be
	// used to create distinct requests with otherwise identical fields.
	Nonce []byte
	// An upper limit on the validity of the request, expressed in nanoseconds
	// since 1970-01-01 (like ic0.time()).
	IngressExpiry uint64
	// The principal of the canister to call.
	CanisterID principal.Principal
	// Name of the canister method to call.
	MethodName string
	// Argument to pass to the canister method.
	Arguments []byte
	// A list of paths, where a path is itself a sequence of blobs.
	Paths [][]hashtree.Label
}

Request is the request to the agent. DOCS: https://smartcontracts.org/docs/interface-spec/index.html#http-call

func (*Request) MarshalCBOR added in v0.2.0

func (r *Request) MarshalCBOR() ([]byte, error)

MarshalCBOR implements the CBOR marshaler interface.

type RequestID

type RequestID [32]byte

RequestID is the request ID.

func NewRequestID

func NewRequestID(req Request) RequestID

NewRequestID creates a new request ID. DOCS: https://smartcontracts.org/docs/interface-spec/index.html#request-id

func (RequestID) Sign

func (r RequestID) Sign(id identity.Identity) []byte

Sign signs the request ID with the given identity.

type RequestType

type RequestType = string

RequestType is the type of request.

const (
	// RequestTypeCall is a call request.
	RequestTypeCall RequestType = "call"
	// RequestTypeQuery is a query request.
	RequestTypeQuery RequestType = "query"
	// RequestTypeReadState is a read state request.
	RequestTypeReadState RequestType = "read_state"
)

type Response

type Response struct {
	Status     string              `cbor:"status"`
	Reply      cbor.RawMessage     `cbor:"reply"`
	RejectCode uint64              `cbor:"reject_code"`
	RejectMsg  string              `cbor:"reject_message"`
	ErrorCode  string              `cbor:"error_code"`
	Signatures []ResponseSignature `cbor:"signatures"`
}

Response is the response from the agent.

type ResponseSignature added in v0.5.0

type ResponseSignature struct {
	Timestamp int64               `cbor:"timestamp"`
	Signature []byte              `cbor:"signature"`
	Identity  principal.Principal `cbor:"identity"`
}

type Status

type Status struct {
	// Identifies the interface version supported.
	Version string
	// Impl describes the implementation of the Internet Computer.
	Impl *Implementation
	// The public key (a DER-encoded BLS key) of the root key of this Internet Computer instance.
	RootKey []byte
}

Status describes various status fields of the Internet Computer.

func (*Status) MarshalCBOR added in v0.3.0

func (s *Status) MarshalCBOR() ([]byte, error)

func (*Status) UnmarshalCBOR

func (s *Status) UnmarshalCBOR(data []byte) error

UnmarshalCBOR implements the CBOR unmarshaler interface.

type SubnetInfo added in v0.5.0

type SubnetInfo struct {
	SubnetID       principal.Principal
	PublicKey      []byte
	CanisterRanges certification.CanisterRanges
	Nodes          []NodeInfo
}

type SubnetMetrics added in v0.5.0

type SubnetMetrics struct {
	NumCanisters            uint64
	CanisterStateBytes      uint64
	ConsumedCyclesTotal     big.Int
	UpdateTransactionsTotal uint64
}

func (*SubnetMetrics) UnmarshalCBOR added in v0.5.0

func (m *SubnetMetrics) UnmarshalCBOR(bytes []byte) error

Directories

Path Synopsis
did
idl
bls
ii
clients
cmd
common
ic
Package ic provides a client for the "ic" canister.
Package ic provides a client for the "ic" canister.
assetstorage
Package assetstorage provides a client for the "assetstorage" canister.
Package assetstorage provides a client for the "assetstorage" canister.
cmc
Package cmc provides a client for the "cmc" canister.
Package cmc provides a client for the "cmc" canister.
governance
Package governance provides a client for the "governance" canister.
Package governance provides a client for the "governance" canister.
icparchive
Package icparchive provides a client for the "icparchive" canister.
Package icparchive provides a client for the "icparchive" canister.
icpledger
Package icpledger provides a client for the "icpledger" canister.
Package icpledger provides a client for the "icpledger" canister.
icrc1
Package icrc1 provides a client for the "icrc1" canister.
Package icrc1 provides a client for the "icrc1" canister.
registry
Package registry provides a client for the "registry" canister.
Package registry provides a client for the "registry" canister.
sns
Package sns provides a client for the "sns" canister.
Package sns provides a client for the "sns" canister.
sns/governance
Package governance provides a client for the "governance" canister.
Package governance provides a client for the "governance" canister.
sns/index
Package index provides a client for the "index" canister.
Package index provides a client for the "index" canister.
sns/ledger
Package ledger provides a client for the "ledger" canister.
Package ledger provides a client for the "ledger" canister.
sns/root
Package root provides a client for the "root" canister.
Package root provides a client for the "root" canister.
sns/swap
Package swap provides a client for the "swap" canister.
Package swap provides a client for the "swap" canister.
wallet
Package wallet provides a client for the "wallet" canister.
Package wallet provides a client for the "wallet" canister.

Jump to

Keyboard shortcuts

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