transactions

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Oct 24, 2025 License: Apache-2.0 Imports: 14 Imported by: 1

README

go-transactions

Go SDK for DIMO transactions

Generating ABI code

go install github.com/ethereum/go-ethereum/cmd/abigen@latest

Source is here where we have JSON definitions of the contracts: https://github.com/DIMO-Network/sacd/tree/main/abis/contracts/Sacd.sol https://github.com/DIMO-Network/dimo-identity/blob/main/abis/contracts/NFTs/VehicleId.sol/VehicleId.json

To generate the code run eg.: abigen --abi sacd.abi.json --pkg sacd --type Sacd --out sacd.go --v2

Vehicleid ABI: abigen --abi vehicleId.abi.json --pkg vehicleid --type Vehicleid --out vehicleid.go --v2

Limitations

  • Only small amount of DIMO protocol transactions is currently implemented
  • Requires already deployed AA wallet
  • Works only with entrypoint 0.7 and Kernel 0.3.1 accounts

Usage

Client creation
import (
    "github.com/DIMO-Network/go-transactions"
    "github.com/DIMO-Network/go-zerodev"
)

clientConfig := transactions.ClientConfig{
    AccountAddress:           <DEFAULT_SENDER_AA_WALLET_ADDRESS>,
    AccountPK:                <DEFAULT_SENDER_PK>,
    RpcURL:                   <RPC_URL>,
    PaymasterURL:             <PAYMASTER_URL>,
    BundlerURL:               <BUNDLER_URL>,
    ChainID:                  <CHAIN_ID>,
    RegistryAddress:          <DIMO_REGISTRY_CONTRACT_ADDRESS>,
    VehicleIdAddress:         <DIMO_VEHICLE_ID_CONTRACT_ADDRESS>,
    SyntheticDeviceIdAddress: <DIMO_SYNTHETIC_DEVICE_ID_CONTRACT_ADDRESS>,
}

client, err := transactions.NewClient(&clientConfig)
defer client.Close()
if err != nil {
    panic(err)
}
Wallet-based transactions

Those transactions are sent on behalf of the configured default AA wallet. Some of them require specific roles granted.

Minting a Vehicle ID
result, _, err := client.MintVehicleWithDD(<MINT_VEHIICLE_WITH_DD_INPUT>, false, false)
if err != nil {
    panic(err)
}

fmt.Println(hexutil.Encode(*result.UserOperationHash))
Minting a Vehicle ID with Synthetic Device
vehicleToMint := <VEHICLE_TO_MINT_INPUT>

// Get TypedData for signing by SD Wallet	
typedSd := client.GetMintVehicleAndSDTypedData(...)

// Sign with SD Wallet
sdSignature := <SD_SIGNATURE>

// Add to payload
vehicleToMint.SyntheticDeviceSig = sdSignature

// Get TypedData for signing by Vehicle owner	
typedV := client.GetMintVehicleWithDDTypedData(...)

// Sign with the owner
ownerSignature := <OWNER_SIGNATURE>

// Add to payload
vehicleToMint.VehicleOwnerSig = ownerSignature

// Mint the vehicle
result, _, err = client.MintVehicleAndSDWithDD(vehicleToMint, false, false)
if err != nil {
    panic(err)
}

fmt.Println(hexutil.Encode(*result.UserOperationHash))
Minting Vehicle IDs with Synthetic Devices in batches

TODO

Waiting for receipts

Transaction calls have option to wait for receipts. For all calls there's the second argument waitForReceipt bool which enables it.

With this option enabled the calls will return when the transaction is finished and confirmed. In returned UserOperationResult the Receipt field will be filled with all receipt data, which can be used to extract additional information from logs, etc.

result, _, err := client.MintVehicleWithDD(<MINT_VEHIICLE_WITH_DD_INPUT>, true, false)
if err != nil {
    panic(err)
}

fmt.Println("Operation Hash:", hexutil.Encode(*result.UserOperationHash))
fmt.Println("From:", hexutil.Encode(*result.Receipt.From.String()))
fmt.Println("To:", hexutil.Encode(*result.Receipt.To.String()))
fmt.Println("Logs count:", hexutil.Encode(*result.Receipt.Logs))
Getting results

Detailed results can be decoded from the receipt of the transaction.

The easiest way is to use the getResult bool argument, which is available for most of the calls. Decoded result is returned as the second return value.

opResult, mintResult, err := client.MintVehicleWithDD(<MINT_VEHIICLE_WITH_DD_INPUT>, true, true)
if err != nil {
    panic(err)
}

fmt.Println("Operation Hash:", hexutil.Encode(*op.UserOperationHash))
fmt.Println("Minted Vehicle TokenID:", mintResult.VehicleId)

When operations have to be divided into two steps (e.g. getting UserOperation and Hash, then sending it as a second call) there are methods to decode this from receipts:

// Get the UserOperation and its hash to sign
op, hash, err := client.GetBurnVehicleByOwnerUserOperationAndHash(ownerAAAddress, <Vehicle TokenID>)
if err != nil {
    panic(err)
}

// Get hash signature from the owner
signature := <USER_SIGNATURE>

// Add signature to UserOperation
op.Signature = signature

// Send updated UserOperation
result, _, err = client.SendSignedUserOperation(op, true, false)
if err != nil {
    panic(err)
}

fmt.Println(hexutil.Encode(*result.UserOperationHash))

burnResult, err := client.GetBurnVehicleByOwnerResult(result)
if err != nil {
    panic(err)
}

fmt.Println("Burned TokenID:", burnResult.VehicleNode)
User-based transactions

Those transactions are sent on behalf of the user (e.g. Vehicle owner). They have to be signed by the User's AA.

Burn Vehicle ID by owner
// Get the UserOperation and its hash to sign
op, hash, err := client.GetBurnVehicleByOwnerUserOperationAndHash(ownerAAAddress, <Vehicle TokenID>)
if err != nil {
    panic(err)
}

// Get hash signature from the owner
signature := <USER_SIGNATURE>

// Add signature to UserOperation
op.Signature = signature

// Send updated UserOperation
result, _, err = client.SendSignedUserOperation(op, false, false)
if err != nil {
    panic(err)
}


fmt.Println(hexutil.Encode(*result.UserOperationHash))
Burn Synthetic Device by owner
// Get the UserOperation and its hash to sign
op, hash, err := client.GetBurnSDByOwnerUserOperationAndHash(ownerAAAddress, <Synthetic Device TokenID>)
if err != nil {
    panic(err)
}

// Get hash signature from the owner
signature := <USER_SIGNATURE>

// Add signature to UserOperation
op.Signature = signature

// Send updated UserOperation
result, _, err = client.SendSignedUserOperation(op, false, false)
if err != nil {
    panic(err)
}


fmt.Println(hexutil.Encode(*result.UserOperationHash))

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BurnSDByOwnerResult added in v0.3.0

type BurnSDByOwnerResult struct {
	registry.RegistrySyntheticDeviceNodeBurned
}

type BurnVehicleByOwnerResult added in v0.3.0

type BurnVehicleByOwnerResult struct {
	registry.RegistryVehicleNodeBurned
}

type Client

type Client struct {
	RegistryAddress          common.Address
	VehicleIdAddress         common.Address
	SyntheticDeviceIdAddress common.Address
	Registry                 *registry.Registry
	SacdRegistry             *sacd.Sacd
	VehicleId                *vehicleid.Vehicleid
	SyntheticDeviceId        *sdid.Sdid
	ZerodevClient            *zerodev.Client
	Config                   ClientConfig
	SacdAddress              common.Address
	// ZerodevSigner is used in cases where eg. backend is doing the payload signing with an AA account. Used in Oracle where oracle owns the vehicles, so we sign mint payload
	ZerodevSigner *account.SmartAccountPrivateKeySigner
}

func NewClient

func NewClient(config *ClientConfig) (*Client, error)

func (*Client) Close

func (c *Client) Close()

func (*Client) GetBurnSDByOwnerResult added in v0.3.0

func (c *Client) GetBurnSDByOwnerResult(result *zerodev.UserOperationResult) (*BurnSDByOwnerResult, error)

func (*Client) GetBurnSDByOwnerUserOperationAndHash added in v0.3.0

func (c *Client) GetBurnSDByOwnerUserOperationAndHash(owner common.Address, syntheticDeviceTokenId *big.Int) (op *zerodev.UserOperation, hash *common.Hash, err error)

func (*Client) GetBurnSDTypedData added in v0.3.0

func (c *Client) GetBurnSDTypedData(vehicleNode *big.Int, syntheticDeviceNode *big.Int) *signer.TypedData

GetBurnSDTypedData generates TypedData for signing by Vehicle owner whenever SD is being burned

func (*Client) GetBurnVehicleByOwnerResult added in v0.3.0

func (c *Client) GetBurnVehicleByOwnerResult(result *zerodev.UserOperationResult) (*BurnVehicleByOwnerResult, error)

func (*Client) GetBurnVehicleByOwnerUserOperationAndHash

func (c *Client) GetBurnVehicleByOwnerUserOperationAndHash(owner common.Address, vehicleTokenId *big.Int) (op *zerodev.UserOperation, hash *common.Hash, err error)

func (*Client) GetMintSDResult added in v0.3.1

func (c *Client) GetMintSDResult(result *zerodev.UserOperationResult) (*MintSDResult, error)

func (*Client) GetMintSDTypedData added in v0.3.1

func (c *Client) GetMintSDTypedData(integrationNode *big.Int, vehicleNode *big.Int) *signer.TypedData

GetMintSDTypedData generates TypedData for signing by Vehicle owner whenever a Synthetic Device for this vehicle is minted

func (*Client) GetMintSDTypedDataV2 added in v0.3.4

func (c *Client) GetMintSDTypedDataV2(connectionID *big.Int, vehicleNode *big.Int) *signer.TypedData

GetMintSDTypedDataV2 generates TypedData for signing by Vehicle owner whenever a Synthetic Device for this vehicle is minted (V2 is using connectionId instead of integration node)

func (*Client) GetMintVehicleAndSDTypedData added in v0.3.0

func (c *Client) GetMintVehicleAndSDTypedData(integrationNode *big.Int) *signer.TypedData

GetMintVehicleAndSDTypedData generates TypedData for signing by Synthetic Device (SD) whenever Vehicle with SD is minted

func (*Client) GetMintVehicleAndSDTypedDataV2 added in v0.3.4

func (c *Client) GetMintVehicleAndSDTypedDataV2(connectionID *big.Int) *signer.TypedData

GetMintVehicleAndSDTypedDataV2 generates TypedData for signing by Synthetic Device (SD) whenever Vehicle with SD is minted (V2 is using connectionId instead of integration node)

func (*Client) GetMintVehicleAndSDWithDDResult added in v0.3.0

func (c *Client) GetMintVehicleAndSDWithDDResult(result *zerodev.UserOperationResult) (*MintVehicleAndSDWithDDResult, error)

func (*Client) GetMintVehicleWithDDResult added in v0.3.0

func (c *Client) GetMintVehicleWithDDResult(result *zerodev.UserOperationResult) (*MintVehicleWithDDResult, error)

func (*Client) GetMintVehicleWithDDTypedData added in v0.3.0

func (c *Client) GetMintVehicleWithDDTypedData(manufacturerNode *big.Int, owner common.Address, deviceDefinitionId string, attributeInfoPairs []registry.AttributeInfoPair) *signer.TypedData

GetMintVehicleWithDDTypedData generates TypedData for signing by Vehicle owner whenever Vehicle with Device Definition is minted

func (*Client) GetReceipt added in v0.3.0

func (c *Client) GetReceipt(result *zerodev.UserOperationResult) (receipt *zerodev.UserOperationReceipt, err error)

func (*Client) GetSafeTransferFromResult added in v0.3.8

func (c *Client) GetSafeTransferFromResult(result *zerodev.UserOperationResult) (*SafeTransferFromResult, error)

GetSafeTransferFromResult used to interpret the result after submitting the transaction for SafeTransferFromUserOperationAndHash

func (*Client) GetSafeTransferFromUserOperationAndHash added in v0.3.8

func (c *Client) GetSafeTransferFromUserOperationAndHash(from common.Address, to common.Address, tokenId *big.Int) (op *zerodev.UserOperation, hash *common.Hash, err error)

GetSafeTransferFromUserOperationAndHash gets the data to be signed by the owner (from address) to transfer a vehicle tokenId to another address (to address)

func (*Client) MintSD added in v0.3.1

func (c *Client) MintSD(data *registry.MintSyntheticDeviceInput, waitForReceipt bool, getResult bool) (*zerodev.UserOperationResult, *MintSDResult, error)

func (*Client) MintVehicleAndSDWithDD added in v0.3.0

func (c *Client) MintVehicleAndSDWithDD(data *registry.MintVehicleAndSdWithDdInput, waitForReceipt bool, getResult bool) (*zerodev.UserOperationResult, *MintVehicleAndSDWithDDResult, error)

MintVehicleAndSDWithDD mints a vehicle and paired synthetic device using data with a device definition. No SACD input is required. Requires SD signature of typed data returned by GetMintVehicleAndSDTypedData Requires Vehicle Owner signature of typed data returned by GetMintVehicleWithDDTypedData

func (*Client) MintVehicleAndSDWithDDAndSACD added in v0.3.0

func (c *Client) MintVehicleAndSDWithDDAndSACD(data *registry.MintVehicleAndSdWithDdInput, sacdInput registry.SacdInput, waitForReceipt bool, getResult bool) (*zerodev.UserOperationResult, *MintVehicleAndSDWithDDResult, error)

MintVehicleAndSDWithDDAndSACD mints a vehicle and paired synthetic device using data with a device definition and separate SACD. Requires SD signature of typed data returned by GetMintVehicleAndSDTypedData Requires Vehicle Owner signature of typed data returned by GetMintVehicleWithDDTypedData

func (*Client) MintVehicleAndSDWithDDBatch added in v0.3.0

func (c *Client) MintVehicleAndSDWithDDBatch(data []registry.MintVehicleAndSdWithDdInputBatch, waitForReceipt bool, getResult bool) (*zerodev.UserOperationResult, error)

MintVehicleAndSDWithDDBatch mints vehicles and paired synthetic devices in batches using data with a device definition and SACD input. Requires SD signature of typed data returned by GetMintVehicleAndSDTypedData Requires Vehicle Owner signature of typed data returned by GetMintVehicleWithDDTypedData

func (*Client) MintVehicleWithDD added in v0.3.0

func (c *Client) MintVehicleWithDD(data *registry.MintVehicleWithDeviceDefinition, waitForReceipt bool, getResult bool) (*zerodev.UserOperationResult, *MintVehicleWithDDResult, error)

func (*Client) SendSignedUserOperation

func (c *Client) SendSignedUserOperation(op *zerodev.UserOperation, waitForReceipt bool) (result *zerodev.UserOperationResult, err error)

type ClientConfig

type ClientConfig struct {
	AccountAddress           common.Address
	AccountPK                *ecdsa.PrivateKey
	RpcURL                   *url.URL
	PaymasterURL             *url.URL
	BundlerURL               *url.URL
	ChainID                  *big.Int
	RegistryAddress          common.Address
	VehicleIdAddress         common.Address
	SyntheticDeviceIdAddress common.Address
	// contract address for sacd, eg in polygon prod: 0x3c152B5d96769661008Ff404224d6530FCAC766d
	SacdAddress                common.Address
	ReceiptPollingDelaySeconds int
	ReceiptPollingRetries      int
}

type MintSDResult added in v0.3.1

type MintSDResult struct {
	registry.RegistrySyntheticDeviceNodeMinted
}

type MintVehicleAndSDWithDDResult added in v0.3.0

type MintVehicleAndSDWithDDResult struct {
	registry.RegistryVehicleNodeMintedWithDeviceDefinition
	registry.RegistrySyntheticDeviceNodeMinted
}

type MintVehicleWithDDResult added in v0.3.0

type MintVehicleWithDDResult struct {
	registry.RegistryVehicleNodeMintedWithDeviceDefinition
}

type SafeTransferFromResult added in v0.3.8

type SafeTransferFromResult struct {
	vehicleid.VehicleidTransfer
}

SafeTransferFromResult used to represnet the vehicle transfer event when we call GetSafeTransferFromResult

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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